1. 程式人生 > >NG Toolset開發筆記--5GNR Resource Grid(41)

NG Toolset開發筆記--5GNR Resource Grid(41)

Procedures to calcuclate TBS for PDSCH/PUSCH:

def getTbs(self, sch='pdsch', tp=0, rnti='c-rnti', tab='qam64', td=1, fd=1, mcs=0, layer=1, dmrs=0, xoh=0, scale=1):
        self.ngwin.logEdit.append('---->inside getTbs: sch="%s", tp=%d, rnti="%s", tab="%s", td=%d, fd=%d, mcs=%d, layer=%d, dmrs=%d, xoh=%d, scale=%.2f' % (sch, tp, rnti, tab, td, fd, mcs, layer, dmrs, xoh, scale)) 
        
        if rnti not in ('c-rnti', 'si-rnti', 'ra-rnti', 'tc-rnti', 'msg3'):
            return None
        
        if tab not in ('qam256', 'qam64', 'qam64LowSE'):
            return None
        
        #reset xoh to 0 for PDSCH when rnti='SI-RNTI', 'RA-RNTI' and for Msg3 PUSCH
        #FIXME what's the case for rnti='TC-RNTI'(msg4)?
        if rnti in ('si-rnti', 'ra-rnti', 'tc-rnti', 'msg3'):
            xoh = 0
        
        #reset scale to 1 for PDSCH when rnti is not 'RA-RNTI' and for PUSCH
        if rnti != 'ra-rnti':
            scale = 1
        
        #refer to 3GPP 38.214 vf30
        #5.1.3	Modulation order, target code rate, redundancy version and transport block size determination
        #6.1.4	Modulation order, redundancy version and transport block size determination
        
        #1st step: get Qm and R(x1024)
        if sch == 'pdsch' or (sch == 'pusch' and tp == 0):
            if rnti == 'c-rnti' and tab == 'qam256':
                val = self.nrPdschMcsTabQam256[mcs]
                if val is None:
                    return None
            elif rnti == 'c-rnti' and tab == 'qam64LowSE':
                val = self.nrPdschMcsTabQam64LowSE[mcs]
                if val is None:
                    return None
            else:
                val = self.nrPdschMcsTabQam64[mcs]
                if val is None:
                    return None
            pass
        elif sch == 'pusch' and tp == 1:
            if rnti == 'c-rnti' and tab == 'qam256':
                val = self.nrPdschMcsTabQam256[mcs]
                if val is None:
                    return None
            elif rnti == 'c-rnti' and tab == 'qam64LowSE':
                val = self.nrPuschTpMcsTabQam64LowSE[mcs]
                if val is None:
                    return None
            else:
                val = self.nrPuschTpMcsTabQam64[mcs]
                if val is None:
                    return None
        else:
            return None
        
        Qm, R = val
        #FIXME what's the case for rnti='TC-RNTI'(msg4)?
        if rnti in ('si-rnti', 'ra-rnti', 'tc-rnti') and Qm > 2:
            self.ngwin.logEdit.append('<font color=red><b>[%s]Error</font>: The UE is not expected to decode a PDSCH scheduled with P-RNTI, RA-RNTI, SI-RNTI and Qm > 2! (FIXME)Assume the same rule applies to PDSCH scheduled with TC-RNTI.' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())))
            return None
        
        #2nd step: get N_RE
        N_RE = self.numScPerPrb * td - dmrs - xoh
        N_RE = min(156, N_RE) * fd
        
        #3rd step: get N_info
        N_info = math.ceil(scale * N_RE * R * Qm * layer / 1024)
        if N_info <= 3824:
            #4th step: get TBS
            n = max(3, math.floor(math.log2(N_info)) - 6)
            N_info = max(24, 2 ** n * math.floor(N_info / 2 ** n))
            
            tbs = None
            for i in self.nrTbsTabLessThan3824:
                if i >= N_info:
                    tbs = i
                    break
        else:
            #5th step: get TBS
            n = math.floor(math.log2(N_info - 24)) - 5
            N_info = max(3840, 2 ** n * math.ceil((N_info - 24) / 2 ** n))
            if R <= 256:
                C = math.ceil((N_info + 24) / 3816)
                tbs = 8 * C * math.ceil((N_info + 24) / (8 * C)) - 24
            else:
                if N_info > 8424:
                    C = math.ceil((N_info + 24) / 8424)
                    tbs = 8 * C * math.ceil((N_info + 24) / (8 * C)) - 24
                else:
                    tbs = 8 * math.ceil((N_info + 24) / 8 ) - 24
        
        if rnti == 'si-rnti' and tbs is not None and tbs > 2976:
            self.ngwin.logEdit.append('<font color=red><b>[%s]Error</font>: The UE is not expected to receive a PDSCH assigned by a PDCCH with CRC scrambled by SI-RNTI with a TBS exceeding 2976 bits!' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())))
            return None
        
        return tbs

Example for calculate TBS for PDSCH scheduled with C-RNTI with DCI 1_1:

 td = int(self.nrDci11PdschTimeAllocLEdit.text())
        if self.nrDci11PdschFreqAllocTypeComb.currentText() == 'RA Type1':
            fd = int(self.nrDci11PdschFreqAllocType1LRbsEdit.text())
        else:
            fd = sum([self.rbgsType0Pdsch[i] for i in range(self.bitwidthType0Pdsch) if self.nrDci11PdschFreqAllocFieldEdit.text()[i] == '1'])
            
        tbs = []
        if len(mcsSet) == 1:
            tbs.append(self.getTbs(sch='pdsch', tp=0, rnti='c-rnti', tab=self.nrDedPdschCfgMcsTableComb.currentText(), td=td, fd=fd, mcs=mcsSet[0], layer=len(dmrsPorts), xoh=int(self.nrDedPdschCfgXOverheadComb.currentText()[3:]), scale=1))
        elif len(mcsSet) == 2:
            numAntPortsCw0 = math.floor(len(dmrsPorts) / 2)
            tbs.append(self.getTbs(sch='pdsch', tp=0, rnti='c-rnti', tab=self.nrDedPdschCfgMcsTableComb.currentText(), td=td, fd=fd, mcs=mcsSet[0], layer=numAntPortsCw0, dmrs = 0, xoh=int(self.nrDedPdschCfgXOverheadComb.currentText()[3:]), scale=1))
            tbs.append(self.getTbs(sch='pdsch', tp=0, rnti='c-rnti', tab=self.nrDedPdschCfgMcsTableComb.currentText(), td=td, fd=fd, mcs=mcsSet[1], layer=len(dmrsPorts)-numAntPortsCw0, dmrs = 0, xoh=int(self.nrDedPdschCfgXOverheadComb.currentText()[3:]), scale=1))
        else:
            return

There are still many internal logics left to be implemented: