LDPC Encode and Decode of 5G NR Streaming Data
This example shows how to simulate the NR LDPC Encoder and NR LDPC Decoder Simulink® blocks and compare the hardware-optimized results with the results from the 5G Toolbox™ functions. These blocks support scalar and vector inputs. The NR LDPC Decoder block enables you to select either Min-sum or Normalized min-sum algorithm for decoding operation.
Generate Input Data for Encoder
Choose a series of input values for bgn and liftingSize according to the 5G new radio (NR) standard. Generate the corresponding input vectors for the selected base graph number (bgn) and liftingSize values. Generate random frames of input data and convert them to Boolean data and control signal that indicates the frame boundaries. encFrameGap accommodates the latency of the NR LDPC Encoder block for bgn and liftingSize values. Use the nextFrame signal to determine when the block is ready to accept the start of the next input frame.
bgn = [0; 1; 1; 0]; liftingSize = [4; 384; 144; 208]; numFrames = 4; serial = false; % true for serial inputs and false for parallel inputs encbgnIn = [];encliftingSizeIn = []; msg = {numFrames}; K =[];N = []; encSampleIn = [];encStartIn = [];encEndIn = [];encValidIn = []; encFrameGap = 2500; for ii = 1:numFrames if bgn(ii) == 0 K(ii) = 22; N(ii) = 66; else K(ii) = 10; N(ii) = 50; end frameLen = liftingSize(ii) * K(ii); msg{ii} = randi([0 1],1,frameLen); if serial len = K(ii) * liftingSize(ii); encFrameGap = liftingSize(ii) * N(ii) + 2500; else len = K(ii) * ceil(liftingSize(ii)/64); %#ok<*UNRCH> encFrameGap = 2500; end encIn = ldpc_dataFormation(msg{ii},liftingSize(ii),K(ii),serial); encSampleIn = logical([encSampleIn encIn zeros(size(encIn,1),encFrameGap)]); %#ok<*AGROW> encStartIn = logical([encStartIn 1 zeros(1,len-1) zeros(1,encFrameGap)]); encEndIn = logical([encEndIn zeros(1,len-1) 1 zeros(1,encFrameGap)]); encValidIn = logical([encValidIn ones(1,len) zeros(1,encFrameGap)]); encbgnIn = logical([encbgnIn repmat(bgn(ii),1,len) zeros(1,encFrameGap)]); encliftingSizeIn = uint16([encliftingSizeIn repmat(liftingSize(ii),1,len) zeros(1,encFrameGap)]); end encSampleIn = timeseries(logical(encSampleIn')); sampleTime = 1; simTime = length(encValidIn); %#ok<NASGU>
Run Encoder Model
The HDL Algorithm subsystem contains the NR LDPC Encoder block. Running the model imports the input signal variables encSampleIn, encStartIn, encEndIn, encValidIn, encbgnIn, encliftingSizeIn, sampleTime, and simTime and exports sampleOut and ctrlOut variables to the MATLAB® workspace.
open_system('NRLDPCEncoderHDL'); encOut = sim('NRLDPCEncoderHDL');

Verify Encoder Results
Convert the streaming data output of the block to frames and then compare them with the output of the nrLDPCEncode function.
startIdx = find(encOut.ctrlOut.start.Data); endIdx = find(encOut.ctrlOut.end.Data); for ii = 1:numFrames encHDL{ii} = ldpc_dataExtraction(encOut.sampleOut.Data,liftingSize(ii),startIdx(ii),endIdx(ii),N(ii),serial); %#ok<*SAGROW> encRef = nrLDPCEncode(msg{ii}',bgn(ii)+1); error = sum(abs(encRef - encHDL{ii})); fprintf(['Encoded Frame %d: Behavioral and ' ... 'HDL simulation differ by %d bits\n'],ii,error); end
Encoded Frame 1: Behavioral and HDL simulation differ by 0 bits Encoded Frame 2: Behavioral and HDL simulation differ by 0 bits Encoded Frame 3: Behavioral and HDL simulation differ by 0 bits Encoded Frame 4: Behavioral and HDL simulation differ by 0 bits
Generate Input Data for Decoder
Use the encoded data from the NR LDPC Encoder block to generate input log-likelihood ratio (LLR) values for the NR LDPC Decoder block. Use channel, modulator, and demodulator system objects to add some noise to the signal. Again, create vectors of bgn and liftingSize and convert the frames of data to LLRs with a control signal that indicates the frame boundaries. decFrameGap accommodates the latency of the NR LDPC Decoder block for bgn, liftingSize, and number of iterations. Use the nextFrame signal to determine when the block is ready to accept the start of the next input frame.
nVar = 1.2; chan = comm.AWGNChannel('NoiseMethod','Variance','Variance',nVar); algo = 'Normalized 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 = []; for ii=1:numFrames mod = nrSymbolModulate(encHDL{ii},'BPSK'); rSig = chan(mod); rxLLR{ii} = nrSymbolDemodulate(rSig,'BPSK',nVar); if serial len = N(ii)* liftingSize(ii); 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)]); end decSampleIn = timeseries(fi(decSampleIn',1,4,0)); simTime = length(decValidIn);
Run Decoder 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 control signal ctrlOut to the MATLAB workspace.
open_system('NRLDPCDecoderHDL'); if alpha ~= 1 set_param('NRLDPCDecoderHDL/HDL Algorithm/NR LDPC Decoder','Algorithm','Normalized min-sum'); else set_param('NRLDPCDecoderHDL/HDL Algorithm/NR LDPC Decoder','Algorithm','Min-sum'); end decOut = sim('NRLDPCDecoderHDL');

Verify Decoder Results
Convert the streaming data output of the block to frames and then compare them with the output of the nrLDPCDecode 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> decRef = nrLDPCDecode(double(rxLLR{ii}),bgn(ii)+1,numIter, 'Algorithm','Normalized min-sum','ScalingFactor',alpha,... 'Termination','max'); error = sum(abs(double(decRef) - decHDL{ii})); fprintf(['Decoded Frame %d: Behavioral and ' ... 'HDL simulation differ by %d bits\n'],ii,error); end
Decoded Frame 1: Behavioral and HDL simulation differ by 0 bits Decoded Frame 2: Behavioral and HDL simulation differ by 0 bits Decoded Frame 3: Behavioral and HDL simulation differ by 0 bits Decoded Frame 4: Behavioral and HDL simulation differ by 0 bits
See Also
Blocks
Functions
nrLDPCDecode(5G Toolbox) |nrLDPCEncode(5G Toolbox)