Commit 21a820b0 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/support-15-kHz-SCS' into integration_2022_wk21b

parents 72d0a4ff e639e792
......@@ -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>
......
......@@ -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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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)
......
......@@ -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);
......
......@@ -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)));
......
......@@ -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)],
......
......@@ -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);
......
......@@ -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);
......
......@@ -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,
......
......@@ -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);
......
......@@ -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)],
......
......@@ -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;
}
}
......
......@@ -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
......
......@@ -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)
......
......@@ -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[
......
......@@ -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)[
......
......@@ -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;
......
......@@ -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);
......
......@@ -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");
......
......@@ -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;
......
......@@ -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
}
......
......@@ -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) {
......
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";
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment