diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 32876634c0..80f18e98a7 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -168,7 +168,8 @@ (Test4: HARQ test 25% TP 4 rounds), (Test5: HARQ test 33% TP 3 rounds), (Test6: HARQ test 50% TP 2 rounds), - (Test7: 25 PRBs, 15 kHz SCS) + (Test7: 25 PRBs, 15 kHz SCS), + (Test8: 32 PRBs, 120 kHz SCS) nr_dlsim -n100 -R106 -b106 -s5 -n100 -R217 -b217 -s5 @@ -176,8 +177,9 @@ -n100 -s1 -S2 -t25 -n100 -s1 -S2 -t33 -n100 -s5 -S7 -t50 - -n100 -m0 -e0 -R25 -b25 -i 2 1 0 - test1 test2 test3 test4 test5 test6 test7 + -n100 -m0 -e0 -R25 -b25 -i 2 1 0 + -n100 -s5 -m3 -R32 -b32 + test1 test2 test3 test4 test5 test6 test7 test8 PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -400,9 +402,10 @@ (Test9: PUSCH Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols), (Test10: PUSCH Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols), (Test11: 25 PRBs, 15 kHz SCS), - (Test12: MCS 0, low SNR performance) - (Test13: MCS 28, 106 PRBs, Time shift 8) - (Test14: SRS, SNR 40 dB) + (Test12: 32 PRBs, 120 kHz SCS), + (Test13: MCS 0, low SNR performance) + (Test14: MCS 28, 106 PRBs, Time shift 8) + (Test15: SRS, SNR 40 dB) nr_ulsim -n100 -m9 -r106 -s5 -n100 -m16 -s10 @@ -415,10 +418,11 @@ -n100 -s5 -T 2,2 -U 1,2,1,1 -n100 -s5 -a4 -b8 -T 1,2 -U 1,3,1,1 -n100 -u0 -m0 -R25 -r25 -i 1,0 + -n100 -s5 -r32 -R32 -u3 -n100 -m0 -S -0.6 -i 1,0 -n100 -m 28 -R106 -r106 -t90 -s24 -S24 -d 8 -n100 -s40 -E 1 - test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 + test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 9b029657ad..5862c91990 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -423,9 +423,7 @@ int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index) { if (frequency_range == FR1) { int bandwidth_index_to_mhz[] = {5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 90, 100}; - AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz), - "Bandwidth index %d is invalid\n", - bw_index); + AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz), "Bandwidth index %d is invalid\n", bw_index); return bandwidth_index_to_mhz[bw_index]; } else { int bandwidth_index_to_mhz[] = {50, 100, 200, 400}; diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nr_rate_matching.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nr_rate_matching.c index a25b6d4b57..46919e1983 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nr_rate_matching.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nr_rate_matching.c @@ -380,24 +380,22 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm, uint8_t rvidx, uint32_t E) { - uint32_t Ncb, ind, k = 0, Nref, N; - if (C == 0) { - LOG_E(PHY, "nr_rate_matching: invalid parameters (C %d\n", C); + LOG_E(PHY, "nr_rate_matching: invalid parameter C %d\n", C); return -1; } - // Bit selection - N = (BG == 1) ? (66 * Z) : (50 * Z); - + //Bit selection + uint32_t N = (BG == 1) ? (66 * Z) : (50 * Z); + uint32_t Ncb; if (Tbslbrm == 0) Ncb = N; else { - Nref = 3 * Tbslbrm / (2 * C); // R_LBRM = 2/3 + uint32_t Nref = 3 * Tbslbrm / (2 * C); //R_LBRM = 2/3 Ncb = min(N, Nref); } - ind = (index_k0[BG - 1][rvidx] * Ncb / N) * Z; + uint32_t ind = (index_k0[BG - 1][rvidx] * Ncb / N) * Z; #ifdef RM_DEBUG printf("nr_rate_matching_ldpc: E %u, F %u, Foffset %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", @@ -430,6 +428,7 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm, if (ind >= Foffset && ind < (F + Foffset)) ind = F + Foffset; + uint32_t k = 0; if (ind < Foffset) { // case where we have some bits before the filler and the rest after memcpy((void *)e, (void *)(d + ind), Foffset - ind); @@ -476,28 +475,22 @@ int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm, uint32_t F, uint32_t Foffset) { - uint32_t Ncb, ind, k, Nref, N; - -#ifdef RM_DEBUG - int nulled = 0; -#endif - if (C == 0) { - LOG_E(PHY, "nr_rate_matching: invalid parameters (C %d\n", C); + LOG_E(PHY, "nr_rate_matching: invalid parameter C %d\n", C); return -1; } - // Bit selection - N = (BG == 1) ? (66 * Z) : (50 * Z); - + //Bit selection + uint32_t N = (BG == 1) ? (66 * Z) : (50 * Z); + uint32_t Ncb; if (Tbslbrm == 0) Ncb = N; else { - Nref = (3 * Tbslbrm / (2 * C)); // R_LBRM = 2/3 + uint32_t Nref = (3 * Tbslbrm / (2 * C)); //R_LBRM = 2/3 Ncb = min(N, Nref); } - ind = (index_k0[BG - 1][rvidx] * Ncb / N) * Z; + uint32_t ind = (index_k0[BG - 1][rvidx] * Ncb / N) * Z; if (Foffset > E) { LOG_E(PHY, "nr_rate_matching: invalid parameters (Foffset %d > E %d)\n", Foffset, E); return -1; @@ -521,8 +514,7 @@ int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm, if (clear == 1) memset(d, 0, Ncb * sizeof(int16_t)); - k = 0; - + uint32_t k = 0; if (ind < Foffset) for (; (ind < Foffset) && (k < E); ind++) { #ifdef RM_DEBUG @@ -566,6 +558,5 @@ int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm, #endif } } - return 0; } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index fc09f23bd6..e3321a93ad 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -147,10 +147,9 @@ extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration /* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1, g_pmi = 0; -void nr_dlsim_preprocessor(module_id_t module_id, - frame_t frame, - sub_frame_t slot) { +void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) +{ NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0]; AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n"); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; @@ -326,7 +325,6 @@ int main(int argc, char **argv) gNB_MAC_INST *gNB_mac; NR_UE_MAC_INST_t *UE_mac; int cyclic_prefix_type = NFAPI_CP_NORMAL; - int run_initial_sync=0; int loglvl=OAILOG_WARNING; //float target_error_rate = 0.01; @@ -357,7 +355,7 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) { + while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ @@ -537,11 +535,6 @@ int main(int argc, char **argv) gNBthreads[sizeof(gNBthreads)-1]=0; break; - case 'Y': - run_initial_sync=1; - //target_error_rate=0.1; - slot = 0; - break; case 'Z' : filename_csv = strdup(optarg); AssertFatal(filename_csv != NULL, "strdup() error: errno %d\n", errno); @@ -551,6 +544,10 @@ int main(int argc, char **argv) delay = atoi(optarg); break; + case 'H': + slot = atoi(optarg); + break; + default: case 'h': printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", @@ -584,6 +581,7 @@ int main(int argc, char **argv) printf("-f raw file containing RRC configuration (generated by gNB)\n"); printf("-g Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300, e.g. -g A\n"); printf("-h This message\n"); + printf("-H Slot number\n"); printf("-i Change channel estimation technique. Arguments list: Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}\n"); printf("-m Numerology\n"); printf("-n Number of frames to simulate\n"); @@ -606,13 +604,12 @@ int main(int argc, char **argv) printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n"); printf("-X gNB thread pool configuration, n => no threads\n"); - printf("-Y Run initial sync in UE\n"); printf("-Z Output filename (.csv format) for stats\n"); exit (-1); break; } } - +printf("%d\n", slot); logInit(); set_glog(loglvl); /* initialize the sin table */ @@ -648,6 +645,11 @@ int main(int argc, char **argv) fill_scc_sim(scc, &ssb_bitmap, N_RB_DL, N_RB_DL, mu, mu); fix_scc(scc, ssb_bitmap); + frame_structure_t frame_structure = {0}; + frame_type_t frame_type = TDD; + config_frame_structure(mu, scc, get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon), frame_type, &frame_structure); + AssertFatal(is_dl_slot(slot, &frame_structure), "The slot selected is not DL. Can't run DLSIM\n"); + // TODO do a UECAP for phy-sim nr_pdsch_AntennaPorts_t pdsch_AntennaPorts = {0}; pdsch_AntennaPorts.N1 = n_tx > 1 ? n_tx >> 1 : 1; @@ -658,6 +660,7 @@ int main(int argc, char **argv) .minRXTXTIME = 6, .do_CSIRS = 0, .do_SRS = 0, + .maxMIMO_layers = g_nrOfLayers, .force_256qam_off = false, .timer_config.sr_ProhibitTimer = 0, .timer_config.sr_TransMax = 64, @@ -843,11 +846,7 @@ int main(int argc, char **argv) UE->nrLDPC_coding_interface = gNB->nrLDPC_coding_interface; UE->max_ldpc_iterations = max_ldpc_iterations; init_nr_ue_phy_cpu_stats(&UE->phy_cpu_stats); - - if (run_initial_sync==1) - UE->is_synchronized = 0; - else - UE->is_synchronized = 1; + UE->is_synchronized = 1; if (init_nr_ue_signal(UE, 1) != 0) { @@ -1048,15 +1047,13 @@ int main(int argc, char **argv) msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0; msgDataTx->gNB = gNB; - if (run_initial_sync) { - nr_common_signal_procedures(gNB,frame,slot,msgDataTx->ssb[0].ssb_pdu); - } else { - start_meas(&gNB->phy_proc_tx); - phy_procedures_gNB_TX(msgDataTx,frame,slot,1); - stop_meas(&gNB->phy_proc_tx); - } + + start_meas(&gNB->phy_proc_tx); + phy_procedures_gNB_TX(msgDataTx,frame,slot,1); + stop_meas(&gNB->phy_proc_tx); + int txdataF_offset = slot * frame_parms->samples_per_slot_wCP; - + if (n_trials==1) { LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][0][txdataF_offset +2 * frame_parms->ofdm_symbol_size], diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 301beb19f5..5688253b8d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -626,6 +626,11 @@ int main(int argc, char *argv[]) fill_scc_sim(scc, &ssb_bitmap, N_RB_DL, N_RB_DL, mu, mu); fix_scc(scc,ssb_bitmap); + frame_structure_t frame_structure = {0}; + frame_type_t frame_type = TDD; + config_frame_structure(mu, scc, get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon), frame_type, &frame_structure); + AssertFatal(is_ul_slot(slot, &frame_structure), "The slot selected is not UL. Can't run ULSIM\n"); + // TODO do a UECAP for phy-sim const nr_mac_config_t conf = {.pdsch_AntennaPorts = {.N1 = 1, .N2 = 1, .XP = 1}, .pusch_AntennaPorts = n_rx, diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a57d2e0287..730f08dd7d 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -274,15 +274,29 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N scc->dmrs_TypeA_Position = NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2; *scc->ssbSubcarrierSpacing = mu_dl; - struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - if (mu_dl == 0) { - *frequencyInfoDL->absoluteFrequencySSB = 520432; - *frequencyInfoDL->frequencyBandList.list.array[0] = 38; - frequencyInfoDL->absoluteFrequencyPointA = 520000; - } else { - *frequencyInfoDL->absoluteFrequencySSB = 641032; - *frequencyInfoDL->frequencyBandList.list.array[0] = 78; - frequencyInfoDL->absoluteFrequencyPointA = 640000; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_Config = scc->tdd_UL_DL_ConfigurationCommon; + switch (mu_dl) { + case 0 : + *frequencyInfoDL->absoluteFrequencySSB = 520432; + *frequencyInfoDL->frequencyBandList.list.array[0] = 38; + frequencyInfoDL->absoluteFrequencyPointA = 520000; + tdd_UL_DL_Config->pattern1.dl_UL_TransmissionPeriodicity = NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms10; + break; + case 1 : + *frequencyInfoDL->absoluteFrequencySSB = 641032; + *frequencyInfoDL->frequencyBandList.list.array[0] = 78; + frequencyInfoDL->absoluteFrequencyPointA = 640000; + tdd_UL_DL_Config->pattern1.dl_UL_TransmissionPeriodicity = NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; + break; + case 3 : + *frequencyInfoDL->absoluteFrequencySSB = 2071387; + *frequencyInfoDL->frequencyBandList.list.array[0] = 257; + frequencyInfoDL->absoluteFrequencyPointA = 2071003; + tdd_UL_DL_Config->pattern1.dl_UL_TransmissionPeriodicity = NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms1p25; + break; + default : + AssertFatal(false, "Numerolgy %d not supported\n", mu_dl); } *frequencyInfoDL->scs_SpecificCarrierList.list.array[0] = configure_scs_carrier(mu_dl, N_RB_DL); @@ -306,7 +320,19 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N timedomainresourceallocation1); struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; - *frequencyInfoUL->frequencyBandList->list.array[0] = mu_ul ? 78 : 38; + switch (mu_ul) { + case 0 : + *frequencyInfoUL->frequencyBandList->list.array[0] = 38; + break; + case 1 : + *frequencyInfoUL->frequencyBandList->list.array[0] = 78; + break; + case 3 : + *frequencyInfoUL->frequencyBandList->list.array[0] = 257; + break; + default : + AssertFatal(false, "Numerolgy %d not supported\n", mu_ul); + } *frequencyInfoUL->absoluteFrequencyPointA = -1; *frequencyInfoUL->scs_SpecificCarrierList.list.array[0] = configure_scs_carrier(mu_ul, N_RB_UL); *frequencyInfoUL->p_Max = 20; @@ -348,18 +374,15 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N scc->ssb_PositionsInBurst->present = NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; *ssb_bitmap = 0xff; - struct NR_TDD_UL_DL_ConfigCommon *tdd_UL_DL_ConfigurationCommon = scc->tdd_UL_DL_ConfigurationCommon; - tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = mu_dl; + tdd_UL_DL_Config->referenceSubcarrierSpacing = mu_dl; - NR_TDD_UL_DL_Pattern_t *p1 = &tdd_UL_DL_ConfigurationCommon->pattern1; - p1->dl_UL_TransmissionPeriodicity = (mu_dl == 0) ? NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms10 - : NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; + NR_TDD_UL_DL_Pattern_t *p1 = &tdd_UL_DL_Config->pattern1; p1->nrofDownlinkSlots = 7; p1->nrofDownlinkSymbols = 6; p1->nrofUplinkSlots = 2; p1->nrofUplinkSymbols = 4; - struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_ConfigurationCommon->pattern2; + struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_Config->pattern2; if (p2) { p2->dl_UL_TransmissionPeriodicity = 321; p2->nrofDownlinkSlots = -1; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c index 1c35fcea63..3ce0867383 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c @@ -63,95 +63,84 @@ uint32_t nr_compute_tbs(uint16_t Qm, const uint32_t nb_re = min(156, nbp_re) * nb_rb; // Intermediate number of information bits // Rx1024 is tabulated as 10 times the actual code rate - const uint32_t R_5 = R/5; // R can be fractional so we can't divide by 10 + const uint32_t R_5 = R / 5; // R can be fractional so we can't divide by 10 // So we ned to right shift by 11 (10 for x1024 and 1 additional as above) - const uint32_t Ninfo = ((nb_re * R_5 * Qm * Nl)>>11)>>tb_scaling; - - uint32_t nr_tbs=0; + const uint32_t Ninfo = ((nb_re * R_5 * Qm * Nl) >> 11) >> tb_scaling; + uint32_t nr_tbs = 0; uint32_t Np_info, C, n; - if (Ninfo <= NR_MAX_PDSCH_TBS) { n = max(3, floor(log2(Ninfo)) - 6); - Np_info = max(24, (Ninfo>>n)<= Np_info){ - nr_tbs = Tbstable_nr[i]; - break; - } - } - } else { - n = log2(Ninfo-24)-5; - Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){ - C = CEILIDIV((Np_info+24),8424); - nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24; - } else { - nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24; - } - } - } - - LOG_D(NR_MAC, "Ninfo %u nbp_re %d nb_re %d Qm %d, R %d, tbs %d bits\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs); - - return nr_tbs; -} - -//tbslbrm calculation according to 5.4.2.1 of 38.212 -uint32_t nr_compute_tbslbrm(uint16_t table, - uint16_t nb_rb, - uint8_t Nl) { - - uint16_t R, nb_re; - uint16_t nb_rb_lbrm=0; - uint8_t Qm; - int i; - uint32_t nr_tbs=0; - uint32_t Ninfo, Np_info, C; - uint8_t n; - - for (i=0; i<7; i++) { - if (NPRB_LBRM[i] >= nb_rb){ - nb_rb_lbrm = NPRB_LBRM[i]; - break; - } - } - - Qm = ((table == 1)? 8 : 6); - R = 948; - nb_re = 156 * nb_rb_lbrm; - - // Intermediate number of information bits - Ninfo = (nb_re * R * Qm * Nl)>>10; - - if (Ninfo <= NR_MAX_PDSCH_TBS) { - n = max(3, floor(log2(Ninfo)) - 6); - Np_info = max(24, (Ninfo>>n)<> n) << n); + for (int i = 0; i < INDEX_MAX_TBS_TABLE; i++) { if (Tbstable_nr[i] >= Np_info){ nr_tbs = Tbstable_nr[i]; break; } } } else { - n = log2(Ninfo-24)-5; - Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){ + C = CEILIDIV((Np_info + 24), 8424); + nr_tbs = (C << 3) * CEILIDIV((Np_info + 24), (C << 3)) - 24; + } else { + nr_tbs = ((CEILIDIV((Np_info + 24), 8)) << 3) - 24; + } + } + } + + LOG_D(NR_MAC, "Ninfo %u nbp_re %d nb_re %d Qm %d, R %d, tbs %d bits\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs); + return nr_tbs; +} + +//tbslbrm calculation according to 5.4.2.1 of 38.212 +uint32_t nr_compute_tbslbrm(uint16_t table, uint16_t nb_rb, uint8_t Nl) +{ + uint16_t nb_rb_lbrm = 0; + for (int i = 0; i < 7; i++) { + if (NPRB_LBRM[i] >= nb_rb){ + nb_rb_lbrm = NPRB_LBRM[i]; + break; + } + } + + int Qm = (table == 1) ? 8 : 6; + uint32_t R = 948; + uint32_t nb_re = 156 * nb_rb_lbrm; + + // Intermediate number of information bits + uint32_t Ninfo = (nb_re * R * Qm * Nl) >> 10; + uint32_t nr_tbs = 0; + uint32_t Np_info, n; + if (Ninfo <= NR_MAX_PDSCH_TBS) { + n = max(3, floor(log2(Ninfo)) - 6); + Np_info = max(24, (Ninfo >> n) << n); + for (int i = 0; i < INDEX_MAX_TBS_TABLE; i++) { + if (Tbstable_nr[i] >= Np_info){ + nr_tbs = Tbstable_nr[i]; + break; + } + } + } else { + n = log2(Ninfo - 24) - 5; + Np_info = max(3840, (ROUNDIDIV((Ninfo - 24), (1 << n))) << n); + int C; if (R <= 256) { - C = CEILIDIV((Np_info+24),3816); - nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24; + C = CEILIDIV((Np_info + 24), 3816); + nr_tbs = (C << 3) * CEILIDIV((Np_info + 24), (C << 3)) - 24; } else { if (Np_info > 8424){ - C = CEILIDIV((Np_info+24),8424); - nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24; + C = CEILIDIV((Np_info + 24), 8424); + nr_tbs = (C << 3) * CEILIDIV((Np_info + 24), (C << 3)) - 24; } else - nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24; + nr_tbs = ((CEILIDIV((Np_info + 24), 8)) << 3) - 24; } } return nr_tbs; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index fda1dc6c11..415cfc79e3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -500,34 +500,28 @@ int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed) * * @param mu numerology * @param scc pointer to scc - * @param cfg pointer to NFAPI config request + * @param tdd_period TDD period + * @param frame_type type of frame structure (FDD or TDD) * @param fs pointer to the frame structure to update - * - * @return Number of periods in frame */ -static int config_frame_structure(int mu, - NR_ServingCellConfigCommon_t *scc, - nfapi_nr_config_request_scf_t *cfg, - frame_structure_t *fs) +void config_frame_structure(int mu, + NR_ServingCellConfigCommon_t *scc, + uint8_t tdd_period, + uint8_t frame_type, + frame_structure_t *fs) { fs->numb_slots_frame = nr_slots_per_frame[mu]; - if (cfg->cell_config.frame_duplex_type.value == TDD) { - cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG; - cfg->num_tlv++; - cfg->tdd_table.tdd_period.value = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon); - LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value); - fs->numb_period_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value); + if (frame_type == TDD) { + fs->numb_period_frame = get_nb_periods_per_frame(tdd_period); fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame; fs->is_tdd = true; config_tdd_patterns(scc->tdd_UL_DL_ConfigurationCommon, fs); - set_tdd_config_nr(cfg, fs); } else { // FDD fs->is_tdd = false; fs->numb_period_frame = 1; fs->numb_slots_period = nr_slots_per_frame[mu]; } AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n"); - return fs->numb_period_frame; } static void config_common(gNB_MAC_INST *nrmac, @@ -819,7 +813,16 @@ static void config_common(gNB_MAC_INST *nrmac, // Frame structure configuration uint8_t mu = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - config_frame_structure(mu, scc, cfg, &nrmac->frame_structure); + if (cfg->cell_config.frame_duplex_type.value == TDD) { + cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG; + cfg->num_tlv++; + cfg->tdd_table.tdd_period.value = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon); + LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value); + } + frame_structure_t *fs = &nrmac->frame_structure; + config_frame_structure(mu, scc, cfg->tdd_table.tdd_period.value, cfg->cell_config.frame_duplex_type.value, fs); + if (cfg->cell_config.frame_duplex_type.value == TDD) + set_tdd_config_nr(cfg, fs); int nb_tx = config->nb_bfw[0]; // number of tx antennas int nb_beams = config->nb_bfw[1]; // number of beams diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index b7ed84ec9a..ee66bcaf90 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -39,6 +39,11 @@ void set_cset_offset(uint16_t); void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers); int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc); +void config_frame_structure(int mu, + NR_ServingCellConfigCommon_t *scc, + uint8_t tdd_period, + uint8_t frame_type, + frame_structure_t *fs); int get_first_ul_slot(const frame_structure_t *fs, bool mixed); int get_ul_slots_per_period(const frame_structure_t *fs); int get_ul_slots_per_frame(const frame_structure_t *fs); diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 18487e9657..86ad6e3469 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -566,9 +566,8 @@ static void config_csiim(int do_csirs, void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig, const NR_ServingCellConfigCommon_t *scc, const NR_UE_NR_Capability_t *uecap, - int maxMIMO_layers) + int maxMIMO_layers) { - if(!pdsch_servingcellconfig->ext1) pdsch_servingcellconfig->ext1=calloc(1,sizeof(*pdsch_servingcellconfig->ext1)); if(!pdsch_servingcellconfig->ext1->maxMIMO_Layers) @@ -871,6 +870,8 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, fs_cc->supportedBandwidthDL.present = NR_SupportedBandwidth_PR_fr1; fs_cc->supportedBandwidthDL.choice.fr1 = bw; } + fs_cc->maxNumberMIMO_LayersPDSCH = calloc(1, sizeof(*fs_cc->maxNumberMIMO_LayersPDSCH)); + *fs_cc->maxNumberMIMO_LayersPDSCH = NR_MIMO_LayersDL_fourLayers; fs_cc->supportedModulationOrderDL = calloc(1, sizeof(*fs_cc->supportedModulationOrderDL)); *fs_cc->supportedModulationOrderDL = NR_ModulationOrder_qam256; asn1cSeqAdd(&fs->featureSetsDownlinkPerCC->list, fs_cc);