03-06-2020 03:54 PM
Hey guys,
I'm pretty new to Labview FPGA. I am just trying to stream data from the FPGA to my RT program. The problem that I am having is that sometimes my FIFOs come across with different numbers of elements. It only happens once every few seconds. One of the FIFOs will have anywhere from 1 to 10 fewer elements than the others. I have seen examples where people use a a single FIFO to do what I am doing which I will probably try next, but I can't make sense of why this wouldn't work too. Any suggestions?
FPGA
RT
Thanks
Solved! Go to Solution.
03-06-2020 11:41 PM
Well, your code will I guess work (sort of) but as you've seen, the number of elements isn't deterministic at the RT side.
How fast is your "Analog Loop Period"? I'm guessing fairly quick...
The RT system probably has 1 or 2 cores, and I'm guessing what happens is something like the following:
You'd be better off specifying how many elements you want to read, if you want to use this system.
If you wire a constant (choosing the value to approximately match the period you want) then you'll need to allow a timeout on the RT, but you should avoid different numbers of outputs (since they're all receiving data at the same rate, based on the visible FPGA code).
03-09-2020 05:25 PM
cbutcher explained a lot of the reasons why I would typically recommend pushing all of the data into a single FIFO
If you put all 4 elements into the same FIFO then all you need to do on the host is look at the number of elements available and use the quotient & remainder function to see how many groups of 4 elements you can read. The decimate array function then makes it simple to break the single array into the 4 individual data streams.
03-10-2020 12:05 PM
I regularly use multiple FIFOs in parallel to transfer data. As cbutcher said, the problem is the lack of determinism in the RT. You can rest assured that the FPGA is certainly putting one element into each FIFO; there is no circumstance where one FIFO will have had more elements put into it than another, instead the RT will have waited different amounts of time between reads.
To get the same number of elements, you should read batches of defined size. The size is pretty arbitrary, but you could even use the first read's Elements Remaining as the subsequent read's Number of Elements.
Alternatively, use a small timeout (10-100 ms) and a large number of elements (1000-10000). The read will either return the number of elements or timeout with a smaller number of elements being returned. You then use a queue to pass the data from your fast polling loop into a slower parallel processing loop. You can decide whether you want to locally buffer (shift register) the smaller number of elements or send it on ASAP. This way you will ensure that your FIFO reads are large and you cycle your FIFO polling loop minimally, while also being responsive to sudden fluxes in data rate.
03-10-2020 01:12 PM
Thank you all for your help! I modified my code as follows and it's working perfectly now. No more gaps in my timestamps which is what I was seeing before.
FPGA:
RT:
03-10-2020 11:06 PM
I think if it works perfectly, you're lucky in your timing. You are sending in groups of 4, but perhaps the RT checks the number of elements and finds it isn't a multiple of 4? That will happen if the 2nd, 3rd, or 4th elements haven't had a chance to be added to the FIFO yet.
You should check the number of elements on read. Do a Mod 4. Multiply the quotient by 4. Then read that. It will leave the stray elements in the FIFO for the next time around. So if let's say 4 elements were put in one batch, and only 3 of the 4 in the next batch at the moment the # of elements check occurs, it will be 7. Mod 4 will give a quotient of 1 (remainder of 3). Multiply by 4. Now read 4 elements. The remaining 3 will stay and be waiting for when the last element of the packet gets entered.
If you don't always read 4 at a time, the 4 arrays will get out of sync.
03-11-2020 12:06 AM - edited 03-11-2020 12:11 AM
Given your new design (4 elements enqueued in order to a single FIFO) I'd suggest (like RavensFan described in detail above) that you should dequeue a multiple of 4 elements every time.
If you have a fixed acquisition rate (polling loop time on FPGA) then I'd say the simplest method is something like the following:
If timeouts are absolutely not allowed, then the appropriate (and slightly more complicated) process is as RavensFan detailed:
Also note if you might want a different number of channels in future (because you're turning some off, or you add new channels) making your "4" value an output of something (class, subVI, global variable, whatever) might be a worthwhile modification, then you only have to change it in one place.
Edit: as a follow-up to that last point, if you change the number of channels whilst you have elements in the queue, things will get messed up. I do this on my FPGA application and I handle this by having the RT and FIFO handshake via a boolean control on the FPGA Main front panel and flushing the FIFO. The process (at a high level) looks something like:
03-11-2020 01:57 PM
Thank you guys, again, for your detailed feedback. I am learning a lot!
For the record, I didn't ignore the initial suggestion to add the divide by 4, multiply by 4 logic. I put that in and set a conditional breakpoint on the remainder. After a couple hours running I hadn't seen anything but zero as the remainder so I made a *bad* assumption that something must be going on in the background that was forcing the correct number of elements in and out of the FIFO. I see now that there is nothing automatically preventing the reads and writes from getting out of sync, I was just lucky. I have put that back in.
Thanks