Putting it to use
So how do we use the Static RAM capabilities of LabVIEW FPGA? Here is a bigger and better example. Start by downloading and opening the “SRAM_w_StateMachine.lvproj” project with LabVIEW 2015:
http://www.quantprogrammer.com/Code/02_SRAM_w_StateMachine.zip – Download
Take a look at the project:
There are 3 sections that we will focus on, the first section is the “Host VIs”, which are VIs that run on the host computer that has the FPGA plugged in to it, or in some case is connected to the FPGA over the network.
Section 1 – Host VIs
- Vi that runs this example, this is what you should open and run. Make sure that you set the FPGA Target to run in “Simulation Mode” first.
Section 2 – FPGA Vis
- This is the top-level FPGA vi, it starts several loops, each of which handles a specific task:
- (Host to FPGA) reading the data from a host-to-target DMA FIFO
- (Data to RAM) writing and reading data to/from SRAM
- (FPGA to Host) sending the results back to the host via a target-to-host DMA FIFO.
- RadioData to SRAM states.ctl
- This defines the states for our “State Machine”, there are 3 states:
- read from SRAM states.ctl
- State machine states for the memory read loop, there are only 2 states:
- FPGA Latch.vi
- Just a re-usable latch vi, instead of implementing a latch every time you need one, you can use this one instead.
Section 3 – FPGA Resources
FPGA Scoped Ram is represented by the icon:
A FIFO is represented by the icon:
- The definition of the FPGA SRAM
- HT stands for “Host-to-Target” and is the FIFO used for transferring data from the Host to the FPGA
- The FIFO which receives command from the Host Computer and transfers them to the FPGA for execution.
- TH stands for “Target-to-Host” and is the FIFO used for transferring data from the FPGA back to the Host.
The host VI (Host-Top-Level.vi) contains some initialization code that opens a reference to the FPGA vi and runs it:
It then starts an event loop and waits for one of 3 actions that get triggered from the buttons on the front panel:
Write Memory – Send array of U64’s to the FPGA for loading in to FPGA SRAM
Read Memory – Send a read command to the FPGA via a Host-to-Target DMA FIFO requested the memory starting at a specific address and a size for the number of elements to return to the host. Then it listens on the target-to-host FIFO for the requested data.
Exit – Exit event. Closes the FPGA reference and terminates the application.
Finally, after the event loop terminates, there is some code to close the FPGA reference:
The top level FPGA vi contains four loops.
- DMA Streaming – Host to Target
- DMA Streaming – Target to Host
- Data to SRAM
- Data from SRAM
First Loop – DMA Streaming Host to Target
This loop listens on the “HT-Data” FIFO for new data coming in from the Host Computer. Any data it receives it sends to the VI-Scoped FIFO “HostData-to-SRAM”. This is a very simple loop and is intended to connect the functionality of this VI with the host. This loop can easily be replaced with another loop whose source of data is another Vi running on the same FPGA, or even to a Test Harness. You can have a Test Harness that runs on the Host or the FPGA, and you want this Test Harness to exercise the functionality of this VI. Additionally, this Vi can now be used in larger components and all you have to do is modify or replace this loop, which serves as a single entry point to this Vi.
Second Loop – DMA Streaming Target to Host
This loop does the opposite of the first loop, it takes the results of any operation carried out by this Vi and sends it back up to the host. Again, you can replace this loop with another loop and use it in a Test Harness or bigger component.
Third Loop – Data to SRAM
This loop contains a state machine with three states:
The idle state is pictured above and it keeps checking the VI-scoped HostData-to-SRAM FIFO for available data, once it detects that data is available on that FIFO it switches to the “write” state.
The Write state reads one element from the VI-Scoped FIFO HostData-to-SRAM and writes that element into the next memory address. The next memory address is tracked by a wire and is incremented only each time new data is written to SRAM.
The final state is the reset state. The loop enters this state whenever it detects that there is no more data to read from the host. This also resets the write address to 0. Note that in most cases data comes from the host in bursts, so you will not enter this state in most cases until everything has been read. But what about the case where the data is sent in multiple bursts? Well… that is an improvement that will make this example a bit more complex. See a future article for how to deal with this, but in a nutshell, you not only send the data from the Host, you precede it with a count for the number of elements being sent and enter the reset state once that count number of elements has been read.
Fourth and Final Loop – Data from SRAM
Above is a VI snippet of the idle state. The idle state listens for commands coming in on the HT-Commands FIFO. When a command is read, a read address counter – i – is set to 0, and the start address and number of elements to read is loaded into the 3 wires pictured above. Then the loop enters the read state.
The read state reads memory from SRAM address starting at “Start Address + i”, saves the results into a Feedback node, increments i and writes the data back to the top “Target-to-Host” loop via the VI-scoped FIFO “SRAM-to-HostData”. After the specified number of elements have been read, the loop enters the idle state.
Please post any questions in the form of comments.