Main Content

LDPC Decode 5G NR Streaming Data for Multiple Code Rates with Early Termination

This example shows how to use multiple code rates and early termination criteria features in the NR LDPC Decoder Simulink® block. The input to the block is generated using the nrLDPCEncode (5G Toolbox) MATLAB® function and the output of the block is compared with the input of the function. In this example, you can select either the min-sum or normalized min-sum algorithm for the decoding operation.

Generate Input Data

Choose a series of input values for the base graph number (bgn) and liftingSize according to the 5G new radio (NR) standard and generate the corresponding input vectors for those values. Use the encoded data from the nrLDPCEncode function to generate input log-likelihood ratio (LLR) values for the NR LDPC Decoder block. Use channel, modulator, and demodulator System objects to add noise to the signal. Again, create vectors of bgn and liftingSize, and then convert the frames of data to LLRs with a control signal that indicates the frame boundaries. The decFrameGap accommodates the latency of the NR LDPC Decoder block for base graph number, liftingSize, and number of iterations. Use the nextFrame output signal to determine when the block is ready to accept the start of the next input frame.

bgn = [1; 0; 0; 1];
liftingSize = [4; 384; 144; 208];
numRows = [6; 38; 24; 10];
numFrames = 4;
serial = false;  % true for serial inputs and false for parallel inputs

msg = {numFrames};
K = [];
N = [];
for ii = 1:numFrames
    if bgn(ii) == 0
        K(ii) = 22;
    else
        K(ii) = 10;
    end
    N(ii) = numRows(ii) + K(ii)-2;
    frameLen = liftingSize(ii)*K(ii);
    msg{ii} = randi([0 1],frameLen,1);

    encTmp = nrLDPCEncode(msg{ii},bgn(ii)+1);
    encOut{ii} = encTmp(1:N(ii)*liftingSize(ii));
end
nVar = 0.5;
chan = comm.AWGNChannel('NoiseMethod','Variance','Variance',nVar);

algo = 'Min-sum'; % 'Min-sum' or 'Normalized min-sum'
if strcmpi(algo,'Min-sum')
    alpha = 1;
else
    alpha = 0.75;
end

numIter = 8;
decbgnIn = [];
decliftingSizeIn = [];
rxLLR = {numFrames};
decSampleIn = [];
decStartIn = [];
decEndIn = [];
decValidIn = [];
decnumRows = [];

for ii=1:numFrames
    mod = nrSymbolModulate(encOut{ii},'BPSK');
    rSig = chan(mod);
    rxLLR{ii}  = nrSymbolDemodulate(rSig,'BPSK',nVar);

    if serial
        len = N(ii)*liftingSize(ii); %#ok<*UNRCH>
        decFrameGap = numIter*7000 + liftingSize(ii)*K(ii);
     else
        len = N(ii)*ceil(liftingSize(ii)/64);
        decFrameGap = numIter*1200;
     end

    decIn = ldpc_dataFormation(rxLLR{ii}',liftingSize(ii),N(ii),serial);

    decSampleIn = [decSampleIn decIn zeros(size(decIn,1),decFrameGap)]; %#ok<*AGROW>
    decStartIn = logical([decStartIn 1 zeros(1,len-1) zeros(1,decFrameGap)]);
    decEndIn = logical([decEndIn zeros(1,len-1) 1 zeros(1,decFrameGap)]);
    decValidIn = logical([decValidIn ones(1,len) zeros(1,decFrameGap)]);
    decbgnIn = logical([decbgnIn repmat(bgn(ii),1,len) zeros(1,decFrameGap)]);
    decliftingSizeIn = uint16([decliftingSizeIn repmat(liftingSize(ii),1,len) zeros(1,decFrameGap)]);
    decnumRows = fi([decnumRows repmat(numRows(ii),1,len) zeros(1,decFrameGap)],0,6,0);
end

decSampleIn = timeseries(fi(decSampleIn',1,4,0));
sampleTime = 1;

simTime = length(decValidIn);

Run Simulink Model

The HDL Algorithm subsystem contains the NR LDPC Decoder block. Running the model imports the input signal variables decSampleIn, decStartIn, decEndIn, decValidIn, decbgnIn, decliftingSizeIn, numIter, sampleTime, and simTime and exports a stream of decoded output samples sampleOut along with a control signal ctrlOut to the MATLAB workspace.

open_system('NRLDPCDecoderCodeRateHDL');
if alpha ~= 1
    set_param('NRLDPCDecoderCodeRateHDL/HDL Algorithm/NR LDPC Decoder','Algorithm','Normalized min-sum');
else
    set_param('NRLDPCDecoderCodeRateHDL/HDL Algorithm/NR LDPC Decoder','Algorithm','Min-sum');
end
decOut = sim('NRLDPCDecoderCodeRateHDL');

Compare Simulink Block Output with MATLAB Function Input

Convert the streaming data output of the NR LDPC Decoder block to frames and then compare the frames with the input of the nrLDPCEncode function.

startIdx = find(decOut.ctrlOut.start.Data);
endIdx = find(decOut.ctrlOut.end.Data);

for ii = 1:numFrames
   decHDL{ii} = ldpc_dataExtraction(decOut.sampleOut.Data,liftingSize(ii),startIdx(ii),endIdx(ii),K(ii),serial); %#ok<*SAGROW>
   error = sum(abs(double(msg{ii})-decHDL{ii}));
   fprintf(['Decoded frame %d: Output data differs by %d bits\n'],ii,error);
   iter_tmp = squeeze(decOut.actIter.Data);
   actIter{ii} = iter_tmp(startIdx(ii));
   fprintf(['Actual iterations taken to decode the frame: %d \n'],actIter{ii});
end
Decoded frame 1: Output data differs by 0 bits
Actual iterations taken to decode the frame: 2 
Decoded frame 2: Output data differs by 0 bits
Actual iterations taken to decode the frame: 8 
Decoded frame 3: Output data differs by 0 bits
Actual iterations taken to decode the frame: 8 
Decoded frame 4: Output data differs by 0 bits
Actual iterations taken to decode the frame: 2 

See Also

Blocks

Functions