02-14-2014 02:30 AM - edited 02-14-2014 02:32 AM
so I'm working on a new FPGA architecture which makes heavy use of data registers for attempts at a nicely scaleable FPGA code. I got the basics working and since my main VI had a code complexity of 19 (!) I decided to refactor.
Since each "module" is a seperate timed loop with the inter-loop communication being performed via Registers (in a cascade fashion) I decided to pop each loop into it's own Sub-VI. But when I tried this (despite the fact that my Loops have only INPUTS and don't have outputs), LabVIEW didn't let me create a sub-vi directly but rather recommended me to make a regular VI which I did. Upon replacing the original code with the new VI, the code was not broken.
This is the result of my "create standard VI and then replace old code with VI). Both wires going to the VI are inputs (clusters of I/O registers).
It seems the check for cycles was a bit over-zealous here. Or have I missed some special arrangement with FPGA targets?
Shane
PS I had actually never encountered this message before and misunderstood the word "cycles" to mean something else on the FPGA target until I googled the message. I WAS wrapping a SCTL after all.
02-19-2014 02:29 AM
Hello Intaris,
I would like to try and help you with this topic.
But first I have got a few questions:
1. what do you mean by "complexity of 19"? Do you mean you have a main VI which then goes down to 19 levels of SubVIs?
2. Using SubVIs on FPGA is a little tricky in general. You should avoid overdoing it since it takes a lot of gates
Also, could you please post a screenshot of your main VI, so I can see what you are doing? I am afraid I can not fully understand your application at this point.
Thank you,
02-19-2014 03:05 AM
Each VI in it sproperties has a "Code Complexity" number which, together with the environment settings for compiler optimisations, decides on whether the VI will be compiled with full or partial optimisations. This value for "Code complexity" was 19. The maximum setting for full compiler optimisations is 10. Therefore this VI could never be fully optimised (at least the LV stage).
My sub-VI is set to be a preallocated clone. It handles creation of many registers (each of which is also within a preallocated clone VI). Using a series of registers I plan to pass data between several loops running in parallel in order to daisy chain together different functionality (I/O, Lockin etc.). The sub-VI is therefore simply an easier method of representing the code, it is not used in multiple places and should (when compiling) be equivalent to having the code ont he Block Diagram of the main VI.
Shane.
02-19-2014 03:23 AM
Also of note: The content of the sub-VI is a simple SCTL with NO outputs, only inputs. It utilised the registers whose references it is passed (as visible in the picture above).
It writes certain registers after reading data from a CLIP. Those registers are then used elsewhere (Read) to allow further processing to be done in a pipelined manner.
Shane.
02-19-2014 04:07 AM - edited 02-19-2014 04:08 AM
This is essentially the content I was converting to a sub-VI (except the actual code back then had no FP terminals in it. It was reading and writing a CLIP node instead of FP terminals).
Shane.
02-19-2014 10:10 AM
Shane,
The point of code complexity as seen in LV itself (VI properties) or in the cyclomatic complexity test of VI Analyzer is not a concern on FPGA as it only refers to optimization on the DFIR and LLVM level from the LV compiler.
In fact, the FPGA module "dissolves" subVIs by moving the content in the caller as one of the first steps. Please note that subVIs on FPGA are by default reentrant and potentially waste resources because of that (but run completly concurrent!). Changing that to non-reentrant will introduce arbitration which can mess up your timings......
Norbert
02-19-2014 10:34 AM - edited 02-19-2014 10:34 AM
I concede your points regarding FPGA compilation. My observation has been, however, that the act of breaking up a VI into smaller code chunks and thus reducing the code complexity still helps the responsiveness of the IDE which otherwise has to slog through a huge amount of code whenever ANYTHING in the VI changes to ensure that the VI hasn't been broken. For this reason, even though it has zero effect on the actual FPGA compilation, it is a good idea to keep the complexity a bit lower. That's just my personal experience. Mileage may vary.
The idea of making a sub-vi is for me to be able to duplicate blocks of code rather easily. Coupling this with registers (the input wires are nothing but clusters of registers) is a real improvement of things in LV 2012. Multiple autonomous timed loops communicating over pre-defined registers.... Reentrant is good, duplication of code is desired in this case.
Either way, the code was not (as far as I can tell) creating a cyclic relationship anywhere.
Shane.
02-19-2014 01:59 PM
Like you said, it does not appear that your code should create any cycles in the dataflow sense. If you can get this error to reproduce I would send the issue to NI to investigate. Your code should work correctly given the screenshots you posted.
02-20-2014 02:25 AM
I'll see if I can reproduce it in a small example.
Shane