LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

sequence structure compiled for FPGA

On a PC/CPU platform the sequence structure, stop all processes (asynchronous task), executes the structure then stopped task can continue.  From the manual "Sequence structure guarantee the order of execution and prohibit parallel operations."

 

Is this also true (asynchronous task stopped) when sequence structure is compiled (Bitfile) for FPGA operations?  I noticed the use of sequence structure throughout FPGA code examples.

0 Kudos
Message 1 of 12
(370 Views)

@richjoh wrote:

On a PC/CPU platform the sequence structure, stop all processes (asynchronous task), executes the structure then stopped task can continue.  From the manual "Sequence structure guarantee the order of execution and prohibit parallel operations."

 

Is this also true (asynchronous task stopped) when sequence structure is compiled (Bitfile) for FPGA operations?  I noticed the use of sequence structure throughout FPGA code examples.


A sequence structure is for when dataflow is not supported due to no common wires between functions.  We could put those functions into a subVI and make common wires so that we can avoid the sequence structure.

 

FPGAs do not have tasks the way a CPU does.

 

In a sense, FPGAs are simpler devices than CPUs, so a sequence structure on an FPGA is less frowned upon.  Would be good to get into some examples for a more specific review.


Certified LabVIEW Architect, Certified Professional Instructor
ALE Consultants

Introduction to LabVIEW FPGA for RF, Radar, and Electronic Warfare Applications
0 Kudos
Message 2 of 12
(362 Views)

@Terry_ALE wrote:

FPGAs do not have tasks the way a CPU does.

 

In a sense, FPGAs are simpler devices than CPUs, so a sequence structure on an FPGA is less frowned upon.  Would be good to get into some examples for a more specific review.


I viewed the many LV examples in the NI FPGA Example Code where sequence structures are used throughout.  Let me ask another way, is a sequence structure OK to use for FPGA since it does not impede program flow? 

 

(I get that FPGA can be configured as a parallel processing device, but examples are showing sequence structures to control serial program flow).  Does it matter if another structure, case, error wire or data wire is used to control programming flow in those examples.

0 Kudos
Message 3 of 12
(308 Views)

Hi richjoh,

 


@richjoh wrote:
Let me ask another way, is a sequence structure OK to use for FPGA since it does not impede program flow? 

Sequence structures were/are recommended for FPGA when you want to make sure your loop (aka "code inside the loop") does respect the wait time you set in your (ordinary) while loop.

This is one item where you don't want to handle parts of code in parallel (like the wait and the rest of the code inside the loop).

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 4 of 12
(296 Views)

Take a look at the RS232 Reference Examples

 

Several of those VIs BD has extensive use of flat sequence structure, even sequence structure recursively.  Is it better practice to use the error wire and other data wire instead of overuse of the sequence structure for programming (operations) of FPGA. 

 

Or is it once final source code is compiled into a Bitfile, the sequence structures overuse is not an issue?  Below is a BD from one of the VIs I linked.  Notice the recursive sequence structures.

UseOfSeqStructFPGA.PNG

0 Kudos
Message 5 of 12
(285 Views)

@richjoh wrote:

Below is a BD from one of the VIs I linked.  Notice the recursive sequence structures.


Note that, unlike "regular" LabVIEW, FPGA code has no Error line to "serialize" functions, especially "timing" functions which operate on sub-microsecond accuracy and precision.  In fact, in "regular" LabVIEW, one of the few placed a sequence structure makes sense is when you need to put some "millisecond wait" between two functions on an Error Line -- make the Error Line run through the Sequence and put the Wait inside.

Note that the nested sequence structures in your example are not "recursive" (look up the definition of "recursion").

 

An example -- you want to make a pulse train with 100 1 micro-second pulse every millisecond.  You can do this with 1 For loop (to count the 100 pulses).  Inside you put a sequence with 4 panels.  In Panel 1, you set the Digital Output line True (= high).  In the second, you put a wait of 1 micro-sec.  In the third, you set the DO line False (= low), and in the final panel you put a wait of 999 micro-sec (to make the time of the single pulse 1 msec.

 

Bob Schor

0 Kudos
Message 6 of 12
(272 Views)

IMHO, my question goes unanswered.  Is overuse or heavy use of the Flat sequence structures good code practice when its on FPGA HW?  Maybe no one here knows what the final Bitfile will "look like" or the serial steps that are compiled.

 

Looks like the FPGA property/invoke node have error terminals, the terminals are not exposed and used here.  My pic below shows one of the terminals.

 

UseOfSeqStructFPGA_ShwErrTerm.PNG

 

I found the Stall Data Flow.vim (basically Wait func) to work just as you described for millisecond wait.
UseOfSeqStructFPGA_StallFlow.PNG

 

In a software context, recursive is use of a function that call itself.  The BD in the pic shows Flat Sequence Structure executing inside of Flat Sequence structure BUT there is more going on of course and sequence structure is not directly calling itself for a solution. 

0 Kudos
Message 7 of 12
(248 Views)

Hello, @richjoh.

 

     I'm not sure why you are arguing with me.  Maybe you didn't learn that LabVIEW is unlike many other programming languages because it uses the principles of Data Flow, which includes the notion that (and I'm paraphrasing here) "once entered, a structure does exit until all of the code inside it has run".  This principle gives LabVIEW concurrency, the ability to do multiple "pieces of code" at the same time.

 

     In a normal CPU, of course, there are a limited number of "sequential processors that work very rapidly" -- tasks distributed to, say, two "cores" of a multi-core chip, can run simultanously (concurrently), but there may be only 8 cores, so you depend on "time-switching" to simulate concurrency.  But an FPGA basically builds as many cores as you program, and forces them to work concurrently.

 

     Another special attribute of LabVIEW is that "time", as well as "numbers", is a primitive data element that can be managed by "time" elements.  But such elements frequently don't have "handles" (such as the Error Line) that allow them to be placed "in sequence" with other pieces of LabVIEW code.  The Sequence structure is necessary to bind a LabVIEW "Wait" function to a LabVIEW "wire", which is precisely the code that the Stall VIM generates.

 

     When you write FPGA code, you are giving the (fairly long and complex) FPGA compiling process instructions to govern when a piece of code is allowed to be marked as "finished" and allowed to do "what comes next".  The FPGA Time Primitives, like the Wait (ms) primitive, has no Error Line, so "best practice" to say "Do this and simultaneously wait this many ticks" requires a Structure to bind them, which is frequently the sequence structure.  Note that for true concurrency (which the FPGA gives you), you don't want an "Error Line" in the timing primitive, since another Data Flow rule is that "Data Flow" prevents concurrency -- you can't simultaneously set a TTL output High and wait 2 ticks if you "serialize" them by using something like the Stall VIM -- you must "enclose them in a Structure".

 

     So regard the Sequence Structure as a "Do-Nothing Concurrency Enforcer" that is the ultimate in "efficiency at run time" at the "cost" of "complexity at compile time" (which the Compiler writers, hopefully, have handled for you.

 

Bob Schor

0 Kudos
Message 8 of 12
(230 Views)

@Bob_Schor wrote:

Hello, @richjoh.

 

The FPGA Time Primitives, like the Wait (ms) primitive, has no Error Line, so "best practice" to say "Do this and simultaneously wait this many ticks" requires a Structure to bind them, which is frequently the sequence structure. 

 

     So regard the Sequence Structure as a "Do-Nothing Concurrency Enforcer" that is the ultimate in "efficiency at run time" at the "cost" of "complexity at compile time" (which the Compiler writers, hopefully, have handled for you.

 

Bob Schor


I found your two sentences quote above helpful toward an explanation of overuse of the Sequence structure.  All the remaining dataflow, error wire etc. is something I didn't initiate into the discussion.  

 

Thanks for the response.

Message 9 of 12
(215 Views)

@Bob_Schor wrote:

Hello, @richjoh.

 

......

 

     So regard the Sequence Structure as a "Do-Nothing Concurrency Enforcer" that is the ultimate in "efficiency at run time" at the "cost" of "complexity at compile time" (which the Compiler writers, hopefully, have handled for you.

 

Bob Schor


First off, great answer.

 

But I'm still going to add my 2c. The very first question which pops into my mind is "Is the FPGA code in a While Loop or a Single-Cycle Timed Loop"?

 

So the TL;DR answer to "Does a Sequence structure affect my FPGA code" : is "In a SCTL, no. In a standard While loop, most likely"

 

Why is this important? Well, if you reference the document "LabVIEW High-Performance FPGA Developer’s Guide" which can be found HERE, on pages 15 and 16 it outlines the differences in how SCTL and standard While loops run on LabVIEW FPGA. It's an old document now (10 years and counting) but I reckon it's changed very little since it was written.

 

In a standard While loop (non-SCTL), flow control implemented behind-the-scenes by LabVIEW is expressed through (in Standard While Loops)

 

"Each node can take one or more cycles to execute. In LabVIEW FPGA applications, code placed outside the SCTL can exhibit varying timing behavior from one  compilation to the next or across different versions of the LabVIEW FPGA Module.
The preservation of structured data flow means that, for chains of nodes with data dependencies, only a subset of the nodes is actively executing at a given time while the rest of the circuitry awaits data."

 

This automatic insertion of lots of Registers (It adds up really quickly) is the reason why

  • Max throughput of While loops are generally much lower than SCTLs
  • Resource usage in While loops is typically significantly higher than in SCTLs
  • Achieving compilation success (no timing violations) is easier in a While loop, because all the timing paths are much shorter (register to register).

 

This means that LabVIEW is adding all kinds of synchronising and serialisation registers depending on the code. It's perfectly feasible that a sequence structure could be respected in this operation, or it could be completely ignored. Only LabVIEW R&D really knows. My assumption would be that it DOES affect the actual operation of these registers implemented behind-the-scenes. It's an explicit use of sequencing so it would make sense for me that the method of sequencing implemented by LabVIEW in non-SCTL code would respect this. I'm not part of LV R&D. I suppose one could theoretically do a Vivado export and look at the code but I've got better things to do with my time.... we don't use standard while loops at all in LabVIEW FPGA.

 

Shane

Message 10 of 12
(184 Views)