Jump to content

How to manage FPGA/RT code destined for multiple target types?


Daklu

Recommended Posts

I've been working on a cRIO-9074 project recently primarily via remote desktop into the customer site.  This morning I discovered my connection was down and there was nobody around to restart it.  I couldn't really do nothing all day, so I cloned my project, ported it to an sbRIO I had on hand, and continued working.

 

I discovered I really like being able to easily shift between RT/FPGA targets.  It makes development so much easier and faster compared to remoting in to a client's site.  My question is what are some good ways to manage code so it can run on multiple target types?

 

Currently I have two targets in my project, one sbRIO and one cRIO.  All the source code is listed under both targets.  It seems to work, but there's a lot of bookkeeping to track because many resources aren't shared between targets.  (FIFOs, registers, memory blocks, build specs, etc.)  It requires me to keep all the resource names synched and make sure the properties are identical.  I'm constantly worrying about screwing it up.  Is there a better way to do this?

 

I noticed the sbRIO-9636 uses the Spartan 6 LX45 and the 9074 uses the Spartan 3 with 2M gates.  I assume I cannot use the bitfile from one for the other?

 

I've been using conditional disable structures a bit and noticed there is a TARGET_CLASS symbol available when using it on an FPGA vi.  The help files don't give any information about that symbol.  Anyone know what it does?

Link to comment

Hi Dalku,

 

it is true that, due to the different model of the FPGA Target, you can not simply load the bitfile from the Spartan 6 LX45 to the Spartan 3. Your FPGA VI needs to be recompiled.

 

The "easiest" way to write code so that it is as portable as possible is, in my opinion, to have as much items in the VI and as little in the project. This mean, using target scoped block memories, registers and FIFO. You can create those items directly in the VI (the functions are in the "Data Storage and Transfer" palette) and thus can simply copy your VI to another target without needing to recreate the project items: they are hard-coded. 

 

Hope this answers your question.

 

Cheers

Edited by Naity
  • Like 1
Link to comment
The "easiest" way to write code so that it is as portable as possible is, in my opinion, to have as much items in the VI and as little in the project. This mean, using target scoped block memories, registers and FIFO.

 

Thanks for the response.  I assume you're referring to the "VI Defined Registers?"

 

post-7603-0-56358600-1369765215.png

 

The problem with these is (as far as I know) they only apply to a single VI.  I'm using registers to send triggers between parallel FPGA components and each component is in its own VI. 

 

Hmm... I just realized the FPGA resource functions have inputs for the resource name.  Using those in my components instead of hard coding the name in the function call might help.  The top level vi could inject the correct resource names into each component.  Would I need a different top level vi for each target, since each target has to define its own resources?

Link to comment
Thanks for the response.  I assume you're referring to the "VI Defined Registers?"

 

Yes, I was refering to this palette (to both registers and block memory... even FIFO if you need them). 

 

Also they do not apply to a single VI but to a single target (you can not define a bloc memory for a single FPGA VI, it physically does not really make sense as the VIs don't exist after compiling no more). If you need to, you can pass their reference as parameter to a sub-vi. 

 

I am not sure about what you mean with "Would I need a different top level vi for each target, since each target has to define its own resources?". If the question is "do I need to create a different "[FPGA] Main.vi" for each target?", the answer is no. It is not a need (and it is the main advantage about thos functions). Theoretically, you can simply copy the VIs to another target, compile and it should work. However it is depending of the ressource usage. A spartan 3 and a spartan 6 do not have the same ammount of slices, gate, LUT and memory available. If you try to use more memory than available, the compilation will fail. However this problem is the same when you create the register and memories in the project explorer.

 

Cheers

  • Like 1
Link to comment
If you need to, you can pass their reference as parameter to a sub-vi. 

 

<The light flickers on.>

 

I get it.  I'm so used to using FPGA resources directly I didn't realize the vi-defined resources have an output terminal.  I think making that switch will make things *much* easier.  Thanks!

 

The natural follow up question:  Am I giving up anything by using vi-defined resources instead of project-defined resources?

Link to comment
The natural follow up question:  Am I giving up anything by using vi-defined resources instead of project-defined resources?

 

It shouldn't. So far I know it is not an algorithm and thus it does not need an clock cycle to be created nor to be passed to a subVI. However I might want to doublecheck that ;)

Link to comment

To follow up some of my earlier questions for future readers:

 

I discovered I really like being able to easily shift between RT/FPGA targets.  It makes development so much easier and faster compared to remoting in to a client's site.  My question is what are some good ways to manage code so it can run on multiple target types?

 

I used to keep copies of all VIs under both targets, but it was a pain keeping them synchronized.  On top of that the classes would end up locked because it was being loaded on multiple targets.  Now I keep all the RT code under one target and copy the top level VIs to the other target when I need to run the code on that target.  It seems to be working quite well. 

 

Currently I have my entire FPGA code fully listed under both targets, but I'm pretty much done with that and just haven't bothered cleaning it up.  It doesn't have the same problem with locking VIs so there's no motivation to mess with it right now.  I suspect I could just copy the top level FPGA VIs to each target and it would work fine.  Each FPGA target does maintain its own project-defined resources and build specs.

 

 

I've been using conditional disable structures a bit and noticed there is a TARGET_CLASS symbol available when using it on an FPGA vi.  The help files don't give any information about that symbol.  Anyone know what it does?

 

I had thought all symbols were defined in the project and the built-in symbols did some magic behind the scenes.  Turns out it is much simpler than that.  I discovered each RT and FPGA target has its own list of conditional disable symbols.  Setting symbols for each target means I don't have to remember to switch symbol values every time I run the code on a different target.  The FPGA_TARGET_CLASS symbol lists the platform model, such as CRIO_9074 and SBRIO_9636.  Very handy.

  • Like 2
Link to comment

Hey Daklu,


Have you discovered any problems with defining internal FIFOs on the block diagram as opposed to in the project? It sounds like a very useful paradigm, don't have a use for it right now but can definitely imagine using it in the future.

 

Cheers,

Alex

Link to comment
Have you discovered any problems with defining internal FIFOs on the block diagram as opposed to in the project? It sounds like a very useful paradigm, don't have a use for it right now but can definitely imagine using it in the future.

 

Nope--I haven't used it yet.  I had already defined the FPGA resources for each target in the project and the code was complete when I posted my original questions.  If it ain't broke...

Link to comment
Have you discovered any problems with defining internal FIFOs on the block diagram as opposed to in the project? It sounds like a very useful paradigm, don't have a use for it right now but can definitely imagine using it in the future. 
The main issue I see is your resource definition is spread about rather than being in one place so if you run into resource issues it is harder to get a picture of what is going on. That said this technique is also great for reusable code. Take a look at the VST sample projects, they make extensive use of this for reusable code modules under FPGA.
Link to comment
  • 1 year later...

Awesome topic!  I've added conditional disables so that I could merge cRIO code and sbRIO code.  So now I have one FGPA program and I created a project with two targets (cRIO/sbRIO).  However, when I compile one, it breaks the other.  So, I can't just switch between the two, without recompiling.  Any ideas of what I could be doing wrong?  The project uses FIFOs, Memory, and Registers, which I have defined in under both targets in the project.

 

THANKS!

Link to comment

The main issue I see is your resource definition is spread about rather than being in one place so if you run into resource issues it is harder to get a picture of what is going on. That said this technique is also great for reusable code. Take a look at the VST sample projects, they make extensive use of this for reusable code modules under FPGA.

 

The upside of this is that if you need 1 instance, you use 1 VI, if you need 8 instances, you use 8 VIs.  Instant scaleability.  That's the main reason why I went in this direction.  In one sense, having all the relevant information in the code instead of spread between code and project makes it (for me at least) easier to understand.  Add in more modular design capabilities with registers instead of globals and things start looking good.

 

Shane.

Link to comment

KingCluster - how are you opening the FPGA VI reference? If you're referring to the VI, then yes, it probably will show up as not compiled because the VI or its subVIs were last saved for a different target. Loading a bitfile or build specification instead should solve the problem. If that's not it, can you be more specific than "breaks"? What error do you get, and where does it occur?

Link to comment

In the RT I create a reference and configure it to the FGPA VI and select dynamic.  The I use a dynamic FPGA interface cast to cast it to a type def, that defines all my indicators, controls, and FIFOs.  HOWEVER, the problem occurs, without even running the RT code.  Simply attempting to run the FPGA code on one target and then on the other requires me to recompile, even without modifying the FPGA code.  I'm not sure what breaks, I just assumed/hoped that I was doing something wrong.  I've been focusing my troubleshooting efforts on the definition of the FIFO, which are currently defined on both the targets to be the same.  One thing that I did notice is a loading of some sort of niFPGAfifoemulation stuff, unfortunately I haven't caught exactly what it is, because it loads too fast.

 

I will try to capture some more data to help everyone understand the issue.

 

Thanks!

Link to comment

I've attached an example project demonstrating how to create a project that can run on two different targets.  Oddly, the issue that I was having requiring me to recompile the FPGA while switching between targets hasn't occurred in this sample project.  Additionally, when I created the FPGA reference on the RT, I did not need to do a dynamic type cast, I simply selected the "correct" FPGA when configuring open FPGA VI reference, which should be noted, is from the correct target.

 

Dual Targets.zip

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.