I'm currently working on a project in which I need to program an FPGA in order to connect it to a photon detector, that generates a TTL pulse when detecting a photon; I need to count this pulses, meaning, I need to count the photons being detected. The duration of each pulse according to the detector documentation is 20 ns.
I'm completely new to hardware programming, but I've been trying to keep up. So far, I was able to replicate a tutorial project (turning on a few leds and altering the cycle with two buttons) provided by the FPGA documentation in order to familiarize myself with some concepts. I also created some modules in Verilog to 'simulate' a square wave signal similar to the one I expect to have from the detector. I testbenched the code and using Questa (the integrated simulation tool in Quartus, the tool I'm using) it looks fine.
I jumpled right into the real design I need to create, and I have managed to create the PulseCounter module and its testbench. The functionality I want is to set intervals in the scale of microseconds and then count the pulses from the detector during that time, up until a total time is completed, so I'm using frames of 100 μs during 1 second. Based on a paper I have, the number of photons is between 0 and 14 (it follows a Poisson distribution with a mean of 3.6) for a 254 μs time frame. Right now the pulse signal in the testbench is running continously. The counting seems to be working fine (at least I saw the counting being restarted), but as I said, I'm a beginner at this so I'm not really sure.
This is the module PulseCounter.v:
module PulseCounter (
input wire clk,
input wire reset,
input wire photon_pulse,
output reg [31:0] count,
output reg interval_done
);
reg photon_pulse_dly; // Delayed version of photon_pulse
reg [31:0] timer;
reg [31:0] total_timer;
parameter INTERVAL = 5000; // 100 us = 0.0001 s @ 50MHz clock
parameter TOTAL_TIME = 50000000; // 1 s @ 50MHz clock
always @(posedge clk or posedge reset) begin
if (reset) begin
count <= 32'b0;
timer <= 32'b0;
total_timer <= 32'b0;
photon_pulse_dly <= 0;
interval_done <= 0;
end else begin
photon_pulse_dly <= photon_pulse;
if (photon_pulse && !photon_pulse_dly) begin // Rising edge detected
count <= count + 1;
end
if (timer == INTERVAL) begin
timer <= 32'b0;
interval_done <= 1;
if (total_timer != TOTAL_TIME) begin
total_timer <= total_timer + INTERVAL;
count <= 32'b0; // Reset count for next interval
end
end else begin
timer <= timer + 1;
interval_done <= 0;
end
end
end
endmodule
And this is the testbench PulseCounter_tb.v:
`timescale 1ns / 1ps
module PulseCounter_tb;
reg clk;
reg reset;
reg photon_pulse;
wire [31:0] count;
wire interval_done;
// Instantiate the PulseCounter module
PulseCounter uut (
.clk(clk),
.reset(reset),
.photon_pulse(photon_pulse),
.count(count),
.interval_done(interval_done)
);
initial begin
// Initialize inputs
clk = 0;
reset = 0;
photon_pulse = 0;
// Apply reset
reset = 1;
#10;
reset = 0;
end
initial begin
// Generate a certain number of pulses
repeat (5000) begin
#20; photon_pulse = 1; // Pulse starts
#20; photon_pulse = 0; // Pulse ends
end
// Stop the simulation after all pulses are generated
#10000;
$finish;
end
// Clock generator
always #10 clk = ~clk;
endmodule
The FPGA I'm using is a DE10-Nano from Terasic and as I mentioned I'm using Quartus. The next step (if anyone agrees that what I have is fine) would be retrieving this information and sending it to my PC. This is what I need help with. I don't know how to do this, and what would be the appropiate way to do it (whether the counting of each interval should be send altogether or at the end of the interval). I'm more familiar with high level programming languages, so the way I visualize it is to have a .txt with the counting for each interval, but then again, I'm lost here. I would appreciate a lot anyone's help.