Physical Channels
Physical Downlink Shared Channel
The module pdsch.py implements the PDSCH class which encapsulates the Physical Downlink Shared Channel.
It is a downlink channel that delivers user data from gNB to UE. PDSCH occupies a grid of Resource Blocks (RBs) within
a slot. Usually, one or more OFDM symbols are used by the PDCCH, and the remaining resources are available for the
PDSCH.
The gNB schedules PDSCH resources for UEs based on their channel quality, data requirements, and fairness considerations. PDSCH uses LDPC (Low-Density Parity-Check) coding to provide forward error correction, enhancing the robustness of data transmission over the wireless channel.
In Multiple Input, Multiple Output (MIMO) systems, a PDSCH is distributed among multiple layers. PDSCH includes
Demodulation Reference Signals (DMRS) to assist the UE in channel estimation and
demodulation, ensuring accurate data reception. It may also include Phase Tracking Reference Signals
(PTRS) which enable suppression of phase noise and common phase error, particularly
important at high carrier frequencies such as millimeter-wave bands.
- class neoradium.pdsch.PDSCH(bwp, **kwargs)
This class encapsulates the configuration and functionality of a Physical Downlink Shared Channel (PDSCH) that delivers user data transmitted from gNB to UE.
- Parameters:
bwp (
BandwidthPart) – TheBandwidthPartobject that represents the resources used by thisPDSCHfor transmission of user data from gNB to UE.kwargs (dict) –
A set of optional arguments.
- mappingType:
The mapping type used by this PDSCH and its associated
DMRSobject. It is a string that can be either'A'or'B'. The default is'A'.In mapping type
'A', the first DM-RS OFDM symbol index is 2 or 3 and DM-RS is mapped relative to the start of slot boundary, regardless of where in the slot the actual data transmission starts. The user data in this case usually occupies most of the slot.In mapping type
'B', the first DM-RS OFDM symbol is the first OFDM symbol of the data allocation, that is, the DM-RS location is not given relative to the slot boundary but relative to where the user data is located. The user data in this case usually occupies a small fraction of the slot to support very low latency.- numLayers:
The number of transmission layers for this
PDSCH. It must be an integer from 1 to 8, with 1 as the default.- modulation:
A string, or a tuple or list of two strings specifying the modulation scheme used for data transmitted in this
PDSCHbased on 3GPP TS 38.211, Table 7.3.1.2-1. The default is'16QAM'. Here is a list of supported modulation schemes:Modulation Scheme
Modulation Order (
qm)QPSK
2
16QAM
4
64QAM
6
256QAM
8
1024QAM
10
If
modulationis a string and there are two codewords in thisPDSCH, the same modulation scheme is used for both codewords. If there are two codewords in thisPDSCH, and you want to use different modulation schemes for the two codewords, you can specify two different modulation schemes in a tuple or list of strings. For example:# Using "QPSK" for the first codeword and "16QAM" for the second codeword modulation = ("QPSK", "16QAM")
The specified modulation scheme(s) are used to create one or two
Modemobjects.- csiRsConfig:
A
CsiRsConfigobject that contains CSI-RS configuration information. If specified, it is used to reserve CSI-RS resources in the grid so that they are not assigned to PDSCH, DM-RS, or PT-RS.- reservedPrbSets:
A list of
ReservedPrbSetobjects that are used to reserve the specified resource blocks (RBs) at the specified OFDM symbols based on the patterns defined in theReservedPrbSetobjects. The default is an empty list which means no reserved PRBs.- portSet:
A list of ports used by this
PDSCHand its associatedDMRSobject. If not specified, by default, this is set based on the number of layers specified bynumLayers. For example, for a 2-layer PDSCH, theportSetis set to{0, 1}, which corresponds to DM-RS port numbers{1000, 1001}.- sliv:
Start and Length Indicator Value. If specified, it is used to determine the start and length of consecutive OFDM symbols used by this
PDSCHbased on 3GPP TS 38.214, Section 5.1.2.1. The default is None. See Specifying the OFDM symbols below for more information.- symStart:
The index of the first OFDM symbol used for this
PDSCH. The default is None. See Specifying the OFDM symbols below for more information.- symLen:
The number of consecutive OFDM symbols used by this
PDSCHstarting atsymStart. The default is None. See Specifying the OFDM symbols below for more information.- symSet:
A list of OFDM symbol indices that are used by this
PDSCH. See Specifying the OFDM symbols below for more information.- prbSet:
The list of physical resource blocks (PRBs) used by this
PDSCH. The default is all the RBs in theBandwidthPartobjectbwp.- interleavingBundleSize:
This is for backward compatibility and will be removed in future versions. Set
interleavingBundleSizein theBandwidthPartobject.- rnti:
The Radio Network Temporary Identifier. The default is 1. It is used with
nIDbelow to initialize a Gold sequence used for the scrambling process. See 3GPP TS 38.211, Section 7.3.1.1 for more information.- nID:
The scrambling identity. It is used with
rntito initialize a Gold sequence used for the scrambling process. See 3GPP TS 38.211, Section 7.3.1.1 for more information. If not specified, it is set tobwp.cellId.- prgSize:
The size of Precoding RB Groups (PRGs). It can be one of 0 (default), 2, or 4. The value 0 means Wideband Precoding which means the same precoding is used for the whole bandwidth of this
PDSCH. Subband values (2or4) enable a separate precoder per PRG; use a smallerprgSizewhen the channel is more frequency-selective (e.g., long delay spread, low antenna correlation across frequency), at the cost of higher PMI feedback overhead.prgSize=4is the natural midpoint when subband precoding is needed without the full overhead ofprgSize=2. See 3GPP TS 38.214, Section 5.1.2.3 for more information.
Specifying the OFDM symbols:
You can specify the OFDM symbols used by this
PDSCHin different ways:If
slivis specified, it is used to determine the start and length of consecutive OFDM symbols used by thisPDSCHbased on 3GPP TS 38.214, Section 5.1.2.1. In this case, the parameterssymStart,symLen, andsymSetare ignored.If
slivis not specified and bothsymStartandsymLenare specified, they are used to determine the OFDM symbols used by thisPDSCH. In this case the parametersymSetis ignored.If
sliv,symStart, andsymLenare not specified butsymSetis specified, it is used to determine the OFDM symbols used by thisPDSCH.If neither of
sliv,symStart,symLen, andsymSetare specified, the OFDM symbols are automatically assigned based onmappingTypeandcpTypeparameter of theBandwidthPartobjectbwp.
Other Properties:
- numCW:
The number of codewords derived from the
numLayersparameter. It is either 1 or 2.- modems:
A list of one or two (depending on
numCW)Modemobject(s) used internally for modulation/demodulation of the codewords.- dmrs:
The
DMRSobject associated with thisPDSCH. You can usesetDMRS()method to set theDMRSobject associated with thisPDSCH.- slotNo:
This returns the
slotNoproperty of theCarrierobject containingbwp.- frameNo:
This returns the
frameNoproperty of theCarrierobject containingbwp.- slotNoInFrame:
This returns the
slotNoInFrameproperty of theCarrierobject containingbwp.
The notebook End-to-End PDSCH Communication Simulation shows how to create an end-to-end PDSCH communication pipeline.
- print(indent=0, title='PDSCH Properties:', getStr=False)
Prints the properties of this
PDSCHobject.- Parameters:
indent (int) – The number of indentation characters.
title (str) – If specified, it is used as the title for the printed information.
getStr (bool) – If True, returns a string instead of printing it.
- Returns:
If the
getStrparameter is True, then this function returns the information in a string. Otherwise, nothing is returned.- Return type:
None or str
- setDMRS(**kwargs)
Creates and initializes a
DMRSobject associated with thisPDSCHobject.- Parameters:
kwargs (dict) – A dictionary of parameters passed directly to the constructor of the
DMRSclass. Please refer to this class for a list of parameters that can be used to configure DM-RS.
- setPTRS(**kwargs)
Creates and initializes a
PTRSobject associated with thisPDSCHobject. Please note that you must first use thesetDMRS()function to initialize theDMRSobject before calling this function.- Parameters:
kwargs (dict) – A dictionary of parameters passed directly to the constructor of the
PTRSclass. Please refer to this class for a list of parameters that can be used to configure PT-RS.
- getGrid()
DEPRECATED: This method is deprecated and will be removed in future releases. Please use the
initGrid()method instead.
- initGrid()
Creates a
Gridobject for thisPDSCHand populates it with the configuredDMRSandPTRSreference signals.If a
CsiRsConfigobject was provided when thisPDSCHwas created, it will be used to reserve the CSI-RS resources so that they are not assigned to PDSCH, DM-RS, or PT-RS.This function also marks all resources corresponding to the
reservedPrbSetsparameter as “RESERVED” in the newly created resource grid.The returned resource grid contains all reference signals and is ready to be populated with the user data (See
setPdschData()method).
- getReIndexes(grid, reTypeStr)
DEPRECATED: This method is deprecated and will be removed in future releases. Please use the
getReIndexes()method instead.
- getNumREsFromIndexes(indexes)
Returns the number of resource elements included in
indexesfor each codeword. The returned value is a list of one or two integers depending on the number of codewords (numCW).- Parameters:
indexes (3-tuple) – A tuple of 3 lists specifying locations of a set of resource elements in the resource grid. For example, this can be obtained using the
getReIndexes()function.- Returns:
A list of one or two integers depending on the number of codewords (
numCW), indicating the number of resource elements (REs) included inindexesfor each codeword.- Return type:
list
- getBitCapacity()
Returns the total number of bits corresponding to PDSCH resource elements. The returned value is a list of one or two integers depending on the number of codewords (
numCW).- Returns:
A list of one or two integers depending on the number of codewords (
numCW), indicating the number of PDSCH bits for each codeword.- Return type:
list
Note
This function replaces the deprecated function
getBitSizes(). The following example shows how to migrate existing code to use this method:# Old: grid = pdsch.getGrid() numBits = pdsch.getBitSizes(grid) # New: pdsch.initGrid() numBits = pdsch.getBitCapacity()
- getBitSizes(grid=None, reTypeStr='PDSCH')
DEPRECATED: This function is deprecated and will be removed in future releases. Please use the
getBitCapacity()method instead.
- setPdschData(dataBits)
Populates this PDSCH’s resource grid with the user data provided in
dataBits.This function performs the following operations:
- Scrambling:
Scrambling of the specified
dataBitsusing therntiandnIDproperties of thisPDSCH. These properties are used to initialize a Gold sequence which is then used for the scrambling process according to 3GPP TS 38.211, Section 7.3.1.1. The data bits for each codeword are scrambled separately.- Modulation:
Converting the scrambled binary data stream into complex symbols for each resource element assigned for user data. The modulation process is performed by the
Modemobjects in themodemslist of thisPDSCH. The modulation for each codeword is performed separately by its own dedicatedModemobject.- Layer Mapping:
Distributing the modulated complex symbols across one or more transmission layers of this
PDSCHaccording to 3GPP TS 38.211, Section 7.3.1.3.
- Parameters:
dataBits (list, tuple, or NumPy array) –
Specifies the user data bits that are used to populate the specified resource grid. It can be one of the following:
- tuple of NumPy arrays:
Depending on the number of codewords (
numCW), the tuple can have one or two 1D NumPy arrays of bits each specifying the user data bits for each codeword.- NumPy array:
A one or two dimensional NumPy array. It is a 1D array, only if we have one codeword and the given NumPy array is used for the single codeword. The 2D NumPy array can be used for cases with one or two codewords. The first dimension of the NumPy array in this case should match the number of codewords (
numCW).- list of NumPy arrays:
Depending on the number of codewords (
numCW), the list can have one or two 1D NumPy arrays of bits each specifying the user data bits for each codeword.
Note
This function replaces the deprecated function
populateGrid(). The following example shows how to migrate existing code to use this method:# Old: grid = pdsch.getGrid() # Create a resource grid already populated with DMRS txBlockSize = pdsch.getTxBlockSize(codeRate) # Calculate the Transport Block Size txBlock = random.bits(txBlockSize[0]) # Create random binary data numBits = pdsch.getBitSizes(grid) # Actual number of bits available in the resource grid rateMatchedCodeBlocks = ldpcEncoder.getRateMatchedCodeBlocks(txBlock, numBits[0]) pdsch.populateGrid(grid, rateMatchedCodeBlocks) # New: pdsch.initGrid() # Create and initialize PDSCH's internal grid txBlock = random.bits(ldpc.txBlockSizes[0]) # Create random binary data numBits = pdsch.getBitCapacity() # Actual number of bits available in the resource grid rateMatchedCodeBlocks = ldpc.encode(txBlock, numBits[0]) pdsch.setPdschData(rateMatchedCodeBlocks)
- populateGrid(grid, bits=None)
DEPRECATED: This function is deprecated and will be removed in future releases. Please use the
setPdschData()method instead.
- getLLRs(eqGrid, llrScales=None, noiseVar=None, useMax=True)
This method is used at the receiving side where the log-likelihood ratios (LLRs) are extracted from the equalized resource grid
eqGrid. This is in some sense the opposite of thesetPdschData()method since it does the following:- Deinterleaving:
Converting Physical Resource Blocks (PRBs) to Virtual Resource Blocks (VRBs). If enabled, the resources are re-ordered based on the interleaving configuration given by
interleavingBundleSizeaccording to 3GPP TS 38.214, Section 5.1.4.1 to get the data in its original order.- Layer Demapping:
Extracting the modulated complex symbols for each codeword from different layers of this
PDSCHaccording to 3GPP TS 38.211, Section 7.3.1.3.- Demodulation:
Converting complex symbols to log-likelihood ratios (LLRs) using the
Modemobjects in themodemslist of thisPDSCH. The demodulation for each codeword is performed separately by its own dedicatedModemobject. This produces one or two sets of LLRs for each codeword.- Descrambling:
The descrambling of the demodulated LLRs using the
rntiandnIDproperties of thisPDSCH. These properties are used to initialize a Gold sequence which is then used for the descrambling process according to 3GPP TS 38.211, Section 7.3.1.1. The LLRs for each codeword are descrambled separately.
This function returns a list of one or two NumPy arrays representing the LLRs for each codeword.
- Parameters:
eqGrid (
Grid) – The equalized received resource grid associated with thisPDSCH. Usually this is theGridobject obtained after equalization in the receiver pipeline (See theequalize()function).llrScales (3-D NumPy array or None) –
The log-likelihood ratio (LLR) scaling factors which are used by demodulation process when extracting log-likelihood ratios (LLRs) from the equalized resource grid. The shape of this array must be the same shape as
eqGrid. Typically obtained as the second return value ofequalize():eqGrid, llrScales = pdsch.equalize(rxGrid, channelMatrix) llrs = pdsch.getLLRs(eqGrid, llrScales)
If
None, no per-RE scaling is applied.noiseVar (float or None) – The variance of the Additive White Gaussian Noise (AWGN) present in the received resource grid. If this is not provided (
noiseVar=None), This function uses thenoiseVarproperty of theeqGridobject.useMax (bool) – If True, this implementation uses the
Maxfunction in the calculation of the LLR values. This is faster but uses an approximation and is slightly less accurate than the actual log-likelihood method which uses logarithm and exponential functions. If False, the slower more accurate method is used.
- Returns:
A list of one or two NumPy arrays each representing the LLRs for each codeword.
- Return type:
list
Note
This function replaces the deprecated function
getLLRsFromGrid(). The following example shows how to migrate existing code to use this method:# Old: llrs = pdsch.getLLRsFromGrid(eqGrid, pdschIndexes, llrScales) # New: llrs = pdsch.getLLRs(eqGrid, llrScales)
- getLLRsFromGrid(rxGrid, pdschIndexes=None, llrScales=None, noiseVar=None, useMax=True)
DEPRECATED: This method is deprecated and will be removed in future releases. Please use the
getLLRs()method instead.This method is used at the receiving side where the log-likelihood ratios (LLRs) are extracted from the received resource grid
rxGrid. This is in some sense the opposite of thepopulateGrid()method since it does the following:- Deinterleaving:
Converting Physical Resource Blocks (PRBs) to Virtual Resource Blocks (VRBs). If enabled, the resources are re-ordered based on the interleaving configuration given by
interleavingBundleSizeaccording to 3GPP TS 38.214, Section 5.1.4.1 to get the data in its original order.- Layer Demapping:
Extracting the modulated complex symbols for each codeword from different layers of this
PDSCHaccording to 3GPP TS 38.211, Section 7.3.1.3.- Demodulation:
Converting complex symbols to log-likelihood ratios (LLRs) using the
Modemobjects in themodemslist of thisPDSCH. The demodulation for each codeword is performed separately by its own dedicatedModemobject. This produces one or two sets of LLRs for each codeword.- Descrambling:
The descrambling of the demodulated LLRs using the
rntiandnIDproperties of thisPDSCH. These properties are used to initialize a Gold sequence which is then used for the descrambling process according to 3GPP TS 38.211, Section 7.3.1.1. The LLRs for each codeword are descrambled separately.
This function returns a list of one or two NumPy arrays representing the LLRs for each codeword.
- Parameters:
rxGrid (
Grid) – The equalized received resource grid associated with thisPDSCH. Usually this is theGridobject obtained after equalization in the receiver pipeline (See theequalize()function).pdschIndexes (3-tuple) – A tuple of 3 lists specifying locations of the set of resource elements in
rxGridthat are assigned to the user data. The functiongetReIndexes()is typically used to obtain this. If not specified, the internal parameterdataIndicesis used.llrScales (3-D NumPy array) – The log-likelihood ratio (LLR) scaling factors which are used by demodulation process when extracting log-likelihood ratios (LLRs) from the equalized resource grid. The shape of this array must be the same shape as
rxGrid.noiseVar (float or None) – The variance of the Additive White Gaussian Noise (AWGN) present in the received resource grid. If this is not provided (
noiseVar=None), This function uses thenoiseVarproperty of therxGridobject.useMax (bool) – If True, this implementation uses the
Maxfunction in the calculation of the LLR values. This is faster but uses an approximation and is slightly less accurate than the actual log-likelihood method which uses logarithm and exponential functions. If False, the slower more accurate method is used.
- Returns:
A list of one or two NumPy arrays each representing the LLRs for each codeword.
- Return type:
list
- getHardBits(eqGrid, llrScales=None, noiseVar=None, useMax=True)
This method first calls the
getLLRs()function above and then uses hard-decisions on the returned LLRs to get the output user bits.This can be used when there is no channel coding in the communication pipeline. It returns a list of one or two NumPy arrays of bits for each codeword.
- Parameters:
eqGrid (
Grid) – The equalized received resource grid associated with thisPDSCH. Usually this is theGridobject obtained after equalization in the receiver pipeline (See theequalize()function).llrScales (3-D NumPy array) – The log-likelihood ratio (LLR) scaling factors which are used by demodulation process when extracting log-likelihood ratios (LLRs) from the equalized resource grid. The shape of this array must be the same shape as
eqGrid.noiseVar (float or None) – The variance of the Additive White Gaussian Noise (AWGN) present in the received resource grid. If this is not provided (
noiseVar=None), This function uses thenoiseVarproperty of theeqGridobject.useMax (bool) – If True, this implementation uses the
Maxfunction in the calculation of the LLR values. This is faster but uses an approximation and is slightly less accurate than the actual log-likelihood method which uses logarithm and exponential functions. If False, the slower more accurate method is used.
- Returns:
A list of one or two NumPy arrays of bits for each codeword.
- Return type:
list
- Returns:
A list of one or two NumPy arrays each representing the LLRs for each codeword.
- Return type:
list
Note
This function replaces the deprecated function
getHardBitsFromGrid(). The following example shows how to migrate existing code to use this method:# Old: llrs = pdsch.getHardBitsFromGrid(eqGrid, pdschIndexes, llrScales) # New: llrs = pdsch.getHardBits(eqGrid, llrScales)
- getHardBitsFromGrid(rxGrid, pdschIndexes, llrScales=None, noiseVar=None, useMax=True)
DEPRECATED: This method is deprecated and will be removed in future releases. Please use the
getHardBits()method instead.
- getDataSymbols(grid=None)
This is a helper function that returns the modulated complex symbols for all user data in
gridfor thisPDSCHobject. The following code shows two different ways to do this:# Getting the indices of user data in "grid" and then using them to get "dataSymbols1": dataReIndexes = myPdsch.getReIndexes(grid, "PDSCH") dataSymbols1 = grid[ dataReIndexes ] # Using the "getDataSymbols" function: dataSymbols2 = myPdsch.getDataSymbols(grid) assert np.all(dataSymbols1==dataSymbols2) # The results are the same
- getPrecodingMatrix(channelMatrix)
This function calculates the precoding matrix that can be applied to a resource grid. This function supports Precoding RB groups (PRGs) which means different precoding matrices could be applied to different groups of subcarriers in the resource grid. See 3GPP TS 38.214, Section 5.1.2.3 for more details. The
prgSizeproperty ofPDSCHdetermines what type of precoding matrix is returned by this function:- Wideband:
If
prgSizeis set to zero, a singleNt x Nlmatrix is returned whereNtis the number of transmitter antennas andNlis the number of layers in thisPDSCH. In this case the same precoding is applied to all subcarriers of the resource grid.- Using PRGs:
If
prgSizeis set to 2 or 4, a list of tuples of the form (groupRBs,groupF) is returned. For each entry in the list, theNt x Nlprecoding matrixgroupFis applied to all subcarriers of the resource blocks listed ingroupRBs.
Note
It is assumed that the
channelMatrixis obtained based on the sameBandwidthPartobject as the one used by thisPDSCH.- Parameters:
channelMatrix (NumPy array) – An
L x K x Nr x Ntcomplex NumPy array representing the channel matrix. It can be obtained directly from a channel model using thegetChannelMatrix()method.- Returns:
Depending on the
prgSizeproperty of thisPDSCH, the returned value can be:- NumPy Array:
If
prgSizeis set to zero, a single WidebandNt x Nl, matrix is returned whereNtis the number of transmitter antennas andNlis the number of layers in thisPDSCH. In this case the same precoding is applied to all subcarriers of the resource grid.- list of tuples:
If
prgSizeis set to 2 or 4, a list of tuples of the form (groupRBs,groupF) is returned. For each entry in the list, theNt x Nlprecoding matrixgroupFis applied to all subcarriers of the resource blocks listed ingroupRBs.
Note
The returned precoding matrix (or each
groupFin the subband case) is normalized by \(1/\sqrt{N_l}\) per 3GPP TS 38.211, Section 6.3.1.5 so that the total transmit power is preserved across layers. If you compose this output with your own additional precoder factors, do not re-apply this normalization.- Return type:
NumPy array or list of tuples
- precodeTo(txGrid, precoder, w=None)
Applies the specified precoding matrix to this grid object and returns a new precoded grid. Optionally, a steering vector can be applied before the precoder. This function supports Precoding RB Groups (PRGs), which means different precoding matrices can be applied to different groups of subcarriers in the resource grid. See 3GPP TS 38.214, Section 5.1.2.3 for more details.
- Parameters:
txGrid (
Grid) – The transmitted resource grid of shapeNt x L x KwhereNtis the number of transmitter antennas,Lis the number of OFDM symbols, andKis the number of subcarriers. The precoded information is placed in this resource grid.precoder (NumPy array or list of tuples) –
This function supports two types of precoding:
- Wideband:
precoderis anNt x Nlmatrix whereNtis the number of transmitter antennas andNlis the number of layers which must match the number of layers in this PDSCH. In this case the same precoding is applied to all subcarriers of this PDSCH.- Using PRGs:
precoderis a list of tuples of the form (groupRBs,groupF). For each entry in the list, theNt x Nlprecoding matrixgroupFis applied to all subcarriers of the resource blocks listed ingroupRBs.
w (NumPy array, optional) – An optional steering vector of shape
Nt x 1applied before the precoder, whereNtis the number of transmitter antennas. When provided, each row of the precoding matrix is multiplied by the corresponding element ofw. This allows a directional steering vector to be combined with a PMI-based precoder. If omitted, only the specified precoder is applied.
Note
This function replaces the deprecated function
precode(). The following example shows how to migrate existing code to use this method:# Old: precodedGrid = grid.precode(precoder) # New: txGrid = bwp.createGrid(channel.txAntenna.numEl) pdsch.precodeTo(txGrid, precoder)
- estimateChannel(rxGrid, **kwargs)
Estimate the effective PDSCH channel from DMRS and return an associated residual-error variance.
This function estimates the effective channel between the PDSCH layers and the receive antennas using the DMRS REs. A local channel estimate is first computed for each CDM group by dividing the received DMRS values by the transmitted DMRS reference values and averaging over the REs in the CDM group.
The per-CDM-group channel estimates are then interpolated:
across subcarriers, using the center subcarrier of each CDM group, and
across OFDM symbols, using the center OFDM symbol of each DMRS symbol position or DMRS symbol pair.
The returned channel estimate is always in physical PRB order. Please refer to the notebook Channel/Noise Estimation for examples of using this function.
- Parameters:
rxGrid (Grid or numpy.ndarray) – The received resource grid used for channel estimation.
**kwargs (dict, optional) –
Optional keyword arguments.
- extrapolatebool or None
If
True, linear extrapolation is used outside the DMRS-supported frequency and time ranges. IfFalse, the channel estimate is clipped to the boundary values at both ends during interpolation. If not specified, linear extrapolation is used when the DMRS’sadditionalPosis non-zero.- estimateNoiseVarbool
If
True, the function also returns the estimated noise variance, in addition to the estimated channel and residual error variance. The noise variance is computed using a calibration table. Note that the accuracy of the noise variance estimate degrades at high SNR values.
- Returns:
chanEst (numpy.ndarray) – The estimated effective channel as a NumPy complex array of shape
(L, K, nr, numLayers), where:Lis the number of OFDM symbols in the received grid,Kis the number of subcarriers in the full bandwidth part (i.e.,bwp.numRbs * 12), not just the PDSCH allocation — the channel estimate is returned over the entire BWP so it can be fed directly toequalize()/getPrecodingMatrix(),nris the number of receive antennas, andnumLayersis the number of PDSCH layers.
errVar (float) – The variance of the effective residual uncertainty associated with the estimated channel. This quantity is computed from the residual between the received CDM-group DMRS values and their reconstruction from the local channel estimates.
This is not the AWGN noise variance applied to the received signal. It is intended for use as the
noiseVarinput ofequalize()when the channel is estimated using this function.estNoiseVar (float) – The estimated noise variance. This is returned only if
estimateNoiseVaris set toTrueinkwargs. The estimate may be less accurate at high SNR.
Note
The local CDM-group channel estimate is computed as the average of
cdmY / cdmXover the REs of each CDM group.For double-symbol DMRS configurations, each adjacent DMRS symbol pair is represented by a single time anchor located at the center of the pair.
If only one DMRS symbol position is present, the frequency-interpolated channel estimate is copied to all OFDM symbols.
The residual-based
errVarreflects the uncertainty associated with the estimated channel and may include contributions from AWGN, channel estimation error, interpolation error, and model mismatch.This function replaces the deprecated function
estimateChannelLS(). The following example shows how to migrate existing code to use this method:# Old: estChannelMatrix, noiseVar = rxGrid.estimateChannelLS(pdsch.dmrs) # New: estChannelMatrix, errVar = pdsch.estimateChannel(rxGrid)
- equalize(rxGrid, h, noiseVar=None)
Equalizes the received resource grid
rxGridusing the effective channelh. The effective channel is assumed to include the effect of the precoding matrix, therefore, its shape isL x K x Nr x NlwhereLis the number of OFDM symbols,Kis the number of subcarriers in the whole bandwidth part,Nris the number of receiver antennas, andNlis the number of layers. The output of the equalization process is a newGridobject of shapeNl x L x Kp, whereKpis the number of subcarriers used by this PDSCH (Kp <= K).The process of de-interleaving resource blocks and mapping from PRBs to VRBs to GRBs (the RBs in the returned resource grid) is performed in this function. Both
rxGridandhare in PRBs. The returned equalized resource grid is in GRBs.This function also outputs log-likelihood ratio (LLR) scaling factors which are used by the demodulation process when extracting log-likelihood ratios (LLRs) from the equalized resource grid.
This method uses the Minimum Mean Squared Error (MMSE) algorithm for the equalization.
- Parameters:
rxGrid (
Grid) – The received resource grid. It is anNr x L x Kresource grid whereNris the number of receiver antennas,Lis the number of OFDM symbols, andKis the number of subcarriers in the whole bandwidth part.h (4-D complex NumPy array) – This is an
L x K x Nr x NlNumPy array representing the estimated channel matrix, whereLis the number of OFDM symbols,Kis the number of subcarriers in the whole bandwidth part,Nris the number of receiver antennas, andNlis the number of layers.noiseVar (float or None) –
The variance of noise applied to the received resource grid. If this is not provided, this method tries to use the noise variance of the resource grid obtained by the OFDM demodulation process for the time-domain case or the variance of the noise applied to the received resource grid by the
addNoise()method for the frequency domain case (See thenoiseVarproperty ofGridclass).Note
When the function
estimateChannel()is used to estimate the channel, theerrVarreturned by that function must be passed to this function through thenoiseVarargument. AlthougherrVaris not exactly the AWGN noise variance applied to the received signal, it should be used for equalization whenever an estimated channel is used. The following example shows equalization with perfect channel knowledge versus equalization with an estimated channel:# Using the perfect channel from a channel model 'channel' channelMatrix = channel.getChannelMatrix() precoder = pdsch.getPrecodingMatrix(channelMatrix) effChannelMatrix = CdlChannel.getEffChannel(channelMatrix, precoder) eqGrid, llrScales = pdsch.equalize(rxGrid, effChannelMatrix) # 'noiseVar' is stored in 'rxGrid' # Using an estimated channel estChannelMatrix, errVar = pdsch.estimateChannel(rxGrid) eqGrid, llrScales = pdsch.equalize(rxGrid, estChannelMatrix, errVar)
- Returns:
eqGrid (
Grid) – The equalized grid object of shapeNl x L x KpwhereNlis the number of layers,Lis the number of OFDM symbols, andKpis the number of subcarriers used by this PDSCH.llrScales (3-D NumPy array) – The log-likelihood ratio (LLR) scaling factors which are used by the demodulation process when extracting log-likelihood ratios (LLRs) from the equalized resource grid. The shape of this array is
Nl x L x Kpwhich is similar toeqGridabove.
Note
This function replaces the deprecated function
equalize(). The following example shows how to migrate existing code to use this method:# Old: eqGrid, llrScales = rxGrid.equalize(effectiveChannelMatrix) # New: eqGrid, llrScales = pdsch.equalize(rxGrid, effectiveChannelMatrix)
- getTxBlockSize(coderates, xOverhead=None, scaleFactor=1.0)
This function calculates the transport block size based on the desired code rate (
coderates), the number of additional overhead resource elements (xOverhead), and the scaling factor (scaleFactor). It returns a list of one or two integer values specifying the size of transport blocks for each codeword. This implementation is based on 3GPP TS 38.214, Section 5.1.3.2.- Parameters:
coderates (float, list, NumPy array, or tuple) – If
coderatesis a float value, it specifies the same code rate for all codewords. If it is a list, NumPy array, or tuple, it should contain one or two code rate values for each codeword. This is the value \(R\) in 3GPP TS 38.214, Section 5.1.3.2.xOverhead (int or None, optional) –
The number of additional overhead resource elements per PRB to consider when calculating the transport block size. This corresponds to \(N^{PRB}_{oh}\) in 3GPP TS 38.214, Section 5.1.3.2 and, when explicitly specified, must be one of
0,6,12, or18according to 3GPP TS 38.331.If set to
None(the default), NeoRadium automatically selects a conservative value based on the configured DM-RS overhead, the maximum CSI-RS overhead that may occur in a slot, and the requested code rate. This helps prevent the effective code rate from becoming excessively large when reference-signal overhead reduces the number of REs available for PDSCH. The automatically selected value remains fixed for the TBS calculation and is chosen from0,6,12, and18.The automatic selection is a NeoRadium implementation convenience based on conservative empirical thresholds. It is not a procedure specified or recommended by 3GPP. To disable the automatic behavior, explicitly provide the desired
xOverheadvalue.scaleFactor (float) – The scaling factor, which must be one of: 0.25, 0.5, or 1.0. This is the value \(S\) in 3GPP TS 38.214, Table 5.1.3.2-2 and reduces the effective TBS by the same proportion. The value is signaled by higher layers;
1.0is the normal case (full capacity), while0.5and0.25are used for more robust/fallback transmissions (e.g., certain DCI Format 1_0 cases).
- Returns:
A list of one or two integers depending on the number of codewords (
numCW), indicating the transport block size for each codeword.- Return type:
list
- getLdpcCodec(coderates, numIter=5, nRef=0)
Creates and returns an
LdpcCodecobject configured based on the currentPDSCHsettings.This method derives the required LDPC coding parameters (modulation schemes and transport block sizes) from the
PDSCHinstance and combines them with the specifiedcoderatesto initialize anLdpcCodecobject. The resulting codec can be used for encoding and decoding the transport block(s) associated with thisPDSCH.- Parameters:
coderates (float, list, tuple, or NumPy array) – One or two code rate values corresponding to the codeword(s) of this
PDSCH. If a single value is provided and two codewords are present (i.e.,numLayers > 4), the same code rate is used for both codewords.numIter (int) – The number of iterations used in the LDPC decoder (Layered Belief Propagation). Higher values may improve decoding performance at the cost of increased complexity. The default is 5.
nRef (int) – The reference buffer size used for Low-Buffer Rate Matching (LBRM). This corresponds to \(N_{ref}\) in 3GPP TS 38.212, Section 5.4.2.1. The default is 0 (LBRM disabled).
- Returns:
An LDPC codec object configured for the current
PDSCH, supporting one or two codewords depending onnumLayers.- Return type:
Notes
The modulation schemes are automatically extracted from the internal
modemsof thisPDSCH.The transport block size(s) are computed using
getTxBlockSize()based on the providedcoderates.The returned
LdpcCodecobject is fully configured and ready for encoding and decoding operations.
- getHarq(coderates, numIter=5, nRef=0, harqType='CC', numProc=8, rvSequence=[0, 2, 3, 1], maxTries=4, eventCallback=None)
Creates and returns a
HarqEntityobject configured based on the currentPDSCHsettings.This method first creates an
LdpcCodecobject using thegetLdpcCodec()method and then uses it to create aHarqEntityobject.For more details about
coderates,numIter, andnRefrefer togetLdpcCodec().For more details about
harqType,numProc,rvSequence,maxTries,eventCallbackrefer toHarqEntity.
- Returns:
A HARQ entity object created based on the given parameters.
- Return type: