LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DMA FIFO switching beteen channels after FPGA sends

Solved!
Go to solution

Hi,

 

it seems that configuring the Timeout of the FPGA to zero and allowing it to write only when there is available space solves the issue. I really do not understand why because this should be equivalent to set up the Timeout to -1. Thanks!!

 

Enrique

0 Kudos
Message 11 of 21
(3,305 Views)

Hello Enrique

 

How did you solve this problem of switching?

 

I am currently using Ni Crio9074 with 6 modules(4 channels per module Ni9215)  in which i am using 22 channels. I tried using the depth of the channel by multiplying with number of channels(22). I see that every time i execute the program there is switching of channels and the switching position changes every time i execute the VI.

 

Attached is the screen shot of FPGA and Target program

 

Regards

SujanReddy

0 Kudos
Message 12 of 21
(3,282 Views)

Please see the help:

"The new depth is implemented when the next FIFO Start, FIFO Read, or FIFO Write method executes. Before the new depth is set, LabVIEW empties all data from the host memory and FPGA FIFO."

"On certain FPGA targets, the value wired to this parameter may not be the actual number of elements allocated for the host FIFO of the DMA channel. On these FPGA targets, the number of bytes allocated in memory is coerced to a value that is valid for the specific target and is a multiple of 4096. This coercion may increase the actual number of elements in the host FIFO of the DMA channel."

 

You have two problems here. First, every time through the host loop, you reconfigure the DMA channel. According to the help, this will clear any existing data from the FIFO. You don't know how much data is in the FIFO nor what channel was last written, so the first element after clearing may not be the first channel of data. Second, depending on your FPGA target, the actual number of elements may be larger than the number you requested, and may not be a multiple of the number of channels. Since you continually read the actual FIFO size rather than the desired number of data points, this could also cause an offset, although you will not see it until after you fix the first problem related to configuring the FIFO size on every loop iteration.

0 Kudos
Message 13 of 21
(3,272 Views)

One more comment - your scheme here won't work well. It won't provide data at a constant rate. Instead it will read a bunch of data, pause when the DMA buffer fills until the host has a chance to empty it, then read a bunch more data and repeat. You should read as much data as is available (modulo the number of channels) which may not be the entire DMA buffer. That way the FPGA should always have some space available to write new data and will not need to wait to enqueue an element in the FIFO. If you want data at a constant rate and the DMA buffer does fill, increase the buffer size.

0 Kudos
Message 14 of 21
(3,265 Views)

One solution for N channels of data :

 

1) On the FPGA target, write your N channels of data plus a channel of zeroes into the FIFO.

2) On the FPGA host, configure your FIFO depth to a nice big size prior to acquisition.

3) In a relatively speedy loop (I use a 20 ms interval), use a zero-size FIFO Read to retrieve the number of elements and read that number of elements.

4) Pass the resulting array into a FGV that concatenates the data until it reaches a desired packet size - in my case, I wanted a packet of 100 ms worth of data, so with N = 6 and Fs = 50 kHz that was 35 000 points.

5) Once the concatenated data is greater than your packet size, split the 1D array of data to create your packet and an overflow. The packet can be offloaded to the next VI whilst the overflow is fed back into a shift register to continue concatenation in the next loop.

6) To sort out the problem of the order, you need to find the index channel of zeroes. You know that the array will be in the correct order relative to this. The index channel has a mean of zero in this instance, but you can use any value you wish for an index to suit the data you're sending through. For instance, if you know the majority of your signals are 1 Vpp sinusoids with zero DC offset, there's a chance a signal channel could have a mean value of exactly 0. My approach is to decimate the array according to my number of channels, including the index channel, figure out which channel has a mean of zero, then create an array by which to index the scaled data so that it's in the correct order.

 

A VI snippet of the steps involved (complete with customary butchering of layout thanks to new terminals being added 🙂 😞

 

fpga-buffer.png

 

FPGA AI is a sub VI containing my FIFO Read nodes (3). This passes data to FPGA Buffer, attached, described in (4) and (5). On successful offload, this data is decoded using FPGA AI Decode (6).


Hope this is of use to somebody else, and if anybody has a better method of ensuring FIFO order with multichannel continuous data acqusition then I'd be delighted to hear it. Would also consider tidying up and putting into a community page if it's useful?

---
CLA
Download All
0 Kudos
Message 15 of 21
(3,258 Views)

Nathand

 

Thank you for replying to my query. Regarding the problems you have pointed out

 

1. Regarding the FIFO data configure in the TARGET file. I have used FIFO configure just to save the time for compiling the FPGA file. If i need to change the size in FIFO  project i need to compile it every time. I will remove FIFO from my target file if this causes a problem.

 

2. I am using NI Crio 9074 with 7 NI9215 modules which has a RAM size of 720kbit. MY FIFO data type is word length of 16bit and integer word length of 5bit.

 

If i use 22 channels is there any relation to decide the maximum sampling rate for a fixed depth of FIFO?

 

I have attached my FPGA and Target files

 

Regards

Sujan

Download All
0 Kudos
Message 16 of 21
(3,240 Views)

SujanReddy wrote:

1. Regarding the FIFO data configure in the TARGET file. I have used FIFO configure just to save the time for compiling the FPGA file. If i need to change the size in FIFO  project i need to compile it every time. I will remove FIFO from my target file if this causes a problem.


You've confused host and target. The TARGET is the FPGA; the HOST is the VI that runs on your real-time system. You named your VIs backwards. The DMA FIFO configure is on the host (the VI you titled "Sahand-Target.vi") so it is not part of the FPGA compile.

 

Please read more carefully. The problem is that you configure the DMA FIFO inside the loop, so you clear the FIFO on every cycle. You should configure it once before the loop starts.


SujanReddy wrote:

2. I am using NI Crio 9074 with 7 NI9215 modules which has a RAM size of 720kbit. MY FIFO data type is word length of 16bit and integer word length of 5bit.

 

If i use 22 channels is there any relation to decide the maximum sampling rate for a fixed depth of FIFO?


There are two different depths for the FIFO. One is in the FPGA memory, the other is in the host memory. The FPGA memory buffer is smaller, and is compiled into the bitfile. The size on the host is much larger and dynamically configurable, using the DMA FIFO Configure method. In the background, the CPU will automatically transfer data from the small FPGA buffer into the much larger memory on the host. It's up to you to determine how fast you want to read data out of the DMA FIFO. The host FIFO depth should be more than large enough to hold as much data as will accumulate between reads. The sampling rate is entirely determined by the FPGA code, and is not related to how fast you read data from the FIFO on the host, so long as you read from the host fast enough to prevent the FIFO from filling. You should not read the entire host buffer at a time because that means the FIFO is full and the FPGA can't write any more samples to it until it empties.

0 Kudos
Message 17 of 21
(3,232 Views)

Thoult - this looks like a neatly-arranged solution. Personally I would try something simpler.

 

You know how much data you want to collect, and the sample rate, so you know how long it will take to collect the data. As a result, no need for the "relatively speedy loop" - instead, use a larger DMA buffer and loop at approximately the rate required to collect the desired amount of data. If you need an exact number of points, then loop at slightly less than the necessary rate, and read the right number of points from the DMA with a small timeout. You probably don't want to do the entire wait using the DMA timeout, though, because that can load the processor unnecessarily. Or, do a read for 0 points with an immediate timeout, and if the desired amount of data is not yet available, wait and then loop again. Either way, reading the exact number of data points that you want in a single read will be simpler and more efficient than merging and splitting arrays.

 

Alternately, if you just need to read a multiple of the number of channels, but don't need to read exactly the same number of scans each time, then you can wait, then do a 0-length read, do a modulo division by the number of channels, and read that number of points, leaving the remainder for the next read.

 

To maintain the ordering, I would use an interrupt or front panel control to synchronize sampling on the FPGA with the host when they first start. You'll never lose ordering so long as the DMA buffer never fills. If the DMA buffer does fill, there are a couple of things you can do. On the FPGA side, you can write to the buffer with a forever timeout, so that the next data point will still be the next channel even if the buffer is momentarily full. Or, if the DMA times out, discard the rest of the array on the FPGA side, and set an interrupt. When the interrupt occurs, the host reads all the data from the FIFO, discards the last incomplete scan, and acknowledges the interrupt which resynchronizes the channels.

0 Kudos
Message 18 of 21
(3,231 Views)

Hi all,

 

I am also facing a similar problem where i see this channel swap effect (when using interleaving in fpga side and decimate in host side). The above discussion was informative which enabled me to learn that if FPGA buffer fills and adding to that if FPGA fifo node's timeout is wired to '0' then there might be effects like these.

 

Possible reasons that FPGA buffer gets filled ::

1) Host reading loop may be slow because of much computational overhead.

2) Host side FIFO depth may be small for the application.

 

And possible solutions enlisted are:

1) wire -1 to fpga fifo node's timeout

2) configure and increase host side buffer.

3) reduce computational overheads or in a way optimize host side code (wrt to time of execution).

 

I Tried all dese and even reduced my host side RT VI code to just read fifos and display.

 

😞 but that swapping or channel switching effect persists. This effect will only happen if me fpga skips a channel once 

 

like say i have two channels (A and B) into one fifo. 

 

AB AB AB AB (SKIPPED A) BA BA BA BA  resulting my fifo elements look like ABABABABBABABA

 

My output should be

psd data without clubbing.JPG

 

 

But my output seems like this ::

 

psd when clubbed.JPG

 

0 Kudos
Message 19 of 21
(2,994 Views)

Have any code we can look at?


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 20 of 21
(2,983 Views)