pavel-demin / red-pitaya-notes

Notes on the Red Pitaya Open Source Instrument
http://pavel-demin.github.io/red-pitaya-notes/
MIT License
338 stars 210 forks source link

Understanding the working of the axis_ram_writer #1114

Closed benjathemin closed 12 months ago

benjathemin commented 12 months ago

Hi Pavel,

This is less of an issue and more of a clarification. I've been trying to figure out how the axis_ram_writer module behaves and have read through most of the issues on the redpitaya forum as well as on this github (at least the related ones). I have also setup the adc_test, adc_recorder and adc_recorder_trigger projects on vivado and inspected their respective c codes.

In your code in the adc_recorder project for instance, you have : ram = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); where: fd = open("/dev/cma", O_RDWR) which means the offset is 0 in the cma and length of the mapping is 1024 sysconf(_SC_PAGESIZE) bytes. I don't have my redpitaya on me at the moment to know what the page size is but I figured it's either 4096 or 65536 as they're what I've frequently seen. The address with which we feed the RAM writer is 1024 sysconf(_SC_PAGESIZE) bytes and the number of samples for the packetizer is set to 1024 * 1024 -1. My question is, does the address that we feed to the RAM writer correspond to the length of the mapping or is that just a coincidence? It feels like it's convenient especially because the RAM offset is 0 in the memory mapping.

Just to further my understanding, let's say fd was defined as follows: fd = open("/dev/mem", O_RDWR) And furthermore, the memory mapping is as follows: ram = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x00a00000); and we still wanted to transfer 1024 1024 -1 samples. From my previous question, I feel that having the address to still be 1024 sysconf(_SC_PAGESIZE) would be slightly erroneous. I read in both your code of the axis_ram_writer and on a post on the forum that the write address, corresponds to cfg_data + 8 * sts_data. In the previous case where fd was defined differently, you didn't need the sts_data to get the write address but in this case with a non-zero offset n the mapping, would you?

The way I thought it would work is that, the offset of the ram mapping would be cfg_data + 8 * sts_data but it doesn't look right. I'm just looking to fully understand this section as I believe it will help me moving forward.

I hope I have been as concise as possible and any direction on this would be much appreciated.

pavel-demin commented 12 months ago

Thank you for your interest in the axis_ram_writer module.

I modified this module quite a bit this year and last year and some of its parts are no longer the same as when I was discussing it on the Red Pitaya forum. Since most of the bugs are now fixed and I am pretty happy with the current version of this module, I should probably add a page to the notes describing it.

The axis_ram_writer module has two dynamically configurable parameters:

The sts_data port of the axis_ram_writer module outputs the current value of the address counter. It can be used to check to what memory addresses the data has already been written.

In the adc_recorder project, the cfg_data parameter is hardcoded to 262143. This limits the maximum size of the memory buffer to 32 MB (262144*128 bytes).

In the C code, the memory buffer size is set to 4 MB (1024*4096 bytes) to be able to record 1 million dual-channel ADC samples. If necessary, this size can be increased up to 32 MB without changing the FPGA configuration.

The C code controls the min_addr parameter of the axis_ram_writer module and the cfg_data parameter of the axis_packetizer. The first parameter should be set to the starting address of the memory buffer and the second parameter should be set to the number of dual-channel ADC samples to record minus one.

I do not know how to answer your questions because they mix values that cannot be mixed. Instead, I can try to list the relationships between different values of configuration and status registers:

If you use /dev/mem and 0x00a00000, then the min_addr parameter of the axis_ram_writer module should be set to 0x00a00000. You will also need to ensure that the cache of the memory buffer starting at 0x00a00000 is correctly managed by both the CPU and the FPGA.

benjathemin commented 12 months ago

Thank you for the response. Brief but concise. A page regarding this module would be much appreciated on your notes for both existing and newcomer RP users. I will redownload the repository and test the updated blocks accordingly.

pavel-demin commented 12 months ago

Here is a link to the new page with my notes on direct memory access:

http://pavel-demin.github.io/red-pitaya-notes/dma

It contains some parts of my posts on the Red Pitaya forum and the description of the axis_ram_writer module from my previous comment.