MATLAB Examples

Verify Turbo Decoder with Streaming Data from MATLAB

This example shows how to verify a hardware-targeted Turbo Decoder design using streaming data from MATLAB®.

To run this example, use the VerifyLTEHDLTurboDecoderStreamingData.m script.

LTE Toolbox™ functions model operations on framed, floating-point and integer data and provide excellent behavioral references. Hardware designs must use streaming Boolean or fixed-point data. This example converts frames to samples in MATLAB and imports the sample stream to Simulink® for hardware algorithm design. The same data is applied to both the hardware algorithm in Simulink, and the behavioral algorithm in MATLAB. The output sample stream from the Simulink simulation is exported to MATLAB and then converted back to framed data for comparison.

Contents

Hardware Targeting in Simulink

The key features of a model for hardware targeting in Simulink® are:

  • Streaming Sample Interface: LTE Toolbox functions process frames while blocks in LTE HDL Toolbox use a streaming sample interface. Serial processing is efficient for hardware designs. For further information, see Streaming Sample Interface. You can convert frames to samples in Simulink using the Frame To Samples block or in MATLAB using the ltehdlFramesToSamples function. In this example, we convert the frames to samples in MATLAB using the ltehdlFramesToSamples function.
  • Subsystem Targeted for HDL Code Generation: Design a hardware-friendly sample-streaming model by selecting blocks from the LTE HDL Toolbox libraries. The part of the design targeted for HDL code generation must be in a separate subsystem.
  • Conversion of Sample-Based Output to Frames: For verification, you can export the result of your hardware-compatible design to the MATLAB® workspace. You can then compare this result with the output of a MATLAB behavioral design. In this example, we convert the samples to frames in MATLAB using the ltehdlSamplesToFrames function.

You can use the VerifyLTEHDLTurboDecoderStreamingData.m MATLAB script to run the MATLAB behavioral code, set up, import data and run the Simulink™ model, export the data, and compare the behavioral and Simulink output.

The MATLAB script contains six parts:

  1. Behavioral Simulation of Turbo Decoder
  2. Conversion of Input Frames to Samples
  3. Set Up the Simulink Model for Hardware Design
  4. Run Simulink Model
  5. Conversion of Output Samples to Frames
  6. Verify Output of Simulink Model

Behavioral Simulation of Turbo Decoder

For a behavioral simulation of the design, use the lteTurboDecode function from LTE Toolbox. This data generated, softBits is used as input for the HDL targeted design. The behavioral output of the lteTurboDecode function, rxBits can be used for comparison to the output of the HDL targeted design. Both softBits and rxBits are frames of floating-point data.

% Turbo decoding of soft bits obtained from a noisy constellation
turboFrameSize = 6144;
txBits = randi([0 1],turboFrameSize,1);
codedData = lteTurboEncode(txBits);
txSymbols = lteSymbolModulate(codedData,'QPSK');
noise = 0.5*complex(randn(size(txSymbols)),randn(size(txSymbols)));
rxSymbols = txSymbols + noise;
scatter(real(rxSymbols),imag(rxSymbols),'co'); hold on;
scatter(real(txSymbols),imag(txSymbols),'rx')
legend('Rx constellation','Tx constellation')
softBits = lteSymbolDemodulate(rxSymbols,'QPSK','Soft');
rxBits = lteTurboDecode(softBits);

Conversion of Input Frames to Samples

First, convert the input frame to fixed-point.

inframes = fi(softBits, 1, 5, 2);

Next, convert the framed data to a stream of samples and control signals using the ltehdlFramesToSamples function. This function also adds invalid samples to the sample stream to mimic streaming hardware data. The output of this function is the input to the Simulink model.

In this example, the ltehdlFramesToSamples function is configured to provide the inputs to the LTE Turbo Decoder block in the Simulink model. No invalid samples are inserted between valid samples.

The LTE Turbo Decoder block takes in a frame of data, one sample at a time, runs through the specified number of iterations and can then accept another input frame. In order to allow the block processing time to run the 6 iterations, we add in invalid samples between frames. In this example, we set the number of invalid samples between frames to 7 iterations (or 14 half-iterations, each of which corresponds to a frame of delay). To calculate the exact cycles needed to process a frame, look at the documentation.

The behavioral Turbo Encoder sends all systematic bits out first, followed by the first set of parity bits and finally, the second set of parity bits. The LTE Turbo Decoder however requires each set of systematic and 2 parity bits to be sent in together. In order to reshape the input data to the Turbo Decoder block accordingly, we choose the option to compose the output samples from interleaved input samples.

inframesize = 18444; % size of softBits
% No invalid cycles between samples
idlecyclesbetweensamples = 0;
% Additional delay in frames for Turbo Decoder output
numTurboIterations = 6;
% approximate latency from Turbo Decoder block per half-iteration
tdlatency = (ceil(turboFrameSize/32)+4)*32;
% approximate delay in frames for Turbo Decoder output
algframedelay = (2*numTurboIterations + 2)*(ceil(tdlatency/turboFrameSize));
idlecyclesbetweenframes = (inframesize/insamplesize)*algframedelay;
% Output is composed of interleaved input samples
% input: S_1 S_2 ... S_n P1_1 P1_2 ... P1_n P2_1 P2_2 ... P2_n
% output: S_1 P1_1 P2_1 S2 P1_2 P2_2 ... Sn P1_n P2_n
interleaveSamples = true;
[sampleIn, ctrlIn] = ...
    ltehdlFramesToSamples(inframes, ...
                          idlecyclesbetweensamples, ...
                          idlecyclesbetweenframes, ...
                          encoderrate, ...
                          interleaveSamples);

Set Up the Simulink Model for Hardware Design

The model imports sample-based data and control and the Turbo Decoder frame size from the MATLAB workspace.

modelname = 'TurboDecoderStreamingDataHDLExample';

The LTE Turbo Decoder subsystem consists of the LTE Turbo Decoder block. This block is set to run 6 iterations of decoding.

The MATLAB code defines the settings for the input size, sample time for the Simulink model, and computes the desired simulation time.

% Settings for Sample Input From Workspace block
samplesizeIn = encoderrate; % samples in at a time
sampletime = 1;
simTime = size(ctrl,1);

Run Simulink Model

You can run the model by clicking the Play button or calling the sim command on the MATLAB command line.

sim(modelname);

Conversion of Output Samples to Frames

Running the model results in streaming samples and control signals logged from the model in the variable sampleOut_ts and ctrlOut_ts. The sample and control data are converted to frames using the ltehdlSamplesToFrames function.

% Reformat the logged data to form the sample and control output
sampleOut = squeeze(sampleOut_ts.Data);
ctrlOut = [squeeze(ctrlOut_ts.start.Data) ...
           squeeze(ctrlOut_ts.end.Data) ...
           squeeze(ctrlOut_ts.valid.Data)];
% Form frames from output sample and control data
outframes = ltehdlSamplesToFrames(sampleOut, ctrlOut);
% Gather all the bits - expecting only one frame
rxBits_hdl = outframes{:};

Verify Output of Simulink Model

Compare the output of the HDL simulation to the output of the behavioral simulation to find the number of bit mismatches between the behavioral code and hardware-targeted model.

This simulation results in no bit errors. Increasing the amount of noise added to the samples or reducing the number of iterations may result in bit errors.

% Check number of bit mismatches
numBitsDiff = sum(rxBits_hdl ~= rxBits);
fprintf(['\nLTE Turbo Decoder: Behavioral and ' ...
   'HDL simulation differ by %d bits\n\n'], numBitsDiff);

Generate HDL Code and Verify its Behavior

Once your design is working in simulation, you can use HDL Coder™ to generate HDL code and test bench for the LTE Turbo Decoder subsystem. Use HDL Verifier™ to generate a System Verilog DPI testbench or run FPGA in the Loop.

makehdl([modelname '/LTE Turbo Decoder'])   % Generate HDL code
makehdltb([modelname '/LTE Turbo Decoder']) % Generate HDL Test bench