Accessing BRAM data from /dev/mem of RedPitaya

Applications, development tools, FPGA, C, WEB
pavel
Posts: 799
Joined: Sat May 23, 2015 5:22 pm

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by pavel » Fri Jun 16, 2023 12:11 pm

I regularly use this command and I never had this kind of problem. So I do not know why it is not working for you.

adiana007
Posts: 21
Joined: Mon Jun 05, 2023 11:44 am

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by adiana007 » Fri Jun 16, 2023 2:24 pm

Hey Pavel,

After trying couple of approaches, when I tried clearing up the cache, I was able to install gcc, I have added to the SD card using the command

Code: Select all

lbu commit -d
As already told, I connected a binary counter as one of the inputs for validating the capture & storage mechanism. I'm currently trying to understand the PL blocks and C code. Is there a readme for the C snippets and other functional blocks such as input to be fed, control and status registers, inputs of gen.c etc.?.
Initially I'm skipping the streaming function and trying to write to a file (only for validating the data, not benchmarking the transfer performance, which I will be performing once functionality is validated) using the following method

Code: Select all

for (int iter = 0; iter < 256 * 1024; iter++)
          {
            fprintf(fptr, "%x\n", *(uint32_t *)(ram + offset + iter));
          }
Thanks in advance

adiana007
Posts: 21
Joined: Mon Jun 05, 2023 11:44 am

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by adiana007 » Mon Jun 26, 2023 3:19 pm

Hey Pavel,

Thanks for the resources, I was able to provide dummy inputs and run the code along with streaming desired number of samples to a local machine.

I'm currently building functionalities for a triggered data capture providing an external trigger signal through the GPIO pins of the RedPitaya. I went through the code base of AXI RAM Writer and understood the AXI signalling taking place and the address increments happening.

But I have some doubts on the way the data is stored into memory. Let's say I get the inputs 1,2,3,... till 65536 (16bit counter) as input into the AXI RAM writer block. From the current example I find that, the position variable in the C code gets the address position from RAM writer block from the variable int_addr_reg whose width is a user defined parameter. So, the memory block gets written completely with address starting from 0 to 2^(ADDR_WIDTH) and keeps overwriting it starting from address 0 again?. As I would like to exactly start capturing from the start position (address corresponding to data = 1). I'm stuck in understanding the limit and the offset variables used, as I find they are contributing a major role in synchronised data capture.

Also from the code below

Code: Select all

assign int_wlast_wire = &int_addr_reg[3:0];
The last data write happens when value 15 reaches. I also find the write valid signals to be toggling after count reaches 15. I fail to understand the significance of storing data in iterations of 16 to the memory?

If the data is sent with corresponding address upon every clock cycle to /dev/cma, why is a fifo used in the RAM writer block.

Thanks in advance :D

pavel
Posts: 799
Joined: Sat May 23, 2015 5:22 pm

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by pavel » Mon Jun 26, 2023 5:53 pm

Why not just use this example as a black box?

It continuously sends data from the FPGA to a computer with a data transfer rate similar to your application requirements. So you can just send the 64k sample packets to the RAM writer via its AXI4-Stream interface and you will receive these 64k sample packets in C code running on the computer.

adiana007
Posts: 21
Joined: Mon Jun 05, 2023 11:44 am

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by adiana007 » Wed Jun 28, 2023 5:53 pm

Dear Pavel,

I made the following modifications. I changed the ADDR_WIDTH to 13 (as I need to capture only 12288 samples of 16-bit each, AXIS_TDATA_WIDTH = 16, input data width to writer block) but AXI_DATA_WIDTH still remains 64 (M_AXIS output). I use a 13-bit counter as input to the writer which starts on the positive edge of the trigger and runs till 8191.

I included a trigger logic, it checks for trigger in first state, then starts a counter in the second state. Then in the third state, I wait for an acknowledgement signal from PS through Configuration register (we feed this signal from PS once the server sends first 32KB to client). In the third state I also make the count value to 0. In the second state when the counter starts, I turn on an enable signal, and turn it off once the counter reaches 8191 and we switch to third state. I send this enable signal to the PS through status register. In the C code, after the reset blocks, I check for this enable signal and run the block that sends 32KB data to client

Code: Select all

if ((limit > 0 && position > limit) || (limit == 0 && position < 4 * 1024)) 


For testing purpose, I send only one trigger and exit the program, but I find that the data captured in the client is either zeroes or starts from random counter value in the middle and counts till 8191, then goes to zero. I am missing the synchronisation part when using the capture block as a black box, so would like to know your ideas on how do I capture data exactly from 0 to 8191 upon trigger.

pavel
Posts: 799
Joined: Sat May 23, 2015 5:22 pm

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by pavel » Wed Jun 28, 2023 6:19 pm

I am currently testing the adc_test application and the similar sdr_receiver_wide application and both work for me with no issues. Captured ADC samples appear to be OK and signal continuity tests are also OK.

If the adc_test application does not work after you changed something in this application, then the problem is probably with your modifications.

Some parameters like ADDR_WIDTH are optimized to maximize data throughput. Reducing ADDR_WIDTH is not a good idea, with a smaller ADDR_WIDTH the data rate may not be enough to meet the requirements of your project.

I can only recommend testing your HDL modules using an HDL simulator to ensure that the ADC samples that you send to the axis_ram_writer module via its AXI4-Stream interface are correct and that the packet lengths are also correct.

Since you mentioned you need to change AXIS_TDATA_WIDTH, I would say you are not using the latest version of the adc_test application. The latest version was previously in the develop branch and since a few days it is in the master branch.

Another suggestion, try to streamline the data flow as much as possible. I do not understand from your description how exactly your application works, but all the extra wait states you add may reduce the data rate and it will be less than the required 64 MB/s.

adiana007
Posts: 21
Joined: Mon Jun 05, 2023 11:44 am

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by adiana007 » Thu Jun 29, 2023 8:35 am

Hey Pavel,

I am receiving trigger from GPIO and upon positive edge of trigger, I'm starting the counter, whereas the enable signal which goes HIGH when the trigger arrives is sent to PS through AXI Status register, which is polled using if statement in the C code. Is this approach causing delays in acquisition?.

Also, can you help me with explanation of why input data to writer is 16 bits but output is taken as 64 bits. I am trying to know the depth of the memory.

I updated the project,uploaded the new bitstream and ran the adc-test-server.c code, but I find the value of position (*rx_cntr) is always a constant 128 and is not changing, because of which it is unable to enter into the loop and send data. Upon examination, I find address of AXI Hub unassigned. I was unable to manually assign an address too.

pavel
Posts: 799
Joined: Sat May 23, 2015 5:22 pm

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by pavel » Thu Jun 29, 2023 10:37 am

I am receiving trigger from GPIO and upon positive edge of trigger, I'm starting the counter, whereas the enable signal which goes HIGH when the trigger arrives is sent to PS through AXI Status register, which is polled using if statement in the C code. Is this approach causing delays in acquisition?
This is exactly what you should avoid if you want to squeeze from the resources available on the Red Pitaya board the performance required for your project.

I am becoming more and more convinced that the Red Pitaya board is not suitable for this project because it does not have the performance required to meet all of your requirements.
Also, can you help me with explanation of why input data to writer is 16 bits but output is taken as 64 bits. I am trying to know the depth of the memory.
16 bits is the width of the ADC samples.

64 bits is the width of the ACP interface.

But again, I recommend not worrying about that kind of detail and trying to use the axis_ram_writer->server->client pipeline as a black box to send data from your FPGA logic to a file on a computer. This is how I use this code in several projects.

The adc_test, sdr_receiver_wide, sdr_receiver_wide_122_88, sdr_receiver_master, sdr_receiver_slave projects all use the same code to send data from the FPGA to a computer.
I updated the project, uploaded the new bitstream and ran the adc-test-server.c code, but I find the value of position (*rx_cntr) is always a constant 128 and is not changing, because of which it is unable to enter into the loop and send data. Upon examination, I find address of AXI Hub unassigned. I was unable to manually assign an address too.
You need to update the entire repository. If you only updated the project without updating the IP cores, this could be a problem.

Try restarting the board. Maybe something is stuck after some previous tests.

The server sends the data only when a client is connected to it. So, make sure that you run one of the two client programs and it connects to the server.

adiana007
Posts: 21
Joined: Mon Jun 05, 2023 11:44 am

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by adiana007 » Thu Jun 29, 2023 11:30 am

Hey Pavel,

Just giving you a basic description of my application. I get a pulsed sine signal of 300us ON period and 650us OFF duration as input to RP. I also get a trigger pulse along with this signal for synchronisation of the signal (300us ON, 650us OFF). In the RP, I get this trigger input, and when positive edge of the trigger arrives, I will have to capture 300us of the signal data into the memory.

The data rate would be 62.5M (sampling freq.) * 300u (capture window) * 2 (bytes per sample) * (1 / 950u) / 1024 / 1024 = 37.64MBps. In this regard, number of samples corresponding to one signal data (when one trigger arrives) would be 18750.
But again, I recommend not worrying about that kind of detail and trying to use the axis_ram_writer->server->client pipeline as a black box to send data from your FPGA logic to a file on a computer.
So, if I had to use your design as a blackbox, how do I exactly capture only the data that corresponds to start of the trigger. Do you mean to capture the entire samples (256kB) and segregate them into multiple 18750 samples using rx_cntr value when the trigger arrived?.
This is exactly what you should avoid if you want to squeeze from the resources available on the Red Pitaya board the performance required for your project.
In one of my previous projects, the FPGA waits for the posedge of the trigger and upon reception, stores the desired number of ADC samples to BRAM (18750 samples), but BRAM to PS transfer did not meet my throughput benchmark, can I still make use of the BRAM to store only desired samples (18750) using trigger signal and input samples to AXI RAM writer?. (as the methodology of communicating trigger to PS is not desirable).
You need to update the entire repository. If you only updated the project without updating the IP cores, this could be a problem.
I pulled the Repo, updated the NAME in the Makefile to adc_test and used the command

Code: Select all

make NAME=adc_test bit
As well, if I upload any old bitstream and run the server, the position values behave normally.

pavel
Posts: 799
Joined: Sat May 23, 2015 5:22 pm

Re: Accessing BRAM data from /dev/mem of RedPitaya

Post by pavel » Thu Jun 29, 2023 12:13 pm

Your requirements have changed significantly from the last time you shared them.
Do you mean to capture the entire samples (256kB) and segregate them into multiple 18750 samples using rx_cntr value when the trigger arrived?.
I do not understand this phrase and why you want to segregate anything using rx_cntr.

I still see no problem sending these groups of 18750 samples continuously to the computer and writing them all to a file. I do not see why you want to do anything with rx_cntr.

From the description that you provide, the project seems very simple and I do not understand why you are trying to make it more complex by introducing additional logic like synchronization, wait states, BRAM buffers, etc.

The logic seems very simple to me:
  • wait for a trigger
  • send 18750 samples to axis_ram_writer
  • repeat
You can send N*18750 samples to axis_ram_writer which will send them to the server which will send them to a client and the client will write them to a file that will contain these N*18750 samples.

However, it would be better to replace 18750 with a multiple of 64 such as 19200 because axis_ram_writer sends data in bursts of 16*8=128 bytes.
As well, if I upload any old bitstream and run the server, the position values behave normally.
The server code also needs to be updated.

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 98 guests