I am trying to interleave 3 1D arrays for writing to a DMA FIFO on an FPGA, however I can't get it to work properly. When I try 2 1D arrays it is ok, but with 3 the elements are not properly interleaved and the result is that all 3 1D arrays are mixed up.
I have tried using the interleave function with 3 inputs and this gives the mixed up result, and I have also tried interleaving 2 arrays and then interleaving the 3rd into this array. This works better as at least I get 2 properly interleaved arrays but the 3rd one goes missing. For testing I used 3 sine waves each of a different amplitude but the same frequency, using the 3 input function the result is a sine wave within a sine wave. Interleaving 2 and then the 3rd one into this array results in three good waveforms but array 2 and 3 are identical.
According to the help it is possible to use the interleave function on an FPGA when the input and results are 1D arrays, which combining 3 1D arrays should be, i think...?
I tested the function in a standard vi and it worked fine so the issue is obviously with the fact it is on an FPGA, but is it because of the FIFO, the interleave function or something else?
The hardware is a 7856R if that makes any difference.
Solved! Go to Solution.
Can you share your code? I've never had a problem with interleaved arrays through a DMA FIFO, but you do need to make sure the FIFO never fills. If it does, and you don't have a way to resynchronize, then the interleaving will be off.
I have used one of the NI examples as a starting point which (according to the description) stops placing data onto the FIFO if it gets close to filling. Also, the error is there right from the beginning, before the FIFO has a chance to fill.
The code is very simple at this stage, sine wave generator into a build array function then into interleave array 1D arrays (along with 2 other inputs). The output is simply decimated and displayed.
Sorry I can't attach the code, I am currently away from computer that this is being developed on.
One other thing is that I am currently simulating the device as I am waiting for it to be delivered, don't know if this makes a difference.
I thought I would quickly make an example that shows how to do it. But now I'm facing the same issue, hehe.
What is wrong with this code?
I have attached a picture. The data going into to the FIFO (probe 4) should be the same as the data coming out (probe 6), with the number of samples being the only difference. However, as you can see, the data points is not in the correct order..
I have no idea what's going on there, and unfortunately I don't have access to LabVIEW 2013 with the FPGA module to take a look at the code. What I really don't understand is the extra 0's at the beginning of the data read from the FIFO. Here are a couple of things I notice, though:
1) Why are there coercion dots on both inputs to the interpolate 1-D array? Maybe it's just a weird effect of fixed-length arrays, but it doesn't look right to me.
2) In the FPGA code, put in something that waits until the host acknowledges that it's ready before you start writing to the DMA FIFO.
3) What's the point of setting the interrupt? The FPGA doesn't wait until it's acknowledged, and the host never acknowledges it, so after the first loop iteration it will have no effect. Also, since you have a forever timeout on the FIFO Read, there's no need for the IRQ.
4) Despite the above comment, it's not a good idea to use a timeout of -1 on a DMA FIFO Read. It would be better to do a read for 0 elements, check how many elements are left, and read all of them. Use some other loop timing mechanism, don't use a -1 timeout.
What sort of loop rates are you running here? Is there ever a timeout at the DMA FIFO Write?
It's "good" to see that I'm not the only one having this issue!
I also have the coercion dots on the input to the interpolate array even though everything is set to FXP with exactly the same configuration so maybe it is just a feature. Even though your comments on the code attached by AEP are probably all valid I don't see how they would affect the data placed onto the FIFO. It shouldn't make any difference to the contents of the queue if you wait for some kind of acknowledge from the host (other than to prevent overflow) as the DMA FIFO is supposed to be lossless first in first out. You may have an unknown starting point when you read the data at the host but all the data should be in an expected order and should accurately recreate the data you placed on to it, other wise what's the point?
The main issue I see is that with 2 1D arrays the whole thing works fine, but with 3 it goes wrong. It appears that the issue is with the LabVIEW function rather than the code, however I can't believe that I am the first person to ever try interleaving 3 1D arrays. Maybe I can try it with 4, could be something to do with the odd number.
In my current configuration I am starting the FPGA with the host vi and data is always available so there is no timeout and also no overflow situation. As I am running the FPGA in simulation mode the loop rate (set by the loop timer) doesn't seem to do much unless it is set very high, which I assume is due to the speed difference between my PC and an FPGA chip.
Actually, with my code I'm only using 2 1D arrays. Whats the difference between my code and yours, since yours is working with 2 arrays?
Are the arrays that you are interleaving of variable length (i.e. can their length be changed by a control on the fly during operation, and have you specifically set the constant/control/indicator related to it to a fixed length)?
If so, I would bet that this is the source of the issue. Array lengths must be defined at compile, otherwise the FPGA can do weird and wonderful things.
I believe that's the cause of the coercion dots.
In general, either try to avoid arrays on the FPGA or be very very specific when defining them. Most operations can be rewritten to operate point-by-point - for instance, rather than interleaving N arrays of data, you can work through them point by point, build an array of N points to write to the FIFO, then write the next N points in the following iteration.
However, I'm creating the arrays inside a for-loop, meaning that the legnth will be fixed to the count terminal.
Implementing Variable-Sized Arrays in FPGA VIs (FPGA Module) => See the for-loop section.
But just to try it out, I opened the SubVI and set the indicators for a fixed length (the same as the for-loop). I still get the same result...
It will be very difficult to avoid using arrays in an FPGA when the only way to pass more than one set of data over the FIFO is to interleave the sets of data into an array. If i have to have a separate FIFO for each data set then I would need a very expensive FPGA setup. The only place I am using arrays it to do this process, as there is no other way. I have several AI connections that need to be passed (individually) through a build array function before they can be interleaved and sent. I am not creating an array and then sending it as such, I am creating the array in order to be able to send it.
I don't see any differences in your code to mine as far as creating the interleaved array is concerned. For me 2 1D arrays works great so maybe I will just have to develop my system with this and then hope there is a solution to this issue with 3 arrays.
EDIT: Just tried using 4 1D arrays and the result was horrible, I may as well have used 4 random number generators in the host.