Real-Time Measurement and Control

cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a way to call FPGA-sub VIs with "Open FPGA VI reference"?

Is there a way to call FPGA-sub VIs with "Open FPGA VI reference"? I don't want to add all fpga controls and indicators in the top VI. I
0 Kudos
Message 1 of 13
(8,766 Views)
[...] It should be so much easier if I could call sub-VIs instead of the top-vi (easier to add external code).
0 Kudos
Message 2 of 13
(8,765 Views)
Hello Ulf!

I am not sure if I understood your question correctly, but I believe the function you are searching for is the "Call VI" function. Here is the description for that specific VI:

"Call VI
Allows you to call a compiled FPGA VI as a subVI from a host VI. To specify the FPGA VI to call, right-click the function on the block diagram and select Select Target VI from the shortcut menu. The Call VI function is similar to the Call By Reference Node. When the Call VI function runs, LabVIEW writes all the inputs to the FPGA VI. The FPGA VI then runs to completion. LabVIEW then returns all outputs from the FPGA VI. The Call VI function is similar to the Call By Reference Node. When the Call VI function runs, LabVIEW writes all the inputs to the FPGA VI. The FPGA VI then runs to completion, and LabVIEW returns all outputs from the FPGA VI."

Regards,
Jimmie A.
Applications Engineer, National Instruments
Regards,
Jimmie Adolph
Systems Engineering Manager, National Instruments Northern European Region

0 Kudos
Message 3 of 13
(8,722 Views)


@jimmie A. wrote:
Hello Ulf!

I am not sure if I understood your question correctly, but I believe the function you are searching for is the "Call VI" function. Here is the description for that specific VI:

"Call VI
Allows you to call a compiled FPGA VI as a subVI from a host VI. To specify the FPGA VI to call, right-click the function on the block diagram and select Select Target VI from the shortcut menu. The Call VI function is similar to the Call By Reference Node. When the Call VI function runs, LabVIEW writes all the inputs to the FPGA VI. The FPGA VI then runs to completion. LabVIEW then returns all outputs from the FPGA VI. The Call VI function is similar to the Call By Reference Node. When the Call VI function runs, LabVIEW writes all the inputs to the FPGA VI. The FPGA VI then runs to completion, and LabVIEW returns all outputs from the FPGA VI."

Regards,
Jimmie A.
Applications Engineer, National Instruments




If you are developing a large FPGA-application with a lot of controls and indicators(and FPGA-functions) and the only "valid" FPGA-VI to call is the Top-VI(in the project), you will have hard time to locate the correct control in LV RT. The code gets very large and ugly as well. It would be much easier if I could call Sub-FPGA VIs within the project(working as "top VI"), then I could stucture the application much easier. One FPGA-VI for quadrature encoders, another for serial read/write, a third for DAQ or whatever. As it is today I must move all code to the FPGA Top-VI.

//Ulf
0 Kudos
Message 4 of 13
(8,720 Views)
Hi Ulf,

It is my understanding that you can only run 1 FPGA VI at any time. If you try to call multiple FPGA VI's during a Real-Time while loop for example, you may get erroneus results, such as one data line responding to inputs on another line.

In my case, I was using an FPGA card and pretty much using all of the IO on it. So I created FPGA VI's for each set of associated IO (You do not have to compile these VI's, as long as they are in the same .lep file as the top-level VI, talked about next). Then I incorporated all of those VI's into a top-level FPGA VI that used clusters of each associated IO such that I would have less than the maximum of 28 IO lines coming into and out of the top-level FPGA VI. And compiled that VI. (Note: Originally I had compiled each of those smaller VI's, but it made each of their files about .5 meg, while an uncompiled version was about 50K. As long as your compile your top-level VI you should be fine.)

I then created a Real-Time VI that used the Open Reference, the Read/Write function, and Close Reference to access whatever lines I needed, using unbundle and bundle functions to gain access to desired IO lines.

I would advise against using the CallVI function (unless you have a specific reason to), as it slowed my development dramatically. That larger the VI became the longer it took to change code. Read/Write worked so much better!

Hope my pain and agony 😉 has helped you some.

- Con
0 Kudos
Message 5 of 13
(8,708 Views)


@wrath_of_con wrote:
Hi Ulf,

It is my understanding that you can only run 1 FPGA VI at any time. If you try to call multiple FPGA VI's during a Real-Time while loop for example, you may get erroneus results, such as one data line responding to inputs on another line.

In my case, I was using an FPGA card and pretty much using all of the IO on it. So I created FPGA VI's for each set of associated IO (You do not have to compile these VI's, as long as they are in the same .lep file as the top-level VI, talked about next). Then I incorporated all of those VI's into a top-level FPGA VI that used clusters of each associated IO such that I would have less than the maximum of 28 IO lines coming into and out of the top-level FPGA VI. And compiled that VI. (Note: Originally I had compiled each of those smaller VI's, but it made each of their files about .5 meg, while an uncompiled version was about 50K. As long as your compile your top-level VI you should be fine.)

I then created a Real-Time VI that used the Open Reference, the Read/Write function, and Close Reference to access whatever lines I needed, using unbundle and bundle functions to gain access to desired IO lines.

I would advise against using the CallVI function (unless you have a specific reason to), as it slowed my development dramatically. That larger the VI became the longer it took to change code. Read/Write worked so much better!

Hope my pain and agony 😉 has helped you some.

- Con




Hi Con!
Thank you for your answer! Do you call the top FPGA-VI or the wanted sub FPGA-VI? By the way, I have noticed some strange behaviour when you are using "complex data types", such as cluster in a cluster. Some elements in the cluster did'nt get updated. Either a bug or me.

//Ulf
0 Kudos
Message 6 of 13
(8,705 Views)
You would call the top-level VI from that Read/Write.

I was able to do a cluster within a cluster. It just took a little while for me to get it. I'll see if I can put an example into words.

There may be other ways to do this, but this is what I did... Lets say I have a top-level VI that has digital inputs and outputs and some of them are really clusters within clusters. I would use a Read/Write, then add a control to the Read/Write for one of the cluster within cluster items. Then I right click on the Read/Write control input and "Create a control", which connects a cluster with a wire to the Read/Write control. Go ahead and delete that wire (just the wire). Add a Bundle by name to the block diagram and wire the input cluster node of the bundle by name to the cluster created above. Connect the output node of the Bundle by name, to the input node on the desired Read/Write control. That bundle by name can be expanded to see whatever other elements are within that cluster. Because that cluster is really a cluster within a cluster, now you can repeat the process by starting at the bundle by name, of the desired cluster element and right clicking and choosing Create Control and going like we did above, until you get down to the desired element.

Outputs are much easier. Simply use unbundle, connect to the output of the FPGA VI Read/Write, then wire indicators. If there are cluster within clusters of outputs, then use a chain of unbundle's to get the element you want.

Whew, Now that I've really made things complicated, maybe someone can come in and simplify stuff. LOL

- Con
0 Kudos
Message 7 of 13
(8,701 Views)
Again, thanks for your answer!
You and I have solved the "problem" in the same way... I have implemented it just as you described. I don't think this is good way to interface the FPGA-VI, but it seems like there are no other ways to do it.

//Ulf
0 Kudos
Message 8 of 13
(8,696 Views)
Cool Ulf.

If you find another way, let me know.

Good luck!

- Con
0 Kudos
Message 9 of 13
(8,693 Views)

 


You would call the top-level VI from that Read/Write.

I was able to do a cluster within a cluster. It just took a little while for me to get it. I'll see if I can put an example into words.

There may be other ways to do this, but this is what I did... Lets say I have a top-level VI that has digital inputs and outputs and some of them are really clusters within clusters. I would use a Read/Write, then add a control to the Read/Write for one of the cluster within cluster items. Then I right click on the Read/Write control input and "Create a control", which connects a cluster with a wire to the Read/Write control. Go ahead and delete that wire (just the wire). Add a Bundle by name to the block diagram and wire the input cluster node of the bundle by name to the cluster created above. Connect the output node of the Bundle by name, to the input node on the desired Read/Write control. That bundle by name can be expanded to see whatever other elements are within that cluster. Because that cluster is really a cluster within a cluster, now you can repeat the process by starting at the bundle by name, of the desired cluster element and right clicking and choosing Create Control and going like we did above, until you get down to the desired element.

Outputs are much easier. Simply use unbundle, connect to the output of the FPGA VI Read/Write, then wire indicators. If there are cluster within clusters of outputs, then use a chain of unbundle's to get the element you want.

Whew, Now that I've really made things complicated, maybe someone can come in and simplify stuff. LOL

- Con

 

 

Can you send a screenshot of this? I am trying to do it, but I don't think I understood what functions you used.

0 Kudos
Message 10 of 13
(4,405 Views)