Main Content

Decode and Recover Message Using DVB-S2 Standard FEC Decoder

This example shows how to decode and recover a message from a codeword using a forward error correction (FEC) decoder according to the Digital Video Broadcast Satellite Second Generation (DVB-S2) standard.

The FEC decoder model in this example comprises a DVB-S2 LDPC Decoder block and a DVB-S2 BCH Decoder block connected in sequence. To provide input to the model, an encoded data of DVB-S2 standard is generated using MATLAB® functions and Satellite Communications Toolbox helper functions. After that, to verify the functionality of the blocks the output of the Simulink® model is compared with the input of the functions. The blocks used in this model support HDL code generation.

Set Up Input Variables

Set up workspace variables to generate inputs. These values are tunable and you can modify them according to your requirement.

numFrames = 2;         % Number of frames
frameType = [1 1];     % Type of FEC frame. 0 for normal frame and 1 for short frame.
                       % You must specify the same FEC frame type for all
                       % the frames.
codeRateIdx = [3 6];   % Code rate index must be in the range 0 to 10 for normal frame
                       % and in the range 0 to 9 for short frame
nIter = 10;            % Number of iterations in the range 1 to 63
EbNo = 15;             % To avoid bit errors, minimum EbNo must be 4 for code rate index values
                       % less than 5 and 15 for code rate index values
                       % greater than or equal to 5.

Download DVB-S2 LDPC Parity Matrices Data Set

To use Satellite Communications Toolbox helper functions, you need a MAT file predefined with DVB-S2 LDPC parity matrices. If the MAT file is not available on the MATLAB path, use these commands to download and unzip the MAT file.

if ~exist('dvbs2xLDPCParityMatrices.mat','file')
    if ~exist('s2xLDPCParityMatrices.zip','file')
        url = 'https://ssd.mathworks.com/supportfiles/spc/satcom/DVB/s2xLDPCParityMatrices.zip';
        websave('s2xLDPCParityMatrices.zip',url);
        unzip('s2xLDPCParityMatrices.zip');
    end
    addpath('s2xLDPCParityMatrices');
end

modelName = 'dvbs2LDPCBCHDecode';
open_system(modelName);

Generate Input Data

Generate input data for the Simulink® model and the MATLAB functions used in this example. Generating the input involves multiple stages as mentioned in this section.

% Initialize inputs
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'};

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

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

for ii = 1:numFrames
    fFrame =  fecFrameType{ii};
    % Input and codeword length calculation
    if strcmpi(fFrame,'Normal')
        cwLen = 64800;
        R = str2num(codeRate{ii}); %#ok<*ST2NM>
        lenList = [16008 21408 25728 32208 38688 43040 48408 51648 53840 57472 58192];
        ldpcDecLat = nIter*25000;
        set_param([modelName '/DVB-S2 LDPC BCH Decoder/DVB-S2 LDPC Decoder'],'FECFrame','Normal')
        set_param([modelName '/DVB-S2 LDPC BCH Decoder/DVB-S2 BCH Decoder'],'FECFrameType','Normal')
    else
        cwLen = 16200;
        ReffList = [1/5 1/3 2/5 4/9 3/5 2/3 11/15 7/9 37/45 8/9];
        RactList = [1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 5/6 8/9];
        Reff = ReffList(RactList == str2num(codeRate{ii}));
        R = Reff(1);
        lenList = [3072 5232 6312 7032 9552 10632 11712 12432 13152 14232];
        ldpcDecLat = nIter*6500;
        set_param([modelName '/DVB-S2 LDPC BCH Decoder/DVB-S2 LDPC Decoder'],'FECFrame','Short')
        set_param([modelName '/DVB-S2 LDPC BCH Decoder/DVB-S2 BCH Decoder'],'FECFrameType','Short')
    end
    inpLen = lenList(codeRateIdx(ii)+1);

    if (codeRateIdx(ii) < 5 || strcmpi(fFrame,'Short'))
        M = 4; % QPSK
    else
        M = 16; % 16-APSK
    end
    bps = log2(M);

    % Input bits generation
    msg{ii} = (randi([0 1],inpLen,1)); % Input to |bchEncode| function

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

    % LDPC encoding
    ldpcOut = satcom.internal.dvbs.ldpcEncode(int8(bchOut), codeRate{ii}, cwLen);

    % Symbol mapping
    modOut = satcom.internal.dvbs.mapper(ldpcOut, M, ...
        codeRate{ii}, cwLen, true);

    % Channel addition - AWGN channel
    EsNo = EbNo + 10*log10(bps);
    snrdB = EsNo + 10*log10(R); % in dB
    noiseVar = 1./(10.^(snrdB/10));
    chan = comm.AWGNChannel('NoiseMethod','Variance','Variance',noiseVar);
    rxData = chan(modOut);

    % Symbol demapping
     demodOut = satcom.internal.dvbs.demapper(rxData, M, ...
        codeRate{ii}, cwLen, noiseVar);

    % Latency calculation considering different frame types and code rate
    % configurations

    ldpcLen = length(demodOut);
    encFrameGap = cwLen + ldpcDecLat + 2000;

    encSampleIn = [encSampleIn demodOut.' zeros(1,encFrameGap)]; %#ok<*AGROW>
    encStartIn = logical([encStartIn 1 zeros(1,ldpcLen-1) zeros(1,encFrameGap)]);
    encEndIn = logical([encEndIn zeros(1,ldpcLen-1) 1 zeros(1,encFrameGap)]);
    encValidIn = logical([encValidIn ones(1,ldpcLen) zeros(1,encFrameGap)]);
    codeRateIn = [codeRateIn repmat(codeRateIdx(ii),1,ldpcLen) zeros(1,encFrameGap)];
end

dataIn = ((encSampleIn.'));
validIn = (encValidIn);
startIn = (encStartIn);
endIn = (encEndIn);
codeRateIdxIn = (codeRateIn);

simTime = length(encValidIn) + encFrameGap;

Run Simulink Model

Running the model imports the input signal variables dataIn, startIn, endIn, validIn, frameTypeIn, codeRateIdxIn, and simTime to the model from the script and exports a stream of decoded output samples dataOut and a control bus containing startOut, endOut, and validOut signals from the model to the MATLAB workspace.

out = sim(modelName);

Compare Simulink Model Output with MATLAB Function Input

Compare the output of the dvbs2LDPCBCHDecode.slx model with the input of the bchEncode function.

startIdx = find(squeeze(out.startOut));
endIdx = find(squeeze(out.endOut));
validOut = (squeeze(out.validOut));
decData = squeeze(out.dataOut);
fprintf('Decoded data with the following configuration: \n');
for ii = 1:numFrames
    idx = startIdx(ii):endIdx(ii);
    decHDL = decData(idx);
    validHDL = validOut(idx);

    HDLOutput = logical(decHDL(validHDL));
    error = sum(abs(logical(msg{ii})-HDLOutput(:)));
    fprintf('Frame: %d, FEC frame type: %s, and Code rate: %s. The Simulink model output and the MATLAB function input differs by %d bits\n', ii, fecFrameType{ii},codeRate{ii},error);

end
h = warning('off','MATLAB:rmpath:DirNotFound');
rmpath('s2xLDPCParityMatrices');
warning(h);clear h;
Decoded data with the following configuration: 
Frame: 1, FEC frame type: Short, and Code rate: 1/2. The Simulink model output and the MATLAB function input differs by 0 bits
Frame: 2, FEC frame type: Short, and Code rate: 3/4. The Simulink model output and the MATLAB function input differs by 0 bits

See Also

Blocks