Main Content

Run and Verify Hardware Implementation

R2026b

After generating and loading a bitstream, use host interface scripts to connect to the radio, exchange data with your DUT, and verify hardware behavior. For the full workflow, see Target NI USRP Radios Workflow.

Running and verifying your implementation requires an NI™ USRP™ radio with a custom FPGA image and a radio setup configuration. To interact with your hardware:

  1. Generate host interface scripts from the HDL Coder workflow.

  2. Use the scripts with your hardware to program, configure, and exercise your design.

  3. Manage the scripts as your design evolves.

Generate Host Interface Scripts

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 an fpga hardware object for interfacing with your FPGA from MATLAB. 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 the fpga 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.

Use Host Interface Scripts with Hardware

For rapid prototyping, customize the host interface script to match modifications you make to your design. After you generate the host interface scripts, follow these steps:

  1. Use the Radio Setup wizard to connect and set up your radio.

  2. Edit the frame size for each streaming interface in the generated setup function.

  3. 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.

  4. Run the modified host interface script.

  5. Release hardware resources.

Once you have iterated and tested the host interface script, you can:

Manage Host Interface Scripts

When you make minor changes such as modifying existing parameters or fixing minor errors, 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 appears about overwriting existing files. To prevent overwriting existing files, rename the files.

The generated bitstream, hand-off information file, and setup function must remain consistent with each other.

Test DUT with Transmit and Capture Antennas

Transmit and capture antennas provide independent RF paths through the radio front end. These antennas are not directly connected to the DUT. To use them for testing, you design an experiment that exercises the DUT by transmitting RF waveforms that the DUT receives through its input streaming interface, or by capturing the RF output that the DUT transmits through its output streaming interface.

To set up and run a test:

  1. Set the TransmitAntennas property to specify antennas for transmitting test waveforms.

  2. Set the CaptureAntennas property to specify antennas for capturing RF output.

  3. Use the transmit function to send a known waveform and the capture function to receive data.

  4. Compare the captured data with the expected result.

When configuring a test:

  • Match the center frequency of the transmit and capture antennas to the center frequency used by the DUT streaming interfaces.

  • Stream no more samples than the CaptureDDRAllocation size. Empty the capture buffer after each acquisition.

You can transmit and capture waveforms over the air, or use the LoopbackMode property to route RF signals between antenna pairs on the FPGA without sending data over the air.

Note

  • If using a resampled rate, the captured data may contain artifacts from the DDC and DUC resampling blocks.

  • The number of antennas available for testing depends on the reference design optimization level. For details, see Reference Design Settings.

Interface Script File

The generated interface script contains sections that program the FPGA, configure the radio, set up DUT interfaces, and provide example read and write commands.

  1. Provides a short overview of how to use the generated interface script.

    %--------------------------------------------------------------------------
    % Host Interface Script
    % 
    % Use this script to access DUT ports in the design that were mapped to
    % compatible IP core interfaces. You can write to input ports in the design
    % and read from output ports directly from MATLAB. To write to input ports,
    % use the "writePort" command and specify the port name and input data. The
    % input data will be cast to the DUT port's data type before writing. To
    % read from output ports, use the "readPort" command and specify the port
    % name. The output data will be returned with the same data type as the DUT
    % port. Use the "release" command to release MATLAB's control of the
    % hardware resources.
    %--------------------------------------------------------------------------
    
  2. Creates a usrp System object™ that represents a connection to your radio. The script contains the programFPGA function that programs the FPGA with the generated bitstream and corresponding device tree. The script also contains the describeFPGA function that configures the DUT interfaces according to the hand-off information file.

    %% Program FPGA
    % Uncomment the line below to program FPGA hardware on the USRP with the
    % designated bitstream. Specify a radio configuration you saved using the
    % Radio Setup wizard.
    hDevice = usrp("MyRadio");
    % programFPGA(hDevice, "build_XXXX_HG/build-XXXX_HG/xxxx.bit", ...
    %  "build_XXXX_HG/build/usrp_xxxx_fpga_HG.dts");
    describeFPGA(hDevice, "modelName_wthandoffinfo.mat");
    
  3. Configures the radio front end parameters by updating usrp System object Properties. The property values derive from the values you set in the Reference Design Settings.

    %% Configure device object
    % Uncomment the below line to specify a different sample rate than the
    % value set during bitstream generation. Specify the radio antennas to use.
    % hDevice.SampleRate = 250e6;
    hDevice.DUTInputAntennas = "RF0:RX2";
    
    % Set the radio parameters to meaningful values for the design. These
    % values may be tuned after setting up the device object.
    hDevice.ReceiveCenterFrequency = 2400000000;
    hDevice.ReceiveRadioGain = 10;
  4. Creates an fpga object that represents a connection to the DUT on your radio.

    %% Create fpga object
    hFPGA = fpga(hDevice);
  5. 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.

    %% Setup fpga and usrp object
    % This function configures the "fpga" object with the same interfaces as
    % the generated IP core. Edit gs_ModelName_setup.m to customise the frame
    % size and timeout for each DUT streaming connection to MATLAB.
    gs_modelName_setup(hFPGA);
    
  6. Connects to and configures the radio using the setup function with the usrp System object. The setup function also initializes the DUT in the default state.

    % Setup the device to connect to the radio and apply properties.
    setup(hDevice);
  7. Contains example commands that read or write data to DUT ports using the readPort and writePort functions. To use these functions to exercise the algorithm running on your radio hardware, uncomment these lines and update them with meaningful values.

    %% Write/read DUT ports
    % Uncomment the following lines to write/read DUT ports in the generated IP
    % Core. Use the writePort or readPort functions at any time between setting
    % up the device and releasing hardware resources. Update the example data
    % in the write commands with meaningful data to write to the DUT.
    % writePort(hFPGA, "Write_Register", zeros([1, 1])); [data_Data_Out, ...
    %  numSamps_Data_Out, overflow_Data_Out] = readPort(hFPGA, "Data_Out");
    % data_Read_Register = readPort(hFPGA, "Read_Register");
  8. Provides code that calls the usrp System object as if it were a function. To stream 1000 samples from the radio front end, uncomment the final line.

    %% Stream samples from the radio front end
    % Specify a number of samples to send to the DUT input streaming
    % connections connected to the radio. Alternatively, stream continuously by
    % specifying Inf.
    % hDevice(1000);
    
  9. Provides an empty section for you to add MATLAB code to interface with your algorithm and your radio.

    %% Implement user design
    % Samples are now available at streaming connections connected to the
    % radio. Implement your algorithm by writing and reading ports on the DUT.
    % Update the example data in the write commands with meaningful data to
    % write to the DUT. 
    % writePort(hFPGA, "Write_Register", zeros([1, 1]));
    % [data_Data_Out, numSamps_Data_Out, overflow_Data_Out] = readPort(hFPGA, "Data_Out");
    % data_Read_Register = readPort(hFPGA, "Read_Register");
  10. Releases hardware resources.

    %% Release hardware resources
    release(hFPGA);
    release(hDevice);

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 object array for each register port, then uses the mapPort function to map the DUT ports to the RFNoC register interface.

%% Add RegisterInterface
addRFNoCRegisterInterface(hFPGA, ...
    "InterfaceID", "dutName", ...
    "RFNoCBlock", "0/dutName#0");

DUTPort_Write_Register = hdlcoder.DUTPort("Write_Register", ...
	"Direction", "IN", ...
	"DataType", "int16", ...
	"IsComplex", false, ...
	"Dimension", [1 1], ...
	"IOInterface", "dutName", ...
	"IOInterfaceMapping", 128);

DUTPort_Read_Register = hdlcoder.DUTPort("Read_Register", ...
	"Direction", "OUT", ...
	"DataType", "int16", ...
	"IsComplex", false, ...
	"Dimension", [1 1], ...
	"IOInterface", "dutName", ...
	"IOInterfaceMapping", 1);

mapPort(hFPGA, [DUTPort_Write_Register,DUTPort_Read_Register]);

For each streaming interface in your model, the setup function adds an RFNoC streaming interface to the DUT with the addRFNoCStreamInterface function, creates a hdlcoder.DUTPort object array for the DUT port, then uses the mapPort function to map the DUT port to the RFNoC streaming interface.

Note

The number of samples per host-side readPort or writePort operation, specified in the FrameSize name-value argument of the addRFNoCStreamInterface function, is set by default to 1e5. To change this value or the value of the Timeout name-value argument, edit the setup function file.

%% Add RFNoC Stream Interface
RX_STREAM0_FrameSize = 1e5;
addRFNoCStreamInterface(hFPGA, ...
    "InterfaceID", "RX_STREAM#0", ...
    "Streamer", "0/RX_STREAM#0", ...
    "Direction", "OUT", ...
    "FrameSize", RX_STREAM0_FrameSize, ...
    "DDRAllocation", RX_STREAM0_FrameSize, ...
    "Timeout", []); % [] calculates a timeout of 1+hDevice.SampleRate/FrameSize

DUTPort_Data_Out = hdlcoder.DUTPort("Data_Out", ...
	"Direction", "OUT", ...
	"DataType", numerictype(1,16,12), ...
	"IsComplex", true, ...
	"Dimension", [1 1], ...
	"IOInterface", "RX_STREAM#0");

mapPort(hFPGA, DUTPort_Data_Out);

The setup script is a reusable file. When you make changes to your IP core, update or regenerate the setup script.

Troubleshooting

Releasing the Radio Takes a Long Time

If the release or reset function takes up to 30 seconds and generates this warning:

Warning: Unable to flush StreamName within 30 seconds.
Check that no new samples are being streamed into StreamName during the operation and try again.
the DUT is still asserting valid_out while the stream buffer drains. To resolve this issue:

  1. Return to the Register Interface Guidelines step and add a register interface to your DUT that controls an output-enable signal.

  2. In your host script, use the writePort function to de-assert the register before releasing or resetting the radio:

    writePort(hFPGA, "OutputEnable", int16(0));
    release(hDevice);

Stream Buffer Overflow

If the overflow output argument of the readPort function returns true, or streaming stops unexpectedly, the DUT produces or consumes data faster than the connected subsystem can handle. To resolve this issue, modify your model to meet the rate constraints described in Streaming Interface Guidelines:

  • For DUT-to-host streams, reduce the rate at which the DUT asserts valid_out, or use the PL DDR buffer.

  • For radio-to-DUT streams, verify that the DUT asserts ready_out at a rate at least equal to the baseband sample rate. If the DUT processes data at a lower rate, add buffering or increase the DUT clock frequency. For more information, see DUT Clock Frequency and Sample Rate.

Frame Size Mismatch

If the writePort function returns an error like this:

Port dimension [50000 1] does not align with expected frame size 100000.
Port dimension must be specified as one of the following: "[100000 1]" or "[1 1]"
verify that the length of the input data matches the FrameSize value specified for the interface in the setup function. Update either the FrameSize setting or the input data so that the sizes match.

See Also

Objects

Functions

Topics