From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Binning in FPGA - parallel loops

Dear all,

I am rather new to FPGA and face a problem:

 

I want to measure analog voltages and a digital frequency at a certain rate, and pass it to a FIFO for further processing.

 

Analog input at a certain rate: no problem, each iteration at that certain loop rate I read one sample.

Now the problem:

To measure an digital frequency (from an encoder), I want to measure the the period (I found examples here) of the signal at the fastest rate possible, buffer the data, and in the same frequency as the analog input, I want to average the buffered frequency data, and add it to the data array to be passed in the FIFO. So that my analog measurements and frequencys are (more or less) syncron.

 

Can anyone help how to do this?

First approach is do have 2 loops at different rates, one for analog signals and passing it to FIFO , the other one at the 40 MHz rate calculating the periods each iteration. My idea was to buffer the data from the fast loop, pass it to the slow where an average is calculated each iteration of the buffered data.

 

Thank you.

0 Kudos
Message 1 of 8
(3,389 Views)

I would do the averaging inside the fast loop. Calculate how many fast loop cycles per cycle of the "slow" loop (if not an exact multiple there are some simple workarounds). Keep a running sum of the measurements in the fast loop, and every n cycles (however many is one slow loop) you divide that sum by n, put the result into a FIFO, zero the sum, and repeat.

0 Kudos
Message 2 of 8
(3,379 Views)

I think I understand what you're doing and I think I've done something similar in the past.

 

In that case I used the crio waveform library (not restricted to crio, just called that -- http://www.ni.com/example/31206/en/) which gives you an FPGA template for aquiring a bunch of data at one rate (or multiple loops for multiple rates). This is great for analog but as you identified its an issue for data where you need to talk to the hardware faster than you actually need data. So then I set up 1 or more parallel high speed loops where I am constantly performing all of the calculations I need and storing that result (I guess an average in your case?) in something like a global or a register item. Then in the sample loop (part of that template where you are reading from AI) I'll read from the memory location.

 

This has the advantage of eliminating any need for handshaking/sync between the fast and slow loops because the fast loop always has a new value available for you. The disadvantage is that the averaging code is a bit more complex, as you have to have a running average.

0 Kudos
Message 3 of 8
(3,359 Views)

Thank you for your help!

My first approach was to run 2 loops at different speed. The fast loop counts the edges of the digital signal and calculated the period at the same rate as the second loop.

I tried to implement this, but I am not sure whether this is going in the right direction. Any comments are appreciated.

Thank you.

0 Kudos
Message 4 of 8
(3,324 Views)

Looks like a good start. a few comments:

-Your bottom loop is very similar to what the cRIO waveform library does, except that library includes a lot of error checking and validation which you are missing. I'd highly recommend taking a look at it.

-The comparison (tick count == sample time?) will not do what you want. That equality will only be true once, I think. Instead you should make a rollover counter (since it a timed loop you get one tick per iteration, and you want the tick count to reset when you reach a certain point)

-Your top loop and bottom loop are almost certainly not synchronized. That is, if your sample rate is 5 ms you could have data as old as 4.999 ms. If this is acceptable then don't worry about it. If you want more current data you can either set up some sort of handshake between the two loops or you could go for a continuous evaluation where the "period (ticks)" value is *always* current and you have a rolling buffer of samples you care about.

0 Kudos
Message 5 of 8
(3,312 Views)

Thank you for your time and the hints.

I implemented some of the error checking and switched to another approach:

The fast loop counts the edges of the digital signal and stores the current count in a local variable.

The slow loop calculates the period based on the counts since its last iteration and the ticks since its last iteration.

I hope this solves some of the issues. The count of the edges in the fast loop is reset whenever its been used in the fast loop. I thought I might run into trouble when the count reaches the "largest possible value", not sure if that wóuld be an issue though.

 

I'd be thankful for any comments.

Jack

0 Kudos
Message 6 of 8
(3,291 Views)

One question is whether a local variable is the most appropriate way to transfer the current 'edge count' from the fast to the slower running loop ?!

Thank you for any hints.

 

Jack

0 Kudos
Message 7 of 8
(3,253 Views)

A local variable is fine. Personally I'd use a Register which is pretty much a local variable without the user interface component. I suspect they're implemented the same way on the FPGA, but I'm not a low-level FPGA expert (that's why I use LabVIEW!).

0 Kudos
Message 8 of 8
(3,248 Views)