MATLAB Examples

Targeting HDL Optimized QPSK Transmitter Using Analog Devices AD9361/AD9364

This example shows how to model an HDL-optimized QPSK transmitter and prototype it on the SDR hardware using the HDL Coder™ workflow advisor. The SDR device in this model will keep transmitting indexed 'Hello world' messages at its specified center frequency. For a full description of targeting, see Targeting Overview in the documentation.

Refer to the Installation for Hardware-Software Co-Design documentation for details on configuring your host computer to work with the Support Package for Xilinx® Zynq-Based Radio. Additionally, targeting requires HDL Coder and Xilinx Vivado®, which must be on the system path. You can add Vivado to the path when you call setupTools. See the targeting requirements for more details.



The commqpsktxhdl example demonstrates building a practical HDL-optimized QPSK transmitter, which includes QPSK modulation and root raised cosine pulse shaping with an oversampling ratio of 4. This example is a combination of the zynqRadioQPSKTxAD9361AD9364SL example and the commqpsktxhdl example. It takes the next steps to generate HDL code from the HDL-optimized transmitter and prototype it on the FPGA of the SDR hardware. Generation of bit frames is done in Simulink® before being packed for transmission over Ethernet to the SDR hardware. The raw data bits are modulated and the resulting symbols are pulse shaped in the programmable logic before being upsampled and sent to the RF front end.

Targeting typically involves a pair of models:

  1. The targeting model, used to generate the HDL code and integrate the DUT (Design Under Test) into the transmit path implemented on the FPGA of the SDR hardware
  2. The retargeted model, which uses the SDR hardware with the included DUT performing a portion of the baseband processing

Note that there are two methods of running this example, based on the targeting/retargeted pair of models:

  1. Run the zynqRadioQPSKTxFPGAAD9361AD9364SL targeting model directly. See the Running the Example: Simulated section.
  2. Generate a targeted bitstream and use the retargeted model zynqRadioQPSKTxFPGAAD9361AD9364RetargetSL. See the Running the Example: Targeted section.


Before running the example, ensure you have performed the following steps:

1. Configure your host computer to work with the Support Package for Xilinx® Zynq-Based Radio. See Installation for Hardware-Software Co-Design for help.

2. Ensure that you have a suitable receiver. This example is designed to work in conjunction with any of the following possible receivers:

Running the Example: Simulated

To run the example directly, open zynqRadioQPSKTxFPGAAD9361AD9364SL and start the simulation. Note that this simulates the entire baseband design in a similar way to the QPSK Transmitter Using Analog Devices AD9361/AD9364 Simulink example i.e. no HDL code is generated, and all of the baseband processing is done in Simulink.

The main benefit of running the example in this way is that you can verify the conversion of your design to fixed point HDL works with real world data. The main disadvantage is that the HDL optimized sections of the model will run significantly slower than their floating point, frame based equivalents. This example uses burst mode to ensure large enough blocks of data are received consecutively to verify the receiver functionality.

Running the Example: Targeted

The zynqRadioQPSKTxFPGAAD9361AD9364SL model can be used to generate a targeted bitstream for the SDR hardware that includes the HDLRx subsystem as a DUT. The DUT is automatically placed in the SDR receiver chain that is implemented on the FPGA.

To generate the new bitstream, perform the following steps:

  1. Make sure you have added Vivado to the system path. See related workflow setup.
  2. Right click on the HDLTx subsystem, select Block Parameters (Subsystem), and ensure that the treat as atomic unit checkbox is selected.
  3. Open the HDL workflow advisor by right-clicking on the HDLTx subsystem and selecting HDL Code -> HDL Workflow Advisor.
  4. In step 1.1, at Target workflow, select IP Core Generation. At Target platform, select the appropriate option for your radio hardware (e.g. 'ZC706 and FMCOMMS2/3/4', 'Zedboard and FMCOMMS2/3/4' or 'ADI RF SOM'). The Synthesis tool field should automatically set to Xilinx Vivado if you added Vivado to the path. Click Apply, then click Run This Task.
  5. In step 1.2, ensure that Reference Design is set to Transmit path. Set the synthesis frequency to a lower rate (1MHz would be appropriate). Click Apply, then click Run This Task.
  6. In step 1.3, ensure Processor/FPGA synchronization is set to Free running, and that each port is mapped to the appropriate interface as shown in the figure below.

  1. The default values for step 2 and step 3 can be used.
  2. Run the Workflow Advisor to step 4.1. A quick way to run all the preceding steps is to right click on 4.1 Create Project in the workflow window and click Run to selected task.
  3. In step 4.2, ensure that the Skip This Task checkbox is selected, and then click Run This Task.
  4. In step 4.3, ensure that the Run build process externally checkbox is selected, then click Run This Task.

If no errors are found, the FPGA programming file generation process starts in an external command shell. You can monitor the implementation progress in the external shell. A message indicating successful completion of file generation is displayed in the shell upon completion.

At this point there are two methods of downloading the generated bitstream to the board. The first method (which requires the Embedded Coder product) is to return to the HDL Workflow Advisor, select Download from the drop-down menu in step 4.4, and click Run This Task. When using this method, note that the bitstream is not persistent across power cycles.

If you want the generated FPGA image to load each time you turn on the board, call the downloadImage method as shown below (assuming the default 'hdl_prj' folder was used in step 1.1). This method does not require Embedded Coder.

>> dev = sdrdev('ADI RF SOM');
>> downloadImage(dev, 'FPGAImage','hdl_prj\vivado_ip_prj\vivado_prj.runs\impl_1\system_wrapper.bit');

The FPGA implementation of the QPSK transmitter can be verified using the companion retargeted model zynqRadioQPSKTxFPGAAD9361AD9364RetargetSL, whose transmit structure is shown in the figure below.

This model can be built from the original zynqRadioQPSKTxFPGAAD9361AD9364SL model by removing the Data Type Conversion block and the HDLTx subsystem. The functionality of these blocks is now implemented on the FPGA.

With the targeted SD card image loaded, simulating the zynqRadioQPSKTxFPGAAD9361AD9364RetargetSL model will start transmitting the 'Hello world' messages.

Transmitter Design: System Architecture

The structure of the full QPSK transmitter in zynqRadioQPSKTxFPGAAD9361AD9364SL is shown in the figure below.

The HDL-optimized part of the QPSK transmitter is modeled in the HDLTx subsystem, whose contents are shown below. This is the DUT that will be implemented in the transmit path on the FPGA fabric.

The IP core generation requires that the input and output interfaces of the HDL subsystem have two 16-bit data signals and a valid signal. These interface signals should be at the highest sample rate of the subsystem.

There are two implementation details that are specific to targeting the SDR hardware: the packing and unpacking of data at the input boundary of the HDLTx subsystem and the repeat/downsampling by 4.

  • To conform to the SDR hardware interface, the input of the HDL-optimized QPSK transmitter must be a 16-bit signed complex value. To meet this requirement, the Host to FPGA Packing subsystem takes the incoming data bits and splits them into IQ channels. Each bit then becomes the LSB of a complex 16-bit integer, which is compatible with the SDR hardware interface. On the FPGA, the Host to FPGA Unpacking subsystem extracts the two LSBs and concatenates them into an unsigned 2-bit integer to be modulated by the Symbol Mapping subsystem.
  • The downsample by 4 at the input to the HDLTx subsystem is paired with the Repeat block at the top level of the model. When targeting a subsystem for inclusion in the SDR transmit chain, the subsystem must have the same sample rate at its input and output. Since the root raised cosine filter increases the sample rate by 4, it is necessary to artificially increase the sample rate at the input to the subsystem by 4. See Targeting Limitations for more information.

List of Example Helper Files

This example uses the following helper files: