Daklu Posted May 28, 2013 Report Share Posted May 28, 2013 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? Quote Link to comment
Naity Posted May 28, 2013 Report Share Posted May 28, 2013 (edited) 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 May 28, 2013 by Naity 1 Quote Link to comment
Daklu Posted May 28, 2013 Author Report Share Posted May 28, 2013 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?" 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? Quote Link to comment
Naity Posted May 29, 2013 Report Share Posted May 29, 2013 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 1 Quote Link to comment
Daklu Posted May 29, 2013 Author Report Share Posted May 29, 2013 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? Quote Link to comment
Naity Posted May 30, 2013 Report Share Posted May 30, 2013 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 Quote Link to comment
Daklu Posted May 30, 2013 Author Report Share Posted May 30, 2013 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. 2 Quote Link to comment
Naity Posted May 30, 2013 Report Share Posted May 30, 2013 Thanks for the summary. I did not know about this conditional disable for FPGA, grat thing Quote Link to comment
ShaunR Posted May 30, 2013 Report Share Posted May 30, 2013 (edited) The FPGA_TARGET_CLASS symbol lists the platform model, such as CRIO_9074 and SBRIO_9636. Very handy. FPGA_TARGET_FAMILY is another useful one since multiple models have the same FPGA (SPARTAN3, VIRTEX5 etc) Edited May 30, 2013 by ShaunR Quote Link to comment
AlexA Posted May 31, 2013 Report Share Posted May 31, 2013 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 Quote Link to comment
Daklu Posted May 31, 2013 Author Report Share Posted May 31, 2013 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... Quote Link to comment
JamesMc86 Posted June 6, 2013 Report Share Posted June 6, 2013 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. Quote Link to comment
king_cluster Posted August 7, 2014 Report Share Posted August 7, 2014 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! Quote Link to comment
shoneill Posted August 7, 2014 Report Share Posted August 7, 2014 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. Quote Link to comment
ned Posted August 7, 2014 Report Share Posted August 7, 2014 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? Quote Link to comment
king_cluster Posted August 7, 2014 Report Share Posted August 7, 2014 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! Quote Link to comment
king_cluster Posted August 8, 2014 Report Share Posted August 8, 2014 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 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.