Jump to content

Values between components


Tim_S

Recommended Posts

I'm still working out structure a FPGA program versus one on a PC, so I have a more theoretical question. I have a FPGA program I'm working on that involves two things:

  1. A large number of hardware I/O and parameters sent to an R-Series card (specifically a PCI-7813R)
  2. Internal calculations made in the that are used in multiple other internal subroutines

I pondered and wound up using global variables to store this glob of internal and external values. I've kept pondering as I'm accustomed to considering globals to be akin to "demon spawn and should be avoided as the plague they are." I've poked about example and tutorial code, but everything I've found is too simplistic in that the entire code is a couple of VIs with no connections between them.

How have you structured code to deal with large number of values that have to go various places? Are globals so evil in a FPGA? How have you dealt with sending subsets of a large number of values from subVI A to subVIs B, C and F without creating obstufication or unmanagable code?

Tim

I didn't fail the test, I just found 100 ways to do it wrong. - Banjamin Franklin

Link to comment

I typically use FIFOs in an FPGA. In my current programs, I use 1 DMA to send data down to the FPGA and another DMA to get data back. I then have one loop that reads in the DMA commands and then sends the commands to the relevant sections of code (I have a digital input, digital output, square wave generation, and specific communication bus sections of code) using FIFOs. By using globals, you can slow down your FPGA since sections of code will be blocked until the other section accesses it. There are times that I used them (non critical timing), but try to avoid them.

Link to comment

A lot of traditional good LabVIEW style doesn't apply to FPGA. You want to avoid arbitration - multiple loops all trying to access the same resource, such as a functional global. Also, to maximize FPGA space available for your logic, you want to minimize the amount of space used for data storage by using FIFOs or memory blocks instead of global variables or functional globals. A memory block acts a lot like a global variable in practice, but it is an efficient way to store and share data on the FPGA, and you can avoid arbitration if you have only one location where you read and one location where you write. Similarly, you can choose to have your FIFOs implemented in memory. Note that there's a difference between a DMA FIFO, which passes data between the FPGA and host, and a FIFO that only passes data around the FPGA.

I try to break up my FPGA code into tasks that are easily separable, because the FPGA is really good at doing work in parallel. For sending large numbers of parameters from the host to the FPGA without using a lot of front panel controls, I'd put three controls on the front panel: a data value, an index, and a boolean indicating that the value has been read (you could also use an interrupt). I'd then have a loop dedicated to monitoring the boolean; whenever it's true, write the data value to the specified index, then set the boolean to false. The host sets the value and index, then the boolean, and waits until the boolean has cleared before sending the next parameter. Another loop in the FPGA code reads from the same memory block as necessary to do calculations.

  • Like 1
Link to comment

I really appreciate the responses. I should mention I'm using LabVIEW 8.6 for my current effort as it appears that there have been significant changes with FPGA between 8.6 and 2010.

In my current programs, I use 1 DMA to send data down to the FPGA and another DMA to get data back.

For sending large numbers of parameters from the host to the FPGA without using a lot of front panel controls, I'd put three controls on the front panel: a data value, an index, and a boolean indicating that the value has been read (you could also use an interrupt). [snip]

That's two interesting approaches. I think the DMA would be less effort on the PC side (send and forget versus needing to check the boolean?) and allow the setting of multiple values at once, but the DMA would require sending two values (index and value) or reserving bytes for index and value. I tried compiling each:

DMA

FIFO is 63 elements long of U32.

post-4230-0-87358600-1291819640_thumb.pn

FRONT PANEL

post-4230-0-57767800-1291819765_thumb.pn

I didn't see much difference in resource usage.

By using globals, you can slow down your FPGA since sections of code will be blocked until the other section accesses it. There are times that I used them (non critical timing), but try to avoid them.

You want to avoid arbitration - multiple loops all trying to access the same resource, such as a functional global.

Okay, globals are still to be avoided.

A memory block acts a lot like a global variable in practice, but it is an efficient way to store and share data on the FPGA, and you can avoid arbitration if you have only one location where you read and one location where you write. Similarly, you can choose to have your FIFOs implemented in memory.

It appears the memory is what I should have used for in a one-write-location, multiple-read-location situation. Globals, unfortunately, are nice in that it's clear what data I'm trying to access. The only ways I can see to make it clear what is being accessed in memory is, 1) to create single-element memory blocks for every piece of internal data to be stored, 2) to create an enumerated typedef to provide the indeces of the data in the block, or 3) to create a subVI to read each data element. (I'm liking 1 or 2...)

Note that there's a difference between a DMA FIFO, which passes data between the FPGA and host, and a FIFO that only passes data around the FPGA.

How is a Target Only FIFO different than a DMA FIFO? I've not been able to locate anything on NI's website or the help files.

Tim

Link to comment

That's two interesting approaches. I think the DMA would be less effort on the PC side (send and forget versus needing to check the boolean?) and allow the setting of multiple values at once, but the DMA would require sending two values (index and value) or reserving bytes for index and value.

There's a limit on how many DMA FIFOs you can use, so I like to save them for streaming large amounts of data. For sending parameters, where I may want to set them in an arbitrary order but speed isn't critical, I use the boolean approach. Also, if I want to test the effect of changing those parameters, using controls lets me set the values directly from the FPGA front panel without any host code.

How is a Target Only FIFO different than a DMA FIFO? I've not been able to locate anything on NI's website or the help files.

Perhaps I made it sound like a bigger difference than there actually is - I just wanted to be clear that there are two distinct types of FIFOs, so crossrulz's suggestion of using a DMA FIFO to transfer data from the host to FPGA is slightly different than your question as to transferring data between loops on the FPGA. A DMA FIFO uses a reserved area of memory on the host and FPGA to do direct transfers of data. A target-scoped FIFO moves data only on the FPGA, and provides implementation options - Flip-Flop, Lookup Table, or memory. The memory option is slowest but can hold the largest number of items without taking up additional FPGA space.

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.