Real-Time Measurement and Control

cancel
Showing results for 
Search instead for 
Did you mean: 

Use one DMA for multiple data sources on FPGA

I would like to use 1 DMA for multiple data sources on the FPGA. I am trying to determine what the best practice is around this. As an experiement, I am building an FPGA vi that acquires raw data from both a 9215 and a 9211 in separate loops. There is one additional loop that retrieves data from both acquisition loops using Target Scoped FIFO's. My intent is to pack the data into the DMA using a header to tell the Host app how many samples are arriving from each module. Unfortunately, the data types of the two sources do not match (9215 -> I16 and 9211 -> I32), and for reasons that I don't understand at all, there is no Type Cast function on the FPGA. I can split the I32, or join the I16's to make a 32 bit data type, but both the join and split primatives result in Unsigned integer data types. What is the best way to put data like this into a single DMA channel (U16, I16, U32, or I32)?

 

It looks like I can use sequentially wired Split Numbers and Join Numbers to convert an I16 into a U16. If this actually works, why can't I just Type Cast something?

 

Thoughts?

Chris

0 Kudos
Message 1 of 9
(5,541 Views)

Chris,

 

I'm doing multi-channels acquisition ( 24 bits or 16 bits, rs232 and other ).

I'm using one DMA FIFO of 64 bits: the first 32 bits (MSB) is use to identify the channel (1 : first channel, 2: second channel) . the other 32 bits is for the data ( fixe-point or other)

In the RT I decode it and process it depending the channel..

I use 64 bits data too then I split in two 32 bits in the FPGA, then I have 2 values of 32 bits to give one of 64 in the RT. 

 

I used to count how many data I have, know I'm writing the PPS from a GPS in this FIFO then I'm able to read data every second and know the sampling rate of each different acquisition system.  

 

I know that is not the best way for memory efficienty!!!

 

Is there anybody doing the same???

 

Math

0 Kudos
Message 2 of 9
(5,516 Views)

Intriguing. I came up with a prototype that works similarly (in theory). At this point I am only testing acquisition from two modules out of 6 on a 9074 integrated chassis & controller. My FPGA VI seems pretty simple, but it chugged away for 6 hours on Friday before erroring out of the compile process. I made some very minor tweaks and I am trying to compile again now. I may not have any new information till tomorrow. The compile error seemed to point to a memory issue. I wasn't that clear on the location of the problem, but I should have plenty of memory on both the FPGA and the compiling computer by my calculations. The way it works is this:
 
There are three loops in the VI. Two of the loops are used to acquire data asynchronously. They are pretty simple while loops with a sequence structure (loop timer in first frame, I/O nodes in second frame with data placed in a module specific FIFO, i.e., one FIFO for data from 9211, and one for 9215). In theory, I can add more loops with corresponding FIFOs for each module I'd like to acquire data from.
The third loop contains a case structure (simple state machine architecture) where the first case initializes an array of 4095 elements and an index. The second and third cases each read data from each of the two target scoped FIFOs (up to 256 points) and place them into the initialized array (as long as the FIFO read does not timeout) along with a "header" element that contains two joined U8's where the first byte is the module number, and the second byte is the number of elements following from the module in the array. There is some fooling around with data types here to get everything into U16 before being (re)placed into the array. The next case takes data out of this array, and puts it into a DMA FIFO. There are 0 timeouts for the FIFO reads, so it should never wait for data; each read case will just take whatever is available from the producer acquisition loops and pipe it through to the RT host. These three cases are just set to cycle through.
 
I'd love to hear any comments on the whole architecture, or any suggestions to improve performance (or likelihood to compile).
 
Thanks,
Chris

 

 

Message Edited by C. Minnella on 05-18-2009 02:41 PM
0 Kudos
Message 3 of 9
(5,499 Views)

I still don't have an answer to the question about the absense of Type Cast on the FPGA, or comments about the design, but here is what I've learned so far:

  • using consecutive split and join numbers primatives effectively allow you to type cast an integer into an unsigned type 
  • putting an array into a shift register is a bad idea--even if there are enough gates to build the memory on the FPGA the compiler's memory usage will blow up. A VI scoped memory block appears to be the right way to go. (this is represented by a Portability:3 error btw).
  • I'm still working on some timing issues. Everything executes so fast that I end up generating a lot of empty "messages", i.e., a I16 for each module indicating 0 length of actual data.

Chris
0 Kudos
Message 4 of 9
(5,465 Views)

Hello Chris,

 

I like your architecture overall.  It does seem like it would be a good idea to limit the speed at which this loop runs.  You can then prevent empty messages and also send data from each module in larger chunks which will reduce the amount of processing overheard necessary in RT. 

I am trying to understand the reason why it is necessary for you to perform this typecasting on the FPGA.  What are you trying to gain by making these values unsigned before sending them to the RT?  Thanks and please continue to post your updates on the forum.  You also might want to consider posting this code as a community example once you have it finished.

0 Kudos
Message 5 of 9
(5,437 Views)

On the idea of reducing the loop rate to send larger messages.. I've tried to do that by essentially setting the rate to the time required to get a full 5000 samples from the 9215. I thought I could do this by setting a timeout of -1 to the Target-scoped FIFO reading data from the 9215 loop. In theory, the communication loop would be forced to wait for 5000 samples to be available before getting out of the 9215 case, and therefore the loop rate of the comm loop would be determined by this. Unfortunately, using -1 for the timeout causes everything to go wonky. The DMA overflows almost immediately. I can successfully limit the loop rate by using a relatively low timeout of about 300 ticks when the 9215 loop executes every 10usec. The math doesn't quite work out; 10usec should be 400ticks, but if I use 400 in the timeout, I get the same effect as using -1. The side effect of using 300 is that I don't quite get 5000 samples per iteration from the FIFO. I get more like 4030 or so. It still works, but I don't understand it.

 

It is necessary to typecast on the FPGA because I wanted to get I16 and I32 data into the same DMA. Using Split Number on the I32 produces two U16's. To use the same DMA, I need the datatype to be the same, so I need to convert the I16 to U16's. I've since learned (today's NI Developer Day) that I could convert the I32 to an array of booleans and then reform the boolean array however I liked. I was avoiding this because in LabVIEW on a desktop booleans occupy 8bits whereas they are represented as only a bit on the FPGA (as they should be). Using this trick, you can also typecast anything, so I continue to ask why we don't have a typecast operator.

 

I also ran across this reference application (http://zone.ni.com/devzone/cda/tut/p/id/9196) that details how to go about converting the Fixed Point data to SGL's on the FPGA, and this seems very promising. I was avoiding using Fixed Point data because I wanted the optimum precision from my acquisition, but it may be too good to avoid using. This prevents the rio from having to do any of the data conversion and scaling, and that may be worth a small loss in precision.

 

Thanks for the feedback Burt.

Chris

 

 

Message Edited by C. Minnella on 05-21-2009 05:53 PM
0 Kudos
Message 6 of 9
(5,427 Views)

Hello Chris,

 

The FIFO behavior you are seeing does seem fairly strange.  Unfortunately I do not have any good theories for why this is happening.  But as for type casting, while there is no Type Cast VI on FPGA, there are VIs for numeric conversion on the palette.  Simply go to Numeric>>Conversion and you should have every conversion option you would want.  It seems like these VIs should work just fine for what you are trying to do.

 

Finally, I agree that fixed point data on FPGA is extremely nice to use.  As you mentioned, in most cases the ease of development is worth the loss in precision.  In fact in most applications the amount of lost precision is completely negligible.  If possible, I would definitely recommend using fixed point in your application.

0 Kudos
Message 7 of 9
(5,411 Views)

There's a way for typecasting any numeric datatype to another on the FPGA: convert your I16s to bool array, concatenate the arrays to one and then convert back to number (with setting the properties of this function to datatype I32 instead of the default value).

 

Because it's only wiring on FPGA no ressources are lost.

0 Kudos
Message 8 of 9
(5,363 Views)

Yep. In the second paragraph of my previous (rather lengthy) reply I figured that out. Also, it looks like the conversion functions also work to a limited degree.

 

Thanks guys.

Chris

0 Kudos
Message 9 of 9
(5,358 Views)