Channel Coding

The module chancodebase.py implements the base class ChanCodeBase for all NeoRadium’s channel coding classes. It encapsulates some basic functionality such as creating, appending, and checking different types of CRC based on 3GPP TS 38.212.

Here a is the hierarchy of current channel coding classes in NeoRadium:

class neoradium.chancodebase.ChanCodeBase

This is the base class for all NeoRadium’s channel coding classes.

classmethod getCrc(bits, poly)

Calculates and returns the CRC based on the bitstream bits and the generator polynomial specified by poly.

Parameters:
  • bits (numpy array) – A 1D or 2D numpy array of bits. If it is a 1D numpy array, the CRC bits are calculated for the given bitstream and a 1D numpy array containing the CRC bits is returned. If bits is an N x L numpy array, it is assumed that we have N bitstreams of length L. In this case the CRC bits are calculated for each one of N bitstreams and an N x C numpy array is returned where C is the CRC length.

  • poly (str) –

    The string specifying the generator polynomial. The following generator polynomials are supported.

    The value of poly

    Generator polynomial

    ’6’

    1100001

    ’11’

    111000100001

    ’16’

    10001000000100001

    ’24A’

    1100001100100110011111011

    ’24B’

    1100000000000000001100011

    ’24C’

    1101100101011000100010111

    For more details please refer to 3GPP TS 38.212, Section 5.1.

Returns:

If bits is a 1D numpy array, the CRC bits are returned in a 1D numpy array. If bits is an N x L numpy array, the CRC bits of N bitstreams are returned in an N x C numpy array where C is the CRC length.

Return type:

numpy array

classmethod checkCrc(bits, poly)

Checks the CRC bits at the end of the bitstream bits and returns True if the CRC is correct (matched) and False if it is not.

Parameters:
  • bits (numpy array) – A 1D or 2D numpy array of bits. If it is a 1D numpy array, the CRC bits are checked for the given bitstream and a boolean value is returned. If bits is an N x L numpy array, it is assumed that we have N bitstreams of length L. In this case the CRC bits are checked for each one of N bitstreams and a boolean numpy array of length N is returned specifying the results of CRC check for each bitstream.

  • poly (str) – The string specifying the generator polynomial. See the getCrc() method above for a list of generator polynomials.

Returns:

If bits is a 1D numpy array, the CRC check result is returned as a boolean value. If bits is an N x L numpy array, the CRC check results of N bitstreams are returned in a boolean numpy array of length N.

Return type:

boolean or numpy array

classmethod appendCrc(bits, poly)

Calculates the CRC bits for the bitstream bits, appends them to the end of the bitstream, and returns the new bitstream containing the original bitstream with CRC bits at the end.

This function calls the getCrc() method to get the CRC bits and then appends them to the end of bits.

Parameters:
  • bits (numpy array) – A 1D or 2D numpy array of bits. If it is a 1D numpy array, the CRC bits are calculated for the given bitstream and a 1D numpy array containing the original bitstream and the CRC bits is returned. If bits is an N x L numpy array, it is assumed that we have N bitstreams of length L. In this case the CRC bits are calculated and appended to the end of each one of N bitstreams and an N x M numpy array is returned where M=L+C and C is the CRC length.

  • poly (str) – The string specifying the generator polynomial. See the getCrc() method above for a list of generator polynomials.

Returns:

If bits is a 1D numpy array, the new bitstream with CRC appended to the end is returned in a 1D numpy array. If bits is an N x L numpy array, the CRC bits for each one of N bitstreams are appended to the end and an N x M numpy array is returned where M=L+C and C is the CRC length.

Return type:

numpy array


LDPC

The module ldpc.py contains the API used for Low-Density Parity Check (LDPC) encoding and decoding. It implements the class LdpcBase which is the base class for LDPC coding and is derived from the ChanCodeBase class. It also implements the classes LdpcEncoder and LdpcDecoder both of which are derived from LdpcBase.

This implementation is based on 3GPP TS 38.212.

class neoradium.ldpc.LdpcBase(baseGraphNo=1, modulation='QPSK', rv=0, txLayers=1, nRef=0)

This is the base class for LDPC coding. Both LdpcEncoder and LdpcDecoder classes are derived from this class.

Parameters:
  • baseGraphNo (int (default: 1)) – The base graph used by the LDPC encoder/decoder. It can be either 1 or 2. The choice of base graph determines the maximum code-block size (8448 bits for base graph 1 and 3840 bits for base graph 2). The base graphs are defined as \(H_{BG}\) in 3GPP 3GPP TS 38.212, Tables 5.3.2-2 and 5.3.2-3.

  • modulation (str (default: 'QPSK')) –

    The modulation scheme use by the physical channel based on table 7.3.1.2-1 in 3GPP TR 38.211. Here is a list of supported Modulation Schemes:

    Modulation Scheme

    Modulation Order (qm)

    BPSK

    1

    QPSK

    2

    16QAM

    4

    64QAM

    6

    256QAM

    8

    1024QAM

    10

  • rv (int (default: 0)) –

    The Redundancy Version used for rate matching. It must be one of 0, 1, 2, or 3. Please refer to 3GPP TS 38.212, Table 5.4.2.1-2 for more details.

    Note

    NeoRadium currently does not support non-zero values of Redundancy Version which are designed to work with Hybrid Automatic Repeat Request (HARQ). So, in this version, this value should be set to zero (default) which corresponds to the first transmission.

txLayers: int (default: 1)

The number of transmission layers in the physical channel that is using this LDPC encoder/decoder.

nRef: int (default: 0)

The is used for Low-Buffer Rate Matching (LBRM). Please refer to 3GPP TS 38.212, Section 5.4.2.1 for more details.

Other Properties:

baseGraph:

The base graph matrix defined as as \(H_{BG}\) in 3GPP 3GPP TS 38.212, Tables 5.3.2-2 and 5.3.2-3.

maxCodeBlockSize:

The maximum code-block size. It is set to 8448 for baseGraphNo=1, and 3840 for baseGraphNo=2. This is \(K_{cb}\) in 3GPP TS 38.212, Section 5.2.2.

txBlockSize:

Transport block size. The length of the transport block in bits. The function getTxBlockSize() could be used to obtain the size of transport block. Note that a transport block is first appended with a 24-bit CRC. The value txBlockSize includes the 24-bit CRC. This is \(B\) in 3GPP TS 38.212, Section 5.2.2.

numCodeBlocks:

The number of code-blocks. This is positive integer determined based on maxCodeBlockSize and txBlockSize. This is \(C\) in 3GPP TS 38.212, Section 5.2.2.

codeBlockSize:

The code-block size. This is \(K\) in 3GPP TS 38.212, Section 5.2.2.

liftingSize:

The lifting size which is used to create a parity-check matrix from the base graph. This value is extracted from 3GPP TS 38.212, Table 5.3.2-1. This is \(Z_c\) in 3GPP TS 38.212, Section 5.2.2.

setIndex:

The Set index (\(i_{LS}\)) in 3GPP TS 38.212, Table 5.3.2-1.

Note

All of these properties are initialized only after a call to doSegmentation() or getRateMatchedCodeWords() methods of LdpcEncoder class or the recoverRate() method of LdpcDecoder class.

isValidCodeword(codeWord)

Checks to see if the given codeWord is a valid LDPC coded bitstream.

Parameters:

codeWord (numpy array) – A numpy array of bits representing the code-word. The length of codeWord must be a multiple of the property liftingSize (\(Z_c\)).

Returns:

True is returned if this is a valid LDPC code-word. Otherwise this function returns False.

Return type:

boolean

class neoradium.ldpc.LdpcEncoder(baseGraphNo=1, modulation='QPSK', rv=0, txLayers=1, nRef=0, targetRate=0.4384765625)

This is the Low-Density Parity Check (LDPC) encoder class. It is derived from the LdpcBase class and performs the following tasks:

  • Code block segmentation based on 3GPP TS 38.212, Section 5.2.2

  • LDPC encoding based on 3GPP TS 38.212, Section 5.3.2

  • Rate Matching with bit selection and Interleaving based on 3GPP TS 38.212, Section 5.4.2

Parameters:
  • baseGraphNo (int (default: 1)) – The base graph used by this LDPC encoder. It can be either 1 or 2. In NR, base graph 1 is designed for code rates from 1/3 to 22/24 (approximately 0.33-0.92) and base graph 2 from 1/5 to 5/6 (approximately 0.2-0.83). The choice between base graph 1 or 2 is based on the transport block size and the targeted code-rate (targetRate). The choice of base graph then determines the maximum code-block size (8448 bits for base graph 1 and 3840 bits for base graph 2). The base graphs are defined as \(H_{BG}\) in 3GPP 3GPP TS 38.212, Tables 5.3.2-2 and 5.3.2-3.

  • modulation (str (default: 'QPSK')) –

    The modulation scheme use by the physical channel based on table 7.3.1.2-1 in 3GPP TR 38.211. Here is a list of supported Modulation Schemes:

    Modulation Scheme

    Modulation Order (qm)

    BPSK

    1

    QPSK

    2

    16QAM

    4

    64QAM

    6

    256QAM

    8

    1024QAM

    10

  • rv (int (default: 0)) –

    The Redundancy Version used for rate matching. It must be one of 0, 1, 2, or 3. Please refer to 3GPP TS 38.212, Table 5.4.2.1-2 for more details.

    Note

    NeoRadium currently does not support non-zero values of Redundancy Version which are designed to work with Hybrid Automatic Repeat Request (HARQ). So, in this version, this value should be set to zero (default) which corresponds to the first transmission.

  • txLayers (int (default: 1)) – The number of transmission layers in the physical channel that is using this LDPC encoder.

  • nRef (int (default: 0)) – The is used for Low-Buffer Rate Matching (LBRM). Please refer to 3GPP TS 38.212, Section 5.4.2.1 for more details.

  • targetRate (float (default: 449/1024)) – The desired code rate which is the ratio of the data bits to the total number of bits transmitted (including the LDPC redundancy bits).

Please refer to LdpcBase class for a list of properties inherited from the base class.

print(indent=0, title=None, getStr=False)

Prints the properties of this LdpcEncoder object.

Parameters:
  • indent (int (default: 0)) – The number of indentation characters.

  • title (str or None (default: None)) – If specified, it is used as a title for the printed information.

  • getStr (Boolean (default: False)) – If True, it returns the information in a text string instead of printing the information.

Returns:

If the getStr parameter is True, then this function returns the information in a text string. Otherwise, nothing is returned.

Return type:

None or str

doSegmentation(txBlock, fillerBit=0)

The first step in LDPC encoding process is breaking down the transport block into smaller more manageable code-blocks. This function receives a transport block txBlock, performs segmentation based on 3GPP TS 38.212, Section 5.2.2, and outputs a 2D C x K numpy array containing C code-blocks of length K.

../../_images/TxpBlock.jpg

Transport Block Segmentation [1]

Parameters:
  • txBlock (numpy array) – A numpy array of bits containing the transport block information.

  • fillerBit (int (default: 0)) – An integer value equal to 0 or -1. The filler bits in the returned code-blocks are filled with this value.

Returns:

A 2D C x K numpy array containing C code-blocks of length K.

Return type:

numpy array

setFillerBits(data, fillerBit=0)

Sets the filler bits in the given bitstream data.

Parameters:
  • data (numpy array) – A numpy array representing the bitstream whose filler bits is updated.

  • fillerBit (int (default: 0)) – An integer value equal to 0 or -1. The filler bits in the bitstream specified by data are updated with this value.

Returns:

A numpy array which is the updated version of the data bitstream.

Return type:

numpy array

encode(codeBlocks, zeroFillerBits=False, puncture=True)

This function encodes a set of code-blocks and returns a set of LDPC-coded code-words based on the procedure explained in 3GPP TS 38.212, Section 5.3.2.

Parameters:
  • codeBlocks (numpy array) – A C x K numpy array containing C code-blocks of length K being LDPC-encoded by this function.

  • zeroFillerBits (Boolean (default: False)) – By default, the filler bits in the returned code-words are set to -1. If zeroFillerBits=True, the filler bits are set to zeros.

  • puncture (Boolean (default: True)) – By default, the first \(2Z_c\) bits of the code-words are punctured (removed). If puncture=False, then the first \(2Z_c\) bits are kept in the returned code-words.

Returns:

A C x N numpy array containing the C encoded code-words.

Return type:

numpy array

rateMatch(codeWords, g=None, concatCBs=True)

This function receives a set of encoded code-words and returns the rate-matched output based on the configured code-rate. It performs bit selection and interleaving based on 3GPP TS 38.212, Section 5.4.2

Parameters:
  • codeWords (numpy array) – A C x N numpy array containing C encoded code-words of length N being rate-matched by this function.

  • g (int or None (default: None)) – This is the total number of bits available for transmission of the transport block. It is the value \(G\) in the bit selection process explained in 3GPP TS 38.212, Section 5.4.2.1. If not provided (default), it is calculated as \(G=\lceil \frac {B-24} R \rceil\) where \(B\) is the transport block size and \(R\) is the code-rate.

  • concatCBs (Boolean (default: True)) – If True (Default), the rate-matched coded-blocks are concatenated and a single array of bits is returned. Otherwise, a list of numpy arrays is returned and each element in the list is the bit array corresponding to each coded-block.

Returns:

If concatCBs is True, a 1-D numpy array is returned containing the concatenation of all rate-matched coded-blocks. Otherwise, a list of numpy arrays is returned and each element in the list is the bit array corresponding to each coded-block.

Return type:

numpy array or list of numpy arrays

getRateMatchedCodeWords(txBlock, g=None, concatCBs=True, addCrc=True)

This function receives a transport block (txBlock) and returns the rate-matched output in a single call. It first appends a 24-bit CRC to the transport block and then uses the functions doSegmentation(), encode(), and rateMatch(), to perform segmentation, encoding, and rate matching.

Parameters:
  • txBlock (numpy array) – A numpy array of bits containing the transport block information.

  • g (int or None (default: None)) – This is the total number of bits available for transmission of the transport block. It is the value \(G\) in the bit selection process explained in 3GPP TS 38.212, Section 5.4.2.1. If not provided (default), it is calculated as \(G=\lceil \frac {B-24} R \rceil\) where \(B\) is the transport block size and \(R\) is the code-rate.

  • concatCBs (Boolean (default: True)) – If True (Default), the rate-matched coded-blocks are concatenated and a single array of bits is returned. Otherwise, a list of numpy arrays is returned and each element in the list is the bit array corresponding to each coded-block.

  • addCrc (Boolean (default: True)) – If True a 24-bit CRC is appended to the txBlock before the encoding process. Otherwise, it is assumed that the txBlock already includes the 24-bit CRC and therefore a CRC is not appended.

Returns:

If concatCBs is True, a 1-D numpy array is returned containing the concatenation of all rate-matched coded-blocks. Otherwise, a list of numpy arrays is returned and each element in the list is the bit array corresponding to each coded-block.

Return type:

numpy array or list of numpy arrays

getDecoder()

This function creates and returns an LdpcDecoder object based on the configuration of this LdpcEncoder. It makes it easier to create a decoder object based on the existing encoder object.

Returns:

An LDPC decoder object created based on this LdpcEncoder.

Return type:

LdpcDecoder

class neoradium.ldpc.LdpcDecoder(baseGraphNo=1, modulation='QPSK', rv=0, txLayers=1, nRef=0)

This is the Low-Density Parity Check (LDPC) decoder class. It is derived from the LdpcBase class and performs rate recovery, LDPC decoding, and code-block-merging. These are basically the opposite of the encoding tasks rate matching, LDCP encoding, and segmentation which are performed in reverse order.

The following example shows a typical use case for decoding the received LDPC-coded information into transport blocks:

An example of LDPC decoding
# Rate recovery
# Let's assume we have:
#   An LdpcDecoder object (ldpcDecoder)
#   The LLRs extracted from a received resource grid (llrs)
#   The transport block size (txBlockSize)
rxCodedBlocks = ldpcDecoder.recoverRate(llrs, txBlockSize)

# LDPC-Decoding
decodedBlocks = ldpcDecoder.decode(rxCodedBlocks)

# CRC-checking and de-segmentation
decodedTxBlockWithCRC, crcMatch = ldpcDecoder.checkCrcAndMerge(decodedBlocks)

# Checking the CRC of the transport block
txBlockCrcMatch = ldpcDecoder.checkCrc(decodedTxBlockWithCRC,'24A')

# Removing the transport block CRC
decodedTxBlock = decodedTxBlockWithCRC[:-24]
Parameters:
  • baseGraphNo (int (default: 1)) – The base graph used by this LDPC decoder. It can be either 1 or 2. In NR, base graph 1 is designed for code rates from 1/3 to 22/24 (approximately 0.33-0.92) and base graph 2 from 1/5 to 5/6 (approximately 0.2-0.83). The choice between base graph 1 or 2 is based on the transport block size and the targeted code-rate (targetRate). The choice of base graph then determines the maximum code-block size (8448 bits for base graph 1 and 3840 bits for base graph 2). The base graphs are defined as \(H_{BG}\) in 3GPP 3GPP TS 38.212, Tables 5.3.2-2 and 5.3.2-3.

  • modulation (str (default: 'QPSK')) –

    The modulation scheme use by the physical channel based on table 7.3.1.2-1 in 3GPP TR 38.211. Here is a list of supported Modulation Schemes:

    Modulation Scheme

    Modulation Order (qm)

    BPSK

    1

    QPSK

    2

    16QAM

    4

    64QAM

    6

    256QAM

    8

    1024QAM

    10

  • rv (int (default: 0)) –

    The Redundancy Version used for rate matching. It must be one of 0, 1, 2, or 3. Please refer to 3GPP TS 38.212, Table 5.4.2.1-2 for more details.

    Note

    NeoRadium currently does not support non-zero values of Redundancy Version which are designed to work with Hybrid Automatic Repeat Request (HARQ). So, in this version, this value should be set to zero (default) which corresponds to the first transmission.

  • txLayers (int (default: 1)) – The number of transmission layers in the physical channel that is using this LDPC decoder.

  • nRef (int (default: 0)) – The is used for Low-Buffer Rate Matching (LBRM). Please refer to 3GPP TS 38.212, Section 5.4.2.1 for more details.

Note

For a pair of LdpcEncoder/LdpcDecoder objects to work properly, all of the above parameters used to configure them should match.

Please refer to LdpcBase class for a list of properties inherited from the base class.

print(indent=0, title=None, getStr=False)

Prints the properties of this LdpcDecoder object.

Parameters:
  • indent (int (default: 0)) – The number of indentation characters.

  • title (str or None (default: None)) – If specified, it is used as a title for the printed information.

  • getStr (Boolean (default: False)) – If True, it returns the information in a text string instead of printing the information.

Returns:

If the getStr parameter is True, then this function returns the information in a text string. Otherwise, nothing is returned.

Return type:

None or str

recoverRate(rxBlock, txBlockSize)

This function receives an array of Log-Likelihood Ratios (LLRs) in rxBlock, and the transport block size txBlockSize, and returns a set of rate-recovered LLRs for each code-word which are ready for LDPC decoding. This function does the exact opposite of the LdpcEncoder’s rateMatch() method. Note that while the rateMatch() works with bits, this method works on LLRs.

The LLRs are usually obtained by performing demodulation process. The method getLLRsFromGrid() of the PDSCH for example can be used to get LLRs form a received resource grid.

Parameters:
  • rxBlock (numpy array) – A numpy array of Log-Likelihood Ratios (LLRs) obtained as a result of demodulation process. Each element is a real LLR value corresponding to a each received bit. The larger the LLR value, the more likely it is for that bit to be a 0.

  • txBlockSize (int) – The transport block size. This is the number of bits in a transport block (Not including the 24-bit CRC that is appended to the transport block). For example, in the case of PDSCH communication, this value can be obtained using the method getTxBlockSize() of the PDSCH class.

Returns:

A C x N numpy array of C received coded blocks of length N containing the LLR values for each coded block ready to be LDPC-decoded.

Return type:

numpy array

decode(rxCodeBlock, numIter=5, onlyInfoBits=True, outputBelief=False)

This function implements the Layered Belief Propagation algorithm for LDPC-decoding of LLRs into decoded code-blocks. This implementation was inspired mostly by LDPC and Polar Codes in 5G Standard set of videos and was written from scratch to efficiently perform the decoding process.

Parameters:
  • rxCodeBlock (numpy array) – A C x N numpy array of C received coded blocks of length N containing the LLR values for each coded block.

  • numIter (int (default: 5)) – The number of iterations in the Layered Belief Propagation decoding algorithm. Larger values in some cases could result in more accurate decoding while making the whole decoding process slower.

  • onlyInfoBits (Boolean (default: True)) – If True (default), only the information bits are returned. Otherwise, the parity bits are also included in the returned values together with the information bits.

  • outputBelief (Boolean (default: False)) – If True, the calculated final belief values are returned for each bit which is the LLR for the decoded bits. Otherwise (default), hard decision is applied to the final belief values and the decoded bits are returned.

Returns:

If onlyInfoBits is set to True, a C x K numpy array of C code blocks of length K is returned, where K is the codeBlockSize. Otherwise, the parity bit information is also included in the returned numpy array which makes each code-block longer than K. The contents of the return numpy array can be bits or belief values based on the outputBelief parameter.

Return type:

numpy array

checkCrcAndMerge(rxDecodedWords)

This function performs CRC checking on the each code-block, re-assembles the transport block by combining the code-blocks, and returns the transport block together with the results of CRC checks for each code-block.

Note that the returned value of this function includes the 24 bits of transport block CRC. The transport block CRC can be checked using the checkCrc() method.

Parameters:

rxDecodedWords (numpy array) – A C x K numpy array of C code-blocks of length K. Each code-block contains a CRC as its last 24 bits. The rxDecodedWords is usually the returned value of the decode() method explained above.

Returns:

  • txBlock (numpy array of bits) – The numpy array containing the transport block together with its 24-bit CRC at the end which can be verified using the checkCrc() method.

  • crcCheckResults (numpy array of booleans) – The boolean numpy array containing the CRC check results for each code block. To have a valid transport block, all of the values in this numpy array must be True,


Polar Coding

The module polar.py contains the API used for Polar coding. It implements the class PolarBase which is the base class for other Polar Coding classes and is derived from the ChanCodeBase class. It also implements the classes PolarEncoder and PolarDecoder both of which are derived from PolarBase.

This implementation is based on 3GPP TS 38.212.

class neoradium.polar.PolarBase(payloadSize=0, rateMatchedLen=0, dataType=None, **kwargs)

This is the base class for all Polar Coding classes. Both PolarEncoder and PolarDecoder classes are derived from this class. In 5G NR, Polar Coding is used for the following cases:

  • Downlink Control Information (DCI)

  • Uplink Control Information (UCI)

  • Physical Broadcast Channel (PBCH)

Parameters:
  • payloadSize (int (default: 0)) – The size of input bitstream not including the CRC bits. This is the value \(A\) in 3GPP TS 38.212, Section 5.2.1.

  • rateMatchedLen (int (default: 0)) – The total length of rate-matched output bitstream. This is the value \(E\) in 3GPP TS 38.212, Sections 5.3.1 and 5.4.1.

  • dataType (str or None (default: None)) –

    The type of data using this Polar encoder/decoder. It can be one of the following:

    ”DCI”:

    Downlink Control Information

    ”UCI”:

    Uplink Control Information

    ”PBCH”:

    Physical broadcast channel

    None:

    Customized Polar Coding.

  • kwargs (dict) –

    A set of optional arguments depending on the dataType:

    iBIL:

    Coded bits Interleaving flag. This is a boolean value that indicates whether coded bits interleaving is enabled (True) or disabled (False). By default iBIL=False. This is the value \(I_{BIL}\) in 3GPP TS 38.212, Section 5.4.1.3. This parameter is ignored if the dataType is not None. In this case, iBIL is set to True for dataType="UCI", and False for dataType="DCI" and dataType="PBCH" cases.

    nMax:

    Max value of \(n\) where \(N=2^n\) is the length of the polar code. By default this is set to 10 (which means \(N=10241\). This is the value \(N_{max}\) in 3GPP TS 38.212, Section 5.3.1.2. This parameter is ignored if the dataType is not None. In this case, nMax=10 when dataType="UCI", and nMax=9 for dataType="DCI" and dataType="PBCH" cases.

    iIL:

    Input Interleaving flag. This is a boolean value that indicates whether input interleaving is enabled (True) or disabled (False). By default iIL=False. This is the value \(I_{IL}\) in 3GPP TS 38.212, Section 5.3.1.1. This parameter is ignored if the dataType is not None. In this case, iIL is set to False for dataType="UCI", and True for dataType="DCI" and dataType="PBCH" cases.

    nPC:

    Total number of Parity Check bits. By default this is set to 0. This is the value \(N_{PC}\) in 3GPP TS 38.212, Section 5.3.1. This parameter is ignored if the dataType is not None. In this case, nPC=0 when dataType is set to "DCI" or "PBCH". For the "UCI" case, this value may be set to 0 or 3 which is determined based on the procedure explained in 3GPP TS 38.212, Section 5.3.1.2.

    nPCwm:

    The number of Low-weight, High-Reliability Parity Check bits out of the total parity check bits nPC. By default this is set to 0. This is the value \(n_{PC}^{wm}\) in 3GPP TS 38.212, Sections 5.3.1.2, 6.3.1.3.1, and 6.3.2.3.1. This parameter is ignored if the dataType is not None. In this case, nPCwm=0 when dataType is set to "DCI" or "PBCH". For the "UCI" case, this value may be set to 0 or 1 which is determined based on the procedures explained in 3GPP TS 38.212, Sections 6.3.1.3.1 and 6.3.2.3.1.

    iSeg:

    Segmentation flag. This is a boolean value that indicates whether segmentation is enabled (True) or disabled (False). By default iSeg=False. This is the value \(I_{seg}\) in 3GPP TS 38.212, Section 5.2.1. This parameter is ignored if the dataType is not None. In this case, iSeg=False when dataType="DCI" or dataType="PBCH". When dataType="UCI", iSeg is set based on the value of payloadSize.

    crcPoly:

    The CRC polynomial. This is a string specifying the CRC polynomial or None. If specified, it must be one of the values specified in getCrc() for the poly parameter. The default value is "11". This parameter is ignored if the dataType is not None. In this case crcPoly is set to "6" or "11" depending on payloadSize for dataType="UCI", and "24C" for dataType="DCI" and dataType="PBCH" cases.

Other Properties:

rateMatchedBlockLen:

The number of rate-matched bits transmitted for each code block when segmented. This is the same as rateMatchedLen if segmentation is disabled. This is the value \(E_r\) in 3GPP TS 38.212, Section 5.5.

codeBlockSize:

The code-block size. This is the value \(K\) in 3GPP TS 38.212, Section 5.3.1 which includes the CRC bits (if any).

polarCodeSize:

The polar code size \(N\). This is always a power of 2.

msgBits:

A list of indexes of the message bits in the coded bitstream.

frozenBits:

A list of indexes of the frozen bits in the coded bitstream.

pcBits:

A list of indexes of the parity check bits in the coded bitstream. This can be empty depending on nPC.

generator:

The polar coding generator matrix as a 2-D numpy array.

setIoSizes(payloadSize, rateMatchedLen)

This function can be called to re-initialize the class properties. When the payloadSize or rateMatchedLen parameter change but other properties remain the same, you can create a new polar encoder/decoder object or you can reuse the existing objects and re-initialize them using this method.

Note that if there is no change in the values of payloadSize and rateMatchedLen, this function returns without doing anything.

Parameters:
  • payloadSize (int) – The new size of input bitstream not including the CRC bits. This is the value \(A\) in 3GPP TS 38.212, Section 5.2.1.

  • rateMatchedLen (int (default: 0)) – The new total length of rate-matched output bitstream. This is the value \(E\) in 3GPP TS 38.212, Sections 5.3.1 and 5.4.1.

class neoradium.polar.PolarEncoder(payloadSize=0, rateMatchedLen=0, dataType=None, **kwargs)

This class is used to encode a bitstream using Polar coding. It is derived from the PolarBase class and performs the following tasks:

  • Segmentation of the transport block based on 3GPP TS 38.212, Section 5.2.1

  • Polar encoding based on 3GPP TS 38.212, Section 5.3.1

  • Rate Matching with Sub-block Interleaving, Bit Selection, and Interleaving of Coded bits based on 3GPP TS 38.212, Section 5.4.1

Parameters:
  • payloadSize (int (default: 0)) – The size of input bitstream not including the CRC bits. This is the value \(A\) in 3GPP TS 38.212, Section 5.2.1.

  • rateMatchedLen (int (default: 0)) – The total length of rate-matched output bitstream. This is the value \(E\) in 3GPP TS 38.212, Sections 5.3.1 and 5.4.1.

  • dataType (str or None (default: None)) –

    The type of data using this Polar encoder/decoder. It can be one of the following:

    ”DCI”:

    Downlink Control Information

    ”UCI”:

    Uplink Control Information

    ”PBCH”:

    Physical broadcast channel

    None:

    Customized Polar Coding.

  • kwargs (dict) –

    A set of optional arguments depending on the dataType:

    iBIL:

    Coded bits Interleaving flag. This is a boolean value that indicates whether coded bits interleaving is enabled (True) or disabled (False). By default iBIL=False. This is the value \(I_{BIL}\) in 3GPP TS 38.212, Section 5.4.1.3. This parameter is ignored if the dataType is not None. In this case, iBIL is set to True for dataType="UCI", and False for dataType="DCI" and dataType="PBCH" cases.

    nMax:

    Max value of \(n\) where \(N=2^n\) is the length of the polar code. By default this is set to 10 (which means \(N=10241\). This is the value \(N_{max}\) in 3GPP TS 38.212, Section 5.3.1.2. This parameter is ignored if the dataType is not None. In this case, nMax=10 when dataType="UCI", and nMax=9 for dataType="DCI" and dataType="PBCH" cases.

    iIL:

    Input Interleaving flag. This is a boolean value that indicates whether input interleaving is enabled (True) or disabled (False). By default iIL=False. This is the value \(I_{IL}\) in 3GPP TS 38.212, Section 5.3.1.1. This parameter is ignored if the dataType is not None. In this case, iIL is set to False for dataType="UCI", and True for dataType="DCI" and dataType="PBCH" cases.

    nPC:

    Total number of Parity Check bits. By default this is set to 0. This is the value \(N_{PC}\) in 3GPP TS 38.212, Section 5.3.1. This parameter is ignored if the dataType is not None. In this case, nPC=0 when dataType is set to "DCI" or "PBCH". For the "UCI" case, this value may be set to 0 or 3 which is determined based on the procedure explained in 3GPP TS 38.212, Section 5.3.1.2.

    nPCwm:

    The number of Low-weight, High-Reliability Parity Check bits out of the total parity check bits nPC. By default this is set to 0. This is the value \(n_{PC}^{wm}\) in 3GPP TS 38.212, Sections 5.3.1.2, 6.3.1.3.1, and 6.3.2.3.1. This parameter is ignored if the dataType is not None. In this case, nPCwm=0 when dataType is set to "DCI" or "PBCH". For the "UCI" case, this value may be set to 0 or 1 which is determined based on the procedures explained in 3GPP TS 38.212, Sections 6.3.1.3.1 and 6.3.2.3.1.

    iSeg:

    Segmentation flag. This is a boolean value that indicates whether segmentation is enabled (True) or disabled (False). By default iSeg=False. This is the value \(I_{seg}\) in 3GPP TS 38.212, Section 5.2.1. This parameter is ignored if the dataType is not None. In this case, iSeg=False when dataType="DCI" or dataType="PBCH". When dataType="UCI", iSeg is set based on the value of payloadSize.

    crcPoly:

    The CRC polynomial. This is a string specifying the CRC polynomial or None. If specified, it must be one of the values specified in getCrc() for the poly parameter. The default value is "11". This parameter is ignored if the dataType is not None. In this case crcPoly is set to "6" or "11" depending on payloadSize for dataType="UCI", and "24C" for dataType="DCI" and dataType="PBCH" cases.

Other Properties:

rateMatchedBlockLen:

The number of rate-matched bits transmitted for each code block when segmented. This is the same as rateMatchedLen if segmentation is disabled. This is the value \(E_r\) in 3GPP TS 38.212, Section 5.5.

codeBlockSize:

The code-block size. This is the value \(K\) in 3GPP TS 38.212, Section 5.3.1 which includes the CRC bits (if any).

polarCodeSize:

The polar code size \(N\). This is always a power of 2.

msgBits:

A list of indexes of the message bits in the coded bitstream.

frozenBits:

A list of indexes of the frozen bits in the coded bitstream.

pcBits:

A list of indexes of the parity check bits in the coded bitstream. This can be empty depending on nPC.

generator:

The polar coding generator matrix as a 2-D numpy array.

print(indent=0, title=None, getStr=False)

Prints the properties of this PolarEncoder object.

Parameters:
  • indent (int (default: 0)) – The number of indentation characters.

  • title (str or None (default: None)) – If specified, it is used as a title for the printed information.

  • getStr (Boolean (default: False)) – If True, it returns the information in a text string instead of printing the information.

Returns:

If the getStr parameter is True, then this function returns the information in a text string. Otherwise, nothing is returned.

Return type:

None or str

doSegmentation(txBlock)

If segmentation is enabled, the first step in Polar encoding process is breaking down the transport block into smaller code-blocks. This function receives a transport block txBlock, performs segmentation depending on the value of iSeg property based on 3GPP TS 38.212, Section 5.2.1, and outputs a 2D C x K numpy array containing C code-blocks of length K. Note that C can only be 1 or 2 and if iSeg=False, then C=1.

Parameters:

txBlock (numpy array) – A numpy array of bits containing the transport block information.

Returns:

A 2D C x K numpy array containing C code-blocks of length K.

Return type:

numpy array

encode(codeBlocks)

This function encodes a set of code-blocks and returns a set of Polar-coded code-words based on the procedure explained in 3GPP TS 38.212, Section 5.3.1.

Parameters:

codeBlocks (numpy array) – A C x K numpy array containing C code-blocks of length K being Polar-encoded by this function.

Returns:

A C x N numpy array containing the C encoded code-words.

Return type:

numpy array

rateMatch(codewords)

This function receives a set of encoded code-words and returns the rate-matched code-words. It first performs Sub-block interleaving based on 3GPP TS 38.212, Section 5.4.1.1, then bit selection is done based on 3GPP TS 38.212, Section 5.4.1.2. Finally, if Coded bits Interleaving is enabled (iBIL=True), this function applies the procedure in 3GPP TS 38.212, Section 5.4.1.3 for Coded bits Interleaving.

Parameters:

codeWords (numpy array) – A C x N numpy array containing C encoded code-words of length N being rate-matched by this function.

Returns:

A C x E numpy array containing the C rate-matched code-words of length E where E=rateMatchedBlockLen.

Return type:

numpy array

class neoradium.polar.PolarDecoder(payloadSize=0, rateMatchedLen=0, dataType=None, **kwargs)

This class is used to decode a set of Log-Likelihood-Ratios (LLRs) to a transport block using the Successive Cancelation List (SCL) [2] algorithm. It is derived from the PolarBase class and performs rate recovery and Polar decoding which are basically the opposite of the encoding tasks performed in reverse order.

The following example shows a typical use case for decoding the received Polar-coded information into transport blocks:

An example of Polar decoding
payloadLen = 30             # A
rateMatchedLen = 120        # E

# Creating a polar decoder object for "DCI" data
polarDecoder = PolarDecoder(payloadLen, rateMatchedLen, 'dci', sclListSize=8, useMinsum=True)

# Rate recovery (Assuming "llrs" contains the LLR values from demodulation process)
rateRecoveredRxBlocks = polarDecoder.recoverRate(llrs)

# Polar Decoding using SCL algorithm
decTxBlock, numCrcErrors = polarDecoder.decode(rateRecoveredRxBlocks)
Parameters:
  • payloadSize (int (default: 0)) – The size of input bitstream not including the CRC bits. This is the value \(A\) in 3GPP TS 38.212, Section 5.2.1.

  • rateMatchedLen (int (default: 0)) – The total length of rate-matched output bitstream. This is the value \(E\) in 3GPP TS 38.212, Sections 5.3.1 and 5.4.1.

  • dataType (str or None (default: None)) –

    The type of data using this Polar decoder. It can be one of the following:

    ”DCI”:

    Downlink Control Information

    ”UCI”:

    Uplink Control Information

    ”PBCH”:

    Physical broadcast channel

    None:

    Customized Polar Coding.

  • kwargs (dict) –

    A set of optional arguments depending on the dataType:

    iBIL:

    Coded bits Interleaving flag. This is a boolean value that indicates whether coded bits interleaving is enabled (True) or disabled (False). By default iBIL=False. This is the value \(I_{BIL}\) in 3GPP TS 38.212, Section 5.4.1.3. This parameter is ignored if the dataType is not None. In this case, iBIL is set to True for dataType="UCI", and False for dataType="DCI" and dataType="PBCH" cases.

    nMax:

    Max value of \(n\) where \(N=2^n\) is the length of the polar code. By default this is set to 10 (which means \(N=10241\). This is the value \(N_{max}\) in 3GPP TS 38.212, Section 5.3.1.2. This parameter is ignored if the dataType is not None. In this case, nMax=10 when dataType="UCI", and nMax=9 for dataType="DCI" and dataType="PBCH" cases.

    iIL:

    Input Interleaving flag. This is a boolean value that indicates whether input interleaving is enabled (True) or disabled (False). By default iIL=False. This is the value \(I_{IL}\) in 3GPP TS 38.212, Section 5.3.1.1. This parameter is ignored if the dataType is not None. In this case, iIL is set to False for dataType="UCI", and True for dataType="DCI" and dataType="PBCH" cases.

    nPC:

    Total number of Parity Check bits. By default this is set to 0. This is the value \(N_{PC}\) in 3GPP TS 38.212, Section 5.3.1. This parameter is ignored if the dataType is not None. In this case, nPC=0 when dataType is set to "DCI" or "PBCH". For the "UCI" case, this value may be set to 0 or 3 which is determined based on the procedure explained in 3GPP TS 38.212, Section 5.3.1.2.

    nPCwm:

    The number of Low-weight, High-Reliability Parity Check bits out of the total parity check bits nPC. By default this is set to 0. This is the value \(n_{PC}^{wm}\) in 3GPP TS 38.212, Sections 5.3.1.2, 6.3.1.3.1, and 6.3.2.3.1. This parameter is ignored if the dataType is not None. In this case, nPCwm=0 when dataType is set to "DCI" or "PBCH". For the "UCI" case, this value may be set to 0 or 1 which is determined based on the procedures explained in 3GPP TS 38.212, Sections 6.3.1.3.1 and 6.3.2.3.1.

    iSeg:

    Segmentation flag. This is a boolean value that indicates whether segmentation is enabled (True) or disabled (False). By default iSeg=False. This is the value \(I_{seg}\) in 3GPP TS 38.212, Section 5.2.1. This parameter is ignored if the dataType is not None. In this case, iSeg=False when dataType="DCI" or dataType="PBCH". When dataType="UCI", iSeg is set based on the value of payloadSize.

    crcPoly:

    The CRC polynomial. This is a string specifying the CRC polynomial or None. If specified, it must be one of the values specified in getCrc() for the poly parameter. The default value is "11". This parameter is ignored if the dataType is not None. In this case crcPoly is set to "6" or "11" depending on payloadSize for dataType="UCI", and "24C" for dataType="DCI" and dataType="PBCH" cases.

    sclListSize:

    The list size of the Successive Cancelation List (SCL) algorithm used for decoding. The default is 8.

    useMinsum:

    A Boolean value indicating whether the Min-Sum approximation should be used in the SCL algorithm. True (default) means the “Min-Sum” approximation is used resulting in faster decoding with slightly less precise results. False means the actual extrinsic likelihood function based on hyperbolic tangent function is used.

Note

For a pair of PolarEncoder/PolarDecoder objects to work properly, the above parameters used to configure them should match.

Please refer to PolarBase class for a list of properties inherited from the base class.

print(indent=0, title=None, getStr=False)

Prints the properties of this PolarDecoder object.

Parameters:
  • indent (int (default: 0)) – The number of indentation characters.

  • title (str or None (default: None)) – If specified, it is used as a title for the printed information.

  • getStr (Boolean (default: False)) – If True, it returns the information in a text string instead of printing the information.

Returns:

If the getStr parameter is True, then this function returns the information in a text string. Otherwise, nothing is returned.

Return type:

None or str

recoverRate(rxBlock)

This function receives an array of Log-Likelihood Ratios (LLRs) in rxBlock and returns a set of rate-recovered LLRs for each code-word which are ready for Polar decoding. This function does the exact opposite of the PolarEncoder’s rateMatch() method. Note that while the rateMatch() works with bits, this method works on LLRs which are usually obtained by performing demodulation process.

Parameters:

rxBlock (numpy array) – A numpy array of Log-Likelihood Ratios (LLRs) obtained as a result of demodulation process. Each element is a real LLR value corresponding to a each received bit. The larger the LLR value, the more likely it is for that bit to be a 0.

Returns:

A C x N numpy array of C received coded blocks of length N containing the LLR values for each coded block ready to be Polar-decoded.

Return type:

numpy array

decode(rxLlrBlocks)

This function implements the Successive Cancelation List (SCL) algorithm for Polar-decoding of LLRs into decoded transport blocks. This implementation was inspired mostly by LDPC and Polar Codes in 5G Standard set of videos and was written from scratch using a recursive algorithm to efficiently perform the SCL decoding process.

Parameters:

rxLlrBlocks (numpy array) – A C x N numpy array of C received coded blocks of length N containing the LLR values for each coded block.

Returns:

  • txBlock (numpy array of bits) – A 1D numpy array of length \(A\) containing the decoded transport block bits where \(A\) is equal to the parameter payloadSize.

  • numCrcErrors (int) – The total number of CRC errors if crcPoly is not None, otherwise zero.


References: