Getting Started with NI USRP Targeting Workflow
This example shows how to deploy a custom algorithm on the FPGA of an NI™ USRP™ radio. The example starts with a Simulink® model of an algorithm that applies a gain to incoming samples and takes you through steps to generate HDL code and deploy the design on your radio.
Introduction
In this example, you follow a step-by-step guide to generate a bitstream from the model in Simulink and deploy it on an NI USRP radio using a generated MATLAB host interface script. This diagram shows the workflow.
Set Up Environment and Radio
To use the NI USRP targeting workflow, you must install and configure additional toolboxes, support packages, and third-party tools. For more information, see Installation for Targeting NI USRP Radios.
If you have not previously saved a radio setup configuration for your radio hardware, use the
function to open the Radio Setup wizard and follow the steps. To see your previously saved radio setup configurations use the radioSetupWizard
function.radioConfigurations
Open the Simulink Model
The Simulink model in this example is a hardware generation model of an SDR algorithm. Using the HDL Code tab in the Simulink Toolstrip or the HDL Workflow Advisor, you can generate a custom HDL IP core from the model, then generate a bitstream and load it onto the FPGA on your radio. You can then generate a host interface script that provides the MATLAB code you need to interact with the hardware.
Open the model from MATLAB.
modelname = 'wtGettingStartedUSRPTargetingGainSL';
open_system(modelname);
The top-level structure of the model includes three subsystems:
The
Inputs
subsystem generates input samples.The
Gain
subsystem applies gain to the incoming samples and outputs the resulting data. This is the DUT.The
Outputs
subsystem processes the output data for visualization.
Simulate Hardware Generation Model
To confirm the behavior of the model, simulate the system using a sine wave as an input. The Inputs
subsystem generates the sine wave using the Signal Generator block and converts the generated samples to a 32-bit unsigned integer, which it inputs to the DUT.
Open the Gain
subsystem.
open_system([modelname '/Gain']);
The Gain
subsystem applies a linear gain to the input samples and sends the data to the Outputs
subsystem. The Outputs
subsystem converts the data into real and imaginary parts, which it sends to the Scope block to be plotted. The figure shows the result when the gain value is set to 4
.
Generate IP Core
When you are satisfied with the simulated behavior of the model, you can proceed to integrate your design into a custom IP core by generating HDL code and mapping the model inputs and outputs to the hardware interfaces.
First, use the hdlsetuptoolpath
(HDL Coder) function to set up the Xilinx® tool chain. Specify the path to your Vivado bin directory.
>> hdlsetuptoolpath('ToolName','Xilinx Vivado','ToolPath','/opt/Xilinx/Vivado/2019.1/bin');
From the Apps tab in the Simulink Toolstrip, select HDLCoder. Open the HDL Code tab and follow these steps:
Ensure the
Gain
subsystem is pinned in the Code for option. To pin this selection, select theGain
subsystem in the Simulink model and click the pin icon.
Select IP Core as the OUTPUT > IP Core option.
Configure HDL Code Generation
Click Settings in the HDL Code tab to open the Configuration Parameters window.
In the basic options of the HDL Code Generation panel, ensure that Language is set to Verilog
. By default, HDL Coder generates the Verilog files in the hdlsrc
folder. You can select an alternative location. If you make any changes, click Apply.
Configure HDL Code Generation Target
In the HDL Code Generation > Target > Workflow Settings, click browse and select the project folder in which you want to save the generated project files.
In the HDL Code generation > Target > Tool and Device Settings, set Target Platform to
USRP N310
. If you are using a different USRP radio, select the corresponding target platform and adjust the reference design parameters accordingly.In the HDL Code generation > Target > Reference Design Settings, set Reference Design to
Receive path
and set the reference design parameters with the following values:
External Memory - Set to
PL DDR Buffer
to stream samples through the memory buffer on the radio. This setting ensures contiguous samples between MATLAB and the radio.Number of Input Streams - Set to
1
because the DUT is connected to one data input stream.Number of Output Streams - Set to
1
because the DUT is connected to one data output stream.Number of Antennas - Set to
1
because the DUT has one radio receive channel.Sample Rate (S/s) - Set to the maximum supported value for the target device. For an N310 radio, this is
153.6e6
. The maximum value is set by default. For a list of supported sample rates, see Baseband Sample Rate in NI USRP Radios.BlockID - Set to any 32-bit hexadecimal number. The default is
12345678
.DUT Clock Source - Set to
Radio
. When this option is selected, the DUT clock frequency is set to the master clock rate (MCR) of the radio. Alternatively, you can set this option toCustom
to enable you to set the DUT clock frequency to a fixed, user-defined value that you can specify in the Target Frequency reference design parameter.Stream Port FIFO Length (Samples) - Set to
Auto
. This option automatically calculates the buffer length for each DUT input and output data streaming port.Register Port FIFO Length (Samples) -Set to
Auto
. This option automatically calculates the buffer length for each DUT register port.
In the HDL Code generation > Target > Objective Settings, when the DUT Clock Source reference design paramater is set to Radio
, this value is fixed at the highest supported MCR of the radio. If you set the DUT Clock Source reference design paramater to Custom
, you can specify the clock frequency for the DUT. To avoid overflows, set the target frequency to a value greater than the specified sample rate.
Click Apply.
Configure Target Interface
In the HDL Code tab, click Target Interface to open the IP Core editor.
In the Interface Mapping tab, reload the port interface mapping options by clicking the
Reload IP core settings and interface mapping table from model
icon. For more information, see Configure Hardware Interfaces.
Assign the data, valid, ready, and last signals.
Assign the input registers of the DUT as write registers.
Assign the output registers of the DUT as read registers.
Each data input and output port has an options menu. For the Data_In
options, set the source connection to Radio
. The input samples to the DUT are received from the radio. Set the stream buffer size to 32768
, which is the default setting. The buffer size must be a power of two to ensure optimal use of the FPGA RAM resources. The buffer size is specified in terms of the number of samples, with each sample having a size of 8 bytes.
For the Data_Out
options, select the PL DDR buffer as the sink connection. The DUT streams samples first to the onboard radio memory buffer, then to MATLAB for post-processing.
Click the Validate IP core settings and interface mapping
icon to validate the interface mapping.
Click Generate IP Core to generate the HDL code and IP Core.
Generate and Load Bitstream
To generate a bitstream from the IP core, first open the deployment settings from the Build Bitstream dropdown and ensure that the Run build process externally option is selected. This setting is the default and it ensures that the bitstream build executes in an external shell, which allows you to continue using MATLAB while building the FPGA image.
Click Build Bitstream to create a Vivado® IP core project and build the bitstream. After the basic project checks complete, the Diagnostic Viewer displays a Build Bitstream Successful
message along with warning messages. However, you must wait until the external shell displays a successful bitstream build before moving to the next step. Closing the external shell before this terminates the build. The bitstream for this project generates with the name n3xx.bit
and is located in the build_N310_HG/build_N310_HG
folder of the working directory after a successful bitstream build.
Open the Deployment Settings from the Build Bitstream dropdown. In the Program target Device settings, set the IP address. The default is 192.168.10.2. If you changed the IP address from the default when you set up your hardware using the Radio Setup wizard, set the IP address accordingly. To load the bitstream onto the device, click Program Target Device from the Build Bitstream dropdown.
Alternatively, if you want to load the bitstream outside of this workflow, use the programFPGA
function in the generated host interface script.
Generate Host Interface Script
In the HDL Code tab, Host Interface Script generates two MATLAB scripts, gs_wtGettingStartedUSRPTargetingGainSL_interface.m
and gs_wtGettingStartedUSRPTargetingGainSL_setup.m
, based on the target interface mapping you configured for your IP core.
The gs_wtGettingStartedUSRPTargetingGainSL_interface.m
script creates an fpga
hardware object for interfacing with your FPGA from MATLAB. It contains MATLAB code that connects to your hardware and programs the FPGA. Code samples get you started with running the algorithm on your radio.
The gs_wtGettingStartedUSRPTargetingGainSL_setup.m
script configures the fpga
object with the hardware interfaces and ports from your DUT algorithm. It also contains DUT port objects that have the port name, direction, data type, and interface mapping information. It maps these DUT ports to the corresponding interfaces.
Use the generated host interface script as a starting point for deployment. Consider saving the generated script under a unique name and develop your algorithm there to read and write ports. The Host Interface Script button generates the scripts in your working directory.
Run Host Interface Script
For rapid prototyping, customize the host interface script based on your algorithm.
Connect your host computer to the radio using the Radio Setup wizard and create a radio configuration, or use a saved radio configuration that you have already set up. Call the
radioConfigurations
function to list all available saved radio configurations.Modify the read and write commands in the interface script file to match your data requirements. Use the modified script interface with your deployed DUT IP core or algorithm running on the target board.
Run the sections of the host interface script to connect to your hardware board, program the FPGA, create an
fpga
object, and set up the interfaces. The interfaces are set up based on the interface setup function file. You need to run these sections only once.Run the modified read and write commands and iterate on these commands.
When you have finished prototyping, release the connection to the hardware board.
This example uses an edited script based on the generated host interface script. Open the script for editing.
edit('wtGettingStartedUSRPTargetingGainSL_LoopbackTest');
Run the script to loop back a sine wave and verify that the gain from your DUT algorithm is applied. An example result is shown in the figure when looping back through the FPGA. The plotted figure shows the real part of the output data from the DUT algorithm when the gain value is set to 1
and then when the gain value is set to 4
.
After 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
You can manage your host interface script files by either updating or regenerates the files. Update host interface script files when you make changes such as modifying parameters, fixing errors. Regenerate host interface script files when you make major changes such as modifying the DUT port mapping, changing the target hardware device vendor, or changing the target software tool. When you regenerate the host interface script files, HDL Coder displays a warning about overwriting the existing files. You can rename your existing files to prevent them from being overwritten.