1
\$\begingroup\$

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.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ Hello and welcome. How fast were the pulses you were counting from the simulator? If they are as fast or faster than the ones from the photon counter, it will be fine -- it doesn't care if they are evenly spaced or not. You also need some kind of time, as presumably you don't want "we saw 77 photons", you want "we saw 77 photons in 1 ms". If you need high timing accuracy consider a GPS unit with pulse-per-second output. \$\endgroup\$
    – jonathanjo
    Commented Oct 23, 2023 at 6:26
  • \$\begingroup\$ I would start with just a pulse counter, show the output via LED's or something like that. Keep it simple to prove that it works. If you've got that working, you can start thinking of going to counts per second. Another way of thinking, if you want to get counts per second, count the time between pulses instead of pulses per second. \$\endgroup\$ Commented Oct 23, 2023 at 6:39
  • \$\begingroup\$ @BasVisscher "count the time between pulses" is good if they are regular or very rare, but question says they are irregular, and separated by nanoseconds. "photons per experiment trigger" might be meaningful. \$\endgroup\$
    – jonathanjo
    Commented Oct 23, 2023 at 8:01
  • \$\begingroup\$ It completely depends on what he wants :) \$\endgroup\$ Commented Oct 23, 2023 at 8:31
  • \$\begingroup\$ @BasVisscher I get the idea. However, as I said, I'm new to this kind of stuff, so I'm a little confused about the design I need to follow. Using just a pulse counter would mean that I just need to have the verilog module, its input for the FPGA and an output? How can I see this output? \$\endgroup\$
    – Jorsa
    Commented Oct 23, 2023 at 20:35

0

Browse other questions tagged or ask your own question.