FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
5975 ディスカッション

Data retrieving using HPS in DE10-Nano

JorgeA
初心者
301件の閲覧回数

Hello,

 

I've been working on a project that consists in program a DE10-Nano to use it as a photon counter. The idea is to count TTL pulses fired by a photon detector. I previously asked here for help, because I'm completely new to hardware programming, but I couldn't make the help I got to work. I searched some more and I found a useful repo dedicated to the DE10-Nano. https://github.com/zangman/de10-nano In there, I was able to use a different approach, which uses the HPS (with an Embedded Linux System based on Debian) to control the FPGA. I ended up making progress using this, an I got the following design:

 

/// PHOTON COUNTER ///

wire photon_pulse;
reg photon_pulse_delay;
reg interval_done;	
reg [31:0] interval_timer;
reg [31:0] total_timer;
reg [63:0] count;
reg [63:0] final_count;

always @(posedge fpga_clk_50 or negedge hps_fpga_reset_n) begin
	 if (~hps_fpga_reset_n) begin
		  interval_timer <= 0;
		  total_timer <= 0;
		  count <= 0;
		  final_count <= 0;
		  interval_done <= 0;
		  photon_pulse_delay <= 0;
    end else begin
		  photon_pulse_delay <= photon_pulse;
		  if (photon_pulse && !photon_pulse_delay) begin
				count <= count + 1;
		  end
		  if (interval_timer == time_interval_export) begin
            interval_done <= 1;
				interval_timer <= 0;
				final_count <= count;
				count <= 0;
			   if (total_timer < total_time_interval_export) begin
				    total_timer <= total_timer + time_interval_export;
			  end
        end else begin
				interval_timer <= interval_timer + 1;
				interval_done <= 0;
		  end
    end
end

assign interval_counting_export = interval_done ? final_count : total_timer == total_time_interval_export ? 6969 : 0;
assign photon_pulse = PHOTON_PULSE_GPIO;

 


Since I'm more familiar with Programming Languages instead of HDL (or anything related to hardware), I found this useful because I can interact with the FPGA using a C code. The C code (provided by the repo) is this:

 

#include <error.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#define BRIDGE 0xC0000000
#define BRIDGE_SPAN 0x18

#define TIME_INTERVAL 0x00
#define TOTAL_TIME_INTERVAL 0x08
#define INTERVAL_COUNTING 0x10

int main(int argc, char **argv) {
  uint64_t time_interval = 0;
  uint64_t total_time_interval = 0;
  uint64_t interval_counting = 0;

  uint8_t *time_interval_map = NULL;
  uint8_t *total_time_interval_map = NULL;
  uint8_t *interval_counting_map = NULL;

  uint8_t *bridge_map = NULL;

  int fd = 0;
  int result = 0;

  if (argc != 3) {
    perror("Only 2 numbers should be passed.");
    return -1;
  }

  time_interval = strtoll(argv[1], NULL, 10); // time_interval in clock cycles (100 us @ 50 MHz = 5000 Clock Cycles)
  total_time_interval = strtoll(argv[2], NULL, 10); // total_time_interval in clock cycles (1 s @ 50 MHz = 50'000.000 Clock Cycles)


  fd = open("/dev/mem", O_RDWR | O_SYNC);

  if (fd < 0) {
    perror("Couldn't open /dev/mem\n");
    return -2;
  }

  bridge_map = (uint8_t *)mmap(NULL, BRIDGE_SPAN, PROT_READ | PROT_WRITE,
                               MAP_SHARED, fd, BRIDGE);

  if (bridge_map == MAP_FAILED) {
    perror("mmap failed.");
    close(fd);
    return -3;
  }

  time_interval_map = bridge_map + TIME_INTERVAL;
  total_time_interval_map = bridge_map + TOTAL_TIME_INTERVAL;
  interval_counting_map = bridge_map + INTERVAL_COUNTING;

  *((uint64_t *)time_interval_map) = time_interval;
  *((uint64_t *)total_time_interval_map) = total_time_interval;

  while (1) {
    
    interval_counting = *((uint64_t *)interval_counting_map);

    if (interval_counting != 0) {
      printf("%" PRIu64 "\n", interval_counting);
    }

    if (interval_counting == 6969) break;
  }

  result = munmap(bridge_map, BRIDGE_SPAN);

  if (result < 0) {
    perror("Couldnt unmap bridge.");
    close(fd);
    return -4;
  }

  close(fd);
  return 0;
}

 

I modified it so it matches my project. My main goal is to provide two parameters (time_interval and total_time_interval) and to obtain the counting data from each interval made by the FPGA, and in this case I do so by accessing the interva_counting (defined as an export in Platform Designer in Quartus). However I'm facing some issues: The first one, is that the counting is different from what is suppossed to be at certain intervals, giving the fact that I'm using a waveform generator of known frequency. The second error is that I'm not getting all the intervals I should be getting (total_time_interval_export/time_interval_export). I'm not sure what can be causing this errors, so I would really appreciate the help. Do I need a different approach?

Thanks a lot.

ラベル(2)
0 件の賞賛
5 返答(返信)
Jeet14
従業員
225件の閲覧回数

Hi,


Please allow sometime to go through this query.

Will get back to you soon.


Regards

Tiwari


Jeet14
従業員
183件の閲覧回数

Hi,


I assume you have already made changes to the device tree files i.e. all bridges should be enabled.


Since, you are referring this https://github.com/zangman/de10-nano?tab=readme-ov-file, I recommend you to post your query on the githib discussion. This page author might help you.


Regards

Tiwari




Jeet14
従業員
160件の閲覧回数

Hi,


Please do let me know if you have any other query on this?


Regards

Tiwari


JorgeA
初心者
150件の閲覧回数

Hi,

 

Yes, I already made changes to the device tree files. As I said before, I did some good advancements following the guide I refered. What I'm asking help about, is more about the C code and Verilog code synchronization to achieve my desired behaviour. With the C code, I'm looking up the counting variable I designated in the Verilog code, however, as I mentioned, this does not get me all the intervals I should be getting. Plus, if I'm using a Signal Generator of 10 MHz, this would mean at the end of every interval I should be getting counts of 1000 pulses, however, at certain intervals, I get different values (some around 1000. some not). Is there a better aproach for this?

JingyangTeh
従業員
94件の閲覧回数

Hi


It is best to post a question regarding the code shared by the repo as we are not expert in the code shared in the git repo.


Regards

Jingyang, Teh


返信