主要内容

Decode and Recover Message Using DVB-S2X Standard FEC Decoder

R2026b
Since R2026b

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 Extensions (DVB-S2X) standard.

The FEC decoder model in this example comprises a DVB-S2X LDPC Decoder block and a DVB-S2X BCH Decoder block connected in sequence. To provide input to the model, an encoded data of DVB-S2X 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 these 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 = [0 2];     % Type of FEC frame. 0 for normal frame, 1 for short frame, and 2 for medium frame.
codeRateIdx = [11 1];  % Code rate index must be in the range 0 to 34 for normal frame,
                       % 0 to 16 for short frame, and in the range 0 to 2 for medium frame.
parallelism = 45;      % Specify parallelism as 45 or 180
nIter = 10;            % Number of iterations in the range 1 to 63
EbNo = 15;             % Adjust to avoid bit errors for selected frame type and code rate.
modOrder = [8 8];      % Modulation order per frame 

Download DVB-S2X LDPC Parity Matrices Data Set

To use Satellite Communications Toolbox helper functions, you need a MAT file predefined with DVB-S2X 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 = 'dvbs2xLDPCBCHDecode';
open_system(modelName);

Simulink model showing a DVB-S2X LDPC and BCH decoder chain. Input signals include dataIn (converted from double to fixed-point), startIn, endIn, and validIn, which are combined using a Sample Control Bus Creator. Additional inputs frameTypeIn (ufix2) and codeRateIdxIn (ufix6) connect directly to the decoder. The central block, labelled “DVB-S2X LDPC BCH Decoder,” processes the input stream and outputs decoded data (bchDataOut) along with control signals (start, end, valid) via a Sample Control Bus Selector. Output ports provide dataOut, startOut, endOut, and validOut signals corresponding to the decoded frame.

Define Frame Type and Code Rate Sets

Define the frame types and the code rates for each frame type.

fecFrameSet = {'Normal','Short','Medium'};

codeRateNormalSet = {'1/4','1/3','2/5','1/2','3/5','2/3','3/4','4/5','5/6','8/9','9/10', ...
    '2/9','13/45','9/20','90/180','96/180','11/20','100/180','104/180','26/45', ...
    '18/30','28/45','23/36','116/180','20/30','124/180','25/36','128/180','13/18', ...
    '132/180','22/30','135/180','140/180','7/9','154/180'};

codeRateShortSet = {'1/4','1/3','2/5','1/2','3/5','2/3','3/4','4/5','5/6','8/9', ...
    '11/45','4/15','14/45','7/15','8/15','26/45','32/45'};

codeRateMediumSet = {'1/5','11/45','1/3'};

fecFrameType = fecFrameSet(frameType+1);
msg = cell(1,numFrames);
codeRateStr = cell(1,numFrames);

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.

encSampleIn = [];
  encValidIn  = [];
  encStartIn  = [];
  encEndIn    = [];
  frameTypeIn = [];
  codeRateIn  = [];
  frameGap = 0;

  % Configure model parallelism (same for all frames)
  set_param([modelName '/DVB-S2X LDPC BCH Decoder/DVB-S2X LDPC Decoder'], ...
      'Parallelism',num2str(parallelism));

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

      % Select code rate string from index
      if strcmpi(fFrame,'Normal')
          codeRate = codeRateNormalSet{codeRateIdx(ii)+1};
      elseif strcmpi(fFrame,'Short')
          codeRate = codeRateShortSet{codeRateIdx(ii)+1};
      else
          codeRate = codeRateMediumSet{codeRateIdx(ii)+1};
      end
      codeRateStr{ii} = codeRate;

      % Get BCH and LDPC lengths
      if parallelism == 45
          ldpcDecLat = nIter*8000;
      else
          ldpcDecLat = nIter*3000;
      end
      if strcmpi(fFrame,'Normal')
          Nldpc = 64800;
          R = str2num(codeRate); %#ok<ST2NM>

          KbchList = [16008,21408,25728,32208,38688,43040,48408,51648,53840,57472,58192,...
                      14208,18528,28968,32208,34368,35448,35808,37248,37248,38688,40128,41208,41568,...
                      43008,44448,44808,45888,46608,47328,47328,48600,50208,50208,55248];
          NbchList = [16200,21600,25920,32400,38880,43200,48600,51840,54000,57600,...
                      58320,14400,18720,29160,32400,34560,35640,36000,37440,37440,38880,40320,41400,...
                      41760,43200,44640,45000,46080,46800,47520,47520,48600,50400,50400,55440];

          Kbch = KbchList(codeRateIdx(ii)+1);
          Nbch = NbchList(codeRateIdx(ii)+1);

      elseif strcmpi(fFrame,'Short')
          Nldpc = 16200;

          KbchList = [3072 5232 6312 7032 9552 10632 11712 12432 13152 14232 ...
              3792 4152 4872 7392 8472 9192 11352];
          NbchList = [3240 5400 6480 7200 9720 10800 11880 12600 13320 14400 ...
              3960 4320 5040 7560 8640 9360 11520];

          Kbch = KbchList(codeRateIdx(ii)+1);
          Nbch = NbchList(codeRateIdx(ii)+1);

          % Effective code rate for SNR calculation
          if codeRateIdx(ii) <= 9
              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)); %#ok<ST2NM>
              R = Reff(1);
          else
              R = str2num(codeRate); %#ok<ST2NM>
          end

      else % Medium
          Nldpc = 32400;
          R = str2num(codeRate); %#ok<ST2NM>

          KbchList = [5660 7740 10620];
          NbchList = [5840 7920 10800];

          Kbch = KbchList(codeRateIdx(ii)+1);
          Nbch = NbchList(codeRateIdx(ii)+1);
      end

      inpLen = Kbch;

      % Modulation used for example input generation
      M = modOrder(ii);
      bps = log2(M);

      % Message bits (input to BCH encoder)
      msg{ii} = randi([0 1],inpLen,1);

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

      % LDPC encoding
      ldpcOut = satcom.internal.dvbs.ldpcEncode(int8(bchOut),codeRate,Nldpc);

      % Symbol mapping
      modOut = satcom.internal.dvbs.mapper(ldpcOut,M,codeRate,Nldpc,true);

      % AWGN channel
      EsNo = EbNo + 10*log10(bps);
      snrdB = EsNo + 10*log10(R);
      noiseVar = 1./(10.^(snrdB/10));
      rxData = awgn(modOut,snrdB,'measured');

      % Symbol demapping
      demodOut = satcom.internal.dvbs.demapper(rxData,M,codeRate,Nldpc,noiseVar);

      % Gap between frames
      ldpcLen = length(demodOut);
      frameGap = Nldpc + ldpcDecLat + 2000;

      encSampleIn = [encSampleIn demodOut.' zeros(1,frameGap)]; %#ok<AGROW>
      encStartIn  = logical([encStartIn 1 zeros(1,ldpcLen-1) zeros(1,frameGap)]); %#ok<AGROW>
      encEndIn    = logical([encEndIn zeros(1,ldpcLen-1) 1 zeros(1,frameGap)]); %#ok<AGROW>
      encValidIn  = logical([encValidIn ones(1,ldpcLen) zeros(1,frameGap)]); %#ok<AGROW>

      frameTypeIn = [frameTypeIn repmat(frameType(ii),1,ldpcLen) zeros(1,frameGap)]; %#ok<AGROW>
      codeRateIn  = [codeRateIn repmat(codeRateIdx(ii),1,ldpcLen) zeros(1,frameGap)]; %#ok<AGROW>
  end
dataIn        = encSampleIn.';
validIn       = encValidIn;
startIn       = encStartIn;
endIn         = encEndIn;
frameTypeIn   = fi(frameTypeIn, 0, 2, 0);   % ufix2
codeRateIdxIn = fi(codeRateIn, 0, 6, 0);    % ufix6
simTime = length(encValidIn) + frameGap;

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 dvbs2xLDPCBCHDecode model with the input of the bchEncode function.

startIdx = find(squeeze(out.startOut));
endIdx   = find(squeeze(out.endOut));

decData  = squeeze(out.dataOut);
validOut = squeeze(out.validOut);
fprintf('Decoded data with the following configuration: \n');
Decoded data with the following configuration: 
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 differ by %d bits.\n',ii, fecFrameType{ii}, codeRateStr{ii}, error);
end
Frame: 1, FEC frame type: Normal, and Code rate: 2/9. The Simulink model output and the MATLAB function input differ by 0 bits.
Frame: 2, FEC frame type: Medium, and Code rate: 11/45. The Simulink model output and the MATLAB function input differ by 0 bits.
h = warning('off','MATLAB:rmpath:DirNotFound');
rmpath('s2xLDPCParityMatrices');
warning(h);
clear h;

See Also

|