This example highlights the low-density parity-check (LDPC) coding chain for the 5G NR downlink and uplink shared transport channels (DL-SCH and UL-SCH).
The example uses the DL-SCH to describe the processing, which also applies to the UL-SCH.
Select parameters for a transport block transmitted on the downlink shared (DL-SCH) channel.
rng(210); % Set RNG state for repeatability A = 10000; % Transport block length, positive integer rate = 449/1024; % Target code rate, 0<R<1 rv = 0; % Redundancy version, 0-3 modulation = 'QPSK'; % Modulation scheme, QPSK, 16QAM, 64QAM, 256QAM nlayers = 1; % Number of layers, 1-4 for a transport block
Based on the selected transport block length and target coding rate, DL-SCH coding parameters are determined using the
% DL-SCH coding parameters cbsInfo = nrDLSCHInfo(A,rate); disp('DL-SCH coding parameters') disp(cbsInfo)
DL-SCH coding parameters CRC: '24A' L: 24 BGN: 1 C: 2 Lcb: 24 F: 244 Zc: 240 K: 5280 N: 15840
DL-SCH supports multi-codeword transmission (i.e. two transport blocks) while UL-SCH supports only a single codeword. UL-SCH also supports pi/2-BPSK modulation in addition to those listed above for DL-SCH.
Data delivered from the MAC layer to the physical layer is termed as a transport block. For the downlink shared channel (DL-SCH), a transport block goes through the processing stages of:
Code block segmentation and code block CRC attachment,
Channel coding using LDPC,
Rate matching and code block concatenation
before being passed on to the physical downlink shared channel (PDSCH) for scrambling, modulation, layer mapping and resource/antenna mapping. Each of these stages is performed by a function as shown next.
% Random transport block data generation in = randi([0 1],A,1,'int8'); % Transport block CRC attachment tbIn = nrCRCEncode(in,cbsInfo.CRC); % Code block segmentation and CRC attachment cbsIn = nrCodeBlockSegmentLDPC(tbIn,cbsInfo.BGN); % LDPC encoding enc = nrLDPCEncode(cbsIn,cbsInfo.BGN); % Rate matching and code block concatenation outlen = ceil(A/rate); chIn = nrRateMatchLDPC(enc,outlen,rv,modulation,nlayers);
The output number of bits from the rate matching and code block concatenation process must match the bit capacity of the PDSCH, based on the available resources. In this example, as the PDSCH is not modeled, this is set to achieve the target code rate based on the transport block size previously selected.
Similar processing applies for the UL-SCH, where the physical uplink shared channel (PUSCH) is the recipient of the UL-SCH codeword. The following schematics depict the processing for the two channels.
A simple bipolar channel with no noise is used for this example. With the full PDSCH or PUSCH processing, one can consider fading channels, AWGN and other RF impairments as well.
chOut = double(1-2*(chIn));
The receive end processing for the DL-SCH channel comprises of the corresponding dual operations to the transmit end that include
Code block desegmentation and CRC decoding
Transport block CRC decoding
Each of these stages is performed by a function as shown next.
% Rate recovery raterec = nrRateRecoverLDPC(chOut,A,rate,rv,modulation,nlayers); % LDPC decoding decBits = nrLDPCDecode(raterec,cbsInfo.BGN,25); % Code block desegmentation and CRC decoding [blk,blkErr] = nrCodeBlockDesegmentLDPC(decBits,cbsInfo.BGN,A+cbsInfo.L); disp(['CRC error per code-block: [' num2str(blkErr) ']']) % Transport block CRC decoding [out,tbErr] = nrCRCDecode(blk,cbsInfo.CRC); disp(['Transport block CRC error: ' num2str(tbErr)]) disp(['Recovered transport block with no error: ' num2str(isequal(out,in))])
CRC error per code-block: [0 0] Transport block CRC error: 0 Recovered transport block with no error: 1
As the displays indicate, there are no CRC errors at both the code-block and transport block levels. This leads to the transport block being recovered and decoded with no errors, as expected, for a noiseless channel.