5/3 update:
aotCsiRs is ok, including:
*transmission of periodic NZP-CSI-RS
*transmission of periodic CSI-IM
*transmission of periodic Tracking-RS(or TRS)
5/5 update:
*TRS periodicity should be slots40.
7/28 update:
*bugfix for NZP-CSI-RS row determination (thanks to @gmg2719)
add 'row' and 'bit string' to UI, rational is specified in 38.331--frequencyDomainAllocation IE:
frequencyDomainAllocation
Frequency domain allocation within a physical resource block in accordance with TS 38.211 [16], clause 7.4.1.5.3. The applicable row number in table 7.4.1.5.3-1 is determined by the frequencyDomainAllocation for rows 1, 2 and 4, and for other rows by matching the values in the column Ports, Density and CDMtype in table 7.4.1.5.3-1 with the values of nrofPorts, cdm-Type and density below and, when more than one row has the 3 values matching, by selecting the row where the column (k bar, l bar) in table 7.4.1.5.3-1 has indexes for k ranging from 0 to 2*n-1 where n is the number of bits set to 1 in frequencyDomainAllocation.
and now debug log will include validateNzpCsiRs status:
part of debug output for NZP-CSI-RS row selection:
#select 'row4'
-->inside validateNzpCsiRs
validateNzpCsiRsKiLi succeed: expectedRow="row4", bit-string="001", key="4_1_fd-CDM2", actualRow=4
#select 'row2'
-->inside validateNzpCsiRs
validateNzpCsiRsKiLi succeed: expectedRow="row2", bit-string="000000000001", key="1_1_noCDM", actualRow=2
#select 'row1'
-->inside validateNzpCsiRs
validateNzpCsiRsKiLi succeed: expectedRow="row1", bit-string="0001", key="1_3_noCDM", actualRow=1
#select 'other' and row=3
-->inside validateNzpCsiRs
validateNzpCsiRsKiLi succeed: expectedRow="other", bit-string="000001", key="2_1_fd-CDM2", actualRow=3
#select 'other' and row=5
-->inside onNzpCsiRsNumPortsCombCurIndChanged, index=2
-->inside validateNzpCsiRs
Warning: Row does not match! (expectedRow="other", actualRow=4, key="4_1_fd-CDM2")
validateNzpCsiRsKiLi succeed: expectedRow="other", bit-string="000001", key="4_1_fd-CDM2", actualRow=5
#select 'other' and row=6/7
-->inside validateNzpCsiRs
[2019-07-28 07:32:17]Warning: Invalid configuration: numKi=4 but numKiConf(frequencyDomainAllocation)=1!
validateNzpCsiRsKiLi failed: expectedRow="other", bit-string="000001", key="8_1_fd-CDM2", actualRow=6
[2019-07-28 07:32:17]Warning: Invalid configuration: numKi=2 but numKiConf(frequencyDomainAllocation)=1!
validateNzpCsiRsKiLi failed: expectedRow="other", bit-string="000001", key="8_1_fd-CDM2", actualRow=7
-->inside validateNzpCsiRs
validateNzpCsiRsKiLi failed: expectedRow="other", bit-string="000011", key="8_1_fd-CDM2", actualRow=6
validateNzpCsiRsKiLi succeed: expectedRow="other", bit-string="000011", key="8_1_fd-CDM2", actualRow=7
-->inside validateNzpCsiRs
validateNzpCsiRsKiLi succeed: expectedRow="other", bit-string="001111", key="8_1_fd-CDM2", actualRow=6
(1) aotCsiRs is added to alwaysOnTr:
if self.msg4Recved:
if not self.error:
self.aotCsirs(hsfn, sfn, slot)
if not self.error:
self.aotSrs(hsfn, sfn, slot)
(2) Transmission of NZP-CSI-RS and TRS
TRS is kind of nzp-csi-rs except that TRS always uses: single port with no CDM and density=3 and periodic TRS doesn't need CSI report.
Procedure to determine :
#refer to 3GPP 38.211 vf40
#Table 7.4.1.5.3-1: CSI-RS locations within a slot.
#determine ki (k0, k1 etc)
ki = []
pos = -1
while True:
try:
pos = self.nrNzpCsiRsFreqAlloc[::-1].index('1', pos+1, len(self.nrNzpCsiRsFreqAlloc))
except Exception as e:
break
if self.nrNzpCsiRsRow in (1, 2):
ki.append(pos)
elif self.nrNzpCsiRsRow == 4:
ki.append(4 * pos)
else:
ki.append(2 * pos)
Procedure to determine startRb and numRbs for NZP-CSI-RS:
#refer to 3GPP 38.214 vf40
#5.2.2.3.1 NZP CSI-RS
#Both nrofRBs and startingRB are configured as integer multiples of 4 RBs, and the reference point for startingRB is CRB 0 on the common resource block grid. If startingRBN_BWP^size+N_BWP^start-N_(initial RB), the UE shall assume that the bandwidth of the CSI-RS resource is N_(CSI-RS)^BW=N_BWP^size+N_BWP^start-N_(initial RB), otherwise N_(CSI-RS)^BW=nrofRBs. In all cases, the UE shall expect that N_(CSI-RS)^BW≥min(24,N_BWP^size).
if self.nrNzpCsiRsStartRb < self.nrCarrierMinGuardBand + self.nrDedDlBwpStartRb:
startRb = self.nrCarrierMinGuardBand + self.nrDedDlBwpStartRb
else:
startRb = self.nrNzpCsiRsStartRb
if self.nrNzpCsiRsNumRbs > self.nrCarrierMinGuardBand + self.nrDedDlBwpStartRb + self.nrDedDlBwpNumRbs - startRb:
numRbs = self.nrCarrierMinGuardBand + self.nrDedDlBwpStartRb + self.nrDedDlBwpNumRbs - startRb
else:
numRbs = self.nrNzpCsiRsNumRbs
Note:
There is a problem with current implementation which is not fully compatible with 3GPP specs:
*BWP RB_Start is defined w.r.t to carrier edge, not w.r.t. CRB0 as defined in 3GPP spec
*it affects calculation of startRb: startRb = self.nrCarrierMinGuardBand + self.nrDedDlBwpStartRb, which should be startRb = self.nrDedDlBwpStartRb as specified in 38.214.
*In current implementation, self.nrCarrierMinGuardBand defines the carrier edge.
Procedure to determine antenna ports p for each CDM group:
#determine antenna ports p
L = len(self.nrNzpCsiRsKap) * len(self.nrNzpCsiRsLap)
N = self.nrNzpCsiRsNumPorts
self.nzpCsiRsApMap = dict()
for j in range(N // L):
self.nzpCsiRsApMap[j] = []
for s in range(L):
self.nzpCsiRsApMap[j].append(3000 + s + j * L)
for key,val in self.nzpCsiRsApMap.items():
self.ngwin.logEdit.append('CDM group index j=%d, antenna ports=%s' % (key, val))
qApp.processEvents()
Example output for Row#17 of Table 7.4.1.5.3-1 of 38.211:
CDM group index j=0, antenna ports=[3000, 3001, 3002, 3003]
CDM group index j=1, antenna ports=[3004, 3005, 3006, 3007]
CDM group index j=2, antenna ports=[3008, 3009, 3010, 3011]
CDM group index j=3, antenna ports=[3012, 3013, 3014, 3015]
CDM group index j=4, antenna ports=[3016, 3017, 3018, 3019]
CDM group index j=5, antenna ports=[3020, 3021, 3022, 3023]
CDM group index j=6, antenna ports=[3024, 3025, 3026, 3027]
CDM group index j=7, antenna ports=[3028, 3029, 3030, 3031]
(3) Transmission of CSI-IM:
Procedure to determine REs for CSI-IM mapping:
#refer to 3GPP 38.211 vf40
#5.2.2.4 Channel State Information – Interference Measurement (CSI-IM)
csiImRes = []
if self.nrCsiImRePattern == 'pattern0':
csiImRes.append([self.nrCsiImScLoc, self.nrCsiImSymbLoc])
csiImRes.append([self.nrCsiImScLoc, self.nrCsiImSymbLoc+1])
csiImRes.append([self.nrCsiImScLoc+1, self.nrCsiImSymbLoc])
csiImRes.append([self.nrCsiImScLoc+1, self.nrCsiImSymbLoc+1])
else:
csiImRes.append([self.nrCsiImScLoc, self.nrCsiImSymbLoc])
csiImRes.append([self.nrCsiImScLoc+1, self.nrCsiImSymbLoc])
csiImRes.append([self.nrCsiImScLoc+2, self.nrCsiImSymbLoc])
csiImRes.append([self.nrCsiImScLoc+3, self.nrCsiImSymbLoc])
self.ngwin.logEdit.append('csiImRePattern="%s",csiImRes=%s' % (self.nrCsiImRePattern, csiImRes))
qApp.processEvents()
CSI-IM mapping is simple, and the tricky part is that: CSI-IM resource is associated with per NZP-CSI-RS as specified in 38.214.
(4) Examples of aotCsiRs output:
Example configurations:
contents of ["freqBand"]: {'opBand': 'n41', 'duplexMode': 'TDD', 'maxDlFreq': 2690, 'freqRange': 'FR1'}
contents of ["ssbGrid"]: {'scs': '30KHz', 'pattern': 'Case C', 'minGuardBand240k': 'NA', 'kSsb': '0', 'nCrbSsb': '30'}
contents of ["ssbBurst"]: {'maxL': 8, 'inOneGroup': '11110000', 'groupPresence': 'NA', 'period': '10ms'}
contents of ["mib"]: {'sfn': '0', 'hrf': '0', 'dmrsTypeAPos': 'pos2', 'commonScs': '30KHz', 'rmsiCoreset0': '10', 'rmsiCss0': '0', 'coreset0MultiplexingPat': 1, 'coreset0NumRbs': 48, 'coreset0NumSymbs': 1, 'coreset0OffsetList': (12,), 'coreset0Offset': 12, 'coreset0StartRb': 0}
contents of ["carrierGrid"]: {'scs': '30KHz', 'bw': '100MHz', 'numRbs': '273', 'minGuardBand': '3'}
contents of ["pci"]: 0
contents of ["numUeAp"]: 4Tx
contents of ["tddCfg"]: {'refScs': '30KHz', 'pat1Period': '5ms', 'pat1NumDlSlots': '7', 'pat1NumDlSymbs': '6', 'pat1NumUlSymbs': '4', 'pat1NumUlSlots': '2', 'pat2Period': 'not used', 'pat2NumDlSlots': '', 'pat2NumDlSymbs': '', 'pat2NumUlSymbs': '', 'pat2NumUlSlots': ''}
contents of ["css0"]: {'aggLevel': '4', 'numCandidates': 'n4'}
contents of ["dci10Sib1"]: {'rnti': '0xFFFF', 'muPdcch': '1', 'muPdsch': '1', 'tdRa': '10', 'tdMappingType': 'Type B', 'tdK0': '0', 'tdSliv': '26', 'tdStartSymb': '12', 'tdNumSymbs': '2', 'fdRaType': 'RA Type1', 'fdRa': '00001011111', 'fdStartRb': '0', 'fdNumRbs': '48', 'fdVrbPrbMappingType': 'interleaved', 'fdBundleSize': 'n2', 'mcsCw0': '2', 'tbs': '408'}
contents of ["dci10Msg2"]: {'rnti': '0x0001', 'muPdcch': '1', 'muPdsch': '1', 'tdRa': '10', 'tdMappingType': 'Type B', 'tdK0': '0', 'tdSliv': '26', 'tdStartSymb': '12', 'tdNumSymbs': '2', 'fdRaType': 'RA Type1', 'fdRa': '00001011111', 'fdStartRb': '0', 'fdNumRbs': '48', 'fdVrbPrbMappingType': 'interleaved', 'fdBundleSize': 'n2', 'mcsCw0': '2', 'tbScaling': '0', 'tbs': '408'}
contents of ["msg3Pusch"]: {'muPusch': '1', 'tdRa': '6', 'tdMappingType': 'Type B', 'tdK2': '1', 'tdDelta': '3', 'tdSliv': '74', 'tdStartSymb': '4', 'tdNumSymbs': '6', 'fdRaType': 'RA Type1', 'fdFreqHop': 'enabled', 'fdRa': '0100000100001101', 'fdStartRb': '0', 'fdNumRbs': '62', 'fdSecondHopFreqOff': '68', 'mcsCw0': '2', 'tbs': '1544'}
contents of ["dci10Msg4"]: {'rnti': '0x0001', 'muPdcch': '1', 'muPdsch': '1', 'tdRa': '10', 'tdMappingType': 'Type B', 'tdK0': '0', 'tdSliv': '26', 'tdStartSymb': '12', 'tdNumSymbs': '2', 'fdRaType': 'RA Type1', 'fdRa': '00001011111', 'fdStartRb': '0', 'fdNumRbs': '48', 'fdVrbPrbMappingType': 'interleaved', 'fdBundleSize': 'n2', 'mcsCw0': '2', 'tbs': '408', 'deltaPri': '1', 'tdK1': '2'}
contents of ["iniDlBwp"]: {'bwpId': '0', 'scs': '30KHz', 'cp': 'normal', 'locAndBw': '12925', 'startRb': '0', 'numRbs': '48'}
contents of ["dmrsSib1"]: {'dmrsType': 'Type 1', 'dmrsAddPos': 'pos0', 'maxLength': 'len1', 'dmrsPorts': '0', 'cdmGroupsWoData': '1', 'numFrontLoadSymbs': '1', 'tdL': [0], 'fdK': [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]}
contents of ["dmrsMsg2"]: {'dmrsType': 'Type 1', 'dmrsAddPos': 'pos0', 'maxLength': 'len1', 'dmrsPorts': '0', 'cdmGroupsWoData': '1', 'numFrontLoadSymbs': '1', 'tdL': [0], 'fdK': [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]}
contents of ["dmrsMsg4"]: {'dmrsType': 'Type 1', 'dmrsAddPos': 'pos0', 'maxLength': 'len1', 'dmrsPorts': '0', 'cdmGroupsWoData': '1', 'numFrontLoadSymbs': '1', 'tdL': [0], 'fdK': [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]}
contents of ["iniUlBwp"]: {'bwpId': '0', 'scs': '30KHz', 'cp': 'normal', 'locAndBw': '1099', 'startRb': '0', 'numRbs': '273'}
contents of ["rach"]: {'prachConfId': '180', 'raFormat': 'C0', 'raX': 1, 'raY': (0,), 'raSubfNumFr1SlotNumFr2': (9,), 'raStartingSymb': 8, 'raNumSlotsPerSubfFr1Per60KSlotFr2': 1, 'raNumOccasionsPerSlot': 3, 'raDuration': 2, 'scs': '30KHz', 'msg1Fdm': '1', 'msg1FreqStart': '0', 'raRespWin': 'sl20', 'totNumPreambs': '64', 'ssbPerRachOccasion': 'one', 'cbPreambsPerSsb': '64', 'contResTimer': 'sf32', 'msg3Tp': 'disabled', 'raLen': 139, 'raNumRbs': 12, 'raKBar': 2}
contents of ["dmrsMsg3"]: {'dmrsType': 'Type 1', 'dmrsAddPos': 'pos1', 'maxLength': 'len1', 'dmrsPorts': '0', 'cdmGroupsWoData': '2', 'numFrontLoadSymbs': '1', 'tdL': [[0], [0]], 'fdK': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
contents of ["dedDlBwp"]: {'bwpId': '1', 'scs': '30KHz', 'cp': 'normal', 'locAndBw': '1099', 'startRb': '0', 'numRbs': '273'}
contents of ["nzpCsiRs"]: {'resSetId': '0', 'trsInfo': 'false', 'resId': '0', 'numPorts': 'p32', 'cdmType': 'cdm4-FD2-TD2', 'density': 'one', 'freqAlloc': '001111', 'firstSymb': '1', 'firstSymb2': '3', 'startRb': '0', 'numRbs': '276', 'period': 'slots20', 'offset': '10', 'row': 17, 'kBarLBar': ((0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)), 'ki': (0, 1, 2, 3, 0, 1, 2, 3), 'li': (0, 0, 0, 0, 1, 1, 1, 1), 'cdmGrpIndj': (0, 1, 2, 3, 4, 5, 6, 7), 'kap': (0, 1), 'lap': (0, 1)}
contents of ["trs"]: {'resSetId': '1', 'trsInfo': 'true', 'resId': '100-101', 'numPorts': 'p1', 'cdmType': 'noCDM', 'density': 'three', 'freqAlloc': '0001', 'firstSymb': '5,9', 'startRb': '0', 'numRbs': '276', 'period': 'slots40', 'offset': '10', 'row': 1, 'kBarLBar': ((0, 0), (4, 0), (8, 0)), 'ki': (0, 0, 0), 'li': (0, 0, 0), 'cdmGrpIndj': (0, 0, 0), 'kap': (0,), 'lap': (0,)}
contents of ["csiIm"]: {'resSetId': '0', 'resId': '0', 'rePattern': 'pattern0', 'scLoc': 's8', 'symbLoc': '1', 'startRb': '0', 'numRbs': '276', 'period': 'slots20', 'offset': '10'}
contents of ["nzpCsiRsResCfg"]: {'resCfgId': '0', 'resSetId': '0', 'bwpId': '1', 'resType': 'periodic'}
contents of ["trsResCfg"]: {'resCfgId': '20', 'resSetId': '1', 'bwpId': '1', 'resType': 'periodic'}
contents of ["csiImResCfg"]: {'resCfgId': '10', 'resSetId': '0', 'bwpId': '1', 'resType': 'periodic'}
contents of ["csiRepCfg"]: {'repCfgId': '0', 'resCfgIdChnMeas': '0', 'resCfgIdCsiImIntf': '10', 'repType': 'periodic', 'period': 'slots320', 'offset': '7', 'ulBwpId': '1', 'pucchRes': '2', 'quantity': 'cri-RI-PMI-CQI'}
contents of ["dedUlBwp"]: {'bwpId': '1', 'scs': '30KHz', 'cp': 'normal', 'locAndBw': '1099', 'startRb': '0', 'numRbs': '273'}
contents of ["srsRes0"]: {'resId': '0', 'numPorts': 'port1', 'nonCbPtrsPort': 'n0', 'numCombs': 'n2', 'combOff': '0', 'startPos': '0', 'numSymbs': 'n1', 'repetition': 'n1', 'freqPos': '0', 'freqShift': '0', 'cSrs': '0', 'bSrs': '0', 'bHop': '0', 'type': 'periodic', 'period': 'sl5', 'offset': '0', 'mSRSb': '4', 'Nb': 1}
contents of ["srsRes1"]: {'resId': '1', 'numPorts': 'port1', 'nonCbPtrsPort': 'n0', 'numCombs': 'n2', 'combOff': '0', 'startPos': '0', 'numSymbs': 'n1', 'repetition': 'n1', 'freqPos': '0', 'freqShift': '0', 'cSrs': '0', 'bSrs': '0', 'bHop': '0', 'type': 'periodic', 'period': 'sl5', 'offset': '0', 'mSRSb': '4', 'Nb': 1}
contents of ["srsRes2"]: {'resId': '2', 'numPorts': 'port1', 'nonCbPtrsPort': 'n0', 'numCombs': 'n2', 'combOff': '0', 'startPos': '0', 'numSymbs': 'n1', 'repetition': 'n1', 'freqPos': '0', 'freqShift': '0', 'cSrs': '0', 'bSrs': '0', 'bHop': '0', 'type': 'periodic', 'period': 'sl5', 'offset': '0', 'mSRSb': '4', 'Nb': 1}
contents of ["srsRes3"]: {'resId': '3', 'numPorts': 'port1', 'nonCbPtrsPort': 'n0', 'numCombs': 'n2', 'combOff': '0', 'startPos': '0', 'numSymbs': 'n1', 'repetition': 'n1', 'freqPos': '0', 'freqShift': '0', 'cSrs': '0', 'bSrs': '0', 'bHop': '0', 'type': 'periodic', 'period': 'sl5', 'offset': '0', 'mSRSb': '4', 'Nb': 1}
contents of ["srsResSet0"]: {'resSetId': '0', 'resIdList': '0', 'type': 'periodic', 'usage': 'codebook'}
contents of ["srsResSet1"]: {'resSetId': '1', 'resIdList': '0,1,2,3', 'type': 'periodic', 'usage': 'nonCodebook'}
contents of ["pucchFmtCfg"]: {'numSlots': 'n1', 'interSlotFreqHop': 'disabled', 'addDmrs': 'true', 'simulAckCsi': 'true'}
contents of ["pucchRes0"]: {'resId': '0', 'format': 'format 0', 'resSetId': '0', 'startRb': '0', 'intraSlotFreqHop': 'disabled', 'secondHopPrb': '', 'numRbs': '1', 'startSymb': '0', 'numSymbs': '1'}
contents of ["pucchRes1"]: {'resId': '1', 'format': 'format 1', 'resSetId': '0', 'startRb': '0', 'intraSlotFreqHop': 'disabled', 'secondHopPrb': '', 'numRbs': '1', 'startSymb': '0', 'numSymbs': '4'}
contents of ["pucchRes2"]: {'resId': '2', 'format': 'format 2', 'resSetId': '1', 'startRb': '0', 'intraSlotFreqHop': 'disabled', 'secondHopPrb': '', 'numRbs': '1', 'startSymb': '0', 'numSymbs': '1'}
contents of ["pucchRes3"]: {'resId': '3', 'format': 'format 3', 'resSetId': '1', 'startRb': '0', 'intraSlotFreqHop': 'disabled', 'secondHopPrb': '', 'numRbs': '1', 'startSymb': '0', 'numSymbs': '4'}
contents of ["pucchRes4"]: {'resId': '4', 'format': 'format 4', 'resSetId': '1', 'startRb': '0', 'intraSlotFreqHop': 'disabled', 'secondHopPrb': '', 'numRbs': '1', 'startSymb': '0', 'numSymbs': '4'}
contents of ["dsrRes0"]: {'resId': '0', 'pucchRes': '0', 'period': 'sym2', 'offset': '0'}
contents of ["dsrRes1"]: {'resId': '1', 'pucchRes': '1', 'period': 'sym2', 'offset': '0'}
contents of ["advanced"]: {'bestSsb': '0', 'sib1PdcchSlot': 'NA', 'prachOccasion': 'NA', 'msg2PdcchOcc': 'NA', 'msg4PdcchOcc': 'NA'}
Debug output as below:
Part of exported excel as below:
Note: CSIRS0 means NZP-CSI-RS of CDM group index j=0, the rest is the same.