The Serial RapidIO Simple Communication sample project demonstrates how to stream data between one or multiple FPGA targets and/or hosts using the Serial RapidIO high-speed serial protocol. Use DMA FIFOs to stream data between the Host and FPGA. Transmit/receive the stream data via Xilinx Serial RapidIO at 3.125 Gb/s on the NI PXIe-6592R. The CLIP supports two independent x1 Serial RapidIO links on Port 0 and Port 1. If modifications are to be made to the SRIO IP core, follow the steps in the attached guide "SRIO Vivado Guide.docx"
This sample project assumes basic familiarity with the Serial RapidIO protocol. This document provides a basic overview of portions of the protocol. For more information, please refer to the Xilinx LogiCORE IP Serial RapidIO Gen2 Endpoint v3.1 Product Guide for Vivado Design Suite (PG007).
The included Serial RapidIO core is configured to run two independent ports (Port 0 and Port 1) at 3.125 Gbps. It uses the Initiator/Target style of I/O port using the HELLO packet format.
This project contains four top-level host VIs:
and one top-level FPGA VI:
This diagram illustrates the data flow through this example and shows how hardware, software, and data interact. The illustration shows Port 0 as the Initiator and Port 1 as the Target. The Initiator sends transaction packets to the Target, which processes the transaction packets and may send response packets back to the Initiator. This example also supports connecting between two different NI 6592R targets.
The following steps describe data flow in the application:
This sample project provides support for the following Serial RapidIO transaction types:
Transaction Type | Description | Expected Response |
---|---|---|
NREAD | Requests an amount of data from the target from the specified memory address. | Response with data |
NWRITE | Sends an amount of data to the target starting at the specified memory address. | No Response |
NWRITE_R | Sends an amount of data to the target starting at the specified memory address. Expects an acknowledgement response without data. | Response with no data |
SWRITE | An optimized, streaming write that sends an amount of data to the target starting at the specified memory address. Uses fewer header fields than NWRITE. | No Response |
DOORBELL | Sends a very short message using the 16-bit info field. Doorbell packets contain no address or data. | Response with no data |
MESSAGE |
Sends an amount of data to the target starting at the specified memory address. Allows sending larger data more efficiently than an NWRITE, NWRITE_R, or SWRITE command by breaking the data into message segments instead of new packets. There are multiple restrictions on MESSAGE transaction data sizes and message length. Message length (the number of segments) cannot be more than 16. All segments must be of the same size (1, 2, 4, 8, 16, or 32 DWORDs), except for the last one, which may be smaller than the other segments. Messages target a mailbox and letter for delivery. This sample project uses Mailbox 0 for Port 1 and Mailbox 1 for Port 0. All received data is also placed in the appropriate Target Request FIFO. The Sample Project prevents you from sending invalid MESSAGE transactions. |
Message Response (No data) |
Atomic Increment | Returns the data (1, 2, or 4 bytes) from the specified memory address. After a response is sent, the value at that address is incremented. | Response with data |
Atomic Decrement | Returns the data (1, 2, or 4 bytes) from the specified memory address. After a response is sent, the value at that address is decremented. | Response with data |
Atomic Set | Returns the data (1, 2, or 4 bytes) from the specified memory address. After a response is sent, the value at that address is set to all 1s. | Response with data |
Atomic Clear | Returns the data (1, 2, or 4 bytes) from the specified memory address. After a response is sent, the value at that address is set to all 0s. | Response with data |
Atomic Swap | Returns the data (1, 2, or 4 bytes) from the specified memory address. After a response is sent, the value at that address is replaced with the write data. | Response with data |
Atomic Compare-and-Swap | Returns the data (8 bytes) from the specified memory address. After a response is sent, the value at that address is compared with the first 8 bytes of the write data. If the values are equal, the second 8 bytes of data are written to the memory location. If the values are not equal, no data are written. | Response with data |
Atomic Test-and-Swap | Returns the data (1, 2, or 4 bytes) from the specified memory address. After a response is sent, if the value at the address is 0, then the second DWORD of data is written to the memory location. | Response with data |
Note that with Atomic operations, because the data is received before the data on the target is updated, repeated Atomic operations may return data that appears to be "off by one". This is intentional and expected behavior of Atomic operations.
If you attempt to send or receive more data than supported in a single packet when using NWRITE, NWRITE_R, SWRITE, or NREAD, the FPGA splits your request into multiple consecutive packets. For example, an NWRITE packet has a maximum of 32 DWORDs of data. If you attempt to send 128 DWORDs, the FPGA will create and send 4 NWRITE packets, each with 32 DWORDs of data.
In the Serial RapidIO protocol, each endpoint has a Device ID. When a transaction is received, the endpoint compares the transaction's target ID against its own device ID and will only process the transaction if they match. The Device ID is editable.
In Example - SRIO Target (Host).vi, the current Device ID is read at start and displayed on the Front Panel. To change the target's Device ID, change the value in the Device ID control and press the Write Device ID button. Subsequent transactions to this target must use the new Device ID.
The Target ID on the Example - SRIO Initiator (Host).vi must match the Device ID on the Target in order for transactions to be successfully received. The initiator sends its own Device ID as part of the transaction, and responses from the Target include the Initiator's Device ID to ensure that the response reaches the correct endpoint.
Although the NI 6592R has 4 ports, this sample project uses a Serial RapidIO core which only instantiates ports 0 and 1. You may connect port 0 and 1 on one NI 6592R or connect ports on two different devices.
Use Example - Prepopulate Memory (Host).vi to write data directly to the FPGA's memory space. This method populates the device memory with known values.
For information about how to integrate Xilinx IP into a LabVIEW project, refer to Knowledge Base article 6R6EOLM3.
An Eye Scan allows you to determine the quality of your link statistically. To run an Eye Scan on a receiver, follow these steps:
For more information regarding Eye Scan, consult the section on Eye Scan Theory in the Xilinx 7 Series FPGAs GTX/GTH Transceivers User Guide (UG476).
If you are trying to stream between two different devices and receive an error because the port is not ready but your cables are connected, run the VI on the other device and try again. There must be an active Serial RapidIO core on both sides of the connection for a high-speed serial link to be established.
Hi Johnnyg17. Recently I am working on a POC and I found your article is really help for me. but I still run into several problems. Could you please help me ? 1.I followed the steps in the attached guide "SRIO Vivado Guide.docx" and I completed all the steps.but the .xci file won't appear in the CLIP file folder automaticly,I need to copy it and add to the folder.Is that right? 2.If I want to run the program, I need to compile the FPGA.vi, right? How to chose the top clock? Should I choose the PXIe-CLK100 or on board clock? 3.When I compile the FPGA.vi,always failed,I don't know where the problem is. That's all the problem I met now,hope that you could give me some information or solution,Thank you very much!
There is a minor typo in this example and the side effect is Port0 on NI 6592R can only be workable as an Initator. If you directly use the example and try to set Port 0 as an SRIO Target and Port 1 as an Initator it won't work.
The fix is to open Example - SRIO Controller (FPGA).vi and change the resource name of PXIe-6592R IO Socket v1\IPort1_m_axis_treq_tuser to PXIe-6592R IO Socket v1\IPort0_m_axis_treq_tuser under Target CLIP Resources - Port0 section block. Check out the following snapshot: