Target NI USRP Radios Workflow
This guide helps you to deploy hardware implementations of software-defined radio (SDR) algorithms for NI™ USRP™ radios.
The workflow enables you to:
Use Simulink® to design, simulate, and verify your user logic.
Generate synthesizable HDL code for your user logic using HDL Coder™.
Map your design to the target platform interfaces and integrate it into a reference design.
Program the FPGA on your device.
Generate scripts that provide the MATLAB® code you need to connect to, configure, and control your device.
Before you begin, you must install and configure additional support packages and third-party tools by following the steps in Installation for Targeting NI USRP Radios.
Note
Generating a bitstream with this workflow is supported only on Linux® operating systems.
Step 1. Verify Radio Connection
Call the radioConfigurations
function to return all available radio setup configurations that you saved using the Radio Setup wizard. Make sure that the
device you are targeting is listed.
For details on how to connect and set up your NI USRP radio, revisit Step 1. Connect and Set Up NI USRP Radios in the installation guide.
Step 2. Set Up Third-Party Tools
Set up your system environment to access Xilinx®
Vivado® from MATLAB. The hdlsetuptoolpath
(HDL Coder) function adds the required
folders to the MATLAB search path, using the Xilinx installation folder that you specify. The folder that you specify should
include the AR73068 patch that you installed in the Xilinx Vivado step in the installation, or
use a Linux environment as described in the 'README'
file that you
download with the patch.
hdlsetuptoolpath('ToolName','Xilinx Vivado','ToolPath', ... '/opt/Xilinx/Vivado/2019.1/bin')
Step 3. Create Algorithm
When designing an SDR algorithm for the NI USRP radio, you can add register interfaces that read or write registers in your user logic and streaming interfaces that stream data between the user logic, the radio front end, and the host. For more information about the hardware interfaces, see Configure Hardware Interfaces.
Input/Output Signal Guidelines
The user logic subsystem is referred to as the design under test (DUT). The workflow has specific requirements for the boundary of the user logic subsystem. The following diagram shows a subsystem with a register input, a register output, an input streaming interface, and an output streaming interface. Designs can contain multiple register ports and streaming interfaces.
When adding data streaming interfaces to your DUT, follow these guidelines.
Each data input or output must be a fixed point data type less than or equal to 32 bits.
Note
Streaming connections to the radio front end must be 32-bit unsigned integers, where bits <31:16> contain the quadrature component of the IQ data and bits <15:0> contain the in-phase component.
Model the valid, last, and ready ports according to the AXI-Stream protocol. For details, see Simplified AXI-Stream Protocol.
Clock the valid, last, and ready signals at the maximum supported sample rate of the target device.
Sample-based Processing
For HDL code generation, your custom algorithm must operate using sample-based processing. You can convert frame-based input signals to the scalar data type by using the Unbuffer block. You can then convert the output back to frame signals using the Buffer block. Within this boundary of Unbuffer and Buffer blocks, the algorithm operates in scalar mode, which is necessary for HDL code generation.
Step 4. Generate HDL Code
HDL IP core generation enables you to generate a shareable and reusable IP core module from a Simulink model automatically. HDL Coder generates HDL code from the Simulink blocks. By using a reference design, you can create an IP core that integrates into the radio hardware.
After you are satisfied with the simulation behavior of the hardware subsystem, generate the HDL IP core and integrate it with the SDR reference design.
Set Up Output Options
The workflow uses the HDL Code tab in the Simulink Toolstrip to access the HDL code generation options and initiate code generation. The Simulink Toolstrip contains contextual tabs that appear only when you need to access them. To access the HDL Code tab, open the HDL Coder app from the Apps tab on the Simulink Toolstrip.
In the Output options, select IP Core.
Make sure that the user logic subsystem in your model, the design under test (DUT), is pinned in the Generate Code options. To pin this selection, select the DUT in your Simulink model and click the pin icon.
Configure HDL Code Generation Settings
Open the Configuration Parameters window by clicking Settings in the HDL Code tab.
In the HDL Code Generation panel, make sure that the
Language is set to Verilog
.
Go to the HDL Code Generation > Target panel.
In Workflow Settings:
Set the Workflow to
IP Core Generation
.Set the Project Folder to the location in which you want to save the generated project files.
In Tool and Device Settings select your device from the Target Platform dropdown list. For more information about supported devices, see Supported Radio Devices.
In Reference Design Settings, select the Reference Design from one of the following options:
Receive path
— Your design includes only input data streaming interfaces from the radio.Transmit path
— Your design includes only output data streaming interfaces to the radio.Transmit and receive path
— Your design includes both input and output data streaming interfaces to and from the radio.
Then, in Reference design parameters:
Set the External Memory parameter to
PL DDR Buffer
orNone
. To enable the option to use the PL DDR buffer on your radio device in the Map Target Interfaces step, selectPL DDR Buffer
. Using onboard data buffering ensures contiguous data transfer.Set the Number of Input Streams parameter according to the number of DUT data streaming inputs in your DUT.
Set the Number of Output Streams parameter according to the number of DUT streaming outputs in your DUT.
Set the Number of Antennas parameter to the number of radio antennas that your design requires. A radio antenna is required for each data streaming interface connected to the radio. For details about the maximum number of antennas available on your radio device, see Supported Radio Devices.
Set the Sample Rate (S/s) parameter to any supported sample rate of your radio device. For details, see Baseband Sample Rate in NI USRP Radios.
Set the BlockID parameter to any 32-bit hexadecimal number. The default is
12345678
. This is the ID given to the IP Core block that you generate from the DUT. To differentiate between bitstreams, change this value when you create successive IP cores.
In Objectives Settings, the Target Frequency (MHz) is set to the maximum supported sample rate of the target device. This is not adjustable.
Click Apply to save your settings.
Map Target Interfaces
In the HDL Code tab, click Target Interface to open the Interface Mapping table in the IP Core editor. To populate the table with your user logic, click the icon.
The Source column contains the DUT input and output ports. For each data streaming interface in your model, the Source column in the interface mapping table contains a data, valid, last, and ready signal. Use the following guidelines for mapping register interfaces and data streaming interfaces to populate the Interface column.
When you have populated the table, click the icon to validate the interface mapping.
Map Register Interfaces. Assign any register input as a Write Register
and any register
output as a Read Register
.
Map Data Streaming Inputs. For the first data streaming input, populate the Interface column with these values.
Data — Assign as
Data_In0
.Valid — Assign as
Valid_In0
.Last — Assign as
Last_In0
.Ready — Assign as
Ready_Out0
.End of burst — Assign as
EOB_In0
(optional).Has time — Assign as
HasTime_In0
(optional).Timestamp — Assign as
Timestamp_In0
(optional).
For each consecutive data streaming output, assign these values and
increment the appended number, for example, assign Data_In1
for the
data port of the second streaming input.
For each data streaming input, open the Set Interface Options window by clicking Options. Assign a source connection from the following options.
Radio
— The streaming input port receives samples from the radio front end.Host
— The streaming input port receives samples from the host.PL DDR Buffer
— The streaming input port receives samples from the host through the PL DDR buffer, which ensures contiguous samples.
Assign the stream buffer size as a number of samples, where each sample is 4 bytes. The default is the maximum possible buffer size.
Note
For optimal usage of FPGA memory resources, set the buffer size to a power of two.
Map Data Streaming Outputs. For the first data streaming output, populate the Interface column with the following values.
Data — Assign as
Data_Out0
.Valid — Assign as
Valid_Out0
.Last — Assign as
Last_Out0
.Ready — Assign as
Ready_In0
.End of burst — Assign as
EOB_Out0
(optional).Has time — Assign as
HasTime_Out0
(optional).Timestamp — Assign as
Timestamp_Out0
(optional).
For each consecutive data streaming input, assign these values and
increment the appended number. For example, assign Data_Out1
for the
data port of the second streaming input.
Radio
— The streaming output port sends samples to the radio front end.Host
— The streaming output port sends samples to the host.PL DDR Buffer
— The streaming output port sends samples to the host through the PL DDR buffer, which ensures contiguous samples.
Generate IP Core
Note
This step is handled automatically in Step 5. Generate Bitstream and Program FPGA. Skip this step unless you want to generate the IP core files without building a bitstream.
To generate an IP core for your user logic without building a bitstream, in the
HDL Code tab, click Generate IP Core. This
generates an RFNoC compatible IP core that you can integrate into a design outside of
MATLAB and Simulink. The IP core files are generated in a folder named rfnoc
within the project folder that you set up in the Configure HDL Code Generation Settings step.
Step 5. Generate Bitstream and Program FPGA
Build Bitstream
Click Build Bitstream to create a Vivado project, generate the IP core, and build a bitstream. The build performs basic
project checks, and then the Diagnostic Viewer displays Build Bitstream
Successful
, along with warning messages. The bitstream build continues in the
external shell. This process can take some time. Wait until the external shell indicates a
successful bitstream build before continuing to the next step.
Note
Closing the external shell before the bitstream build is complete terminates the build.
The build creates the following files:
The hand-off information file,
<modelName>_wthandoffinfo.mat
, is generated in the project folder that you set up in the Configure HDL Code Generation Settings step. This MAT-file describes the DUT interfaces.The bitstream file, a
.bit
file, is generated in the project folder, for example,<projectFolder>/build_N320_HG/build-N320_HG/n3xx.bit
.The device tree file, a
.dts
file, is generated in the project folder, for example,<projectFolder>/build_N320_HG/build/usrp_n320_fpga_HG.dts
. If your radio is an NI USRP X310, the build does not create this file.
To build a bitstream, your host must have enough memory. The size of the bitstream depends on the complexity of your design and the target NI USRP radio device.
Radio Device | RAM Required for a Typical Bitstream |
---|---|
USRP N310 | 9GB |
USRP N320 USRP N321 | 8GB |
USRP X310 | 8GB |
USRP X410 | 21GB |
Step 6. Run and Verify Hardware Implementation
You can generate host interface scripts that contain the MATLAB code you need to connect to your radio and interact with your algorithm running on the FPGA. To generate host interface scripts, in the HDL Code tab, click Host Interface Script. This step creates two scripts in the MATLAB current folder:
gs_<modelName>_interface.m
— This script creates anfpga
hardware object for interfacing with your FPGA from MATLAB. You can use the MATLAB code provided to connect to your hardware, program the FPGA, and exchange data with your algorithm as it runs on your radio.gs_<modelName>_setup.m
— This script configures thefpga
object with the hardware interfaces and ports from your DUT algorithm. The script includes the port name, direction, data type, and interface mapping information for each DUT port.
Interface Script File
Creates a
usrp
System object™, which represents a connection to your radio. The script contains theprogramFPGA
function that programs the FPGA with the generated bitstream and corresponding device tree. The script also contains thedescribeFPGA
function that configures the DUT interfaces according to the hand-off information file.Configures the radio front end parameters by updating
usrp
System object Properties.Creates an
fpga
object that represents a connection to the DUT on your radio.Configures the
fpga
object with the hardware interfaces and ports from your DUT algorithm using the setup function script. For details, see Setup Function File.Connects to and configures the radio using the
setup
function on theusrp
System object.Contains example commands that read or write data to DUT ports using the
readPort
andwritePort
functions, which you can use to exercise the algorithm running on the hardware. Update the commands with meaningful values before running the script.Calls the
usrp
System object as if it were a function to start streaming samples from the radio front end.Provides an empty section for you to add MATLAB code to interface with your algorithm and your radio.
Releases hardware resources.
Setup Function File
The setup function file configures your fpga
object with
the same interfaces as your generated IP core.
If your DUT has register ports, the setup function adds an RFNoC register interface
with the addRFNoCRegisterInterface
function, creates a hdlcoder.DUTPort
(HDL Coder) object array for each register port, then uses the mapPort
function
to map the DUT ports to the RFNoC register interface. The image shows an example for a DUT
with one write register and one read register.
For each RFNoC streaming interface in your model, the setup function adds an RFNoC
streaming interface to the DUT with the addRFNoCStreamInterface
function, creates a hdlcoder.DUTPort
(HDL Coder) object array for the DUT port, then uses the mapPort
function
to map the DUT port to the RFNoC streaming interface. The image shows an example for a DUT
with one output streaming interface.
The setup script is a reusable file. When you make changes to your IP core, you must update or regenerate the setup script.
Use Host Interface Scripts with Hardware
For rapid prototyping, customize the host interface script in line with modifications you make to your design. After you generate the host interface scripts, follow these steps:
Use the Radio Setup wizard to connect and set up your radio.
Modify the read and write commands in the interface script file to match your data requirements. Use the modified script to interface with the radio and your deployed algorithm.
Run the modified host interface script.
Release hardware resources.
Once you have iterated and tested the host interface script, you can:
Integrate the script into a testing or verification workflow.
Create a live script and interactively prototype your design.
Manage Host Interface Scripts
When you make minor changes such as modifying existing parameters or making minor error fixes, you can update your existing host interface script.
When you make major changes such as modifying the interface mapping table or changing the target device, regenerate the host interface script files. When you regenerate the host interface script files, a warning is displayed about overwriting existing files. To prevent existing files from being overwritten, rename the files.
Note
Use the BlockID reference design parameter to identify iterations of your design. You set this in the Configure HDL Code Generation Settings step.