Main Content

DVB-S2 HDL BCH Encoder

This example shows how to implement a DVB-S2 BCH encoder using Simulink® blocks that are optimized for HDL code generation.

To verify the behavior of the DVB-S2 HDL BCH Encoder example, you compare the output of the example with the bchEncode helper function.

Introduction

Digital Video Broadcast Satellite Second Generation (DVB-S2) is a European Telecommunications Standards Institute (ETSI) standard for digital data transmission through satellites. DVB-S2 offers powerful forward error correction (FEC) based on low-density parity-check (LDPC) codes concatenated with Bose-Chaudhuri-Hocquenghem (BCH) codes.

The FEC mechanism performs outer coding with BCH codes and inner coding with LDPC codes. This mechanism accepts baseband frames (BBFRAMEs) of $\textbf{K}_{\mathrm{\textbf{bch}}}$ bits as input and gives out forward error correction frames (FECFRAMEs) of $\textbf{n}_{\mathrm{\textbf{ldpc}}}$ bits as output as specified in the section 5.3 of ETSI EN 302 307-1 [ 1 ]. This figure shows the frame format of FECFRAME data.

The DVB-S2 standard specifies 11 code rates for normal frames and 10 code rates for short frames. In tables 5a and 5b in the section 5.3 of [ 1 ], the standard defines BCH code rates for different uncoded block lengths and for different frame types.

Model Architecture

This figure shows the architecture block diagram of the DVB-S2 BCH Encoder example implementation.

This figure shows the top-level structure of the dvbs2hdlBCHEncoder model. You can generate the HDL code for the DVB-S2 BCH Encoder subsystem in the model.

modelName = 'dvbs2hdlBCHEncoder';
open_system(modelName);
set_param(modelName,'Open','on');

DVB-S2 BCH Encoder

The DVB-S2 BCH Encoder subsystem accepts input data, a control signal, a frame type, and a code rate index. The subsystem samples frameTypeIn and codeRateIdxIn signals at the start of the frame. The Input Controller subsystem controls the write and read operation of the input data to and from the RAM, respectively, inside the Store and Retrieve Input subsystem. The DVB-S2 BCH Encoder subsystem performs the BCH encoding after writing the whole frame to the RAM. Use tables 5a, 5b, 6a, and 6b in section 5.3 of [ 1 ] to calculate the generator polynomial. Using the Parity Generator subsystem, generate parity bits using the generator polynomial. This subsystem also stores and retrieves parity bits using RAM and performs parity indexing. Using the Output Controller subsystem, append the input data with the generated parity bits and generate output control signals.

set_param(modelName,'Open','off');
open_system([modelName '/DVB-S2 BCH Encoder']);

Input Controller

The Input Controller subsystem consists of these sections:

  • The Sample Bus Controller section accepts the input sample control bus and identifies the start, end, and valid signals. This section also generates the reset signal.

  • The Sampler section samples the frameType and codeRateIdx using start signal and outputs the corresponding input frame length and parity length. This section also validates frame parameters and returns the result in the validateFrameFlag indicator.

  • The Write Address Generator section has a write counter that runs till the input frame length and generates the address at which it stores the input bits inside the RAM.

  • The Read Address Generator section has a read counter that runs till the input frame length and generates the address for reading the stored input bits from the RAM. validFrameFlag signal enables read address generation only after storing the entire input frame inside the RAM.

set_param([modelName '/DVB-S2 BCH Encoder'],'Open','off');
open_system([modelName '/DVB-S2 BCH Encoder/Input Controller']);

Store and Retrieve Input

After generating the read and write address, the Store and Retrieve Input subsystem uses the Data RAM block to read and write the bits. For each high value of the outRd_valid signal, this subsystem reads a data bit from the Data RAM block and feeds it into the Parity Generator subsystem. The Store and Retrieve Input subsystem also compares the read addresses with the input frame length and indicates the end of the parity calculation using ParityCalCompFlag signal.

set_param([modelName '/DVB-S2 BCH Encoder'],'Open','off');
open_system([modelName '/DVB-S2 BCH Encoder/Store and Retrieve Input']);

Parity Generator

The parityBitsGenerator function generates a parity bit vector of length 192 for every input data bit according to the section 5.3.1 in [ 1 ]. For the parity lengths 168, 160, and 128, this function generates parity bit vectors of corresponding lengths appends zeros to create a vector of the length 192. The write address iwr_addr is always 0. The Read Address Generator section generates the read address. The Store and Retrieve Parity subsystem stores and retrieves the vector parity bits. The parityIndexing function block outputs the scalar parity bits from the parity vector based on the parity index that the Parity Bit Read Counter block generates.

set_param([modelName '/DVB-S2 BCH Encoder'],'Open','off');
open_system([modelName '/DVB-S2 BCH Encoder/Parity Generator']);

Output Controller

The Output Controller subsystem consists of these sections:

  • The Next Frame Generator generates the next frame logic using the previous state of nxtFrame, sampledStartIn, sampledEndIn, endOut, enbBCHEnc, unitFrameLen, validCodeRate, and frameLen signals.

  • The Output Generator section multiplexes the message and parity to generate the output data. This subsystem also generates the output sample control bus using an Output Counter block that runs till the output frame length.

set_param([modelName '/DVB-S2 BCH Encoder'],'Open','off');
open_system([modelName '/DVB-S2 BCH Encoder/Output Controller']);

Set Up Input Variables

Choose input values for the FEC frame type and the corresponding code rates according to the DVB-S2 standard. You can change the variable values in this section based on your requirements. Specify the codeRateIdx values as integers in the range [0, 10] that correspond to the codeRateSet values '1/4', '1/3', '2/5', '1/2', '3/5', '2/3', '3/4', '4/5', '5/6', '8/9', and '9/10'.

fecFrameSet = {'Normal','Short'};
codeRateSet = {'1/4','1/3','2/5','1/2','3/5','2/3','3/4','4/5','5/6','8/9','9/10'};

frameType = [1 0];   % FEC frame type
codeRateIdx = [1 0]; % Code rate index
numFrames = 2;

Generate Input Data

Generate inputs for the bchEncode helper function with the specified frame type and code rate variables. Create vectors of the frame type and code rate index using the frameTypeIn and codeRateIdxIn variables, respectively. Convert the frames of input data to samples with a control bus signal that indicates the frame boundaries. Provide these vectors and the control bus as inputs to the DVB-S2 BCH Encoder subsystem.

The encFrameGap variable accommodates the latency of the DVB-S2 BCH Encoder subsystem for the specified block length and code rate.

fecFrameType = fecFrameSet(frameType+1);
codeRate = codeRateSet(codeRateIdx+1);
msg = {numFrames};
refOut = cell(1,numFrames);

encSampleIn = [];
encStartIn = [];
encEndIn = [];
encValidIn = [];
fFrameIn = [];
codeRateIn = [];

for framIdx = 1:numFrames
    fFrame =  fecFrameType{framIdx};

    % Input and code word length calculation
    if strcmpi(fFrame,'Normal')
        cwLen = 64800;
        inpFrameLenList = [16008 21408 25728 32208 38688 43040 48408 51648 53840 57472 58192];
        inpRateList = [1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 5/6 8/9 9/10];
        frameLenArr = inpFrameLenList(inpRateList == str2num(codeRate{framIdx}));
        frameLen = frameLenArr(1);
    else
        cwLen = 16200;
        inpFrameLenList = [3072  5232  6312  7032  9552 10632 11712 12432 13152 14232];
        inpRateList = [1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 5/6 8/9];
        frameLenArr = inpFrameLenList(inpRateList == str2num(codeRate{framIdx}));
        frameLen = frameLenArr(1);
    end
    inpLen = frameLen;

    % Input bits generation
    msg{framIdx} = (randi([0 1],inpLen,1));

    % BCH encoding
    refOut{framIdx} = satcom.internal.dvbs.bchEncode(int8(msg{framIdx}),inpLen,cwLen);

    % Select the value cwLen*2 to accommodate the maximum latency of the
    % block considering different frame type and code rate configurations
    encFrameGap = cwLen*2;

    encSampleIn = [encSampleIn msg{framIdx}' zeros(1,encFrameGap)]; %#ok<*AGROW>
    encStartIn = logical([encStartIn 1 zeros(1,inpLen-1) zeros(1,encFrameGap)]);
    encEndIn = logical([encEndIn zeros(1,inpLen-1) 1 zeros(1,encFrameGap)]);
    encValidIn = logical([encValidIn ones(1,inpLen) zeros(1,encFrameGap)]);
    fFrameIn = logical([fFrameIn repmat(frameType(framIdx),1,inpLen) zeros(1,encFrameGap)]);
    codeRateIn = [codeRateIn repmat(codeRateIdx(framIdx),1,inpLen) zeros(1,encFrameGap)];
end

dataIn = logical(encSampleIn');
startIn = encStartIn;
endIn = encEndIn;
validIn = encValidIn;
frameTypeIn = fFrameIn;
codeRateIdxIn = codeRateIn;

simTime = length(encValidIn);

Run Simulink Model

The DVB-S2 BCH Encoder subsystem contains the implementation of the DVB-S2 BCH Encoder. Run the model to import the input signal variables dataIn, startIn, endIn, validIn, frameTypeIn, codeRateIdxIn, and simTime to the example from the script. The model exports a stream of encoded output samples encOut and a control bus containing startOut, endOut, and validOut signals to the MATLAB® workspace.

enc = sim(modelName);

Compare Block Output with Function Output

Convert the streaming output data of the DVB-S2 BCH Encoder subsystem to frames. Compare the frames with the output of the bchEncode helper function.

startIdx = find(squeeze(enc.startOut));
endIdx = find(squeeze(enc.endOut));
encData = squeeze(enc.dataOut);

encHDL = {numFrames};
for framIdx = 1:numFrames
    idx = startIdx(framIdx):endIdx(framIdx);
    encHDL{framIdx} = encData(idx);
    HDLOutput = double(encHDL{framIdx}(1:length(refOut{framIdx})));
    error = sum(abs(double(refOut{framIdx})-HDLOutput(:)));
    fprintf('Encoded %s FEC frame and code rate %s: Output data differs by %d bits\n',fecFrameType{framIdx},codeRate{framIdx},error);
end
Encoded Short FEC frame and code rate 1/3: Output data differs by 0 bits
Encoded Normal FEC frame and code rate 1/4: Output data differs by 0 bits

Calculate Latency

The latency of the DVB-S2 BCH Encoder in this example is $\textbf{K}_{\mathrm{\textbf{bch}}}+10$ clock cycles, where $\textbf{K}_{\mathrm{\textbf{bch}}}$ is input frame length of the BCH encoder.

This figure shows the latency of the DVB-S2 BCH Encoder example when you set the frameType input port to 0 and the codeRateIdx input port to 3.

Generate HDL Code

To check and generate HDL code for this example, you must have an HDL Coder™ license. Use the makehdl and makehdltb commands to generate the HDL code and test bench for the DVB-S2 BCH Encoder subsystem.

Synthesize the DVB-S2 BCH Encoder subsystem on a Xilinx® Xilinx Zynq® UltraScale+ RFSoC xczu29dr-ffvf1760-2-e. This table shows the resource utilization results.

F = table(...
    categorical({'Slice LUT';'Slice Registers';'RAMB36';'DSP'; ...
    'Max. Frequency (MHz)'}) ,...
    categorical({'1401';'1032';'2';'0';'602.71'}), ...
    'VariableNames',{'Resources','Values'});

disp(F);
         Resources          Values
    ____________________    ______

    Slice LUT               1401  
    Slice Registers         1032  
    RAMB36                  2     
    DSP                     0     
    Max. Frequency (MHz)    602.71

References

  1. ETSI 302 307-1 "Second generation framing structure, channel coding and modulation systems for Broadcasting, Interactive Services, News Gathering and other broadband satellite applications; Part 1: DVB-S2." Digital Video Broadcasting. https://www.etsi.org