From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, 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: 

Dynamic choice of FPGA I/Os

Solved!
Go to solution

Hello all,

I have a question about LabVIEW FPGA coding.

So I have a cRIO-9040  and I also have 4x NI-9238 cards.

I am essentially writing code that takes voltage measurements utilizing the 16 channels of the 4 cards.

I would like to dynamically select which inputs are being used by the measurement, instead of hard coding which inputs to use.

Instead of having to make a case structure with every single possibility for 16 channels (65,535 possibilities) like this:

gif.gif

I would like to just specify on my PC application: Mod1/AIO, Mod1/AI3, Mod3/AI2, etc.

Is there some way to do this that I am overlooking besides coding 65,535 possibilities?

0 Kudos
Message 1 of 13
(3,719 Views)

When I develop similar application, I don't use case structure.

Your idea is general but as you know, is troublesome. How about following code?

 

fpga.png

 

Anyway, in my general step, I place all IO node which would be required. I do an operation of the channels as array operation.

 

Certified LabVIEW Developer
There are only two ways to tell somebody thanks: Kudos and Marked Solutions

GCentral
0 Kudos
Message 2 of 13
(3,693 Views)

That would mean that I would still have to acquire all 16 channels every time. Also, I perform some computations based on the measurements taken, which I need to process in parallel for speed reasons, hence, I do not wish to join the different fixed-point values and then cycle through them all in an array serially.

 

If a for loop on LabVIEW FPGA doesn't have any iteration-to-iteration dependencies, are all iterations computed at once?

0 Kudos
Message 3 of 13
(3,666 Views)

In my opinion, placing FPGA AI I/O into case structure lose an outlook of program.

It makes difficult to check source code and if a node is placed in multiple case, it wastes FPGA resource.

If you just want to compute data, I recommend to do the operation in SubVI and use SGL or standardized fixed-data type.

Certified LabVIEW Developer
There are only two ways to tell somebody thanks: Kudos and Marked Solutions

GCentral
0 Kudos
Message 4 of 13
(3,645 Views)

I don't have a solution regarding the different fixed-point types (but why/how do you have these - you said two of the same module, no?) but you don't have to acquire all channels - you can (I think) use array subsets.

 

You cannot allow the references to be dynamic though - so you can't for example specify them from the host PC (again, AFAIK). They must be specified as BD constants (you also can't select by reference, which is annoying but I'm told a necessary requirement, see https://forums.ni.com/t5/LabVIEW-FPGA-Idea-Exchange/Selecting-between-two-I-O-refnums-not-allowed/id...).

 

If you have a For loop in a SCTL, the loop will be unraveled and all iterations will happen at once. If this can't be done, the compilation will fail. You don't need to add the P node.

Outside of a SCTL, I think it behaves like a normal For loop on e.g. Windows - they will run one after another.

If I set a For loop with "Iteration Parallelism" (i.e. the P node) then I get an error - "For Loop with iteration parallelism is not supported on this target." (cRIO-9045, presumably general?)

This is true both inside and outside of SCTL (so you can never have the P node).


GCentral
Message 5 of 13
(3,628 Views)

Hi Gryffin,

 


@Gryffin wrote:

So I have a cRIO-9040  and I also have 4x NI-9238 cards.

Is there some way to do this that I am overlooking besides coding 65,535 possibilities?


The FPGA is quite good at converting integer data into their bits so all you need is a U16 for selection:

check.png

On FPGA you also have the problem of "fixed-size arrays", so it becomes hard to change array size at runtime.

I also think it's easier (less FPGA fabric) to read all 16 IO nodes all the time and only process the samples you need…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 6 of 13
(3,623 Views)

Following on from GerdW's post, you can also do the following:

Example_VI_BD.png


GCentral
0 Kudos
Message 7 of 13
(3,618 Views)

Hi Gryffin,

 


@Gryffin wrote:

That would mean that I would still have to acquire all 16 channels every time. Also, I perform some computations based on the measurements taken, which I need to process in parallel for speed reasons, hence, I do not wish to join the different fixed-point values and then cycle through them all in an array serially.


What's wrong with reading 16 samples?

Those 9238 modules give you (at max) 50kS/s: the FPGA should be fast enough to process those 16 samples at a rate of 50kHz! So why do you think you need to process them in parallel?

 


@Gryffin wrote:

If a for loop on LabVIEW FPGA doesn't have any iteration-to-iteration dependencies, are all iterations computed at once?


I don't think so, but I'm no expert in all those compiler optimizations NI and Xilinx implemented over the years…

When you want to process 16 samples in parallel you still can do so: just get rid of the BuildArray node and process each sample on it's own. But from your description you still need some other data (like scaling factors) to be applied for each channel/sample, so (autoindexing) FOR loops might become handy anyway…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 8 of 13
(3,603 Views)
Solution
Accepted by topic author Gryffin

Even if you really, really, really only want\need to read the channels you need, you wouldn't need 2^16 cases.

 

You'd only need 17 cases, duplicated 16 times. Potentially 17 cases in a sub VI, copied 16 times.

 

Each case would read 0 or 1 specific AI, depending on a value. Repeated 16 times, you can read 0-16 channels, specifying which channels you want.

 

I agree though that the simple solution is to simply read the 16 channels. (Pick your battles, optimize when\where needed, live happily ever after, and so on...)

0 Kudos
Message 9 of 13
(3,596 Views)

You're absolutely right, now that I realize.

If I create 16 different controls of channels i.e. Mod1/AI0, Mod2/AI3, etc.

And then create a case structure of 16 different cases being 1 channel, 2 channels, etc.

And then use local variables created from all of the controls for each case, I can dynamically select how many channels to use and which channels to assign!

 

Thank you for your help!

0 Kudos
Message 10 of 13
(3,505 Views)