Decode and Recover Message Using DVB-S2X Standard FEC Decoder
R2026bThis 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);

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;