diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 14daa644dfca7ff260037666a74eb974c954cfea..a2c68e9ef6a31d6f560006d43f17847b82c654e1 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1104,7 +1104,8 @@ (Test19: Mapping type A, 3 DMRS Symbols), (Test20: Mapping type B, 4 DMRS Symbols), (Test21: 4x4 MIMO, 1 Layer), - (Test22: 4x4 MIMO, 2 Layers)</desc> + (Test22: 4x4 MIMO, 2 Layers), + (Test23: 25 PRBs, 15 kHz SCS)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1132,8 +1133,9 @@ -n100 -s2 -U 2 0 2 -n100 -s2 -U 2 1 3 -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4 - -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args> - <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22</tags> + -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4 + -n100 -m0 -e0 -R25 -b25 -i</main_exec_args> + <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23</tags> <search_expr_true>PDSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> @@ -1306,9 +1308,10 @@ (Test12: SC-FDMA, 216 PRBs), (Test13: SC-FDMA, 273 PRBs), (Test14: SC-FDMA, 3 DMRS), - (Test15: MCS 19 50 PRBs 2 RX_Antenna) - (Test16: MCS 9 106 PRBs MIMO 2 layers) - (Test17: MCS 9 106 PRBs MIMO 4 layers)</desc> + (Test15: MCS 19 50 PRBs 2 RX_Antenna), + (Test16: MCS 9 106 PRBs MIMO 2 layers), + (Test17: MCS 9 106 PRBs MIMO 4 layers), + (Test18: 25 PRBs, 15 kHz SCS)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1331,9 +1334,9 @@ -n100 -s5 -Z -U 2 0 2 -n100 -m19 -s10 -S15 -z2 -n100 -m9 -r106 -s10 -W2 -y2 -z2 - -n100 -m9 -r106 -s20 -W4 -y4 -z4</main_exec_args> - - <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17</tags> + -n100 -m9 -r106 -s20 -W4 -y4 -z4 + -n100 -u0 -m0 -R25 -r25 -i</main_exec_args> + <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18</tags> <search_expr_true>PUSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> @@ -1344,10 +1347,11 @@ <desc>nr_prachsim Test cases. (Test1: 30kHz SCS, 106 PRBs, Prach format A2), (Test2: 30kHz SCS, 217 PRBs, Prach format A2), (Test3: 30kHz SCS, 273 PRBs, Prach format A2), - (Test4: 30kHz SCS, 106 PRBs, Prach format 0), + (Test4: 30kHz SCS, 106 PRBs, Prach format 0), (Test5: 120kHz SCS, 32 PRBs, Prach format A2), (Test6: 120kHz SCS, 66 PRBs, Prach format A2), - (Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)</desc> + (Test7: 120kHz SCS, 66 PRBs, High Speed Enabled), + (Test8: 15kHz SCS, 25 PRBs)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1357,11 +1361,12 @@ <main_exec_args>-a -s -30 -n 100 -p 63 -R 106 -a -s -30 -n 100 -p 63 -R 217 -a -s -30 -n 100 -p 63 -R 273 - -a -s -30 -n 100 -p 63 -R 106 -c 4 - -a -s -30 -n 100 -p 32 -R 32 -m 3 -c52 - -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52 - -a -s -30 -n 100 -R 66 -m 3 -c52 -H</main_exec_args> - <tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7</tags> + -a -s -30 -n 100 -p 63 -R 106 -c 4 + -a -s -30 -n 100 -p 32 -R 32 -m 3 -c52 + -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52 + -a -s -30 -n 100 -R 66 -m 3 -c52 -H + -a -s -30 -n 100 -p 99 -R 25 -m 0</main_exec_args> + <tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7 nr_prachsim.test8</tags> <search_expr_true>PRACH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index d06f2195ee7921c40cfef5f5e5a1a5acf3885e3c..e448117385a932318358d578e83499c5632853cf 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -80,7 +80,7 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, notifiedFIFO_t *reponseFifo, void (*processingFunc)(void *)) { notifiedFIFO_elt_t *ret; - AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), ""); + AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) calloc(1, sizeof(notifiedFIFO_elt_t)+size+32)), ""); ret->next=NULL; ret->key=key; ret->reponseFifo=reponseFifo; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index fbe757ca300ec1489dd6a67f05cba4b965c1fa29..52578b9d0f651650b655dba68358444b06ff3326 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -719,10 +719,17 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); - if(slot%(fp->slots_per_subframe/2)) - siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); - else - siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + if (fp->slots_per_subframe == 1) { + if (txsymb <= 7) + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + siglen = 2 * (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 2) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + } else { + if(slot%(fp->slots_per_subframe/2)) + siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + } //+ ru->end_of_burst_delay; flags = 3; // end of burst diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index c7638bab0f0a7ca23b4ae2333fb75d108517ae79..9a570095783bcc34c7792114202ea198a1848638 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -673,14 +673,18 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int n_buf = Prx*max_ul_mimo_layers; + int nb_re_pusch = N_RB_UL * NR_NB_SC_PER_RB; +#ifdef __AVX2__ + int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); +#else + int nb_re_pusch2 = nb_re_pusch; +#endif + for (int ULSCH_id=0; ULSCH_id<gNB->number_of_nr_ulsch_max; ULSCH_id++) { pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) ); pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->rxdataF_ext2 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_estimates = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ptrs_phase_per_slot = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); @@ -688,32 +692,29 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->rho = (int32_t ***)malloc16_clear(Prx*sizeof(int32_t**) ); + pusch_vars[ULSCH_id]->rho = (int32_t ***)malloc16(Prx*sizeof(int32_t **) ); pusch_vars[ULSCH_id]->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers*sizeof(int32_t *) ); for (i=0; i<Prx; i++) { - pusch_vars[ULSCH_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); - pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear(NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); for (int j=0; j< max_ul_mimo_layers; j++) { for (int k=0; k<max_ul_mimo_layers; k++) { - pusch_vars[ULSCH_id]->rho[i][j*max_ul_mimo_layers+k]=(int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_UL*12*7*2 ); + pusch_vars[ULSCH_id]->rho[i][j*max_ul_mimo_layers+k]=(int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); } } } for (i=0; i<n_buf; i++) { - pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); - pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); - pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); - pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs - pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size ); pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot); // symbols per slot - pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); - pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*nb_re_pusch2*fp->symbols_per_slot ); } for (i=0; i< max_ul_mimo_layers; i++) { @@ -838,7 +839,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(pusch_vars[ULSCH_id]->llr_layers[i]); for (int i = 0; i < Prx; i++) { free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]); - free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]); for (int j=0; j< max_ul_mimo_layers; j++) { for (int k=0; k<max_ul_mimo_layers; k++) free_and_zero(pusch_vars[ULSCH_id]->rho[i][j*max_ul_mimo_layers+k]); @@ -849,8 +849,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]); - free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]); - free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]); free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i]); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]); @@ -860,11 +858,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) } free_and_zero(pusch_vars[ULSCH_id]->llr_layers); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext); - free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext); - free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates); - free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext); free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time); free_and_zero(pusch_vars[ULSCH_id]->ul_valid_re_per_slot); @@ -928,7 +923,12 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, //gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; gNB->mac_enabled = 1; - if (mu==1) { + if (mu==0) { + fp->dl_CarrierFreq = 2600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 2600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); + fp->nr_band = 38; + // fp->threequarter_fs= 0; + } else if (mu==1) { fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->nr_band = 78; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 238016460ca8557de868f2f202e4e5f8de686dca..fcbbd49b445a206811c8df13ba89b0c4b3c4670c 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -76,7 +76,6 @@ void phy_init_nr_ue_PDSCH(NR_UE_PDSCH *const pdsch, pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); // the allocated memory size is fixed: AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4 @@ -86,7 +85,6 @@ void phy_init_nr_ue_PDSCH(NR_UE_PDSCH *const pdsch, pdsch->rxdataF_uespec_pilots[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); pdsch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 ); pdsch->ptrs_re_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14); - pdsch->dl_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num); pdsch->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t *) ); for (int j=0; j<NR_MAX_NB_LAYERS; j++) { @@ -126,7 +124,6 @@ void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp free_and_zero(pdsch->rxdataF_uespec_pilots[i]); free_and_zero(pdsch->ptrs_phase_per_slot[i]); free_and_zero(pdsch->ptrs_re_per_slot[i]); - free_and_zero(pdsch->dl_ch_ptrs_estimates_ext[i]); free_and_zero(pdsch->rho[i]); } free_and_zero(pdsch->pmi_ext); @@ -149,7 +146,6 @@ void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp free_and_zero(pdsch->dl_ch_magr0); free_and_zero(pdsch->ptrs_phase_per_slot); free_and_zero(pdsch->ptrs_re_per_slot); - free_and_zero(pdsch->dl_ch_ptrs_estimates_ext); } int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index b1a108f24756294a2ce77390db3d667779ae435d..8352a7f5a64a00bb45a2abb8a0e0a7b21b0f6159 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -665,8 +665,9 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) { + const int sample_offset = fp->nb_prefix_samples / fp->ofdm_offset_divisor; for (int i = 0; i < fp->ofdm_symbol_size; i++) { - double poff = -i * 2.0 * M_PI * 144.0 / 2048.0 / fp->ofdm_offset_divisor; + double poff = -i * 2.0 * M_PI * sample_offset / fp->ofdm_symbol_size; double exp_re = cos(poff); double exp_im = sin(-poff); fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767); diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index eb26dfc02bfb6e3b6a222521ec70d3f64ec6e487..139b730ce1bb515046340fef8fc6394d5c22451a 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -34,47 +34,6 @@ #define LOG_I(A,B...) printf(A) #endif*/ -dft_size_idx_t get_dft_size_idx(uint16_t ofdm_symbol_size) -{ - switch (ofdm_symbol_size) { - case 128: - return DFT_128; - - case 256: - return DFT_256; - - case 512: - return DFT_512; - - case 1024: - return DFT_1024; - - case 1536: - return DFT_1536; - - case 2048: - return DFT_2048; - - case 3072: - return DFT_3072; - - case 4096: - return DFT_4096; - - case 6144: - return DFT_6144; - - case 8192: - return DFT_8192; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); - } - - return DFT_SIZE_IDXTABLESIZE; -} - int nr_slot_fep(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, @@ -96,7 +55,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, nb_prefix_samples0 = frame_parms->nb_prefix_samples; } - dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); // This is for misalignment issues int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); @@ -195,7 +154,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, } unsigned int frame_length_samples = frame_parms->samples_per_frame; - dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); // This is for misalignment issues int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); @@ -289,7 +248,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples; unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; - dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); // This is for misalignment issues int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 9e2b3d2d4e0c5f5f675d61a59670f68658802e2d..7b526876da771e997b4343a2413b6ce15f12fef4 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -665,6 +665,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = ch_0 / 4; ch[1] = ch_1 / 4; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch; + ul_ch+=24; +#else multadd_real_vector_complex_scalar(filt8_avlip0, ch, ul_ch, @@ -682,6 +686,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); ul_ch -= 24; +#endif for (pilot_cnt=4; pilot_cnt<4*(nb_rb_pusch-1); pilot_cnt += 4) { @@ -716,6 +721,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = ch_0 / 4; ch[1] = ch_1 / 4; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch; + ul_ch+=24; +#else ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 @@ -737,6 +746,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); ul_ch -= 16; +#endif } // Last PRB ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; @@ -770,6 +780,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = ch_0 / 4; ch[1] = ch_1 / 4; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch; + ul_ch+=24; +#else ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 @@ -784,6 +798,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch, ul_ch, 8); +#endif } #ifdef DEBUG_PUSCH ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; @@ -890,7 +905,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, /*------------------------------------------------------------------------------------------------------- */ nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb, rel15_ul->rnti, - (int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch], nr_tti_rx, symbol,frame_parms->ofdm_symbol_size, (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)], diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index c65ca3799d6348c81c39fae8a9a2d627f6fcedfa..b78a89b12c8085304c26b6f2bee0345b09557269 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -120,8 +120,6 @@ EXTERN time_stats_t generic_time[TIME_LAST]; /************** FUNCTION ******************************************/ -idft_size_idx_t get_idft(int ofdm_symbol_size); -dft_size_idx_t get_dft(int ofdm_symbol_size); void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue); void free_context_synchro_nr(void); void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue); diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index 68134eb02ddb61b2dd7d63b54180cebc05bd64e1..5df4a25656f1cf12f2356c26501c3ae6a6304b87 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -230,7 +230,6 @@ int8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, ui * dmrsConfigType: DMRS configuration type * nb_rb : No. of resource blocks * rnti : RNTI - * ptrs_ch_p : pointer to ptrs channel structure * Ns : * symbol : OFDM symbol * ofdm_symbol_size: OFDM Symbol Size @@ -249,7 +248,6 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t dmrsConfigType, uint16_t nb_rb, uint16_t rnti, - int16_t *ptrs_ch_p, unsigned char Ns, unsigned char symbol, uint16_t ofdm_symbol_size, @@ -269,6 +267,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, } uint16_t sc_per_symbol = (nb_rb + K_ptrs - 1)/K_ptrs; c16_t ptrs_p[(1 + sc_per_symbol/4)*4]; + c16_t ptrs_ch_p[(1 + sc_per_symbol/4)*4]; c16_t dmrs_comp_p[(1 + sc_per_symbol/4)*4]; double abs = 0.0; double real = 0.0; @@ -306,13 +305,13 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, *ptrs_sc = re_cnt; /*Multiple compensated data with conj of PTRS */ - mult_cpx_vector((int16_t*)dmrs_comp_p, (int16_t*)ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted + mult_cpx_vector((int16_t*)dmrs_comp_p, (int16_t*)ptrs_p, (int16_t*)ptrs_ch_p, (1 + sc_per_symbol/4)*4, 15); // 2^15 shifted /* loop over all ptrs sub carriers in a symbol */ /* sum the error vector */ for(int i = 0;i < sc_per_symbol; i++) { - real+= ptrs_ch_p[(2*i)]; - imag+= ptrs_ch_p[(2*i)+1]; + real += ptrs_ch_p[i].r; + imag += ptrs_ch_p[i].i; } #ifdef DEBUG_PTRS alpha = atan(imag/real); diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h index 41acde0d0648ecbef152dfae6a7e39aca0e614c0..f46c5c7aeecb65e28740d9616d5ea8b2931008d8 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.h +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -96,7 +96,6 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t dmrsConfigType, uint16_t nb_rb, uint16_t rnti, - int16_t *ptrs_ch_p, unsigned char Ns, unsigned char symbol, uint16_t ofdm_symbol_size, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index b12a58526d9a202ae842aedc5e4f99d9fe8e78c1..eb012532ce6ffd2799ed9149760a63a5f982750b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -175,11 +175,19 @@ void rx_nr_prach_ru(RU_t *ru, int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; int sample_offset_slot; - if (!(slot%(fp->slots_per_subframe/2))) - sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); - else - sample_offset_slot = (prachStartSymbol==0?0:prachStartSymbol*(fp->ofdm_symbol_size+fp->nb_prefix_samples)); - //to be checked for mu=0; + if (prachStartSymbol == 0) { + sample_offset_slot = 0; + } else if (fp->slots_per_subframe == 1) { + if (prachStartSymbol <= 7) + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + else + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2; + } else { + if (!(slot%(fp->slots_per_subframe/2))) + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + else + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; + } LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion); @@ -193,89 +201,167 @@ void rx_nr_prach_ru(RU_t *ru, prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2,fp,0)+sample_offset_slot-ru->N_TA_offset]; } - idft_size_idx_t dftsize; - int dftlen=0; + int reps; + int Ncp; + int dftlen; int mu = fp->numerology_index; - int Ncp = 0; - int16_t *prach2; if (prach_sequence_length == 0) { LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n", ru->idx,frame,slot2,prachFormat,msg1_frequencystart); - AssertFatal(prachFormat<4,"Illegal prach format %d for length 839\n",prachFormat); switch (prachFormat) { case 0: + reps = 1; Ncp = 3168; + dftlen = 24576; break; - + case 1: + reps = 2; Ncp = 21024; + dftlen = 24576; break; - + case 2: + reps = 4; Ncp = 4688; + dftlen = 24576; break; - + case 3: + reps = 4; Ncp = 3168; + dftlen = 6144; + break; + + default: + AssertFatal(1==0, "Illegal prach format %d for length 839\n", prachFormat); break; - } } else { LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n", ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol); - switch (prachFormat) { case 4: //A1 - Ncp = 288/(1<<mu); + reps = 2; + Ncp = 288 >> mu; break; - + case 5: //A2 - Ncp = 576/(1<<mu); + reps = 4; + Ncp = 576 >> mu; break; - + case 6: //A3 - Ncp = 864/(1<<mu); + reps = 6; + Ncp = 864 >> mu; break; - + case 7: //B1 - Ncp = 216/(1<<mu); - break; - + reps = 2; + Ncp = 216 >> mu; + break; + /* // B2 and B3 do not exist in FAPI case 4: //B2 - Ncp = 360/(1<<mu); + reps = 4; + Ncp = 360 >> mu; break; - + case 5: //B3 - Ncp = 504/(1<<mu); + reps = 6; + Ncp = 504 >> mu; break; */ + case 8: //B4 - Ncp = 936/(1<<mu); + reps = 12; + Ncp = 936 >> mu; break; - + case 9: //C0 - Ncp = 1240/(1<<mu); + reps = 1; + Ncp = 1240 >> mu; break; - + case 10: //C2 - Ncp = 2048/(1<<mu); + reps = 4; + Ncp = 2048 >> mu; break; - + default: AssertFatal(1==0,"unknown prach format %x\n",prachFormat); break; } + dftlen = 2048 >> mu; + } + + //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary + if(fp->numerology_index == 0) { + if (prachStartSymbol == 0 || prachStartSymbol == 7) + Ncp += 16; + } + else { + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + Ncp += 16; } + + switch(fp->samples_per_subframe) { + case 7680: + // 5 MHz @ 7.68 Ms/s + Ncp >>= 2; + dftlen >>= 2; + break; + + case 15360: + // 10, 15 MHz @ 15.36 Ms/s + Ncp >>= 1; + dftlen >>= 1; + break; + + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + Ncp = Ncp; + dftlen = dftlen; + break; + + case 46080: + // 40 MHz @ 46.08 Ms/s + Ncp = (Ncp*3)/2; + dftlen = (dftlen*3)/2; + break; + + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + Ncp <<= 1; + dftlen <<= 1; + break; + + case 92160: + // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s + Ncp *= 3; + dftlen *= 3; + break; + + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s + Ncp <<= 2; + dftlen <<= 2; + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); + } + + const idft_size_idx_t dftsize = get_dft(dftlen); + // Do forward transform if (LOG_DEBUGFLAG(PRACH)) { - LOG_D(PHY,"rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d\n",ru->nb_rx, Ncp); + LOG_D(PHY, "rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d dftlen:%d\n", ru->nb_rx, Ncp, dftlen); } - // Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below int kbar = 1; @@ -299,357 +385,13 @@ void rx_nr_prach_ru(RU_t *ru, k*=K; k+=kbar; - int reps=1; - for (int aa=0; aa<ru->nb_rx; aa++) { AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa); // do DFT - if (mu==1) { - switch(fp->samples_per_subframe) { - case 15360: - // 10, 15 MHz @ 15.36 Ms/s - prach2 = prach[aa] + (1*Ncp); // Ncp is for 30.72 Ms/s, so divide by 2 to bring to 15.36 Ms/s and multiply by 2 for I/Q - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=12288; - dft(DFT_12288,prach2,rxsigF[aa],1); - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_12288,prach2+(24576*2),rxsigF[aa]+(24576*2),1); - dft(DFT_12288,prach2+(24576*3),rxsigF[aa]+(24576*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=3072; - for (int i=0;i<4;i++) dft(DFT_3072,prach2+(i*3072*2),rxsigF[aa]+(i*3072*2),1); - reps=4; - } - } else { // 839 sequence - if (prachStartSymbol == 0) prach2+=16; // 8 samples @ 15.36 Ms/s in first symbol of each half subframe (15/30 kHz only) - - dftlen=512; - dft(DFT_512,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_512,prach2+1024,rxsigF[aa]+1024,1); - reps++; - } - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_512,prach2+1024*2,rxsigF[aa]+1024*2,1); - dft(DFT_512,prach2+1024*3,rxsigF[aa]+1024*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_512,prach2+1024*4,rxsigF[aa]+1024*4,1); - dft(DFT_512,prach2+1024*5,rxsigF[aa]+1024*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_512,prach2+(1024*i),rxsigF[aa]+(1024*i),1); - reps+=6; - } - } - break; - - case 30720: - // 20, 25, 30 MHz @ 30.72 Ms/s - prach2 = prach[aa] + (2*Ncp); // Ncp is for 30.72 Ms/s, so just multiply by 2 for I/Q - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=24576; - dft(DFT_24576,prach2,rxsigF[aa],1); - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_24576,prach2+(49152*2),rxsigF[aa]+(49152*2),1); - dft(DFT_24576,prach2+(49152*3),rxsigF[aa]+(49152*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=6144; - for (int i=0;i<4;i++) dft(DFT_6144,prach2+(i*6144*2),rxsigF[aa]+(i*6144*2),1); - reps=4; - } - } else { // 839 sequence - if (prachStartSymbol == 0) prach2+=32; // 16 samples @ 30.72 Ms/s in first symbol of each half subframe (15/30 kHz only) - - dftlen=1024; - dft(DFT_1024,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_1024,prach2+2048,rxsigF[aa]+2048,1); - reps++; - } - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_1024,prach2+2048*2,rxsigF[aa]+2048*2,1); - dft(DFT_1024,prach2+2048*3,rxsigF[aa]+2048*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_1024,prach2+2048*4,rxsigF[aa]+2048*4,1); - dft(DFT_1024,prach2+2048*5,rxsigF[aa]+2048*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_1024,prach2+(2048*i),rxsigF[aa]+(2048*i),1); - reps+=6; - } - } - break; - - case 61440: - // 40, 50, 60 MHz @ 61.44 Ms/s - prach2 = prach[aa] + (4*Ncp); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=49152; - dft(DFT_49152,prach2,rxsigF[aa],1); - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1); - dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=12288; - for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); - reps=4; - } - } else { // 839 sequence - if (prachStartSymbol == 0) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) - - dftlen=2048; - dft(DFT_2048,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); - reps++; - } - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); - dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); - dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); - reps+=6; - } - } - break; - - case 46080: - // 40 MHz @ 46.08 Ms/s - prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=36864; - dft(DFT_36864,prach2,rxsigF[aa],1); - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1); - dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=9216; - for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); - reps=4; - } - } else { // 839 sequence - if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) - - dftlen=1536; - dft(DFT_1536,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); - reps++; - } - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); - dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); - dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); - reps+=6; - } - } - break; - - case 122880: - // 70, 80, 90, 100 MHz @ 122.88 Ms/s - prach2 = prach[aa] + (8*Ncp); - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=98304; - dft(DFT_98304,prach2,rxsigF[aa],1); - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1); - dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=24576; - for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); - reps=4; - } - } else { // 839 sequence - if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - - dftlen=4096; - dft(DFT_4096,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); - dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); - dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1); - reps+=6; - } - } - break; - - case 92160: - // 80, 90 MHz @ 92.16 Ms/s - prach2 = prach[aa] + (6*Ncp); - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=73728; - dft(DFT_73728,prach2,rxsigF[aa],1); - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_73728,prach2+147456,rxsigF[aa]+147456,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_73728,prach2+(147456*2),rxsigF[aa]+(147456*2),1); - dft(DFT_73728,prach2+(147456*3),rxsigF[aa]+(147456*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=18432; - for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); - reps=4; - } - } else { - if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - - dftlen=3072; - dft(DFT_3072,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); - dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); - dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); - reps+=6; - } - } - break; - default: - AssertFatal(1==0,"sample_rate %f MHz not support for NR PRACH yet\n", fp->samples_per_subframe / 1000.0); - } - } - else if (mu==3) { - if (fp->threequarter_fs) { - AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); - } - if (prach_sequence_length == 0) { - AssertFatal(1==0,"long prach not supported for numerology %d\n",mu); - } - if (fp->N_RB_UL == 32) { - prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 for 61.44Msps - if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) - prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe - dftlen=512; - dftsize = DFT_512; - } - else if (fp->N_RB_UL == 66) { - prach2 = prach[aa] + (Ncp<<3); // Ncp is for 30.72 Ms/s, so multiply by 4 for I/Q, and 2 for 122.88Msps - if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) - prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe - dftlen=1024; - dftsize = DFT_1024; - } - else { - AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); - } - - dft(dftsize,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(dftsize,prach2+dftlen*2,rxsigF[aa]+dftlen*2,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(dftsize,prach2+dftlen*4,rxsigF[aa]+dftlen*4,1); - dft(dftsize,prach2+dftlen*6,rxsigF[aa]+dftlen*6,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(dftsize,prach2+dftlen*8,rxsigF[aa]+dftlen*8,1); - dft(dftsize,prach2+dftlen*10,rxsigF[aa]+dftlen*10,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) - dft(dftsize,prach2+(dftlen*2*i),rxsigF[aa]+(dftlen*2*i),1); - reps+=6; - } - } - else { - AssertFatal(1==0,"Numerology not supported\n"); - } + int16_t *prach2 = prach[aa] + (2*Ncp); // times 2 for complex samples + for (int i = 0; i < reps; i++) + dft(dftsize, prach2 + 2*dftlen*i, rxsigF[aa] + 2*dftlen*i, 1); //LOG_M("ru_rxsigF_tmp.m","rxsFtmp", rxsigF[aa], dftlen*2*reps, 1, 1); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 3b4ce9a42354c76b127bc338bbc822c3974f95f3..037851be0c388f218e7561e2252a1787ba79e4ad 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -34,6 +34,7 @@ //#define DEBUG_PDSCH //#define DEBUG_PDCCH +#define NO_INTERP 1 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, @@ -692,7 +693,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, k = bwp_start_subcarrier; int re_offset = k; -#ifdef DEBUG_CH +#ifdef DEBUG_PDSCH printf("PDSCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -1244,6 +1245,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = ch_0 / 6; ch[1] = ch_1 / 6; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)dl_ch)[i] = *(int32_t*)ch; + dl_ch+=24; +#else multadd_real_vector_complex_scalar(filt8_avlip0, ch, dl_ch, @@ -1261,6 +1266,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); dl_ch -= 24; +#endif for (pilot_cnt=6; pilot_cnt<6*(nb_rb_pdsch-1); pilot_cnt += 6) { @@ -1308,6 +1314,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = ch_0 / 6; ch[1] = ch_1 / 6; + +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)dl_ch)[i] = *(int32_t*)ch; + dl_ch+=24; +#else dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 @@ -1329,6 +1340,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); dl_ch -= 16; +#endif } ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; @@ -1375,6 +1387,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = ch_0 / 6; ch[1] = ch_1 / 6; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)dl_ch)[i] = *(int32_t*)ch; + dl_ch+=24; +#else dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 @@ -1389,6 +1405,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 8); +#endif } else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB int32_t ch_0, ch_1; @@ -1424,6 +1441,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = ch_0 / 4; ch[1] = ch_1 / 4; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)dl_ch)[i] = *(int32_t*)ch; + dl_ch+=24; +#else multadd_real_vector_complex_scalar(filt8_avlip0, ch, dl_ch, @@ -1441,6 +1462,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); dl_ch -= 24; +#endif for (pilot_cnt=4; pilot_cnt<4*(nb_rb_pdsch-1); pilot_cnt += 4) { int32_t ch_0, ch_1; @@ -1476,6 +1498,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = ch_0 / 4; ch[1] = ch_1 / 4; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)dl_ch)[i] = *(int32_t*)ch; + dl_ch+=24; +#else dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 @@ -1497,6 +1523,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); dl_ch -= 16; +#endif } ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; @@ -1530,6 +1557,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = ch_0 / 4; ch[1] = ch_1 / 4; +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)dl_ch)[i] = *(int32_t*)ch; + dl_ch+=24; +#else dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 @@ -1544,6 +1575,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 8); +#endif } #ifdef DEBUG_PDSCH dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; @@ -1673,7 +1705,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /*------------------------------------------------------------------------------------------------------- */ nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb, rnti, - (int16_t *)&pdsch_vars[gNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch], nr_slot_rx, symbol,frame_parms->ofdm_symbol_size, (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 4927fe37a2516eac1dd8d6524067f8c5cf350cdf..8437b8f8f3782eda710138cffe054c74ea02a40f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -67,7 +67,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found; uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0; uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=INT16_MAX, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx; - int16_t prach_tmp[98304*2*4] __attribute__((aligned(32))); + int16_t prach_tmp[(4688+4*24576)*4*2] __attribute__((aligned(32))); int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; int32_t Xu_re, Xu_im; @@ -102,10 +102,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, ue->X_u); - if (slot % (fp->slots_per_subframe / 2) == 0) - sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); - else - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; + if (prachStartSymbol == 0) { + sample_offset_slot = 0; + } else if (fp->slots_per_subframe == 1) { + if (prachStartSymbol <= 7) + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + else + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2; + } else { + if (slot % (fp->slots_per_subframe / 2) == 0) + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + else + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; + } prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot; @@ -232,897 +241,254 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t preamble_offset, first_nonzero_root_idx); - Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; - - #if defined (PRACH_WRITE_OUTPUT_DEBUG) - LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1); - #endif - - /******************************************************** - * - * In function init_prach_tables: - * to compute quantized roots of unity ru(n) = 32767 * exp j*[ (2 * PI * n) / N_ZC ] - * - * In compute_prach_seq: - * to calculate Xu = DFT xu = xu (inv_u*k) * Xu[0] (This is a Zadoff-Chou sequence property: DFT ZC sequence is another ZC sequence) - * - * In generate_prach: - * to do the cyclic-shifted DFT by multiplying Xu[k] * ru[k*preamble_shift] as: - * If X[k] = DFT x(n) -> X_shifted[k] = DFT x(n+preamble_shift) = X[k] * exp -j*[ (2*PI*k*preamble_shift) / N_ZC ] - * - *********************************************************/ - - if (mu==1) { - switch(fp->samples_per_subframe) { - case 15360: - // 10, 15 MHz @ 15.36 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 12288; - if (prach_fmt_id == 3) - dftlen = 3072; - } else { // 839 sequence - dftlen = 512; - } - break; - - case 30720: - // 20, 25, 30 MHz @ 30.72 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 24576; - if (prach_fmt_id == 3) - dftlen = 6144; - } else { // 839 sequence - dftlen = 1024; - } - break; - - case 46080: - // 40 MHz @ 46.08 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 36864; - if (prach_fmt_id == 3) - dftlen = 9216; - } else { // 839 sequence - dftlen = 1536; - } - break; - - case 61440: - // 40, 50, 60 MHz @ 61.44 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 49152; - if (prach_fmt_id == 3) - dftlen = 12288; - } else { // 839 sequence - dftlen = 2048; - } - break; - - case 92160: - // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 73728; - if (prach_fmt_id == 3) - dftlen = 18432; - } else { // 839 sequence - dftlen = 3072; - } - break; - - case 122880: - // 70, 80, 90, 100 MHz @ 122.88 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 98304; - if (prach_fmt_id == 3) - dftlen = 24576; - } else { // 839 sequence - dftlen = 4096; - } - break; - - default: - AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); - } - } - else if (mu==3) { - if (fp->threequarter_fs) - AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); - - if (prach_sequence_length == 0) - AssertFatal(1==0,"long prach not supported for numerology %d\n",mu); - - if (fp->N_RB_UL == 32) - dftlen=512; - else if (fp->N_RB_UL == 66) - dftlen=1024; - else - AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); - } - - - for (offset=0,offset2=0; offset<N_ZC; offset++,offset2+=preamble_shift) { - - if (offset2 >= N_ZC) - offset2 -= N_ZC; - - Xu_re = (((int32_t)Xu[offset<<1]*amp)>>15); - Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15); - prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15; - prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15; - - if (k==dftlen) k=0; - } - - #if defined (PRACH_WRITE_OUTPUT_DEBUG) - LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1); - LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1); - #endif - + // Ncp and dftlen here is given in terms of T_s wich is 30.72MHz sampling if (prach_sequence_length == 0) { - - AssertFatal(prach_fmt_id < 4, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id); - - // Ncp here is given in terms of T_s wich is 30.72MHz sampling switch (prach_fmt_id) { case 0: Ncp = 3168; + dftlen = 24576; break; + case 1: Ncp = 21024; + dftlen = 24576; break; + case 2: Ncp = 4688; + dftlen = 24576; break; + case 3: Ncp = 3168; + dftlen = 6144; break; - } + default: + AssertFatal(1==0, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id); + break; + } } else { - switch (prach_fmt_id) { case 4: //A1 - Ncp = 288/(1<<mu); + Ncp = 288 >> mu; break; + case 5: //A2 - Ncp = 576/(1<<mu); + Ncp = 576 >> mu; break; + case 6: //A3 - Ncp = 864/(1<<mu); + Ncp = 864 >> mu; break; + case 7: //B1 - Ncp = 216/(1<<mu); - break; + Ncp = 216 >> mu; + break; + /* case 4: //B2 - Ncp = 360/(1<<mu); + Ncp = 360 >> mu; break; + case 5: //B3 - Ncp = 504/(1<<mu); + Ncp = 504 >> mu; break; */ + case 8: //B4 - Ncp = 936/(1<<mu); + Ncp = 936 >> mu; break; + case 9: //C0 - Ncp = 1240/(1<<mu); + Ncp = 1240 >> mu; break; + case 10: //C2 - Ncp = 2048/(1<<mu); + Ncp = 2048 >> mu; break; + default: AssertFatal(1==0,"Unknown PRACH format ID %d\n", prach_fmt_id); break; } + dftlen = 2048 >> mu; } - #ifdef NR_PRACH_DEBUG - LOG_D(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen); - #endif - //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary - uint8_t use_extended_prach_prefix = 0; if(fp->numerology_index == 0) { if (prachStartSymbol == 0 || prachStartSymbol == 7) - use_extended_prach_prefix = 1; + Ncp += 16; } else { if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) - use_extended_prach_prefix = 1; + Ncp += 16; } - if (mu == 3) { - switch (fp->samples_per_subframe) { - case 61440: // 32 PRB case, 61.44 Msps - Ncp<<=1; //to account for 61.44Mbps - // This is after cyclic prefix - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_sequence_length == 0) - AssertFatal(1==0,"no long PRACH for this PRACH size %d\n",fp->N_RB_UL); - else { - if (use_extended_prach_prefix) - Ncp+=32; // 16*kappa, kappa=2 for 61.44Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - idft(IDFT_512,prachF,prach2,1); - // here we have |empty | Prach512 | - if (prach_fmt_id != 9) { - memmove(prach2+(512<<1),prach2,(512<<2)); - prach_len = (512*2)+Ncp; - } - else prach_len = (512*1)+Ncp; - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have |Prefix | Prach512 | Prach512 (if ! 0xc0) | - } else if (prach_fmt_id == 5) { // 6x512 - idft(IDFT_512,prachF,prach2,1); - // here we have |empty | Prach512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have |empty | Prach512 | Prach512| empty512 | empty512 | - memmove(prach2+(512<<2),prach2,(512<<3)); - // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have |Prefix | Prach512 | - prach_len = (512*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x512 - idft(IDFT_512,prachF,prach2,1); - // here we have |empty | Prach512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have |empty | Prach512 | Prach512| empty512 | empty512 | empty512 | empty512 - memmove(prach2+(512<<2),prach2,(512<<3)); - // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | empty512 | empty512 - memmove(prach2+(512<<3),prach2,(512<<3)); - // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have |Prefix | Prach512 | - prach_len = (512*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x512 - idft(IDFT_512,prachF,prach2,1); - // here we have |empty | Prach512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have |empty | Prach512 | Prach512| empty512 | empty512 | empty512 | empty512 - memmove(prach2+(512<<2),prach2,(512<<3)); - // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | empty512 | empty512 - memmove(prach2+(512<<3),prach2,(512<<3)); - // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 - memmove(prach2+(512<<1)*6,prach2,(512<<2)*6); - // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512| - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have |Prefix | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512| - prach_len = (512*12)+Ncp; - } - } - break; + switch(fp->samples_per_subframe) { + case 7680: + // 5 MHz @ 7.68 Ms/s + Ncp >>= 2; + dftlen >>= 2; + break; - case 122880: // 66 PRB case, 122.88 Msps - Ncp<<=2; //to account for 122.88Mbps - // This is after cyclic prefix - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_sequence_length == 0) - AssertFatal(1==0,"no long PRACH for this PRACH size %d\n",fp->N_RB_UL); - else { - if (use_extended_prach_prefix) - Ncp+=64; // 16*kappa, kappa=4 for 122.88Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - idft(IDFT_1024,prachF,prach2,1); - // here we have |empty | Prach1024 | - if (prach_fmt_id != 9) { - memmove(prach2+(1024<<1),prach2,(1024<<2)); - prach_len = (1024*2)+Ncp; - } - else prach_len = (1024*1)+Ncp; - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have |Prefix | Prach1024 | Prach1024 (if ! 0xc0) | - } else if (prach_fmt_id == 5) { // 6x1024 - idft(IDFT_1024,prachF,prach2,1); - // here we have |empty | Prach1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | - memmove(prach2+(1024<<2),prach2,(1024<<3)); - // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have |Prefix | Prach1024 | - prach_len = (1024*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x1024 - idft(IDFT_1024,prachF,prach2,1); - // here we have |empty | Prach1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | empty1024 | empty1024 - memmove(prach2+(1024<<2),prach2,(1024<<3)); - // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | empty1024 | empty1024 - memmove(prach2+(1024<<3),prach2,(1024<<3)); - // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have |Prefix | Prach1024 | - prach_len = (1024*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x1024 - idft(IDFT_1024,prachF,prach2,1); - // here we have |empty | Prach1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | empty1024 | empty1024 - memmove(prach2+(1024<<2),prach2,(1024<<3)); - // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | empty1024 | empty1024 - memmove(prach2+(1024<<3),prach2,(1024<<3)); - // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 - memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6); - // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024| - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have |Prefix | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024| - prach_len = (1024*12)+Ncp; - } - } - break; + case 15360: + // 10, 15 MHz @ 15.36 Ms/s + Ncp >>= 1; + dftlen >>= 1; + break; - default: - AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); - } - } else if (mu == 1) { - switch (fp->samples_per_subframe) { - case 15360: // full sampling @ 15.36 Ms/s - Ncp = Ncp/2; // to account for 15.36 Ms/s - // This is after cyclic prefix - prach2 = prach+(2*Ncp); // times 2 for complex samples - if (prach_sequence_length == 0){ - if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s - idft(IDFT_12288,prachF,prach2,1); - // here we have | empty | Prach12288 | - memmove(prach,prach+(12288<<1),(Ncp<<2)); - // here we have | Prefix | Prach12288 | - prach_len = 12288+Ncp; - } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s - idft(IDFT_12288,prachF,prach2,1); - // here we have | empty | Prach12288 | empty12288 | - memmove(prach2+(12288<<1),prach2,(12288<<2)); - // here we have | empty | Prach12288 | Prach12288 | - memmove(prach,prach+(12288<<2),(Ncp<<2)); - // here we have | Prefix | Prach12288 | Prach12288 | - prach_len = (12288*2)+Ncp; - } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s - idft(IDFT_12288,prachF,prach2,1); - // here we have | empty | Prach12288 | empty12288 | empty12288 | empty12288 | - memmove(prach2+(12288<<1),prach2,(12288<<2)); - // here we have | empty | Prach12288 | Prach12288 | empty12288 | empty12288 | - memmove(prach2+(12288<<2),prach2,(12288<<3)); - // here we have | empty | Prach12288 | Prach12288 | Prach12288 | Prach12288 | - memmove(prach,prach+(12288<<3),(Ncp<<2)); - // here we have | Prefix | Prach12288 | Prach12288 | Prach12288 | Prach12288 | - prach_len = (12288*4)+Ncp; - } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 3072 samples @ 15.36 Ms/s - idft(IDFT_3072,prachF,prach2,1); - // here we have | empty | Prach3072 | empty3072 | empty3072 | empty3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have | empty | Prach3072 | Prach3072 | empty3072 | empty3072 | - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have | empty | Prach3072 | Prach3072 | Prach3072 | Prach3072 | - memmove(prach,prach+(3072<<3),(Ncp<<2)); - // here we have | Prefix | Prach3072 | Prach3072 | Prach3072 | Prach3072 | - prach_len = (3072*4)+Ncp; - } - } else { // short PRACH sequence - if (use_extended_prach_prefix) - Ncp += 8; // 16*kappa, kappa=0.5 for 15.36 Ms/s - prach2 = prach+(2*Ncp); // times 2 for complex samples - if (prach_fmt_id == 9) { - idft(IDFT_512,prachF,prach2,1); - // here we have | empty | Prach512 | - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have | Prefix | Prach512 | - prach_len = (512*1)+Ncp; - } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { - idft(IDFT_512,prachF,prach2,1); - // here we have | empty | Prach512 | empty512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have | empty | Prach512 | Prach512 | - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have | Prefix | Prach512 | Prach512 | - prach_len = (512*2)+Ncp; - } else if (prach_fmt_id == 5) { // 4x512 - idft(IDFT_512,prachF,prach2,1); - // here we have | empty | Prach512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | - memmove(prach2+(512<<2),prach2,(512<<3)); - // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | - prach_len = (512*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x512 - idft(IDFT_512,prachF,prach2,1); - // here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<2),prach2,(512<<3)); - // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | - memmove(prach2+(512<<3),prach2,(512<<3)); - // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | - prach_len = (512*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x512 - idft(IDFT_512,prachF,prach2,1); - // here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<1),prach2,(512<<2)); - // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<2),prach2,(512<<3)); - // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<3),prach2,(512<<3)); - // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | - memmove(prach2+(512<<1)*6,prach2,(512<<2)*6); - // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | - memmove(prach,prach+(512<<1),(Ncp<<2)); - // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | - prach_len = (512*12)+Ncp; - } - } - break; + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + Ncp = Ncp; + dftlen = dftlen; + break; - case 30720: // full sampling @ 30.72 Ms/s - Ncp = Ncp*1; // to account for 30.72 Ms/s - // This is after cyclic prefix - prach2 = prach+(2*Ncp); // times 2 for complex samples - if (prach_sequence_length == 0){ - if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s - idft(IDFT_24576,prachF,prach2,1); - // here we have | empty | Prach24576 | - memmove(prach,prach+(24576<<1),(Ncp<<2)); - // here we have | Prefix | Prach24576 | - prach_len = 24576+Ncp; - } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s - idft(IDFT_24576,prachF,prach2,1); - // here we have | empty | Prach24576 | empty24576 | - memmove(prach2+(24576<<1),prach2,(24576<<2)); - // here we have | empty | Prach24576 | Prach24576 | - memmove(prach,prach+(24576<<2),(Ncp<<2)); - // here we have | Prefix | Prach24576 | Prach24576 | - prach_len = (24576*2)+Ncp; - } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s - idft(IDFT_24576,prachF,prach2,1); - // here we have | empty | Prach24576 | empty24576 | empty24576 | empty24576 | - memmove(prach2+(24576<<1),prach2,(24576<<2)); - // here we have | empty | Prach24576 | Prach24576 | empty24576 | empty24576 | - memmove(prach2+(24576<<2),prach2,(24576<<3)); - // here we have | empty | Prach24576 | Prach24576 | Prach24576 | Prach24576 | - memmove(prach,prach+(24576<<3),(Ncp<<2)); - // here we have | Prefix | Prach24576 | Prach24576 | Prach24576 | Prach24576 | - prach_len = (24576*4)+Ncp; - } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s - idft(IDFT_6144,prachF,prach2,1); - // here we have | empty | Prach6144 | empty6144 | empty6144 | empty6144 | - memmove(prach2+(6144<<1),prach2,(6144<<2)); - // here we have | empty | Prach6144 | Prach6144 | empty6144 | empty6144 | - memmove(prach2+(6144<<2),prach2,(6144<<3)); - // here we have | empty | Prach6144 | Prach6144 | Prach6144 | Prach6144 | - memmove(prach,prach+(6144<<3),(Ncp<<2)); - // here we have | Prefix | Prach6144 | Prach6144 | Prach6144 | Prach6144 | - prach_len = (6144*4)+Ncp; - } - } else { // short PRACH sequence - if (use_extended_prach_prefix) - Ncp += 16; // 16*kappa, kappa=1 for 30.72Msps - prach2 = prach+(2*Ncp); // times 2 for complex samples - if (prach_fmt_id == 9) { - idft(IDFT_1024,prachF,prach2,1); - // here we have | empty | Prach1024 | - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have | Prefix | Prach1024 | - prach_len = (1024*1)+Ncp; - } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { - idft(IDFT_1024,prachF,prach2,1); - // here we have | empty | Prach1024 | empty1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have | empty | Prach1024 | Prach1024 | - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have | Prefix | Prach1024 | Prach1024 | - prach_len = (1024*2)+Ncp; - } else if (prach_fmt_id == 5) { // 4x1024 - idft(IDFT_1024,prachF,prach2,1); - // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<2),prach2,(1024<<3)); - // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | - prach_len = (1024*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x1024 - idft(IDFT_1024,prachF,prach2,1); - // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<2),prach2,(1024<<3)); - // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<3),prach2,(1024<<3)); - // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | - prach_len = (1024*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x1024 - idft(IDFT_1024,prachF,prach2,1); - // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<1),prach2,(1024<<2)); - // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<2),prach2,(1024<<3)); - // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<3),prach2,(1024<<3)); - // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | - memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6); - // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | - memmove(prach,prach+(1024<<1),(Ncp<<2)); - // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | - prach_len = (1024*12)+Ncp; - } - } - break; + case 46080: + // 40 MHz @ 46.08 Ms/s + Ncp = (Ncp*3)/2; + dftlen = (dftlen*3)/2; + break; - case 61440: // full sampling @ 61.44 Ms/s - Ncp = Ncp*2; // to account for 61.44 Ms/s - // This is after cyclic prefix - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_sequence_length == 0){ - if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s - idft(IDFT_49152,prachF,prach2,1); - // here we have |empty | Prach49152| - memmove(prach,prach+(49152<<1),(Ncp<<2)); - // here we have |Prefix | Prach49152| - prach_len = 49152+Ncp; - } else if (prach_fmt_id == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s - idft(IDFT_49152,prachF,prach2,1); - memmove(prach2+(49152<<1),prach2,(49152<<2)); - // here we have |empty | Prach49152 | Prach49152| - memmove(prach,prach+(49152<<2),(Ncp<<2)); - // here we have |Prefix | Prach49152 | Prach49152| - prach_len = (49152*2)+Ncp; - } else if (prach_fmt_id == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s - idft(IDFT_49152,prachF,prach2,1); - memmove(prach2+(49152<<1),prach2,(49152<<2)); - // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152 - memmove(prach2+(49152<<2),prach2,(49152<<3)); - // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152 - memmove(prach,prach+(49152<<3),(Ncp<<2)); - // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152 - prach_len = (49152*4)+Ncp; - } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s - idft(IDFT_12288,prachF,prach2,1); - memmove(prach2+(12288<<1),prach2,(12288<<2)); - // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288 - memmove(prach2+(12288<<2),prach2,(12288<<3)); - // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288 - memmove(prach,prach+(12288<<3),(Ncp<<2)); - // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288 - prach_len = (12288*4)+Ncp; - } - } else { // short PRACH sequence - if (use_extended_prach_prefix) - Ncp+=32; // 16*kappa, kappa=2 for 61.44Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - idft(IDFT_2048,prachF,prach2,1); - // here we have |empty | Prach2048 | - if (prach_fmt_id != 9) { - memmove(prach2+(2048<<1),prach2,(2048<<2)); - prach_len = (2048*2)+Ncp; - } - else prach_len = (2048*1)+Ncp; - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) | - } else if (prach_fmt_id == 5) { // 6x2048 - idft(IDFT_2048,prachF,prach2,1); - // here we have |empty | Prach2048 | - memmove(prach2+(2048<<1),prach2,(2048<<2)); - // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | - memmove(prach2+(2048<<2),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | - prach_len = (2048*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x2048 - idft(IDFT_2048,prachF,prach2,1); - // here we have |empty | Prach2048 | - memmove(prach2+(2048<<1),prach2,(2048<<2)); - // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 - memmove(prach2+(2048<<2),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048 - memmove(prach2+(2048<<3),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | - prach_len = (2048*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x2048 - idft(IDFT_2048,prachF,prach2,1); - // here we have |empty | Prach2048 | - memmove(prach2+(2048<<1),prach2,(2048<<2)); - // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 - memmove(prach2+(2048<<2),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048 - memmove(prach2+(2048<<3),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 - memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| - prach_len = (2048*12)+Ncp; - } - } - break; + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + Ncp <<= 1; + dftlen <<= 1; + break; - case 46080: // threequarter sampling @ 46.08 Ms/s - Ncp = (Ncp*3)/2; - prach2 = prach+(Ncp<<1); - if (prach_sequence_length == 0){ - if (prach_fmt_id == 0) { - idft(IDFT_36864,prachF,prach2,1); - // here we have |empty | Prach73728| - memmove(prach,prach+(36864<<1),(Ncp<<2)); - // here we have |Prefix | Prach73728| - prach_len = (36864*1)+Ncp; - } else if (prach_fmt_id == 1) { - idft(IDFT_36864,prachF,prach2,1); - memmove(prach2+(36864<<1),prach2,(36864<<2)); - // here we have |empty | Prach73728 | Prach73728| - memmove(prach,prach+(36864<<2),(Ncp<<2)); - // here we have |Prefix | Prach73728 | Prach73728| - prach_len = (36864*2)+Ncp; - } else if (prach_fmt_id == 2) { - idft(IDFT_36864,prachF,prach2,1); - memmove(prach2+(36864<<1),prach2,(36864<<2)); - // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 - memmove(prach2+(36864<<2),prach2,(36864<<3)); - // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728 - memmove(prach,prach+(36864<<3),(Ncp<<2)); - // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 - prach_len = (36864*4)+Ncp; - } else if (prach_fmt_id == 3) { - idft(IDFT_9216,prachF,prach2,1); - memmove(prach2+(9216<<1),prach2,(9216<<2)); - // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216 - memmove(prach2+(9216<<2),prach2,(9216<<3)); - // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216 - memmove(prach,prach+(9216<<3),(Ncp<<2)); - // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216 - prach_len = (9216*4)+Ncp; - } - } else { // short sequence - if (use_extended_prach_prefix) - Ncp+=24; // 16*kappa, kappa=1.5 for 46.08Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - idft(IDFT_1536,prachF,prach2,1); - // here we have |empty | Prach1536 | - if (prach_fmt_id != 9) { - memmove(prach2+(1536<<1),prach2,(1536<<2)); - prach_len = (1536*2)+Ncp; - } else prach_len = (1536*1)+Ncp; - - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) | - - } else if (prach_fmt_id == 5) { // 6x1536 - idft(IDFT_1536,prachF,prach2,1); - // here we have |empty | Prach1536 | - memmove(prach2+(1536<<1),prach2,(1536<<2)); - // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | - memmove(prach2+(1536<<2),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | - prach_len = (1536*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x1536 - idft(IDFT_1536,prachF,prach2,1); - // here we have |empty | Prach1536 | - memmove(prach2+(1536<<1),prach2,(1536<<2)); - // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 - memmove(prach2+(1536<<2),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536 - memmove(prach2+(1536<<3),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | - prach_len = (1536*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x1536 - idft(IDFT_1536,prachF,prach2,1); - // here we have |empty | Prach1536 | - memmove(prach2+(1536<<1),prach2,(1536<<2)); - // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 - memmove(prach2+(1536<<2),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536 - memmove(prach2+(1536<<3),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 - memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536| - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536| - prach_len = (1536*12)+Ncp; - } - } - break; + case 92160: + // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s + Ncp *= 3; + dftlen *= 3; + break; - case 122880: // full sampling @ 122.88 Ms/s - Ncp<<=2; //to account for 122.88Mbps - // This is after cyclic prefix - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_sequence_length == 0){ - if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s - idft(IDFT_98304,prachF,prach2,1); - // here we have |empty | Prach98304| - memmove(prach,prach+(98304<<1),(Ncp<<2)); - // here we have |Prefix | Prach98304| - prach_len = (98304*1)+Ncp; - } else if (prach_fmt_id == 1) { - idft(IDFT_98304,prachF,prach2,1); - memmove(prach2+(98304<<1),prach2,(98304<<2)); - // here we have |empty | Prach98304 | Prach98304| - memmove(prach,prach+(98304<<2),(Ncp<<2)); - // here we have |Prefix | Prach98304 | Prach98304| - prach_len = (98304*2)+Ncp; - } else if (prach_fmt_id == 2) { - idft(IDFT_98304,prachF,prach2,1); - memmove(prach2+(98304<<1),prach2,(98304<<2)); - // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304 - memmove(prach2+(98304<<2),prach2,(98304<<3)); - // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304 - memmove(prach,prach+(98304<<3),(Ncp<<2)); - // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304 - prach_len = (98304*4)+Ncp; - } else if (prach_fmt_id == 3) { // 4x6144, Ncp 3168 - idft(IDFT_24576,prachF,prach2,1); - memmove(prach2+(24576<<1),prach2,(24576<<2)); - // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576 - memmove(prach2+(24576<<2),prach2,(24576<<3)); - // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576 - memmove(prach,prach+(24576<<3),(Ncp<<2)); - // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576 - prach_len = (24576*4)+Ncp; - } - } else { // short sequence - if (use_extended_prach_prefix) - Ncp+=64; // 16*kappa, kappa=4 for 122.88Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - idft(IDFT_4096,prachF,prach2,1); - // here we have |empty | Prach4096 | - if (prach_fmt_id != 9) { - memmove(prach2+(4096<<1),prach2,(4096<<2)); - prach_len = (4096*2)+Ncp; - } else prach_len = (4096*1)+Ncp; - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) | - } else if (prach_fmt_id == 5) { // 4x4096 - idft(IDFT_4096,prachF,prach2,1); - // here we have |empty | Prach4096 | - memmove(prach2+(4096<<1),prach2,(4096<<2)); - // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | - memmove(prach2+(4096<<2),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | - prach_len = (4096*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6x4096 - idft(IDFT_4096,prachF,prach2,1); - // here we have |empty | Prach4096 | - memmove(prach2+(4096<<1),prach2,(4096<<2)); - // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 - memmove(prach2+(4096<<2),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096 - memmove(prach2+(4096<<3),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | - prach_len = (4096*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12x4096 - idft(IDFT_4096,prachF,prach2,1); - // here we have |empty | Prach4096 | - memmove(prach2+(4096<<1),prach2,(4096<<2)); - // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 - memmove(prach2+(4096<<2),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096 - memmove(prach2+(4096<<3),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 - memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096| - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096| - prach_len = (4096*12)+Ncp; - } - } - break; + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s + Ncp <<= 2; + dftlen <<= 2; + break; - case 92160: // three quarter sampling @ 92.16 Ms/s - Ncp = (Ncp*3); //to account for 92.16 Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_sequence_length == 0){ - if (prach_fmt_id == 0) { - idft(IDFT_73728,prachF,prach2,1); - // here we have |empty | Prach73728| - memmove(prach,prach+(73728<<1),(Ncp<<2)); - // here we have |Prefix | Prach73728| - prach_len = (73728*1)+Ncp; - } else if (prach_fmt_id == 1) { - idft(IDFT_73728,prachF,prach2,1); - memmove(prach2+(73728<<1),prach2,(73728<<2)); - // here we have |empty | Prach73728 | Prach73728| - memmove(prach,prach+(73728<<2),(Ncp<<2)); - // here we have |Prefix | Prach73728 | Prach73728| - prach_len = (73728*2)+Ncp; - } if (prach_fmt_id == 2) { - idft(IDFT_73728,prachF,prach2,1); - memmove(prach2+(73728<<1),prach2,(73728<<2)); - // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 - memmove(prach2+(73728<<2),prach2,(73728<<3)); - // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728 - memmove(prach,prach+(73728<<3),(Ncp<<2)); - // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 - prach_len = (73728*4)+Ncp; - } else if (prach_fmt_id == 3) { - idft(IDFT_18432,prachF,prach2,1); - memmove(prach2+(18432<<1),prach2,(18432<<2)); - // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432 - memmove(prach2+(18432<<2),prach2,(18432<<3)); - // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432 - memmove(prach,prach+(18432<<3),(Ncp<<2)); - // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432 - prach_len = (18432*4)+Ncp; - } - } else { // short sequence - if (use_extended_prach_prefix) - Ncp+=48; // 16*kappa, kappa=3 for 92.16Msps - prach2 = prach+(Ncp<<1); //times 2 for complex samples - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - idft(IDFT_3072,prachF,prach2,1); - // here we have |empty | Prach3072 | - if (prach_fmt_id != 9) { - memmove(prach2+(3072<<1),prach2,(3072<<2)); - prach_len = (3072*2)+Ncp; - } else prach_len = (3072*1)+Ncp; - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | - } else if (prach_fmt_id == 6) { // 6x3072 - idft(IDFT_3072,prachF,prach2,1); - // here we have |empty | Prach3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072 - memmove(prach2+(3072<<3),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | - prach_len = (3072*6)+Ncp; - } else if (prach_fmt_id == 5) { // 4x3072 - idft(IDFT_3072,prachF,prach2,1); - // here we have |empty | Prach3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | - prach_len = (3072*4)+Ncp; - } else if (prach_fmt_id == 6) { // 12x3072 - idft(IDFT_3072,prachF,prach2,1); - // here we have |empty | Prach3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072 - memmove(prach2+(3072<<3),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 - memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072| - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072| - prach_len = (3072*12)+Ncp; - } - } - break; + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); + } - default: - AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); + #ifdef NR_PRACH_DEBUG + LOG_I(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen); + #endif + + /******************************************************** + * + * In function init_prach_tables: + * to compute quantized roots of unity ru(n) = 32767 * exp j*[ (2 * PI * n) / N_ZC ] + * + * In compute_prach_seq: + * to calculate Xu = DFT xu = xu (inv_u*k) * Xu[0] (This is a Zadoff-Chou sequence property: DFT ZC sequence is another ZC sequence) + * + * In generate_prach: + * to do the cyclic-shifted DFT by multiplying Xu[k] * ru[k*preamble_shift] as: + * If X[k] = DFT x(n) -> X_shifted[k] = DFT x(n+preamble_shift) = X[k] * exp -j*[ (2*PI*k*preamble_shift) / N_ZC ] + * + *********************************************************/ + + Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; + + #if defined (PRACH_WRITE_OUTPUT_DEBUG) + LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1); + #endif + + for (offset=0,offset2=0; offset<N_ZC; offset++,offset2+=preamble_shift) { + + if (offset2 >= N_ZC) + offset2 -= N_ZC; + + Xu_re = (((int32_t)Xu[offset<<1]*amp)>>15); + Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15); + prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15; + prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15; + + if (k==dftlen) k=0; + } + + #if defined (PRACH_WRITE_OUTPUT_DEBUG) + LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1); + LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1); + #endif + + // This is after cyclic prefix + prach2 = prach+(2*Ncp); // times 2 for complex samples + const idft_size_idx_t idft_size = get_idft(dftlen); + idft(idft_size, prachF, prach, 1); + memmove(prach2, prach, (dftlen<<2)); + + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0) { + // here we have | empty | Prach | + memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); + // here we have | Prefix | Prach | + prach_len = dftlen+Ncp; + } else if (prach_fmt_id == 1) { + // here we have | empty | Prach | empty | + memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); + // here we have | empty | Prach | Prach | + memcpy(prach, prach+(dftlen<<2), (Ncp<<2)); + // here we have | Prefix | Prach | Prach | + prach_len = (dftlen*2)+Ncp; + } else if (prach_fmt_id == 2 || prach_fmt_id == 3) { + // here we have | empty | Prach | empty | empty | empty | + memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); + // here we have | empty | Prach | Prach | empty | empty | + memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3)); + // here we have | empty | Prach | Prach | Prach | Prach | + memcpy(prach, prach+(dftlen<<3), (Ncp<<2)); + // here we have | Prefix | Prach | Prach | Prach | Prach | + prach_len = (dftlen*4)+Ncp; + } + } else { // short PRACH sequence + if (prach_fmt_id == 9) { + // here we have | empty | Prach | + memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); + // here we have | Prefix | Prach | + prach_len = (dftlen*1)+Ncp; + } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { + // here we have | empty | Prach | empty | + memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); + // here we have | empty | Prach | Prach | + memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); + // here we have | Prefix | Prach | Prach | + prach_len = (dftlen*2)+Ncp; + } else if (prach_fmt_id == 5) { // 4xdftlen + // here we have | empty | Prach | empty | empty | empty | + memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); + // here we have | empty | Prach | Prach | empty | empty | + memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3)); + // here we have | empty | Prach | Prach | Prach | Prach | + memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); + // here we have | Prefix | Prach | Prach | Prach | Prach | + prach_len = (dftlen*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6xdftlen + // here we have | empty | Prach | empty | empty | empty | empty | empty | + memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); + // here we have | empty | Prach | Prach | empty | empty | empty | empty | + memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3)); + // here we have | empty | Prach | Prach | Prach | Prach | empty | empty | + memcpy(prach2+(dftlen<<3), prach2, (dftlen<<3)); + // here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | + memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); + // here we have | Prefix | Prach | Prach | Prach | Prach | Prach | Prach | + prach_len = (dftlen*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12xdftlen + // here we have | empty | Prach | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | + memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); + // here we have | empty | Prach | Prach | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | + memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3)); + // here we have | empty | Prach | Prach | Prach | Prach | empty | empty | empty | empty | empty | empty | empty | empty | + memcpy(prach2+(dftlen<<3), prach2, (dftlen<<3)); + // here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | empty | empty | empty | empty | empty | empty | + memcpy(prach2+(dftlen<<1)*6, prach2, (dftlen<<2)*6); + // here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | + memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); + // here we have | Prefix | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | + prach_len = (dftlen*12)+Ncp; } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 13ed436273ee9d0f79ee8b308b6596873c559dd8..d2034f3abf45d567d1915be0ce40736227bd613f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -48,126 +48,8 @@ #include "PHY/NR_REFSIG/sss_nr.h" #include "PHY/NR_UE_TRANSPORT/cic_filter_nr.h" -/******************************************************************* -* -* NAME : get_idft -* -* PARAMETERS : size of ofdm symbol -* -* RETURN : index pointing to the dft func in the dft library -* -* DESCRIPTION : get idft function depending of ofdm size -* -*********************************************************************/ - //#define DBG_PSS_NR -idft_size_idx_t get_idft(int ofdm_symbol_size) -{ - - - switch (ofdm_symbol_size) { - case 128: - return IDFT_128; - break; - - case 256: - return IDFT_256; - break; - - case 512: - return IDFT_512; - break; - - case 1024: - return IDFT_1024; - break; - - case 1536: - return IDFT_1536; - break; - - case 2048: - return IDFT_2048; - break; - - case 3072: - return IDFT_3072; - break; - - case 4096: - return IDFT_4096; - break; - - case 8192: - return IDFT_8192; - break; - - default: - printf("function get_idft : unsupported ofdm symbol size \n"); - assert(0); - break; - } - return IDFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function -} - -/******************************************************************* -* -* NAME : get_dft -* -* PARAMETERS : size of ofdm symbol -* -* RETURN : function for discrete fourier transform -* -* DESCRIPTION : get dft function depending of ofdm size -* -*********************************************************************/ - -dft_size_idx_t get_dft(int ofdm_symbol_size) -{ - - - switch (ofdm_symbol_size) { - case 128: - return DFT_128; - break; - - case 256: - return DFT_256; - break; - - case 512: - return DFT_512; - break; - - case 1024: - return DFT_1024; - break; - - case 1536: - return DFT_1536; - break; - - case 2048: - return DFT_2048; - break; - - case 4096: - return DFT_4096; - break; - - case 8192: - return DFT_8192; - break; - - default: - printf("function get_dft : unsupported ofdm symbol size \n"); - assert(0); - break; - } - return DFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function; -} - /******************************************************************* * * NAME : generate_pss_nr diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 145fbe4a31a2867e21f1ba645ea0ebef125a0a55..839beb3dc9a4f5911ed775dff3e37eaadc59f3ee 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -33,7 +33,9 @@ extern "C" { #endif +#include <stdio.h> #include <stdint.h> +#include <assert.h> #include "PHY/sse_intrin.h" #define CEILIDIV(a,b) ((a+b-1)/b) @@ -315,6 +317,65 @@ typedef enum dft_size_idx { #define SZ_iENUM(Sz) IDFT_ ## Sz, +/******************************************************************* +* +* NAME : get_dft +* +* PARAMETERS : size of ofdm symbol +* +* RETURN : function for discrete fourier transform +* +* DESCRIPTION : get dft function depending of ofdm size +* +*********************************************************************/ +static inline +dft_size_idx_t get_dft(int ofdm_symbol_size) +{ + switch (ofdm_symbol_size) { + case 128: + return DFT_128; + case 256: + return DFT_256; + case 512: + return DFT_512; + case 1024: + return DFT_1024; + case 1536: + return DFT_1536; + case 2048: + return DFT_2048; + case 3072: + return DFT_3072; + case 4096: + return DFT_4096; + case 6144: + return DFT_6144; + case 8192: + return DFT_8192; + case 9216: + return DFT_9216; + case 12288: + return DFT_12288; + case 18432: + return DFT_18432; + case 24576: + return DFT_24576; + case 36864: + return DFT_36864; + case 49152: + return DFT_49152; + case 73728: + return DFT_73728; + case 98304: + return DFT_98304; + default: + printf("function get_dft : unsupported ofdm symbol size \n"); + assert(0); + break; + } + return DFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function; +} + typedef enum idft_size_idx { FOREACH_IDFTSZ(SZ_iENUM) IDFT_SIZE_IDXTABLESIZE @@ -340,6 +401,64 @@ struct { #endif +/******************************************************************* +* +* NAME : get_idft +* +* PARAMETERS : size of ofdm symbol +* +* RETURN : index pointing to the dft func in the dft library +* +* DESCRIPTION : get idft function depending of ofdm size +* +*********************************************************************/ +static inline +idft_size_idx_t get_idft(int ofdm_symbol_size) +{ + switch (ofdm_symbol_size) { + case 128: + return IDFT_128; + case 256: + return IDFT_256; + case 512: + return IDFT_512; + case 1024: + return IDFT_1024; + case 1536: + return IDFT_1536; + case 2048: + return IDFT_2048; + case 3072: + return IDFT_3072; + case 4096: + return IDFT_4096; + case 6144: + return IDFT_6144; + case 8192: + return IDFT_8192; + case 9216: + return IDFT_9216; + case 12288: + return IDFT_12288; + case 18432: + return IDFT_18432; + case 24576: + return IDFT_24576; + case 36864: + return IDFT_36864; + case 49152: + return IDFT_49152; + case 73728: + return IDFT_73728; + case 98304: + return IDFT_98304; + default: + printf("function get_idft : unsupported ofdm symbol size \n"); + assert(0); + break; + } + return IDFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function +} /*!\fn int32_t rotate_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 2ced28821ace6a6d5e2a8407f7345ebcb5ea9b86..647619819ff96be882fb131fbb435f70432320ac 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -428,10 +428,6 @@ typedef struct { /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..2*ofdm_symbol_size[ int32_t **rxdataF_ext; - /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_ext2; /// \brief Hold the channel estimates in time domain based on DRS. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..4*ofdm_symbol_size[ @@ -444,14 +440,6 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_estimates_ext; - /// \brief Hold the PTRS phase estimates in frequency domain. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_ptrs_estimates; - /// \brief Uplink phase estimates extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_ptrs_estimates_ext; /// \brief Holds the compensated signal. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 82de7ed96ea014d117fc68f37d2c0129f575775a..baf8dff8a8ef24c4e68864cc30c8dc4449946cb8 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -279,10 +279,6 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **dl_ch_estimates_ext; - /// \brief Downlink channel estimates extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_ptrs_estimates_ext; /// \brief Downlink beamforming channel estimates in frequency domain. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index d7503ce738211870c7833e0d691e0895bb3f202e..35575b77b5c3fd756109bdcadfa5fe8e315f7796 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -96,7 +96,6 @@ uint16_t sl_ahead=0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; THREAD_STRUCT thread_struct; nfapi_ue_release_request_body_t release_rntis; -uint32_t N_RB_DL = 106; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; @@ -658,7 +657,7 @@ int main(int argc, char **argv) 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 -t Delayspread -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", + 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", argv[0]); printf("-h This message\n"); printf("-L <log level, 0(errors), 1(warning), 2(analysis), 3(info), 4(debug), 5(trace)>\n"); @@ -667,7 +666,7 @@ int main(int argc, char **argv) printf("-n Number of frames to simulate\n"); printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); + //printf("-t Delay spread for multipath channel\n"); printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n"); printf("-y Number of TX antennas used in gNB\n"); printf("-z Number of RX antennas used in UE\n"); @@ -853,10 +852,14 @@ int main(int argc, char **argv) double fs,bw; - if (mu == 1 && N_RB_DL == 217) { + if (mu == 0 && N_RB_DL == 25) { + fs = 7.68e6; + bw = 5e6; + } + else if (mu == 1 && N_RB_DL == 217) { fs = 122.88e6; bw = 80e6; - } + } else if (mu == 1 && N_RB_DL == 245) { fs = 122.88e6; bw = 90e6; @@ -877,6 +880,10 @@ int main(int argc, char **argv) fs = 61.44e6; bw = 60e6; } + else if (mu == 1 && N_RB_DL == 24) { + fs = 15.36e6; + bw = 10e6; + } else if (mu == 3 && N_RB_DL == 66) { fs = 122.88e6; bw = 100e6; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 325cbb1eccf0915f7b5b98c1bb257f39c6953df6..33717c944dcd5e7eff84e679d9dbc456b10e080e 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -240,7 +240,7 @@ int main(int argc, char **argv){ int i, l, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0; - uint8_t frame = 1, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; + uint8_t config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1; uint32_t tx_lev = 10000, prach_errors = 0; //,tx_lev_dB; uint64_t SSB_positions = 0x01; @@ -536,7 +536,7 @@ int main(int argc, char **argv){ frame_parms->N_RB_UL = N_RB_UL; frame_parms->threequarter_fs = threequarter_fs; frame_parms->frame_type = TDD; - frame_parms->freq_range = (mu==1 ? nr_FR1 : nr_FR2); + frame_parms->freq_range = (mu != 3 ? nr_FR1 : nr_FR2); frame_parms->numerology_index = mu; nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); @@ -546,9 +546,11 @@ int main(int argc, char **argv){ frame_parms->numerology_index, frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index)); - uint8_t subframe = slot/frame_parms->slots_per_subframe; + uint8_t frame = 1; + uint8_t subframe = 9; + uint8_t slot = 10 * frame_parms->slots_per_subframe - 1; - if (config_index<67 && mu==1) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } + if (config_index<67 && mu != 3) { prach_sequence_length=0; slot = subframe * frame_parms->slots_per_subframe; } uint16_t N_ZC = prach_sequence_length == 0 ? 839 : 139; printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length); @@ -569,9 +571,11 @@ int main(int argc, char **argv){ ru->gNB_list[0] = gNB; gNB->gNB_config.carrier_config.num_tx_ant.value = 1; gNB->gNB_config.carrier_config.num_rx_ant.value = 1; - if (mu==1) + if (mu == 0) + gNB->gNB_config.tdd_table.tdd_period.value = 7; + else if (mu == 1) gNB->gNB_config.tdd_table.tdd_period.value = 6; - else if (mu==3) + else if (mu == 3) gNB->gNB_config.tdd_table.tdd_period.value = 3; else { printf("unsupported numerology %d\n",mu); @@ -585,7 +589,7 @@ int main(int argc, char **argv){ int ret = get_nr_prach_info_from_index(config_index, (int)frame, - (int)slot_gNB, + (int)slot, absoluteFrequencyPointA, mu, frame_parms->frame_type, @@ -717,12 +721,7 @@ int main(int argc, char **argv){ bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index); AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n", bw, frame_parms->numerology_index, N_RB_UL); - if (bw <= 30.72e6) - fs = 30.72e6; - else if (bw <= 61.44e6) - fs = 61.44e6; - else if (bw <= 122.88e6) - fs = 122.88e6; + fs = frame_parms->samples_per_subframe * 1e3; LOG_I(PHY,"Running with bandwidth %f Hz, fs %f samp/s, FRAME_LENGTH_COMPLEX_SAMPLES %d\n",bw,fs,FRAME_LENGTH_COMPLEX_SAMPLES); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 6a0d48904da5d39e9b1ddb5fd302e47965850239..248c4084e0667c1ad1c231236e2c4fa84e0844a0 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -91,7 +91,6 @@ double cpuf; uint64_t downlink_frequency[MAX_NUM_CCs][4]; THREAD_STRUCT thread_struct; nfapi_ue_release_request_body_t release_rntis; -uint32_t N_RB_DL = 106; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; @@ -306,7 +305,6 @@ int main(int argc, char **argv) int32_t txlev_sum = 0, atxlev[4]; int start_rb = 0; int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) - float target_error_rate = 0.01; int print_perf = 0; cpuf = get_cpu_freq_GHz(); int msg3_flag = 0; @@ -314,7 +312,7 @@ int main(int argc, char **argv) float roundStats[100]; double effRate[100]; double effTP[100]; - //float eff_tp_check = 0.7; + float eff_tp_check = 0.7; uint8_t snrRun; int prb_inter = 0; @@ -322,8 +320,8 @@ int main(int argc, char **argv) int modify_dmrs = 0; /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */ int ptrs_arg[2] = {-1,-1};// Invalid values - /* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */ - int dmrs_arg[2] = {-1,-1};// Invalid values + /* mapping type = dmrs_arg[0], Add Pos = dmrs_arg[1], dmrs config type = dmrs_arg[2] */ + int dmrs_arg[3] = {-1,-1,-1};// Invalid values uint16_t ptrsSymPos = 0; uint16_t ptrsSymbPerSlot = 0; uint16_t ptrsRePerSymb = 0; @@ -350,7 +348,7 @@ int main(int argc, char **argv) /* initialize the sin-cos table */ InitSinLUT(); - while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) { + while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:t:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) { printf("handling optarg %c\n",c); switch (c) { @@ -488,11 +486,10 @@ int main(int argc, char **argv) start_rb = atoi(optarg); break; -/* case 't': eff_tp_check = (float)atoi(optarg)/100; break; -*/ + /* case 'r': ricean_factor = pow(10,-.1*atof(optarg)); @@ -594,7 +591,7 @@ int main(int argc, char **argv) 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 -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId -Z Enable SC-FDMA in Uplink \n", argv[0]); + 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 -Z Enable SC-FDMA in Uplink \n", argv[0]); //printf("-d Use TDD\n"); printf("-d Introduce delay in terms of number of samples\n"); printf("-f Number of frames to simulate\n"); @@ -606,7 +603,7 @@ int main(int argc, char **argv) printf("-m MCS value\n"); printf("-n Number of trials to simulate\n"); printf("-p Use extended prefix mode\n"); - printf("-t Delay spread for multipath channel\n"); + //printf("-t Delay spread for multipath channel\n"); printf("-u Set the numerology\n"); printf("-w Start PRB for PUSCH\n"); //printf("-x Transmission mode (1,2,6 for the moment)\n"); @@ -649,16 +646,37 @@ int main(int argc, char **argv) double sampling_frequency; double bandwidth; - if (N_RB_UL >= 217) sampling_frequency = 122.88; - else if (N_RB_UL >= 106) sampling_frequency = 61.44; - else if (N_RB_UL >= 32) sampling_frequency = 32.72; - else { printf("Need at least 106 PRBs\b"); exit(-1); } - if (N_RB_UL == 273) bandwidth = 100; - else if (N_RB_UL == 217) bandwidth = 80; - else if (N_RB_UL == 106) bandwidth = 40; - else if (N_RB_UL == 32) bandwidth = 50; - else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); } + if (mu == 0 && N_RB_UL == 25 ) { + sampling_frequency = 7.68; + bandwidth = 5; + } + else if (mu == 1 && N_RB_UL == 273) { + sampling_frequency = 122.88; + bandwidth = 100; + } + else if (mu == 1 && N_RB_UL == 217) { + sampling_frequency = 122.88; + bandwidth = 80; + } + else if (mu == 1 && N_RB_UL == 106) { + sampling_frequency = 61.44; + bandwidth = 40; + } + else if (mu == 1 && N_RB_UL == 24) { + sampling_frequency = 15.36; + bandwidth = 10; + } + else if (mu == 3 && N_RB_UL == 32) { + sampling_frequency = 61.44; + bandwidth = 50; + } + else { + printf("Add N_RB_UL %d\n",N_RB_UL); + exit(-1); + } + LOG_I( PHY,"++++++++++++++++++++++++++++++++++++++++++++++%i+++++++++++++++++++++++++++++++++++++++++",loglvl); + if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75; UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, @@ -872,8 +890,12 @@ int main(int argc, char **argv) /* Additional DMRS positions */ if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 ) add_pos = dmrs_arg[1]; + /* DMRS Conf Type 1 or 2 */ + if(dmrs_arg[2] == 1) + dmrs_config_type = pusch_dmrs_type1; + else if(dmrs_arg[2] == 2) + dmrs_config_type = pusch_dmrs_type2; } - printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos ); uint8_t length_dmrs = pusch_len1; uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs, start_symbol, NR_MIB__dmrs_TypeA_Position_pos2); @@ -892,6 +914,7 @@ int main(int argc, char **argv) AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); dmrs_config_type = pusch_dmrs_type1; + nb_re_dmrs = 6; printf("[ULSIM]: TRANSFORM PRECODING ENABLED. Num RBs: %d, index for DMRS_SEQ: %d\n", nb_rb, index); } @@ -1560,7 +1583,7 @@ int main(int argc, char **argv) if(n_trials==1) break; - if ((float)n_errors[0][snrRun]/(float)n_trials <= target_error_rate) { + if (effRate[snrRun] > (eff_tp_check*TBS)) { printf("*************\n"); printf("PUSCH test OK\n"); printf("*************\n"); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 9292d1f96210f883899aed8725af726a5f01dd3f..6ceab3b97d1ea0fb7fad61d2004e5ca403a19d14 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -213,15 +213,20 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R // *scc->n_TimingAdvanceOffset=NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0; *scc->ssb_periodicityServingCell=NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20; scc->dmrs_TypeA_Position=NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2; - *scc->ssbSubcarrierSpacing=NR_SubcarrierSpacing_kHz30; - *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=641032; - *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=78; - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=640000; + *scc->ssbSubcarrierSpacing=mu_dl; + if (mu_dl == 0) { + *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=520432; + *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=38; + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=520000; + } else { + *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=641032; + *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=78; + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=640000; + } scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; - scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=NR_SubcarrierSpacing_kHz30; - + scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_dl; scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_DL; - scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth=13036; + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth=275*(N_RB_DL-1); scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing=mu_dl;//NR_SubcarrierSpacing_kHz30; *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=12; *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero=0; @@ -235,13 +240,13 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R timedomainresourceallocation1->startSymbolAndLength=57; ASN_SEQUENCE_ADD(&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list, timedomainresourceallocation1); - *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]=78; + *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]=mu_ul?78:38; *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA=-1; scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; - scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=NR_SubcarrierSpacing_kHz30; + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_ul; scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_UL; *scc->uplinkConfigCommon->frequencyInfoUL->p_Max=20; - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth=13036; + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth=275*(N_RB_UL-1); scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing=mu_ul;//NR_SubcarrierSpacing_kHz30; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex=98; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM=NR_RACH_ConfigGeneric__msg1_FDM_one; @@ -277,8 +282,11 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal=-90; scc->ssb_PositionsInBurst->present=NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; *ssb_bitmap=0xff; - scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing=NR_SubcarrierSpacing_kHz30; - scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; + scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing=mu_dl; + if (mu_dl == 0) + scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms10; + else + scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots=7; scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols=6; scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots=2; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e5cabb452155f7ac44bb9ad986d012d0b52eae3b..3fd1802432a75b72901c4ef2d71f069ed281f25c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1686,7 +1686,7 @@ int get_nr_prach_info_from_index(uint8_t index, } if ( (s_map>>subframe)&0x01 ) { *N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe - if (mu == 1) { + if (mu == 1 && index >= 67) { if ( (*N_RA_slot <= 1) && (slot%2 == 0) ) return 0; // no prach in even slots @ 30kHz for 1 prach per subframe } diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index e5c98eacd6f27c386dde23d0f2b050d9f82eb59a..1df14760295ee47fceff76a66b709f12c5b8777c 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -419,7 +419,7 @@ void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, } AssertFatal(bw_rb>0,"Could not find scs-SpecificCarrierList element for scs %d",scs); int bw = get_supported_band_index(scs, band, bw_rb); - AssertFatal(bw>0,"Supported band corresponding to %d RBs not found\n", bw_rb); + AssertFatal(bw>=0,"Supported band corresponding to %d RBs not found\n", bw_rb); bool supported = false; if (band>256) { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf new file mode 100644 index 0000000000000000000000000000000000000000..6af135608888ea1f106e839710851e7c26fa4ca2 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf @@ -0,0 +1,266 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac"; + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + min_rxtxtime = 6; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150 MHz + 12 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block + absoluteFrequencySSB = 430432; + dl_frequencyBand = 66; + # this is 2150 MHz + dl_absoluteFrequencyPointA = 430000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 0; + dl_carrierBandwidth = 25; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=25 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 0; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + ul_absoluteFrequencyPointA = 350000; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 0; + ul_carrierBandwidth = 25; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 0; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + msg1_SubcarrierSpacing = 0; +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 0x1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 0; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 0; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + thread_pool_size = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 50; + eNB_instances = [0]; + ## beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ## beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + + log_config : + { + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + }; +