Main Content

Introduction to 5G NR Signal Detection on NI USRP Radio

Since R2024b

This example shows how to deploy a hardware implementation of a 5G NR signal detection algorithm on the FPGA of an NI™ USRP™ radio.

Introduction

In this example, you start with a Simulink® model of an algorithm that retrieves master information block (MIB) information from a 5G NR signal. 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. The example enables you to view the cross-correlation signal and adaptive threshold, then decode the MIB information from the captured data.

Design Overview

The example uses the algorithm from the Introduction to 5G NR Signal Detection (Wireless HDL Toolbox) example. The algorithm implements a primary synchronization signal (PSS) detector to identify 5G NR signals, then performs OFDM demodulation using the timing information from the PSS. The result is a synchronization signal block (SSB) signal. This design modifies the interfaces that enables you to deploy the generated bitstream on the FPGA of an NI USRP radio.

The algorithm transfers the SSB signal to the host through the onboard PL DDR buffer. On the host, the provided live script decodes the master information block (MIB) from the SSB grid to verify the accuracy of the SSB grid data captured and demodulated on the hardware.

Open Simulink Model

The Simulink model implements the signal detection and demodulation algorithm using a hardware modeling style and uses blocks that support HDL code generation. It uses fixed-point arithmetic and includes control signals that control the flow of data through the model.

Open the model from MATLAB.

open_system('wtNrDetectionSL');

The model generates input data for and reads output data from the SSBDetectAndDemod subsystem.

Open the SSBDetectAndDemod subsystem.

open_system('wtNrDetectionSL/SSBDetectAndDemod');

Data flows through these blocks and subsystems:

  • The Prebuffer block buffers and reshape input samples.

  • The SSBDetection subsystem detects and demodulates a PSS and outputs the SSB.

  • The OutputSelector subsystem processes the SSB and selects the data to stream out.

  • The Data Packager block reformats the output samples.

The Prebuffer and Data Packager blocks enable rapid development by reformatting the input and output data to conform with the AXI-Stream protocol required by NI USRP radio device reference design. These blocks are in the targetingLib.slx library.

The timing diagram shows how the Prebuffer block reformats the input data by reformatting the data samples so that they are output at consistent clock cycle intervals. The reformatting facilitates the reuse of DSP within the SSBDetection subsystem.

The Data Packager block formats the raw streams of output data into the AXI-Stream format. The output packet length is 256 samples, which is the recommended value. The timing diagram shows the inputs and the output, where the output signals conform to the simplified AXI-stream protocol. For more information, see Simplified AXI-Stream Protocol.

Open the SSBDetection subsystem.

open_system('wtNrDetectionSL/SSBDetectAndDemod/SSBDetection');

The SSBDetection subsystem detects a PSS signal and then demodulates the SSB. You can select to output the cross-correlation data alongside threshold values for visualization purposes, or to output the demodulated SSB signal for decoding. The adaptive threshold and minimum threshold are adjustable.

open_system('wtNrDetectionSL');

You can select to output either the cross-correlation data and threshold values or the demodulated signal by writing either 0 or 1 to the DataSel port.

Simulate Design

Verify the design by simulating the model. Set the cell ID to 1.

NCellID = 1;

Set the SSB subcarrier spacing, scsSSB, based on the SSB pattern. SSB pattern Case A uses 15 kHz subcarrier spacing. SSB patterns Case B and Case C use 30 kHz subcarrier spacing.

scsSSB = 30;

Initialize the constants required by the Simulink model.

sl_in = Nr5GDetectionSimSetup(NCellID, scsSSB);

Run the Simulink model.

sl_out = sim("wtNrDetectionSL.slx");

Process the simulation output data.

sl_demod = sl_out.demodData(sl_out.demodValid);
demoCellID = sl_out.PSSID(find(sl_out.demodValid, 1));
sl_SSBGrid = reshape(sl_demod,240,[]);
numTB = size(sl_SSBGrid,2)/4;

You can use this scope to view the cross-correlation and threshold values during the simulation. The display shows PSS0 correlation peaks are detected during every burst.

Decode and plot the demodulated data.

fprintf('Decoding MIB from Simulink SSB grid \n');
Decoding MIB from Simulink SSB grid 
Lmax = 8;
figure;
for ii = 0:numTB-1
    startIndex = ii * 4 + 1;
    finishIndex = (ii+1)* 4;
    sl_SSBGridBurst = sl_SSBGrid(1:240, startIndex:finishIndex);
    [~, nCellID, ssbIndex, bchCRC(ii+1)] = ...
        mibDecode(sl_SSBGridBurst, double(demoCellID), Lmax); %#ok<SAGROW>
    subplot(4,2,ii+1)
    imagesc(abs(sl_SSBGridBurst));
    title(['Simulink SSB Grid Burst ', num2str(ii+1)])
    ylabel('Subcarrier');
    xlabel('OFDM Symbol');
end
if(any(bchCRC))
    fprintf('MIB decode failed, bchCRC was nonzero\n');
else
    fprintf('MIB decode successful\n');
end
MIB decode successful

Set Up Environment and Radio

To target an NI USRP radio with Wireless Testbench™, you must first 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 radioSetupWizard function to open the Radio Setup wizard and follow the steps. To see your previously saved radio setup configurations, use the radioConfigurations function.

Generate IP Core

First, use the hdlsetuptoolpath (HDL Coder) function to set up the Xilinx® tool chain.

>> hdlsetuptoolpath('ToolName','Xilinx Vivado','ToolPath','/opt/Xilinx/Vivado/2019.1/bin');

From the Apps tab in the Simulink Toostrip, select HDLCoder. Open the HDL Code tab and follow these steps:

  1. Ensure the SSBDetectAndDemod subsystem is pinned in the Code for option. To pin this selection, select the SSBDetectAndDemod subsystem in the Simulink model and click the pin icon.

  1. Select IP Core as the Output > IP Core option.

Configure HDL Code Generation Settings

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.

In HDL Code Generation > Target > Workflow Settings, click browse and select the project folder in which you want to save the generated project files.

In 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 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 7.68 MHz, which is the bandwith of the synchronization signal block (SSB) in the 5G downlink signal. 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. This option selects the highest supported master clock rate (MCR) of the radio as the DUT clock.

  • Stream Port FIFO Length (Samples) - Set to Auto.

  • Register Port FIFO Length (Samples) - Set to Auto.

Note that, in HDL Code generation > Target > Objective Settings, the target frequency is set by default to the maximum supported MCR of the radio.

Click Apply.

For more information, see Configure HDL Code Generation Settings.

Configure Target Interface

  1. In the HDL Code tab, click Target Interface to open the IP Core editor.

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

  • Assign the input registers of the DUT as write registers.

  • Assign the output registers of the DUT as read registers.

  • Assign the data, valid, ready, last, and end of burst (EOB) signals.

Each data input and output port has an options menu. For the DataIn 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.

For the DataOut 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. For more information, see Map Target Interfaces.

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 menu 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. The bitstream build process could take several hours. Closing the external shell before the indication of a successful build 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 Deployment Settings from the Build Bitstream menu. 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 menu.

Alternatively, if you want to load the bitstream outside of this workflow, use the programFPGA function in the generated host interface script. For more information, see Generate Bitstream and Program FPGA

Generate and Modify Host Interface Setup Script

In the HDL Code tab, select Host Interface Script to generate MATLAB scripts that enable you to connect to and run your deployed design on your radio. These scripts are specific to the target interface mapping of your IP core. For more information, see Run and Verify Hardware Implementation

The fpga 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. Before you run the host interface script, you must first modify the configuration of the DataOut port.

Open the setup script file. Increase the frame size and DDR allocation size to 1e7. Modify the numeric type of the output data from a real 32-bit unsigned integer to a complex 16-bit signed integer:

  • Update the value of "DataType" from "uint32" to "int16"

  • Update the value of "IsComplex" to true

  • Increase the value of "RX_STREAM0_FrameSize" to 1e7

RX_STREAM0_FrameSize = 1e7;
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_DataOut = hdlcoder.DUTPort("DataOut", ...
 "Direction", "OUT", ...
 "DataType", "int16", ...
 "IsComplex", true, ...
 "Dimension", [1 1], ...
 "IOInterface", "RX_STREAM#0");

Run Host Interface Script

After you have generated the bitstream, open Detect5GNRSignalUsingNIUSRPExampleInterface.mlx. This live script enables you to connect to, configure, and control your radio device with the 5G NR detection algorithm deployed on the FPGA. You follow these steps to run and verify your hardware implementation:

  1. Transmit a 5G SSB test waveform.

  2. Plot the PSS correlation peaks and threshold and use the results to adjust the thresholds of your detection algorithm.

  3. Decode the MIB from the captured SSB and verify that it matches the transmitted waveform.

open("Detect5GNR_Host/Detect5GNRSignalUsingNIUSRPExampleInterface.mlx");

Related Topics