我是靠谱客的博主 知性花卷,最近开发中收集的这篇文章主要介绍NG Toolset开发笔记--5GNR Resource Grid(48),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

3/17 update:

sendMsg1 is ready now, including:

*PRACH association period determination

*SSB to PRACH occasion mapping

*PRACH time-domain/freq-domain resource mapping

 

(1) PRACH association period determination

Used method is trying to find minimum valid prach occasions during 160ms (16 frames) period:

self.minNumValidPrachOccasionPerAssociationPeriod = math.ceil(self.numTxSsb / self.nrRachSsbPerRachOccasionM8 * 8)

where:

*numTxSsb is number of transmitted SSBs

*nrRachSsbPerRachOccasionM8 is ssb-perRACH-Occasion multiplied by 8.

Procedure to validate prach occasions:

#refer to 3GPP 38.213 vf40 8.1
#For paired spectrum all PRACH occasions are valid.
#If a UE is provided TDD-UL-DL-ConfigurationCommon, a PRACH occasion in a PRACH slot is valid if
#-	it is within UL symbols, or
#-	it does not precede a SS/PBCH block in the PRACH slot and starts at least N_gap symbols after a last downlink symbol and at least N_gap symbols after a last SS/PBCH block transmission symbol, where N_gap is provided in Table 8.1-2.
for s in raSlots:
for t in range(self.nrRachCfgNumOccasionsPerSlot):
if self.nrDuplexMode == 'FDD':
for f in range(self.nrRachMsg1Fdm):
validPrachOccasionsPerAssociationPeriod.append([[curHsfn, curSfn, s], t, f])
else:
scaleTd = self.baseScsTd // self.prachScs
rachFirstSymbInBaseScsTd = (s * self.nrSymbPerSlotNormCp + self.nrRachCfgStartSymb + t * self.nrRachCfgDuration) * scaleTd
rachSymbsInbaseScsTd = [rachFirstSymbInBaseScsTd+k for k in range(self.nrRachCfgDuration*scaleTd)]
nGapInBaseScsTd = 0 if self.nrRachScs in ('1.25', '5') or self.nrRachCfgFormat == 'B4' else 2*(self.baseScsTd//self.prachScs)
valid = True
for k in rachSymbsInbaseScsTd:
if tdGrid[k] != 'U':
valid = False
break
for k in range(rachFirstSymbInBaseScsTd, (s+1)*self.nrSymbPerSlotNormCp):
if tdGrid[k] == 'SSB':
valid = False
break
for k in range(max(0, rachFirstSymbInBaseScsTd - nGapInBaseScsTd), rachFirstSymbInBaseScsTd):
if tdGrid[k] in ('SSB', 'SIB1'):
valid = False
break
if valid:
for f in range(self.nrRachMsg1Fdm):
validPrachOccasionsPerAssociationPeriod.append([[curHsfn, curSfn, s], t, f])
else:
for f in range(self.nrRachMsg1Fdm):
invalidPrachOccasionsPerAssociationPeriod.append([[curHsfn, curSfn, s], t, f])

Example as below:

Configurations:
contents of ["freqBand"]: {'opBand': 'n77', 'duplexMode': 'TDD', 'maxDlFreq': 4200, 'freqRange': 'FR1'}
contents of ["ssbGrid"]: {'scs': '30KHz', 'pattern': 'Case C', 'minGuardBand240k': 'NA', 'kSsb': '0', 'nCrbSsb': '4'}
contents of ["ssbBurst"]: {'maxL': 8, 'inOneGroup': '10111111', 'groupPresence': 'NA', 'period': '20ms'}
contents of ["mib"]: {'sfn': '0', 'hrf': '0', 'dmrsTypeAPos': 'pos2', 'commonScs': '15KHz', 'rmsiCoreset0': '0', 'rmsiCss0': '0', 'coreset0MultiplexingPat': 1, 'coreset0NumRbs': 48, 'coreset0NumSymbs': 1, 'coreset0OffsetList': (2,), 'coreset0Offset': 2, 'coreset0StartRb': 0}
contents of ["carrierGrid"]: {'scs': '15KHz', 'bw': '10MHz', 'numRbs': '52', 'minGuardBand': '2'}
contents of ["pci"]: 0
contents of ["numUeAp"]: 4Tx
contents of ["tddCfg"]: {'refScs': '15KHz', 'pat1Period': '5ms', 'pat1NumDlSlots': '3', 'pat1NumDlSymbs': '10', 'pat1NumUlSymbs': '2', 'pat1NumUlSlots': '1', 'pat2Period': 'not used', 'pat2NumDlSlots': '', 'pat2NumDlSymbs': '', 'pat2NumUlSymbs': '', 'pat2NumUlSlots': ''}
contents of ["css0"]: {'aggLevel': '4', 'numCandidates': 'n4'}
contents of ["dci10Sib1"]: {'rnti': '0xFFFF', 'muPdcch': '0', 'muPdsch': '0', 'tdRa': '2', 'tdMappingType': 'Type A', 'tdK0': '0', 'tdSliv': '95', 'tdStartSymb': '2', 'tdNumSymbs': '9', 'fdRaType': 'RA Type1', 'fdRa': '00001011111', 'fdStartRb': '0', 'fdNumRbs': '48', 'fdVrbPrbMappingType': 'interleaved', 'fdBundleSize': 'n2', 'mcsCw0': '2', 'tbs': '1864'}
contents of ["dmrsSib1"]: {'dmrsType': 'Type 1', 'dmrsAddPos': 'pos2', 'maxLength': 'len1', 'dmrsPorts': '0', 'cdmGroupsWoData': '2', 'numFrontLoadSymbs': '1', 'tdL': [2, 6, 9], 'fdK': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
contents of ["iniUlBwp"]: {'bwpId': '0', 'scs': '15KHz', 'cp': 'normal', 'locAndBw': '14025', 'startRb': '0', 'numRbs': '52'}
contents of ["rach"]: {'prachConfId': '27', 'raFormat': '0', 'raX': 1, 'raY': (0,), 'raSubfNumFr1SlotNumFr2': (1, 3, 5, 7, 9), 'raStartingSymb': 0, 'raNumSlotsPerSubfFr1Per60KSlotFr2': 1, 'raNumOccasionsPerSlot': 1, 'raDuration': 0, 'scs': '1.25KHz', 'msg1Fdm': '2', 'msg1FreqStart': '2', 'totNumPreambs': '64', 'ssbPerRachOccasion': 'oneHalf', 'cbPreambsPerSsb': '8', 'msg3Tp': 'disabled', 'raLen': 839, 'raNumRbs': 6, 'raKBar': 7}
output for determining valid PRACH occasions:
contents of validPrachOccasionsPerAssociationPeriod(size=14,minSize=14):
[[0, 0, 9], 0, 0],[[0, 0, 9], 0, 1],[[0, 1, 9], 0, 0],[[0, 1, 9], 0, 1],[[0, 2, 9], 0, 0],[[0, 2, 9], 0, 1],[[0, 3, 9], 0, 0],[[0, 3, 9], 0, 1],[[0, 4, 9], 0, 0],[[0, 4, 9], 0, 1],[[0, 5, 9], 0, 0],[[0, 5, 9], 0, 1],[[0, 6, 9], 0, 0],[[0, 6, 9], 0, 1]
contents of invalidPrachOccasionsPerAssociationPeriod(size=50):
[[0, 0, 7], 0, 0],[[0, 0, 7], 0, 1],[[0, 1, 1], 0, 0],[[0, 1, 1], 0, 1],[[0, 1, 3], 0, 0],[[0, 1, 3], 0, 1],[[0, 1, 5], 0, 0],[[0, 1, 5], 0, 1],[[0, 1, 7], 0, 0],[[0, 1, 7], 0, 1],[[0, 2, 1], 0, 0],[[0, 2, 1], 0, 1],[[0, 2, 3], 0, 0],[[0, 2, 3], 0, 1],[[0, 2, 5], 0, 0],[[0, 2, 5], 0, 1],[[0, 2, 7], 0, 0],[[0, 2, 7], 0, 1],[[0, 3, 1], 0, 0],[[0, 3, 1], 0, 1],[[0, 3, 3], 0, 0],[[0, 3, 3], 0, 1],[[0, 3, 5], 0, 0],[[0, 3, 5], 0, 1],[[0, 3, 7], 0, 0],[[0, 3, 7], 0, 1],[[0, 4, 1], 0, 0],[[0, 4, 1], 0, 1],[[0, 4, 3], 0, 0],[[0, 4, 3], 0, 1],[[0, 4, 5], 0, 0],[[0, 4, 5], 0, 1],[[0, 4, 7], 0, 0],[[0, 4, 7], 0, 1],[[0, 5, 1], 0, 0],[[0, 5, 1], 0, 1],[[0, 5, 3], 0, 0],[[0, 5, 3], 0, 1],[[0, 5, 5], 0, 0],[[0, 5, 5], 0, 1],[[0, 5, 7], 0, 0],[[0, 5, 7], 0, 1],[[0, 6, 1], 0, 0],[[0, 6, 1], 0, 1],[[0, 6, 3], 0, 0],[[0, 6, 3], 0, 1],[[0, 6, 5], 0, 0],[[0, 6, 5], 0, 1],[[0, 6, 7], 0, 0],[[0, 6, 7], 0, 1]

(2) SSB to valid PRACH occasion mapping

#SSB and PRACH occasion mapping
ssb2RachOccasionMap = dict()
if self.nrRachSsbPerRachOccasionM8 < 8:
numRachOccasionPerSsb = 8 // self.nrRachSsbPerRachOccasionM8
count = 0
for issb in range(len(self.ssbSet)):
if self.ssbSet[issb] == '1':
rachOccasions = [validPrachOccasionsPerAssociationPeriod[numRachOccasionPerSsb*count+k] for k in range(numRachOccasionPerSsb)]
cbPreambs = list(range(0, self.nrRachCbPreambsPerSsb))
ssb2RachOccasionMap[issb] = [rachOccasions, cbPreambs]
count = count + 1
else:
numSsbPerRachOccasion = self.nrRachSsbPerRachOccasionM8 // 8
availCbPreambsPerSsb = self.nrRachTotNumPreambs // numSsbPerRachOccasion
count = 0
for issb in range(len(self.ssbSet)):
if self.ssbSet[issb] == '1':
rachOccasions = [validPrachOccasionsPerAssociationPeriod[count // numSsbPerRachOccasion]]
cbPreambs = [availCbPreambsPerSsb*(count%numSsbPerRachOccasion)+k for k in range(self.nrRachCbPreambsPerSsb)]
ssb2RachOccasionMap[issb] = [rachOccasions, cbPreambs]
count = count + 1

Example output:

output of SSB-to-PRACH occasion mapping:
contents of ssb2RachOccasionMap:
issb=0: rachOccasion=[[[0, 0, 9], 0, 0], [[0, 0, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]
issb=2: rachOccasion=[[[0, 1, 9], 0, 0], [[0, 1, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]
issb=3: rachOccasion=[[[0, 2, 9], 0, 0], [[0, 2, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]
issb=4: rachOccasion=[[[0, 3, 9], 0, 0], [[0, 3, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]
issb=5: rachOccasion=[[[0, 4, 9], 0, 0], [[0, 4, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]
issb=6: rachOccasion=[[[0, 5, 9], 0, 0], [[0, 5, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]
issb=7: rachOccasion=[[[0, 6, 9], 0, 0], [[0, 6, 9], 0, 1]], cbPreambs=[0, 1, 2, 3, 4, 5, 6, 7]

(3) PRACH time-domain/freq-domain resource mapping:

time-domain:

#PRACH time/freq domain RE mapping
msg1Hsfn, msg1Sfn, msg1Slot = bestSsbRachOccasion[0]
msg1OccasionInd = bestSsbRachOccasion[1]
msg1FdmInd = bestSsbRachOccasion[2]
scaleTd = self.baseScsTd // self.prachScs
msg1FirstSymbInBaseScsTd = (msg1Slot * self.nrSymbPerSlotNormCp + self.nrRachCfgStartSymb + msg1OccasionInd * self.nrRachCfgDuration) * scaleTd
msg1SymbsInBaseScsTd = [msg1FirstSymbInBaseScsTd+k for k in range(self.nrRachCfgDuration*scaleTd)]

freq-domain:

#determine freq-domain
scaleFd = self.nrIniUlBwpScs // self.baseScsFd
msg1FirstScInBaseScsFd = self.nrCarrierMinGuardBand * self.nrScPerPrb * (self.nrCarrierScs // self.baseScsFd) + self.nrIniUlBwpStartRb * self.nrScPerPrb * scaleFd + (self.nrRachMsg1FreqStart + msg1FdmInd * self.nrRachNumRbs) * self.nrScPerPrb * scaleFd
msg1ScsInBaseScsFd = [msg1FirstScInBaseScsFd+k for k in range(self.nrRachNumRbs*self.nrScPerPrb*scaleFd)]

 

Final note: I'm planning to release first alpha version of '5GNR Resource Grid tool'.

最后

以上就是知性花卷为你收集整理的NG Toolset开发笔记--5GNR Resource Grid(48)的全部内容,希望文章能够帮你解决NG Toolset开发笔记--5GNR Resource Grid(48)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(97)

评论列表共有 0 条评论

立即
投稿
返回
顶部