LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Large FIFO interleave vs smaller individual resources (out-of-sequence FIFO interleave error)

Solved!
Go to solution

I am using cRIO 9045 with NI-9227. One issue that I have been having is with streaming current on all 4 channels interleaving the 4 points of data. Occasionally, these will go out of sync. For example, [1.12, 0, 0, 0] becomes [0, 0, 0, 1.12]. Despite my best efforts (flushing the FIFO/reading any remaining data), the out-of-sequence pattern persists. As you can see in the screenshots below, I have been very particular with my state machine, to properly Start/Stop and leave On/Off the card. This includes reading any remaining data on the card.

 

 

None of this however works 100%. I still get out-of sequence data even after turning on/off my card and the related FIFO logic. This got me thinking, is there any real downside to have 4 smaller FIFOs instead of 1 large one? This would stop my FIFO out-of-sequence error completely. Why would anyone interleave anything when they run the risk of something like this happening?

 

 

Whenever "False" Flush FIFO on the FPGA side is ONWhenever "False" Flush FIFO on the FPGA side is ONstandard read FIFO in units of 4.standard read FIFO in units of 4.state machine for reading the card and writing the the device-- FIFO ONstate machine for reading the card and writing the the device-- FIFO ONFIFO STOPFIFO STOPFIFO OFFFIFO OFFFIFO STARTFIFO START

0 Kudos
Message 1 of 10
(296 Views)

Hi eli,

 

Be careful when flushing a FIFO with interleaved channels. If you flush the full buffer, the number of flushed elements will likely not be a multiple of the number of channels (here 4), which will shift your data's positions in the packet. Here it appears you flush your FIFO irrespective of the number of channels on both sides (host and FPGA).

 

2 solutions:

 

1. Flush always a multiple of the number of interleaved channels, from the host side, exactly like a normal read (and don't flush from the FPGA side);

 

2. Or, first make sure the FPGA stops writing to the FIFO, then flush the FIFO from the FPGA side, then flush the full FIFO buffer from the host side, finally you can make the FPGA start writing to the FIFO again. This is much more complicated and requires a kind of state machine on the FPGA side and a synchronization mechanism with the host.

 

Also, why using "Acquire Read Region" when flushing? You are creating (and not destroying) block references for nothing. Use the simple Read instead.

 

Regards,

Raphaël.

0 Kudos
Message 2 of 10
(278 Views)

Raphaël,

 

If I understand you correctly.

1. Wrap Flush FIFO logic around flat sequence structure: Before or after writing the FIFO Items.

2. Flush FIFO logic must also include generate system interrupt to allow for flushing from the host side after the FPGA side has been flushed.

3. replace "Acquire Read Region" with read

 

Flushing, only from the host side (sets of 4) is an interesting idea, but I don't know how it would work if the device is already out of sequence.

 

 

0 Kudos
Message 3 of 10
(255 Views)
Solution
Accepted by topic author eli.barber

Not really, I will try to be clearer:

 

On the host side:

 - Before running your FPGA VI, the FIFO should have been configured using the "Configure" method with a sufficient depth.

 - Always read the FIFOs as you do in your "standard read" case, then use the values or not depending on your needs. It should be done frequently enough so that the FIFO depth is never reached.

 - Remove your "False" case, which is useless.

 

On the FPGA side:

 - Do not flush here, you do not know how many you flush.

 

If the buffer on the host side is correctly sized and the read operation frequent enough, the FIFO buffer will never fill up and you avoid having to manage the complicated case were the data are out of place.

 

Check example "Interleaving Channel Data (DMA).lvproj" in the example finder.

 

When that works, if it is still a requirement to manage the case of the buffer filling up, then you can proceed using a state machine and a synchronization mechanism (using interrupts, controls, handshakes or whatever...). As explained, you must ensure the FPGA stops writing, then empty both buffers (FPGA and host sides), then you are good to start writing again.

Regards,

Raphaël.

Message 4 of 10
(249 Views)

Thank you,

 

Removed the excess code and it seems to run fine always recording. I think my mistake was thinking I need to be able to precisely start/stop the card in order consistently collect a precise/exact amount of data points. I think I am OK with some small amount of variance now in the starting data as it depends on how much data is already in the FIFO block.

0 Kudos
Message 5 of 10
(222 Views)

@eli.barber wrote:

I think I am OK with some small amount of variance now in the starting data as it depends on how much data is already in the FIFO block.


You can avoid that by delaying the FPGA acquisition until you are completely ready to read the elements on the host side.

 

2 possibilities come to my mind:

1. Use a boolean control on the FPGA front panel to enable writing to the FIFO.

2. Uncheck "Run the FPGA VI" in the "Open FPGA VI Reference" node configuration and use the "Run" method later.

0 Kudos
Message 6 of 10
(210 Views)

Thank you, I will need to look into running the VI immediately before the the loop somehow. I added a loop indicator and realize that I occasionally get the massive spikes in loop time which is most likely the culprit for giving me an out of sequence problem. I still am getting this even after replacing a loop with a timed loop at 20ms. Thoughts?

elibarber_0-1730490608920.png

 

0 Kudos
Message 7 of 10
(136 Views)

@eli.barber  a écrit :

[...] I occasionally get the massive spikes in loop time [...]


Which loop? Host side? FPGA side?

I can't really help further unless you post some actual code (".vi", ".ctl" and ".lvproj" files in a zip, not screenshots of code). Also post both FPGA and host codes. Maximum version LV2021, otherwise from the project explorer, use menu "File" > "Save for Previous Version..." > 21.0.

0 Kudos
Message 8 of 10
(113 Views)

Is there some kind of toolkit I could use to track what is going on during the time spikes? Nothing would run unless I share all the VI's and there are a lot of them, I don't think I can do that. Anything with the timed loop that is obviously wrong?

elibarber_0-1730849103241.png

 

0 Kudos
Message 9 of 10
(54 Views)

Nothing seems wrong with the Timed Loop configuration.

 

It mostly depends on what is done inside your timed loop. If you initialize things or allocate a lot of memory on the first iteration, that may take a lot of time. Try measuring your max iteration time by ignoring the first few iterations to confirm that.

 

Then simply by adding "Tick Count (ms)" functions in your code and computing the time differences, you will be able to see what part of your code takes longer sometimes.

 

If you want to go further with advanced tools, there is the Desktop Execution Trace Toolkit (for PC applications) and the RT Execution Trace Toolkit (for RT applications). However, I would really try the techniques I explained above first, because it is usually quite hard to get something out of these tools.

 

Regards,

Raphaël.

0 Kudos
Message 10 of 10
(30 Views)