LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

FPGA Table Based AO

I have a Windows based PC and an R series FPGA card.  I would like to be able for my host PC to send to the FPGA a table of times and values, and then have the FPGA play them, interpolating the voltage it should output between points.  I don't think this is impossible but it will need lots of high precision mulipliers (of which I have few), and floating point math (which is costly in size).

 

In addition to this my end goal will also have a DO that can be corelated to my AO table, and have it be on it's own time scale or sync to the same table as the AO.

 

Lastly I'd like to be able to sample an AI at the same clock, or a decimated clock from my AO.

 

I think the majority of these things can be done, but I'm hoping that some of this has been done by someone else.  Searching for arbitrary waveform output from an FPGA generally has you dumping the slices of the wave down to the card, and then it plays the outputs from a look up table.  This won't really work here because the wave maybe 10s of hours long, and slicing that up into micro second outputs means lookup tables larger then what is possible.  Any thoughts?  Has anyone attempted something like this?

 

Example Table:

 

Time(s)---Voltage(V)

0---0

10---3

50---2

1000---0

 

In this example at 5 seconds after starting the output should be 1.5V.

 

 

0 Kudos
Message 1 of 7
(2,789 Views)

Hi there,

 

You may be able to push that large look up table on a memory item. The idea is to use RAM instead of the slices. You can find more information here:

 

1. Storing Data on an FPGA Target (FPGA Module)

2. Transferring Data Among Parallel Loops (FPGA Module)

3. Periodic Waveform Generation with LabVIEW FPGA (Memory Read and Write)

 

I hope this information can provide a starting point to build your application

 

Regards,

Alejandro C. | National Instruments
Message 2 of 7
(2,736 Views)

How about reformatting the problem slightly? Send an initial value to the FPGA. Then, send a table containing pairs of increments and repetitions (number of times to increment/decrement by that amount). This moves most of the difficult math to the host PC where it's easy, while sending a similar amount of data to the FPGA.

Message 3 of 7
(2,729 Views)

Thank you both for you advice but it is not what I want, and I feel like this is my fault in not explaining.  It was a Friday night that I posted on my way out of the office.

 

My requirement is to be able to set an analog output, based on a table.  That table of values does not repeat, and maybe as long as 10 hours.  This is not a wave or a periodic signal just a table of times and voltages.  The number of time/voltage pairs is probably never going to be over 50.

 

My plan is to put the time and value pairs down on the FPGA using a DMA, and then tell the FPGA to go, and it will consider time=0 my start.  Based on how much time has elapsed from the start, output the appropriate voltage updating as often as possible.  Hopefully in the hundreds of kHz or even MHz.

 

I wrote several test VIs and the most successful was using 2 1D array of fixed point numbers on the front panel instead of the DMA.  One of the arrays was time, the other voltages that AO0 would output.  I used the 32 bit micro-second counter, entered values, hit go, and it tracked to the voltage using linear interpolate code from basic algebra.  The code used several multiply and divide functions but it fit and it ran fine.

 

I then copied that code back to the host to test it and simulate 10 hours of elapsed time.  Before finishing my test I realized a 32-bit unsigned timer in micro seconds would elapse in 2 hours.  So I wrote my own 64 bit micro second timer.  On the Windows side this worked, and accuratly output the values I wanted for the simulated 10 hours.

 

Now I am working on making it fit on the FPGA.  Timing violations at the moment, and converting to use a DMA instead of the arrays.

0 Kudos
Message 4 of 7
(2,706 Views)

Okay so I think I have a working solution.  You provide a table to times, and voltages for AO0, and digitals that DO0 and DO1 should be as well.  You then put those on the FPGA using a FIFO.  Then say how many times this profile should cycle through that table.  The table is what I mentioned before that maybe 10 hours long and not repeating.  The repeating part is those 10 hours can repeat.  The profile can have time above 10 hours, but the number of points are limited to 512 at the moment.  I can increase this but I don't know how much.

 

The host can then get feedback on how many cycles it has completed, and how far into the current cycle it is (both are progress bars).

 

The host also gets a FIFO of an AI that is being sampled at the same time the output is being sent.  These two things aren't synced but for me that's fine the user just wants to see some feedback that the analog output profile is working.  Not that it lines up with the profile down to the microsecond.

 

It takes up a decent amount of resources on the FPGA, but it does all fit on the low end FPGA, and there is still some room to grow.

0 Kudos
Message 5 of 7
(2,673 Views)

I don't know if anyone actually cares but I found a bug with my U64 timer.  I convert microseconds to seconds by multiplying by 0.000001.  Problem is with fixed point you can't represent that exactly and you get a timing drift issue.  The easy fix is to instead divide by 1000000.  Make this fix to the U64 Timer Control Loop.

 

Using this technique I estimate that my analog output update rate is 280KHz, and my digital output update rate is 975KHz.

0 Kudos
Message 6 of 7
(2,654 Views)

I do appoligize for quadrupal posting but I wanted to post my conclusion so others could use it.  I updated the code to work faster, and verified the functionality with a scope.  I have posted my code here.

0 Kudos
Message 7 of 7
(2,603 Views)