- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 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.
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 and I'm using Quartus. The next step would be retrieving this information and sending it to my PC. This is what I need help with. I've been looking and I found an alternative which is USB-to-UART connection. 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you want to retrieve the RTL count data in a .txt file, you can use PIO IP to pass the RTL count data to embedded system to be written in .txt file.
PIO IP reference link - https://www.macnica.co.jp/en/business/semiconductor/articles/intel/113961/
TXT file mounting video link - https://www.youtube.com/watch?v=kbIcXwtfBiY&t=414s
To mount the text file in embedded system (eclipse), will need to debug the software Debug As -> Nios II Hardware.
For USB-to-UART, you may refer to this video link https://www.youtube.com/watch?v=7xJ9dhVDCwU&t=271s and reference design https://www.intel.com/content/www/us/en/design-example/715139/cyclone-v-uart-rs-232-maximum-baud-rate-reference-design.html. For the USB part putty (HPS), may be you need to open a new thread in https://community.intel.com/t5/Intel-SoC-FPGA-Embedded/bd-p/soc-fpga-embedded-development-suite to get more details.
If want to send the count data at end of interval, may be can do something like below in RTL:
assign count = (timer == 32'd4999) ? count_reg : 32'b0;
Btw, I had create a design uart_putty.zip attached below for demonstration. The ./software/usbuart/output_end_interval.txt record the count data at end interval while the ./software/usbuart/output_whole_interval.txt record the count data for whole interval.
Let me know if you have any further update or concern.
Thanks,
Best Regards,
Sheng
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you want to retrieve the RTL count data in a .txt file, you can use PIO IP to pass the RTL count data to embedded system to be written in .txt file.
PIO IP reference link - https://www.macnica.co.jp/en/business/semiconductor/articles/intel/113961/
TXT file mounting video link - https://www.youtube.com/watch?v=kbIcXwtfBiY&t=414s
To mount the text file in embedded system (eclipse), will need to debug the software Debug As -> Nios II Hardware.
For USB-to-UART, you may refer to this video link https://www.youtube.com/watch?v=7xJ9dhVDCwU&t=271s and reference design https://www.intel.com/content/www/us/en/design-example/715139/cyclone-v-uart-rs-232-maximum-baud-rate-reference-design.html. For the USB part putty (HPS), may be you need to open a new thread in https://community.intel.com/t5/Intel-SoC-FPGA-Embedded/bd-p/soc-fpga-embedded-development-suite to get more details.
If want to send the count data at end of interval, may be can do something like below in RTL:
assign count = (timer == 32'd4999) ? count_reg : 32'b0;
Btw, I had create a design uart_putty.zip attached below for demonstration. The ./software/usbuart/output_end_interval.txt record the count data at end interval while the ./software/usbuart/output_whole_interval.txt record the count data for whole interval.
Let me know if you have any further update or concern.
Thanks,
Best Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Any further update or concern on this thread?
Thanks,
Best Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Thank's a lot for your help. I'm currently trying to understand the example design you provided. As I mentioned, I'm completely new to hardware programming in general (not only FPGA's), so It's being a little difficult to understand the design. I have also checked the resources you provided for context, but it's still challenging. If you can provide a general description of this it would be really helpful. Finally, would this design be ready for the FPGA programming? I'm sorry for the inconvenience.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Thank's a lot for your help. I'm currently trying to understand the example design you provided. As I mentioned, I'm completely new to hardware programming in general (not only FPGA's), so It's being a little difficult to understand the design. I have also checked the resources you provided for context, but it's still challenging. If you can provide a general description of this it would be really helpful. Finally, would this design be ready for the FPGA programming? I'm sorry for the inconvenience.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The 32-bits RTL count data obtained is passed to the embedded system through the PIO IP.
In <path>/uart_putty/software/uabuart/main.c:
FILE* - specify a file name.
fopen - open the .txt file
reg_bb[0] = *(volatile unsigned char *) PIO_3_BASE;
reg_bb[1] = *(volatile unsigned char *) PIO_2_BASE;
reg_bb[2] = *(volatile unsigned char *) PIO_1_BASE;
reg_bb[3] = *(volatile unsigned char *) PIO_0_BASE;
int combinedValue = (reg_bb[0] << 24) | (reg_bb[1] << 16) | (reg_bb[2] <<
Retrieve the PIO value (RTL count data) 8-bits each and then combine to 32-bits.
sprintf - convert the combined value to string
strcpy - copy the string to buffer
fputs - write the buffer value to the .txt file and fclose
PutUart1() and GetUart1() are for uart transmit and receive respectively. For the uart transmit to the putty (usb-to-uart), this probably will need help from another forum because will require some board configuration.
Yes, this design is ready for the FPGA programming. Have to program the .sof and .elf files. If you use other boards, try to regenerate all the things.
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page