Main Content

Spectrum Visualization on NI USRP Radio

Since R2024b

This example shows how to deploy a real-time, wideband spectrum visualization design on an NI™ USRP™ radio. The algorithm synchronizes data streams from two antennas to produce a spectrogram with twice the bandwidth that a single antenna can achieve.

Introduction

In this example, you start with a Simulink® model of an algorithm that does the following:

  1. Synchronizes two input data streams captured over the air on two independent antennas.

  2. Performs an FFT on each input data stream.

  3. Calculates the spectrum density of each input data stream.

  4. Packages the processed data to send to the host.

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 then enables you to visualize the spectrum density data and adjust and tune the center frequency, frequency resolution, and antenna gains in real time.

Design Overview

In this design, two RF data streams captured on independent radio antennas are input to the spectrum visualization system through the on-board analog to digital converter (ADC) and digital down converter (DDC). Within the spectrum monitoring algorithm on the FPGA, a spectrum calculation is performed that applies an FFT to each incoming data stream. Then, a density calculation is performed on each FFT output to determine the spectral density over a specified time period. Finally, the data is packaged in a single output stream so that it can be sent to the host for visualization.

Open Simulink Model

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

Open the wtSpectrumVisualizationSL model.

open_system('wtSpectrumVisualizationSL');

The top level model, wtSpectrumVisualizationSL, includes three subsystems:

  • The SpectrogramBlock subsystem implements the spectrum visualization algorithm. This subsystem is the device under test (DUT).

  • The RadioRFSource subsystem simulates the radio front end to provide a test input to the DUT.

  • The MatlabHostInterface subsystem simulates the connections between the host and the DUT, including register and streaming interfaces.

Open the SpectrogramBlock subsystem.

open_system('wtSpectrumVisualizationSL/SpectrogramBlock')

The data streaming inputs from the radio to the DUT are int16 complex numbers that have been quantized by an analog-to-digital converter in the radio front end. The FFTs block does the following to calculate the power spectral density of the input streams:

  1. Computes a 1024-point FFT for both input data streams.

  2. Calculates the square of the FFT to give the power spectral density of the RF signal received by each antenna. The unit of power is arbitrary and is not normalized to the frequency resolution.

  3. Converts the resulting power to floating point to enable it to be efficiently converted to a dB value relative to an arbitrary power value of 1.

  4. Quantizes the result to 8 bits, which is 128 bins.

The FFTs block has several write register ports that control the quantization. The Level0 and Level1 inputs control the power level of the spectrum output of each stream. The Amp0 and Amp1 inputs control the spectrum power resolution of each stream. The FrameNum input controls how many frames to receive in each read from the host.

The DensityCalculationController block accumulates the power calculated in the FFTs block to produce a histogram. The total number of bins is the length of the FFT multiplied by the number of quantized bins, which is 1024 * 128. In each iteration of the accumulation, 1 is added to each bin that corresponds to the power level measured at that FFT point. There are 16 iterations for each frame of data, so the range of output values for each bin is between 0 and 16. When the host plots this data as a histogram, each value corresponds to a color ranging from cool to warm. The accumulated data for each data stream is stored in a RAM block, RAM0 and RAM1.

Finally, the DataPackager block packages the concatenated spectrum density data frames. The raw streams of output data are formatted into packets that conform to the simplified AXI-stream protocol. The output packet length is 256 samples, which is the recommended value. For more information, see Simplified AXI-Stream Protocol. The timestamp from the hardware is latched every time the DataPackager sends data to the host.

To ensure synchronization between the two streams of RF data, the sync_streamers block performs an AND operation on the two valid_in signals from the input stream port. The result of this operation is sent back to both ready_out ports, which guarantees that the two data streams are synchronized. In addition, a ready_override input is added to override the ready signal of the DUT. The ready_override signal is asserted during the transition period when data streaming is started or stopped. This prevents an interlock between the two data streamers, which ensures that the internal buffers do not overflow.

The timestamp can be read from TSOut0H and TSOut0H as the lower and higher 32-bit integer of the 64-bit timestamp. Since the two input streams are synchronized, their timestamps are the same. For this reason, only TS0 and HasTime0 are used by the TSLatch block to produce the DUT timestamp output. The HasTime0 input port indicates that there is a timestamp.

Simulate Design

To simulate the model, a band-limited noise signal is generated using a random number generator and a low-pass filter. This signal is the input signal to both stream ports simultaneously. You can visualize the output by using the hPlotSimulationResult helper function. Four frames of data are plotted for visual verification of each port.

Verify the design by simulating the model.

sl_out = sim("wtSpectrumVisualizationSL.slx");

Use the hPlotSimulationResult helper function to plot the output data.

hPlotSimulationResult(sl_out);

The output shows four spectrums of low-pass filtered noise from stream port 0 and stream port 1. The results from each stream are identical and match the stimulus data. In the hardware implementation, each antenna receives distinct signals in adjacent frequency bandwidths that are received by the two stream ports. This setup doubles the bandwidth for spectrum visualization.

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. Specify the path to your Vivado® installation.

>> 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:

  1. Ensure the SpectrogramBlock subsystem is pinned in the Code for option. To pin this selection, select the SpectrogramBlock 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.

Configure HDL Code Generation Settings

In HDL Code Generation > Target > Workflow Settings, 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 N320. 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 2 because the DUT is connected to two parallel input data streams.

  • Number of Output Streams - Set to 1 because the DUT is connected to one output data stream.

  • Number of Antennas - Set to 2 because the DUT has two radio receive channels.

  • Sample Rate (S/s) - Set to 250 MHz. Set the sample rate to any combination of a supported master clock rate (MCR) divided by a supported decimation or interpolation factor for your radio. For more information, see Determine Radio Device Capabilities.

  • BlockID - Set to any 32-bit hexadecimal number. The default is 12345678.

  • DUT Clock Source - Set to Radio. This option selects the highest supported 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 to the maximum supported MCR of the radio.

In HDL Code Generation > Optimization > Distributed Pipelining Settings, select Distributed pipelining.

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 16384. This is lower than the default setting to reduce the hardware resources required and enable the design to meet timing requirements. 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, where each sample has 8 bytes.

For the DataOut options, select the host as the sink connection to stream samples directly 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.

To generate the HDL code and IP core without building a bitstream, click Generate IP Core. To generate and load a bitstream, skip this step and proceed with the example.

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. Closing the external shell before this terminates the build. If you are generating a bitstream for a USRP N320, the bitstream for this project generates with the name n3xx.bit and is located in the build_N320_HG/build_N320_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

To generate MATLAB scripts that enable you to connect to and run the deployed design on your radio, click Host Interface Script in the HDL Code tab. These scripts are specific to the target interface mapping of your IP core.

The gs_wtSpectrumVisualizationSL_setup.m script configures the fpga object with the hardware interfaces and ports from your DUT algorithm. The script also contains DUT port objects that have the port name, direction, data type, and interface mapping information, which it maps to the corresponding interfaces.

Before you run the host interface script, you must first modify the configuration of the DataOut port. Open the wtSpectrumVisualizationSL.m host interface script file and increase the frame size and modify the timeout value of the DUT port object that corresponds to the DataOut port to increase the system robustness.

  1. Increase the value of FrameSize to 32768 * 8, where 32768 is the data length in samples of each frame and 8 is the number frames to transmit host each time. You can increase this value if you have a 10 Gigabit Ethernet connection. Update gs_wtSpectrumVisualizationSL_setup.m and hPlotSpectrumScroll.m with the same timeout value.

  2. Set the value of Timeout to 0.5.

addRFNoCStreamInterface(hFPGA, ...
    "InterfaceID", "RX_STREAM#0", ...
    "Streamer", "0/RX_STREAM#0", ...
    "Direction", "OUT", ...
    "FrameSize", 32768*8, ...
    "Timeout", 0.5);

For more information, see Generate Bitstream and Program FPGA.

Run Host Interface Script

After you have generated the bitstream, open InteractWithSpectrumVisualizationBlockScript.mlx. This ready-to-use live script enables you to connect to, configure, and control your radio device with the spectrum visualization algorithm deployed on the FPGA. Follow these step to run and verify your hardware implementation:

open("SpectrumVisualization_Host/InteractWithSpectrumVisualizationBlockScript.mlx");

1. Visualize the spectrum in real-time.

2. Tune the center frequency.

3. Tune the frequency resolution.

4. Tune the power level and scaling.

Further Exploration

You can use the spectrogram to visualize real wireless signals. For example, connect your mobile device or computer to a WLAN router and tune the spectrum visualization algorithm to the frequency band that your device is connected to. Run a speed test from your device and you can monitor the activity on the spectrogram. For example, the following spectrogram obtained when running a speed test shows activity in WLAN channel 121, which has a center frequency of 5.605 GHz.

Related Topics