LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Adding DRAM storage to "Finite Acquisition Multiple Channels" on FPGA

I am writing a data acquisition code for the 7962R with the 5752 Adapter Module using LabVIEW 2012. The basic idea is similar to the "Finite Acquisition Multiple Channels" example with additional features for larger data sets. The FPGA waits for a trigger on the PXI backpane; acquires a 16 channels at a user defined rate (~10 MHz) for a user defined number of points (> 10K); and saves them to the DRAM. Once this is completed, the DRAM then transfers the data to the host computer using a DMA FIFO. For small sets of data I can get this to work storing data in target scoped FIFOs. However, now that I have added DRAM, the code seems to work the first time the acquire button is pressed, then on subsequent acquires, returns the correct number of points all with a single value. 

 

I am currently using the DRAM as a FIFO, as this seemed the simplest implimentation. I understand there are alternatives, but am unsure if I made the correct choice.

 

Also, if I understand correctly, the analog channels must be acquired using the IO clock on the 5752 card. Can I use this same clock for writing and reading data to and from the DRAM? 

 

Any suggestions as to why each channel has a fixed value after the first acquire would be greatly appreciated. 

Thanks.

0 Kudos
Message 1 of 11
(3,944 Views)

jp82,

 

You can use the IO clock on the 5752 card to read and write data to and from the DRAM. It looks like you have already implemented this in your code as well. Can you explain in a little more detail what you mean by fixed value. Is the first read an accurate value? Also, are you monitoring this from the Target to Host FIFO? You are not doing anything with your Time Out? case. it could be trying to write your DRAM faster than your DMA FIFO can keep up. In that case, you will need to add some handshaking logic to make sure the DMA FIFO is ready to send the next element.

 

If you could explain maybe the first five iterations of what you would expect, and the actual values you are getting. I would also advise using Simulated I/O and Highlight Execution to see if your FPGA is behaving as you would expect.

 

Best,

tannerite

Tannerite
National Instruments
0 Kudos
Message 2 of 11
(3,922 Views)

tannerite, 

Thanks for your response. To explain what I mean about a fixed value, I have attached two screen captures from the graphs, which show the analog output. The first time I press the fire button I can see the bit noise from the digitizer as there is no signal (First Iteration.jpg). I have also tested the channels with a sine wave from a function generator to ensure that I am getting the signal I expect and I do. If I press the fire button three more times, I see a similar signal. On the fifth button press, I see a spike and then fixed value on each channel - no bit noise (Fifth Iteration.jpg). On subsequent presses, I see a just a fixed value on each channel. I can change the number of fire button presses I get by changing the number of points acquired.

 

I am controlling the transfer between DRAM and DMA FIFO by using "Get Number of Elements to Write" on the FIFO and making sure that this is greater than zero before allowing transfer as shown in the "Transfer" state. Today I added a time out indicator to make sure this FIFO is not timing out. With the Host side code, I look at this just before I read data from the FIFO. I do not believe that the FIFO is being overloaded.

 

Thanks, 

Jim

Download All
0 Kudos
Message 3 of 11
(3,913 Views)

jp82,

 

I now understand what you are talking about. I think it would be worth disabling the actual inputs (shown in screenshot by using a diagram disable) and tieing it to your counter line so we can verify if the data is coming in correctly or if it may be the actual hardware. I have been looking through your code and everything seems to be coded properly. It is very peculiar that you can read data for the first four triggers but the fifth behaves this way. This hardware is fairly hard to come by here and I am trying to wrangle some up to try and reproduce but I think sending counter data in will definitely help us monitor what the FPGA is doing. It would also be helpful to put indicators before and after you write and read from DRAM to make sure it is the same data. The DRAM FIFO is a destroy type of read so it should be popping that off of the FIFO and not filling it up over time.

 

Also, you said you were monitoring the FIFO timeout. It would help if you used a latch in case it ever went TRUE and using the DRAM Full method to latch if that ever goes TRUE as well. 

 

 DRAMCapture.JPG

Tannerite
National Instruments
0 Kudos
Message 4 of 11
(3,895 Views)
tannerite, I made the modified the code to disable the actual inputs and just use the counter into the DRAM as you suggested in your figure above. I now always receive a single value as the output, which is the same for every channel. I added a latching time out indicator for the DMA FIFO. This never latches. I added an indicator showing the last data point read into the DRAM and the last data point read from the DRAM into the DMA FIFO. These were not the same. I added a latching 'Full' indicator for both Bank 0 and 1 DRAM banks. Both of these do latch. I am confused by this for a couple of reasons. First, the DRAM FIFO should be cleared when the card is reset at the beginning of the code running on the host machine. The code uses a counter to ensure that only 5000 points (or whatever the user specifies) gets written to the DRAM. The PXIe-7962R has 512 MB of onboard RAM. I don't see how I could fill this with 20,000 64 bit integers (5000 x 4). Second, looking at the help file for the FIFO - 128 Bit Memory Interface, the second to last paragraph states, "The FIFO - 129 Bit Memory Interface is designed to simultaneously read and write data at speeds up to 40 MHz. It is possible to run the interface up to 200 MHz. However, at speeds greater than 40 Mhz, the 'Full' and 'Data_Available' signals may temporarily become TRUE and FALSE, respectively." Since I am using the IO Module Clock (50 MHz), it seems like the 'Full' indicator may be unreliable. I repeated this with the DRAM clock and loop clock set as the 40 MHz clock and the same thing occurred. So somehow, the DRAM is filling up. I'm at a bit of a loss for how this is happening though.
0 Kudos
Message 5 of 11
(3,887 Views)

jp82,

 

That is odd. Have you tried lowering the numbe of data points to 1000 and seeing if you can run it more than five times? That should confirm if you are actually filling up the DRAM. I am still looking into why this may be happening.

 

-tannerite

Tannerite
National Instruments
0 Kudos
Message 6 of 11
(3,877 Views)

jp82,

 

It will also be helpful to clear your DRAM at the beginning of your FPGA code. I attached a screenshot of how I would accomplish this.It is possible that you filled up your DRAM in the past so reading all of the DRAM at the beginning should effectively clear it.

 

DRAM_Empty.JPG 

 

Warm Regards,

 

-tannerite

Tannerite
National Instruments
0 Kudos
Message 7 of 11
(3,870 Views)

I have added code to clear the DRAM FIFO. I had to add it to the state "Waiting for Trigger" because I use the IO Module Clock for the DRAM. When I tried to exit the loop as indicated in your screenshot, I would get an error message stating that I cannot exit a loop that uses an external clock. I think my solution should do the same thing that yours does though. I also added an indicator to show when the DRAM banks were empty so I would know the system was ready to trigger. I did not want this one to latch.

 

When I ran the code, the indicator would rarely be lit, meaning it would occasionally light up, but only for short periods of time (<1 s). I believe this means that either there is a problem with the Data_Available or something else is writing to the DRAM FIFO. I have attached an updated version of the code below.

 

Thanks, 

Jim

0 Kudos
Message 8 of 11
(3,863 Views)

Hi jp82,

 

It like this may not behaving in the same way as I was wanting. Having a loop at the beginning of the code while make sure it reads all of the data from DRAM at the beginning. This should allow you to have access to all of the DRAM in your actual state machine loop. Could you reference the IO Module Clock as shown in the below screenshot? This loop is iterating through all of the elements in DRAM and reading them which should eliminate them from DRAM at that point. It should only need to be implemented at the beginning as it looks like you are successfully reading and writing from DRAM in your main loop. This is a good check to verify that the reads and the writes are working properly, however. This is essentially creating a clean slate before your actual program starts. If you create a new frame at the beginning of your sequence and add the following code inside of that frame, that should effectively clear the DRAM before your main loop executes.

 

DRAM_Clear.JPG

 

-tannerite

Tannerite
National Instruments
0 Kudos
Message 9 of 11
(3,844 Views)

On Friday, I had tried what you are showing in the picture with having the loop at the beginning. During the compile process, I get a Code Generation Error. "Loops using external clocks must never exit." The details say

 

"FPGA VIs do not support exiting loops that use external clocks. This restriction keeps improper block diagram execution contained within the loop if the clock glitches or setup/hold requirements are otherwise violated on flip-flops in the single-cycle Timed Loop. Unwire the conditional terminal for exiting the loop."

 

This is why I had moved it to the first state in the state machine.

0 Kudos
Message 10 of 11
(3,834 Views)