Hi. It is my first post at the NI forums. I did some research about the following problem but I could not find a way to solve it.
I have a high speed scanning system, triggered to acquire shots of 200 k samples at a rate of 250 MHz. When the acquisition is done, a scanning motor moves the material to the next spot and triggers a new acquisition of 200 k samples. It works continuously: when the last spot is reached, the motors move back to the fist position and start over. This system should produce real-time tomographic images. After the acquisition, some data processing is necessary: filtering, normalization, FFT, down sampling and so on. Before start acquiring a new image, the system can have a little break to finish the processing and empty the queue, avoiding overflow.
At this time, the FPGA code simply acquire the data and send it to the Host VI through a ‘Target to Host-DMA’ FIFO. However, due to the low transfer rate to the host VI, the queue rapidly overflow and it is not enough to acquire 10% of the data necessary for one image. I created another loop that ‘hold’ the acquisition and re-enable it when the FIFO has reasonable space available. All the processing data routines are done at the host VI.
However, I would like to implement the acquisition and all the data processing functions at the FPGA board. For the data acquisition, single-cycle timed loop (SCTL) is used – 250 MHz. Since only few functions work inside SCTL, another clock domain was created with a frequency of 80 MHz – higher loop frequencies generate compilation errors due to time violations.
The problem arises when I want to send data from one clock domain to another. A regular FIFO has size limitations and it still overflows when both loops are working. So, I need a bigger buffer to stack the data before it is processed. Block memory is more feasible for this purpose, but the latency time prevent its use inside a SCTL.
So, my question is how to have high speed data acquisition and data processing inside the FPGA. My idea is to use a producer-consumer framework. While the acquisition loop adds elements to the queue (ex. memory block), the consumer loop drops and process it according to its capability. The queue works as a buffer and should be big enough to avoid overflow.
My latest code use a SCTL to acquire and send data to a FIFO (please see the chart attached). The timed loop reads data from FIFO and sends it to the block memory (pre-processing). A third loop reads the pre-process memory, execute some functions and adds the processed data to a post-processing block memory. The fourth loop uses a second FIFO (target to host – DMA) to send the processed data to the Host VI. Instead of the original 200k points, only ~5k are send to the host. However, it still fails due to the use of read/write operations of the memory at different clock domains.
Is there any other way to implement this code. Or how could I configure the hardware to allow this use.
My hardware is:
Chassi PXIe-1082
Acquisition board: PXIe-7965R with an IO module NI 5761R
It also have a PXI-7851R which is used to drive the motors and for another triggering purporses.
I appreciate any help. Thanks.