Merge remote-tracking branch 'origin/develop' into NR_MAC_SSB

This commit is contained in:
francescomani
2021-03-30 09:35:18 +02:00
132 changed files with 7904 additions and 2668 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ int test_ldpc(short No_iteration,
t_nrLDPC_procBuf nrLDPC_procBuf;
t_nrLDPC_procBuf* p_nrLDPC_procBuf = &nrLDPC_procBuf;
t_nrLDPC_time_stats decoder_profiler;
t_nrLDPC_time_stats decoder_profiler = {0};
t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ;
int32_t n_iter = 0;
+2 -2
View File
@@ -464,8 +464,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
gNB->mac_enabled = 1;
if (mu==1) {
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
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;
// fp->threequarter_fs= 0;
} else if (mu==3) {
+4 -4
View File
@@ -125,7 +125,7 @@ int nr_phy_init_RU(RU_t *ru) {
int beam_count = 0;
if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
for (p=0;p<ru->nb_log_antennas;p++) {
if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
//if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
beam_count++;
}
AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
@@ -133,7 +133,7 @@ int nr_phy_init_RU(RU_t *ru) {
int l_ind = 0;
for (i=0; i<RC.nb_nr_L1_inst; i++) {
for (p=0;p<ru->nb_log_antennas;p++) {
if ((fp->L_ssb >> (63-p)) & 0x01) {
//if ((fp->L_ssb >> (63-p)) & 0x01) {
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; j<ru->nb_tx; j++) {
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
@@ -142,8 +142,8 @@ int nr_phy_init_RU(RU_t *ru) {
//printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
l_ind++;
} // for j
} // for p
}
//}
} // for p
} //for i
}
} // !=IF5
+82 -101
View File
@@ -71,33 +71,39 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) );
// FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
// FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
pdsch->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->rxdataF_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->rho = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t **) );
pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
//pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
//pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
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 <= 2, "nb_antennas_rx > 2" );
AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4
const size_t num = 7*2*fp->N_RB_DL*12;
for (int i=0; i<fp->nb_antennas_rx; i++) {
pdsch->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) );
pdsch->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
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<4; j++) { //fp->nb_antennas_tx; j++)
const int idx = (j<<1)+i;
const size_t num = 7*2*fp->N_RB_DL*12;
pdsch->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->rxdataF_uespec_pilots[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
for (int j=0; j<NR_MAX_NB_LAYERS; j++) {
const int idx = (j*fp->nb_antennas_rx)+i;
for (int k=0; k<NR_MAX_NB_LAYERS; k++) {
pdsch->rho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
}
pdsch->rxdataF_comp0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
pdsch->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
@@ -108,9 +114,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->dl_ch_magr0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->ptrs_re_per_slot[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * 14);
pdsch->ptrs_phase_per_slot[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 );
pdsch->dl_ch_ptrs_estimates_ext[idx]= (int32_t *)malloc16_clear( sizeof(int32_t) * num);
}
}
}
@@ -139,16 +142,14 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
int n_scid;
abstraction_flag = 0;
fp->nb_antennas_tx = 1;
fp->nb_antennas_rx=1;
// dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
// ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx);
//LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
//LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_INST);
phy_init_nr_top(ue);
// many memory allocation sizes are hard coded
AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[gNB_id]" );
AssertFatal(nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
AssertFatal( fp->nb_antennas_rx <= 4, "hard coded allocation for ue_common_vars->dl_ch_estimates[gNB_id]" );
AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
// init phy_vars_ue
for (i=0; i<4; i++) {
@@ -276,7 +277,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
//PDCCH DMRS init (eNB offset = 0)
//PDCCH DMRS init (gNB offset = 0)
ue->nr_gold_pdcch[0] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0];
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
@@ -291,7 +292,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
//PDSCH DMRS init (eNB offset = 0)
//PDSCH DMRS init (gNB offset = 0)
ue->nr_gold_pdsch[0] = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0];
@@ -329,31 +330,25 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p = ue->pdsch_vars[0][gNB_id]->llr_shifts;
ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear(sizeof(int16_t *));
ue->pdsch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16_clear(fp->nb_antennas_rx*sizeof(int32_t *));
ue->pdsch_vars[th_id][gNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p = ue->pdsch_vars[0][gNB_id]->llr_shifts;
ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
}
for (int i=0; i<fp->nb_antennas_rx; i++) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
}
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (i=0; i<fp->nb_antennas_rx; i++)
for (j=0; j<4; j++) {
const int idx = (j<<1)+i;
const int idx = (j*fp->nb_antennas_rx)+i;
const size_t num = 7*2*fp->N_RB_DL*12+4;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
}
}
@@ -361,15 +356,15 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
for (k=0; k<8; k++) { //harq_pid
for (l=0; l<8; l++) { //round
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (int i=0; i<fp->nb_antennas_rx; i++)
for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
const int idx = (j<<1)+i;
const int idx = (j*fp->nb_antennas_rx)+i;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
@@ -383,26 +378,26 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdcch_vars[th_id][gNB_id]->llr = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t));
ue->pdcch_vars[th_id][gNB_id]->llr16 = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t));
ue->pdcch_vars[th_id][gNB_id]->wbar = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t));
ue->pdcch_vars[th_id][gNB_id]->e_rx = (int16_t *)malloc16_clear(4*2*100*12 );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16(fp->nb_antennas_rx*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->llr = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->llr16 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->wbar = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->e_rx = (int16_t *)malloc16_clear( 4*2*100*12 );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
// Channel estimates
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
for (i=0; i<fp->nb_antennas_rx; i++) {
ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4));
for (j=0; j<4; j++) {
int idx = (j<<1) + i;
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->ofdm_symbol_size*2);
int idx = (j*fp->nb_antennas_rx)+i;
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
// size_t num = 7*2*fp->N_RB_DL*12;
size_t num = 4*273*12; // 4 symbols, 100 PRBs, 12 REs per PRB
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
@@ -414,24 +409,24 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
// PBCH
pbch_vars[gNB_id]->rxdataF_ext = (int32_t **)malloc16(fp->nb_antennas_rx*sizeof(int32_t *));
pbch_vars[gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
pbch_vars[gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
pbch_vars[gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
pbch_vars[gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
pbch_vars[gNB_id]->llr = (int16_t *)malloc16_clear(1920); //
prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear(sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)));
prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear(sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)));
pbch_vars[gNB_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
pbch_vars[gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
pbch_vars[gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
pbch_vars[gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
pbch_vars[gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
pbch_vars[gNB_id]->llr = (int16_t *)malloc16_clear( 1920 ); //
prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
for (i=0; i<fp->nb_antennas_rx; i++) {
pbch_vars[gNB_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) {
int idx = (j<<1)+i;
pbch_vars[gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*20*12*4);
pbch_vars[gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size));
pbch_vars[gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size));
pbch_vars[gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*20*12*4);
int idx = (j*fp->nb_antennas_rx)+i;
pbch_vars[gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
pbch_vars[gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
pbch_vars[gNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
pbch_vars[gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
}
}
}
@@ -507,50 +502,36 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){
if (fp->frame_type == FDD) {
ue->N_TA_offset = 0;
} else {
int N_RB = fp->N_RB_DL;
int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
double factor = 1;
double factor = 1.0;
switch (fp->numerology_index) {
case 0: //15 kHz scs
AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
if (N_RB <= 25) factor = .25; // 7.68 Ms/s
else if (N_RB <=50) factor = .5; // 15.36 Ms/s
else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
else AssertFatal(1==0, "Too many PRBS for mu=0\n");
factor = fp->samples_per_subframe / 30720.0;
break;
case 1: //30 kHz sc
AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
factor = fp->samples_per_subframe / 30720.0;
break;
case 2: //60 kHz scs
AssertFatal(1==0, "scs_common should not be 60 kHz\n");
break;
case 3: //120 kHz scs
AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
factor = fp->samples_per_subframe / 61440.0;
break;
case 4: //240 kHz scs
AssertFatal(1==0, "scs_common should not be 60 kHz\n");
if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB);
AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n");
factor = fp->samples_per_subframe / 61440.0;
break;
if (N_RB == 100)
ue->N_TA_offset = 624;
else if (N_RB == 50)
ue->N_TA_offset = 624/2;
else if (N_RB == 25)
ue->N_TA_offset = 624/4;
default:
AssertFatal(1==0, "Invalid scs_common!\n");
}
if (fp->threequarter_fs == 1)
factor = factor*.75;
ue->N_TA_offset = (int)(N_TA_offset * factor);
LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB);
LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index);
}
}
+24 -99
View File
@@ -69,9 +69,8 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
return symbol;
}
void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
{
switch(mu) {
case NR_MU_0: //15kHz scs
@@ -93,108 +92,17 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
else
AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu);
}
switch(bw){
case 5:
case 15:
case 20:
case 25:
case 30:
case 40: //40 MHz
if (fp->threequarter_fs) {
fp->ofdm_symbol_size = 1536;
fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
fp->nb_prefix_samples0 = 132;
fp->nb_prefix_samples = 108;
}
else {
fp->ofdm_symbol_size = 2048;
fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 )
fp->nb_prefix_samples0 = 176;
fp->nb_prefix_samples = 144;
}
break;
case 50:
case 60:
case 70:
case 80: //80 MHz
if (fp->threequarter_fs) {
fp->ofdm_symbol_size = 3072;
fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
fp->nb_prefix_samples0 = 264;
fp->nb_prefix_samples = 216;
}
else {
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
}
break;
case 90:
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
case 100:
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
default:
AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
}
break;
case NR_MU_2: //60kHz scs
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
switch(bw){ //FR1 bands only
case 10:
case 15:
case 20:
case 25:
case 30:
case 40:
case 50:
case 60:
case 70:
case 80:
case 90:
case 100:
default:
AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
}
break;
case NR_MU_3:
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
fp->ssb_type = nr_ssb_type_D;
switch(bw){
case 100:
fp->ofdm_symbol_size = 1024;
fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 )
fp->nb_prefix_samples0 = 136;
fp->nb_prefix_samples = 72;
break;
case 50:
fp->ofdm_symbol_size = 512;
fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 )
fp->nb_prefix_samples0 = 68;
fp->nb_prefix_samples = 36;
break;
default:
AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
}
break;
case NR_MU_4:
@@ -203,9 +111,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
fp->ssb_type = nr_ssb_type_E;
break;
default:
AssertFatal(1==0,"Invalid numerology index %d", mu);
default:
AssertFatal(1==0,"Invalid numerology index %d", mu);
}
if(fp->threequarter_fs)
fp->ofdm_symbol_size = 3 * 128;
else
fp->ofdm_symbol_size = 4 * 128;
while(fp->ofdm_symbol_size < N_RB_DL * 12)
fp->ofdm_symbol_size <<= 1;
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
}
uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
@@ -274,13 +194,13 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
fp->half_frame_bit = 0; // half frame bit initialized to 0 here
fp->numerology_index = mu;
set_scs_parameters(fp, mu, cfg->carrier_config.dl_bandwidth.value);
set_scs_parameters(fp, mu, fp->N_RB_DL);
fp->slots_per_frame = 10* fp->slots_per_subframe;
fp->nb_antenna_ports_gNB = cfg->carrier_config.num_tx_ant.value;// It corresponds to pdsch_AntennaPorts
fp->nb_antenna_ports_gNB = 1; // It corresponds to the number of common antenna ports
fp->nb_antennas_rx = cfg->carrier_config.num_rx_ant.value; // It denotes the number of rx antennas at gNB
fp->nb_antennas_tx = 1; // It corresponds to the number of UE Tx antennas
fp->nb_antennas_tx = cfg->carrier_config.num_tx_ant.value; // It corresponds to pdsch_AntennaPorts
fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
@@ -328,6 +248,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
uint8_t Nid_cell = 0;
int Ncp = NORMAL;
if(fp->nb_antennas_rx == 0)
fp->nb_antennas_rx = 1;
if(fp->nb_antennas_tx == 0)
fp->nb_antennas_tx = 1;
// default values until overwritten by RRCConnectionReconfiguration
fp->nb_antenna_ports_gNB = nb_ant_ports_gNB;
fp->tdd_config = tdd_cfg;
@@ -367,7 +292,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->Ncp = Ncp;
set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth);
set_scs_parameters(fp, fp->numerology_index, fp->N_RB_DL);
fp->slots_per_frame = 10* fp->slots_per_subframe;
fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
+5 -4
View File
@@ -145,7 +145,8 @@ int nr_beam_precoding(int32_t **txdataF,
int slot,
int symbol,
int aa,
int nb_antenna_ports)
int nb_antenna_ports,
int offset)
{
@@ -155,14 +156,14 @@ int nr_beam_precoding(int32_t **txdataF,
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size));
for (p=0; p<nb_antenna_ports; p++) {
if ((frame_parms->L_ssb >> (63-p)) & 0x01) {
multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size],
//if ((frame_parms->L_ssb >> (63-p)) & 0x01) {
multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset],
(int16_t*)beam_weights[p][aa],
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
0,
frame_parms->ofdm_symbol_size,
15);
}
//}
}
return 0;
}
+2 -5
View File
@@ -51,16 +51,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
UE_nr_rxtx_proc_t *proc,
unsigned char l,
unsigned char Ns,
int sample_offset,
int no_prefix);
unsigned char Ns);
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix);
int sample_offset);
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
+169 -36
View File
@@ -22,6 +22,101 @@
#include "nr_modulation.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
//Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j
char nr_W_1l_2p[6][2][1] = {
{{'1'}, {'0'}},//pmi 0
{{'0'}, {'1'}},
{{'1'}, {'1'}},
{{'1'}, {'n'}},
{{'1'}, {'j'}},
{{'1'}, {'o'}}//pmi 5
};
//Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j
char nr_W_1l_4p[28][4][1] = {
{{'1'}, {'0'}, {'0'}, {'0'}},//pmi 0
{{'0'}, {'1'}, {'0'}, {'0'}},
{{'0'}, {'0'}, {'1'}, {'0'}},
{{'0'}, {'0'}, {'0'}, {'1'}},
{{'1'}, {'0'}, {'1'}, {'0'}},
{{'1'}, {'0'}, {'n'}, {'0'}},
{{'1'}, {'0'}, {'j'}, {'0'}},
{{'1'}, {'0'}, {'o'}, {'0'}},//pmi 7
{{'0'}, {'1'}, {'0'}, {'1'}},//pmi 8
{{'0'}, {'1'}, {'0'}, {'n'}},
{{'0'}, {'1'}, {'0'}, {'j'}},
{{'0'}, {'1'}, {'0'}, {'o'}},
{{'1'}, {'1'}, {'1'}, {'1'}},
{{'1'}, {'1'}, {'j'}, {'j'}},
{{'1'}, {'1'}, {'n'}, {'n'}},
{{'1'}, {'1'}, {'o'}, {'o'}},
{{'1'}, {'j'}, {'1'}, {'j'}},//pmi 16
{{'1'}, {'j'}, {'j'}, {'n'}},
{{'1'}, {'j'}, {'n'}, {'o'}},
{{'1'}, {'j'}, {'o'}, {'1'}},
{{'1'}, {'n'}, {'1'}, {'n'}},
{{'1'}, {'n'}, {'j'}, {'o'}},
{{'1'}, {'n'}, {'n'}, {'1'}},
{{'1'}, {'n'}, {'o'}, {'j'}},//pmi 23
{{'1'}, {'o'}, {'1'}, {'o'}},//pmi 24
{{'1'}, {'o'}, {'j'}, {'1'}},
{{'1'}, {'o'}, {'n'}, {'j'}},
{{'1'}, {'o'}, {'o'}, {'n'}}//pmi 27
};
//Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2 'n' = -1 and 'o' = -j
char nr_W_2l_2p[3][2][2] = {
{{'1', '0'}, {'0', '1'}},//pmi 0
{{'1', '1'}, {'1', 'n'}},
{{'1', '1'}, {'j', 'o'}} //pmi 2
};
//Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j
char nr_W_2l_4p[22][4][2] = {
{{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}},//pmi 0
{{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}},
{{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}},
{{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}},//pmi 3
{{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}},//pmi 4
{{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}},
{{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}},
{{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}},
{{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}},//pmi 8
{{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}},
{{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}},
{{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}},//pmi 11
{{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}},//pmi 12
{{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}},
{{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}},
{{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}},//pmi 15
{{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}},//pmi 16
{{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}},
{{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}},
{{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}},//pmi 19
{{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}},
{{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}}//pmi 21
};
//Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j
char nr_W_3l_4p[7][4][3] = {
{{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'},{'0', '0', '0'}},//pmi 0
{{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'},{'0', '0', '1'}},
{{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'},{'0', '0', '1'}},
{{'1', '1', '1'}, {'1', 'n', '1'}, {'1', '1', 'n'},{'1', 'n', 'n'}},//pmi 3
{{'1', '1', '1'}, {'1', 'n', '1'}, {'j', 'j', 'o'},{'j', 'o', 'o'}},//pmi 4
{{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'},{'n', '1', '1'}},
{{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'},{'o', 'j', 'j'}}
};
//Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j
char nr_W_4l_4p[5][4][4] = {
{{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}},//pmi 0
{{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}},
{{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'j', 'o', '0', '0'}, {'0', '0', 'j', 'o'}},
{{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'1', '1', 'n', 'n'}, {'1', 'n', 'n', '1'}},//pmi 3
{{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}}//pmi 4
};
void nr_modulation(uint32_t *in,
uint32_t length,
uint16_t mod_order,
@@ -37,7 +132,7 @@ void nr_modulation(uint32_t *in,
uint32_t i,j;
uint32_t bit_cnt;
uint64_t x,x1,x2;
#if defined(__SSE2__)
__m128i *nr_mod_table128;
__m128i *out128;
@@ -56,7 +151,7 @@ void nr_modulation(uint32_t *in,
// the bits that are left out
i = i*8/2;
nr_mod_table32 = (int32_t*) nr_qpsk_mod_table;
while (i<length/2){
while (i<length/2) {
idx = ((in_bytes[(i*2)/8]>>((i*2)&0x7)) & mask);
out32[i] = nr_mod_table32[idx];
i++;
@@ -78,7 +173,7 @@ void nr_modulation(uint32_t *in,
out64[i] = nr_16qam_byte_mod_table[in_bytes[i]];
// the bits that are left out
i = i*8/4;
while (i<length/4){
while (i<length/4) {
idx = ((in_bytes[(i*4)/8]>>((i*4)&0x7)) & mask);
out32[i] = nr_16qam_mod_table[idx];
i++;
@@ -88,7 +183,7 @@ void nr_modulation(uint32_t *in,
case 6:
j = 0;
for (i=0; i<length/192; i++) {
x = in64[i*3];
x = in64[i*3];
x1 = x&4095;
out64[j++] = nr_64qam_mod_table[x1];
x1 = (x>>12)&4095;
@@ -140,7 +235,7 @@ void nr_modulation(uint32_t *in,
bit_cnt += 24;
}
return;
case 8:
nr_mod_table32 = (int32_t*) nr_256qam_mod_table;
for (i=0; i<length/8; i++)
@@ -151,20 +246,20 @@ void nr_modulation(uint32_t *in,
break;
}
AssertFatal(false,"Invalid or unsupported modulation order %d\n",mod_order);
}
void nr_layer_mapping(int16_t **mod_symbs,
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers) {
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers)
{
LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs);
switch (n_layers) {
case 1:
memcpy((void*)tx_layers[0], (void*)mod_symbs[0], (n_symbs<<1)*sizeof(int16_t));
break;
break;
case 2:
case 3:
@@ -174,7 +269,7 @@ void nr_layer_mapping(int16_t **mod_symbs,
tx_layers[l][i<<1] = mod_symbs[0][(n_layers*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[0][((n_layers*i+l)<<1)+1];
}
break;
break;
case 5:
for (int i=0; i<n_symbs>>1; i++)
@@ -186,8 +281,8 @@ void nr_layer_mapping(int16_t **mod_symbs,
for (int l=2; l<5; l++) {
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
}
break;
}
break;
case 6:
for (int q=0; q<2; q++)
@@ -196,7 +291,7 @@ void nr_layer_mapping(int16_t **mod_symbs,
tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1];
}
break;
break;
case 7:
for (int i=0; i<n_symbs/3; i++)
@@ -209,7 +304,7 @@ void nr_layer_mapping(int16_t **mod_symbs,
tx_layers[l][i<<1] = mod_symbs[0][((i<<2)+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<2)+l)<<1)+1];
}
break;
break;
case 8:
for (int q=0; q<2; q++)
@@ -218,42 +313,42 @@ void nr_layer_mapping(int16_t **mod_symbs,
tx_layers[l][i<<1] = mod_symbs[q][((i<<2)+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[q][(((i<<2)+l)<<1)+1];
}
break;
break;
default:
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
default:
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
}
}
void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers) {
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers)
{
int16_t *mod_symbs;
switch (n_layers) {
case 1:
mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
for (int i=0; i<n_symbs; i++){
for (int i=0; i<n_symbs; i++) {
tx_layers[0][i<<1] = (mod_symbs[i<<1]*AMP)>>15;
tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15;
}
break;
break;
case 2:
case 3:
case 4:
mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
for (int i=0; i<n_symbs/n_layers; i++){
for (int i=0; i<n_symbs/n_layers; i++) {
for (int l=0; l<n_layers; l++) {
tx_layers[l][i<<1] = (mod_symbs[(n_layers*i+l)<<1]*AMP)>>15;
tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15;
}
}
break;
break;
case 5:
mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
@@ -271,11 +366,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
tx_layers[l][i<<1] = (mod_symbs[(3*i+l)<<1]*AMP)>>15;
tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
}
break;
break;
case 6:
for (int q=0; q<2; q++){
for (int q=0; q<2; q++) {
mod_symbs = (int16_t *)ulsch_ue[q]->d_mod;
for (int i=0; i<n_symbs/3; i++)
@@ -284,7 +378,7 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
}
}
break;
break;
case 7:
mod_symbs = (int16_t *)ulsch_ue[1]->d_mod;
@@ -302,11 +396,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15;
tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15;
}
break;
break;
case 8:
for (int q=0; q<2; q++){
for (int q=0; q<2; q++) {
mod_symbs = (int16_t *)ulsch_ue[q]->d_mod;
for (int i=0; i<n_symbs>>2; i++)
@@ -315,10 +408,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15;
}
}
break;
break;
default:
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
default:
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
}
}
@@ -651,3 +744,43 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
}
}
}
int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset)
{
int32_t precodatatx_F = 0;
for (int al = 0; al<n_layers; al++) {
int16_t antenna_re = datatx_F_precoding[al][re_offset<<1];
int16_t antenna_im = datatx_F_precoding[al][(re_offset<<1) +1];
switch (prec_matrix[al]) {
case '0': //multiply by zero
break;
case '1': //multiply by 1
((int16_t *) &precodatatx_F)[0] += antenna_re;
((int16_t *) &precodatatx_F)[1] += antenna_im;
break;
case 'n': // multiply by -1
((int16_t *) &precodatatx_F)[0] -= antenna_re;
((int16_t *) &precodatatx_F)[1] -= antenna_im;
break;
case 'j': //
((int16_t *) &precodatatx_F)[0] -= antenna_im;
((int16_t *) &precodatatx_F)[1] += antenna_re;
break;
case 'o': // -j
((int16_t *) &precodatatx_F)[0] += antenna_im;
((int16_t *) &precodatatx_F)[1] -= antenna_re;
break;
}
}
return precodatatx_F;
// normalize
/* ((int16_t *)precodatatx_F)[0] = (int16_t)((((int16_t *)precodatatx_F)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/
}
+20 -5
View File
@@ -28,7 +28,13 @@
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
#define DMRS_MOD_ORDER 2
/*Precoding matices: W[pmi][antenna_port][layer]*/
extern char nr_W_1l_2p[6][2][1];
extern char nr_W_2l_2p[3][2][2];
extern char nr_W_1l_4p[28][4][1];
extern char nr_W_2l_4p[22][4][2];
extern char nr_W_3l_4p[7][4][3];
extern char nr_W_4l_4p[5][4][4];
/*! \brief Perform NR modulation. TS 38.211 V15.4.0 subclause 5.1
@param[in] in, Pointer to input bits
@param[in] length, size of input bits
@@ -74,7 +80,6 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
\param symbol symbol within slot (0..12/14)
\param Ns Slot number (0..19)
\param sample_offset offset within rxdata (points to beginning of subframe)
\param no_prefix if 1 prefix is removed by HW
*/
int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
@@ -82,8 +87,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix);
int sample_offset);
/*!
\brief This function implements the dft transform precoding in PUSCH
@@ -100,7 +104,8 @@ int nr_beam_precoding(int32_t **txdataF,
int slot,
int symbol,
int aa,
int nb_antenna_ports
int nb_antenna_ports,
int offset
);
void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
@@ -118,4 +123,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int first_symbol,
int nsymb,
int length);
/*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5
@param[in] datatx_F_precoding, Pointer to n_layers*re data array
@param[in] prec_matrix, Pointer to precoding matrix
@param[in] n_layers, number of DLSCH layers
*/
int nr_layer_precoder(int16_t **datatx_F_precoding,
char *prec_matrix,
uint8_t n_layers,
int32_t re_offset);
#endif
+171 -336
View File
@@ -29,362 +29,227 @@
//#define DEBUG_FEP
#define SOFFSET 0
/*#ifdef LOG_I
#undef LOG_I
#define LOG_I(A,B...) printf(A)
#endif*/
int nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix)
dft_size_idx_t get_dft_size_idx(uint16_t ofdm_symbol_size)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
unsigned char aa;
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
unsigned int abs_symbol;
if (ue->is_synchronized) {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
}
else {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
}
//unsigned int subframe_offset;//,subframe_offset_F;
unsigned int slot_offset;
//int i;
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
unsigned int rx_offset;
dft_size_idx_t dftsize;
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
switch (frame_parms->ofdm_symbol_size) {
switch (ofdm_symbol_size) {
case 128:
dftsize = DFT_128;
break;
return DFT_128;
case 256:
dftsize = DFT_256;
break;
return DFT_256;
case 512:
dftsize = DFT_512;
break;
return DFT_512;
case 1024:
dftsize = DFT_1024;
break;
return DFT_1024;
case 1536:
dftsize = DFT_1536;
break;
return DFT_1536;
case 2048:
dftsize = DFT_2048;
break;
return DFT_2048;
case 3072:
dftsize = DFT_3072;
break;
return DFT_3072;
case 4096:
dftsize = DFT_4096;
break;
return DFT_4096;
case 6144:
return DFT_6144;
case 8192:
dftsize = DFT_8192;
break;
return DFT_8192;
default:
printf("unsupported ofdm symbol size \n");
assert(0);
}
if (no_prefix) {
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
return DFT_SIZE_IDXTABLESIZE;
}
int nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
if (ue->is_synchronized) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
} else {
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
}
/*if (l<0 || l>=7-frame_parms->Ncp) {
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
return(-1);
}*/
dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
return(-1);
}
unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
rx_offset = sample_offset + slot_offset - SOFFSET;
// Align with 256 bit
// rx_offset = rx_offset&0xfffffff8;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= nb_prefix_samples / 8;
#ifdef DEBUG_FEP
// if (ue->frame <100)
/*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
// if (ue->frame <100)
printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset);
#endif
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
rx_offset += frame_parms->ofdm_symbol_size * symbol;
if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
rx_offset += nb_prefix_samples;
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
(short*) &common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
memcpy((void *)tmp_dft_in,
(void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
dft(dftsize,(int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
}
} else {
rx_offset += nb_prefix_samples0;
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
(void *) &common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
memcpy((void *)tmp_dft_in,
(void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
dft(dftsize,(int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
}
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
// if input to dft is not 256-bit aligned
if ((rx_offset & 7) != 0) {
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
frame_parms->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
}
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft(dftsize,
rxdata_ptr,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
#ifdef DEBUG_FEP
// if (ue->frame <100)
printf("slot_fep: symbol %d rx_offset %u\n", symbol, rx_offset);
printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset,
symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
#endif
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
(int16_t*)&rot2,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
frame_parms->ofdm_symbol_size,
15);
}
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
#endif
return(0);
return 0;
}
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix)
int sample_offset)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
unsigned char aa;
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
unsigned int abs_symbol;
if (ue->is_synchronized) {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
else {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
}
//unsigned int subframe_offset;//,subframe_offset_F;
unsigned int slot_offset;
//int i;
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
unsigned int rx_offset;
unsigned int frame_length_samples = frame_parms->samples_per_frame;
dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
dft_size_idx_t dftsize;
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
switch (frame_parms->ofdm_symbol_size) {
case 128:
dftsize = DFT_128;
break;
case 256:
dftsize = DFT_256;
break;
case 512:
dftsize = DFT_512;
break;
case 1024:
dftsize = DFT_1024;
break;
case 1536:
dftsize = DFT_1536;
break;
case 2048:
dftsize = DFT_2048;
break;
case 3072:
dftsize = DFT_3072;
break;
case 4096:
dftsize = DFT_4096;
break;
case 8192:
dftsize = DFT_8192;
break;
default:
printf("unsupported ofdm symbol size \n");
assert(0);
}
if (no_prefix) {
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
} else {
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
}
/*if (l<0 || l>=7-frame_parms->Ncp) {
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
return(-1);
}*/
if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
return(-1);
}
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
rx_offset = sample_offset + slot_offset - SOFFSET;
// Align with 256 bit
// rx_offset = rx_offset&0xfffffff8;
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int rx_offset = sample_offset + slot_offset;
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
#ifdef DEBUG_FEP
// if (ue->frame <100)
/*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
// if (ue->frame <100)
printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
#endif
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
rx_offset += frame_parms->ofdm_symbol_size * symbol;
int16_t *rxdata_ptr;
if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
if (frame_length_samples - rx_offset < frame_parms->ofdm_symbol_size) {
rx_offset += nb_prefix_samples;
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
(short*) &common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
(frame_length_samples - rx_offset) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[frame_length_samples - rx_offset],
(void *)&common_vars->rxdata[aa][0],
(frame_parms->ofdm_symbol_size - (frame_length_samples - rx_offset)) * sizeof(int32_t));
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
memcpy((void *)tmp_dft_in,
(void *) &common_vars->rxdata[aa][rx_offset],
frame_parms->ofdm_symbol_size*sizeof(int));
dft(dftsize,(int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
} else if ((rx_offset & 7) != 0) {
// if input to dft is not 256-bit aligned
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
frame_parms->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
}
} else {
rx_offset += nb_prefix_samples0;
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
(void *) &common_vars->rxdata[aa][0],
frame_parms->ofdm_symbol_size*sizeof(int));
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
memcpy((void *)tmp_dft_in,
(void *) &common_vars->rxdata[aa][rx_offset],
frame_parms->ofdm_symbol_size*sizeof(int));
dft(dftsize,(int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
}
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
// use dft input from RX buffer directly
rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
}
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft(dftsize,
rxdata_ptr,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
@@ -400,14 +265,13 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
frame_parms->ofdm_symbol_size,
15);
}
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
#endif
return(0);
return 0;
}
@@ -416,89 +280,60 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix)
int sample_offset)
{
int32_t slot_offset, rxdata_offset;
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
int tmp_dft_in[8192] __attribute__ ((aligned (32)));
dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
dft_size_idx_t dftsize;
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
switch (frame_parms->ofdm_symbol_size) {
case 128:
dftsize = DFT_128;
break;
// offset of first OFDM symbol
int32_t rxdata_offset = slot_offset + nb_prefix_samples0;
// offset of n-th OFDM symbol
rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples);
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rxdata_offset -= nb_prefix_samples / 8;
case 256:
dftsize = DFT_256;
break;
int16_t *rxdata_ptr;
case 512:
dftsize = DFT_512;
break;
if(sample_offset > rxdata_offset) {
case 1024:
dftsize = DFT_1024;
break;
memcpy((void *)&tmp_dft_in[0],
(void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset],
(sample_offset - rxdata_offset) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset],
(void *)&rxdata[0],
(frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t));
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
case 1536:
dftsize = DFT_1536;
break;
} else if (((rxdata_offset - sample_offset) & 7) != 0) {
case 2048:
dftsize = DFT_2048;
break;
// if input to dft is not 256-bit aligned
memcpy((void *)&tmp_dft_in[0],
(void *)&rxdata[rxdata_offset - sample_offset],
(frame_parms->ofdm_symbol_size) * sizeof(int32_t));
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
case 4096:
dftsize = DFT_4096;
break;
} else {
case 8192:
dftsize = DFT_8192;
break;
// use dft input from RX buffer directly
rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset];
default:
dftsize = DFT_512;
break;
}
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
if(symbol == 0)
rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
else
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
if(sample_offset>rxdata_offset) {
memcpy1((void *)tmp_dft_in,
(void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset],
(sample_offset-rxdata_offset)*sizeof(int));
memcpy1((void *)&tmp_dft_in[sample_offset-rxdata_offset],
(void *) &rxdata[0],
(frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int));
dft(dftsize,(int16_t *)&tmp_dft_in,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
}
else {
//dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset],
// (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
memcpy((void *)tmp_dft_in,
(void *) &rxdata[rxdata_offset-sample_offset],
(frame_parms->ofdm_symbol_size)*sizeof(int));
dft(dftsize,(int16_t *)&tmp_dft_in,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
}
dft(dftsize,
rxdata_ptr,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
1);
// clear DC carrier from OFDM symbols
rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
return(0);
return 0;
}
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
@@ -37,22 +37,20 @@
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
{
int temp, i, aa, max_pos = 0, max_val = 0;
short Re, Im;
uint8_t cyclic_shift = 0;
int i, aa, max_pos = 0, max_val = 0;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size);
int sync_pos = frame_parms->nb_prefix_samples / 8;
for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
temp = 0;
int temp = 0;
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
@@ -73,7 +73,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol;
k = bwp_start_subcarrier;
int re_offset = k;
int re_offset;
uint16_t nb_rb_pusch = pusch_pdu->rb_size;
@@ -170,6 +170,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
re_offset = k;
memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
+105 -23
View File
@@ -141,6 +141,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
int16_t **tx_layers = (int16_t**)dlsch->txdataF;
int16_t **txdataF_precoding = (int16_t**)dlsch->txdataF_precoding;
int8_t Wf[2], Wt[2], l0, l_prime, l_overline, delta;
uint8_t dmrs_Type = rel15->dmrsConfigType;
int nb_re_dmrs;
@@ -264,9 +265,6 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
}
#endif
/// Antenna port mapping
//to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
/// DMRS QPSK modulation
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
if (rel15->dlDmrsSymbPos & (1 << l)) {
@@ -290,7 +288,9 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart+rel15->BWPStart)*NR_NB_SC_PER_RB;
if (start_sc >= frame_parms->ofdm_symbol_size)
start_sc -= frame_parms->ofdm_symbol_size;
int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
#ifdef DEBUG_DLSCH_MAPPING
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
@@ -311,9 +311,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol);
#endif
uint16_t m=0, dmrs_idx=0, k=0;
int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
uint16_t m=0, dmrs_idx=0;
// Loop Over OFDM symbols:
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
@@ -347,7 +345,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
}
}
k = start_sc;
uint16_t k = start_sc;
// Loop Over SCs:
for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
/* check if cuurent RE is PTRS RE*/
@@ -367,12 +365,12 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
/* Map DMRS Symbol */
if ( ( dmrs_symbol_map & (1 << l) ) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
dmrs_idx++;
k_prime++;
@@ -381,8 +379,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
}
/* Map PTRS Symbol */
else if(is_ptrs_re){
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
@@ -391,17 +389,20 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
ptrs_idx++;
}
/* Map DATA Symbol */
else {
if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
else if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
m++;
}
m++;
}
/* mute RE */
else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0;
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
@@ -409,6 +410,87 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
} // symbol loop
}// layer loop
///Layer Precoding and Antenna port mapping
// tx_layers 1-8 are mapped on antenna ports 1000-1007
// The precoding info is supported by nfapi such as numPRGs, prgSize, and PMIdx
// The same precoding matrix is applied on prgSize RBs, Thus
// pmi = PMIdx[rbidx/prgSize], rbidx =0,...,rbSize-1
// The Precoding matrix:
// The Codebook Type I and Type II are not supported yet.
// We adopt the precoding matrices of PUSCH for 4 layers.
for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
uint16_t k = start_sc;
for (int rb=0; rb<rel15->rbSize; rb++) {
//get pmi info
uint8_t pmi;
if (rel15->precodingAndBeamforming.prgSize > 0)
pmi = rel15->precodingAndBeamforming.PMIdx[(int)rb/rel15->precodingAndBeamforming.prgSize];
else
pmi = 0;//no precoding
if (pmi == 0) {//unitary Precoding
if(ap<rel15->nrOfLayers)
memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
(void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)],
NR_NB_SC_PER_RB*sizeof(int32_t));
else
memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset +k],
0,
NR_NB_SC_PER_RB*sizeof(int32_t));
k += NR_NB_SC_PER_RB;
if (k >= frame_parms->ofdm_symbol_size) {
k -= frame_parms->ofdm_symbol_size;
}
}
else {
//get the precoding matrix weights:
char *W_prec;
switch (frame_parms->nb_antennas_tx) {
case 1://1 antenna port
W_prec = nr_W_1l_2p[pmi][ap];
break;
case 2://2 antenna ports
if (rel15->nrOfLayers == 1)//1 layer
W_prec = nr_W_1l_2p[pmi][ap];
else//2 layers
W_prec = nr_W_2l_2p[pmi][ap];
break;
case 4://4 antenna ports
if (rel15->nrOfLayers == 1)//1 layer
W_prec = nr_W_1l_4p[pmi][ap];
else if (rel15->nrOfLayers == 2)//2 layers
W_prec = nr_W_2l_4p[pmi][ap];
else if (rel15->nrOfLayers == 3)//3 layers
W_prec = nr_W_3l_4p[pmi][ap];
else//4 layers
W_prec = nr_W_4l_4p[pmi][ap];
break;
default:
LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
W_prec = nr_W_1l_2p[pmi][ap];
break;
}
for (int i=0; i<NR_NB_SC_PER_RB; i++) {
int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset);
((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
#ifdef DEBUG_DLSCH_MAPPING
printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
#endif
if (++k >= frame_parms->ofdm_symbol_size) {
k -= frame_parms->ofdm_symbol_size;
}
}
}
} //RB loop
} // symbol loop
}// port loop
dlsch->slot_tx[slot]=0;
}// dlsch loop
+34 -41
View File
@@ -61,10 +61,8 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273 +1;
}
}
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY,"Freeing dlsch %p\n",dlsch);
#endif
@@ -133,7 +131,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273 +1;
}
}
uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
@@ -145,31 +143,30 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
dlsch->Mdlharq = Mdlharq;
dlsch->Mlimit = 4;
dlsch->Nsoft = Nsoft;
for (layer=0; layer<NR_MAX_NB_LAYERS; layer++) {
dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(64 * sizeof(int32_t *));
for (aa = 0; aa < 64; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t));
for (re = 0; re < OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
for (layer=0; layer<NR_MAX_NB_LAYERS; layer++) {
dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
for (aa=0; aa<64; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
}
}
dlsch->txdataF[layer] =
(int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH / NR_MAX_NB_LAYERS)
* sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
dlsch->txdataF_precoding[layer] = (int32_t *)malloc16(2*14*frame_parms->ofdm_symbol_size*sizeof(int32_t));
}
for (int q = 0; q < NR_MAX_NB_CODEWORDS; q++)
dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH * sizeof(int32_t));
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
dlsch->calib_dl_ch_estimates = (int32_t **)malloc16(64 * sizeof(int32_t *));
for (aa = 0; aa < 64; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t));
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*));
for (aa=0; aa<64; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
}
for (i = 0; i < 20; i++) {
for (i=0; i<20; i++) {
dlsch->harq_ids[0][i] = 0;
dlsch->harq_ids[1][i] = 0;
}
@@ -268,7 +265,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
float Coderate = 0.0;
uint8_t Nl = 4;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = rel15->TBSize[0]<<3;
@@ -304,7 +300,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
harq->B = A+24;
// harq->b = a;
@@ -323,7 +319,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
a[1+(A>>3)] = ((uint8_t*)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
harq->B = A+16;
// harq->b = a;
@@ -339,17 +335,17 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
Coderate = (float) R /(float) 1024;
else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
Coderate = (float) R /(float) 2048;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
harq->BG = 2;
else
harq->BG = 1;
start_meas(dlsch_segmentation_stats);
Kb = nr_segmentation(harq->b, harq->c, harq->B, &harq->C, &harq->K, Zc, &harq->F, harq->BG);
stop_meas(dlsch_segmentation_stats);
F = harq->F;
Kr = harq->K;
#ifdef DEBUG_DLSCH_CODING
uint16_t Kr_bytes;
@@ -357,7 +353,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
#endif
//printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,harq->K,Kr,BG,harq->C);
for (r=0; r<harq->C; r++) {
//d_tmp[r] = &harq->d[r][0];
//channel_input[r] = &harq->d[r][0];
@@ -369,7 +365,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
LOG_D(PHY,"%d ", harq->c[r][cnt]);
}
LOG_D(PHY,"\n");
#endif
//ldpc_encoder_orig((unsigned char*)harq->c[r],harq->d[r],*Zc,Kb,Kr,BG,0);
//ldpc_encoder_optim((unsigned char*)harq->c[r],(unsigned char*)&harq->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
@@ -380,23 +376,22 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
impp.tinput = tinput;
impp.tparity = tparity;
impp.toutput = toutput;
for(int j=0;j<(harq->C/8+1);j++) {
impp.macro_num=j;
nrLDPC_encoder(harq->c,harq->d,*Zc,Kb,Kr,harq->BG,&impp);
}
#ifdef DEBUG_DLSCH_CODING
write_output("enc_input0.m","enc_in0",&harq->c[0][0],Kr_bytes,1,4);
write_output("enc_output0.m","enc0",&harq->d[0][0],(3*8*Kr_bytes)+12,1,4);
#endif
F = harq->F;
Kr = harq->K;
for (r=0; r<harq->C; r++) {
if (F>0) {
for (int k=(Kr-F-2*(*Zc)); k<Kr-2*(*Zc); k++) {
// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
@@ -405,15 +400,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
//printf("r %d filler bits [%d] = %d \n", r,k, harq->d[r][k]);
}
}
#ifdef DEBUG_DLSCH_CODING
LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
#endif
E = nr_get_E(G, harq->C, mod_order, rel15->nrOfLayers, r);
//#ifdef DEBUG_DLSCH_CODING
LOG_D(PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
r,
@@ -423,13 +416,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
F,
Kr-F-2*(*Zc),
mod_order,nb_rb);
// for tbslbrm calculation according to 5.4.2.1 of 38.212
if (rel15->nrOfLayers < Nl)
Nl = rel15->nrOfLayers;
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
start_meas(dlsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
+286 -191
View File
@@ -301,205 +301,300 @@ void rx_nr_prach_ru(RU_t *ru,
// do DFT
if (mu==1) {
if (fp->N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL);
else if (fp->N_RB_UL < 137) {
if (fp->threequarter_fs==0) {
//40 MHz @ 61.44 Ms/s
//50 MHz @ 61.44 Ms/s
prach2 = prach[aa] + (Ncp<<2); // 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);
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;
}
}
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;
}
}// 839 sequence
else {
if (prachStartSymbol == 0)
prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
break;
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;
}
}
} else { // threequarter sampling
// 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) {
AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=36864;
dft(DFT_36864,prach2,rxsigF[aa],1);
reps++;
}
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 {
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;
}
} // short format
} // 3/4 sampling
} // <=50 MHz BW
else if (fp->N_RB_UL <= 273) {
if (fp->threequarter_fs==0) {
prach2 = prach[aa] + (Ncp<<3);
//80,90,100 MHz @ 122.88 Ms/s
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)
if (prach_sequence_length == 0) {
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=98304;
dft(DFT_98304,prach2,rxsigF[aa],1);
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;
}
}
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 {
if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
break;
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;
}
}
} else {
AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
prach2 = prach[aa] + (6*Ncp);
// 80 MHz @ 92.16 Ms/s
if (prach_sequence_length == 0) {
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
dftlen=73728;
dft(DFT_73728,prach2,rxsigF[aa],1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2) {
dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
reps++;
}
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)
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=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;
}
}
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);
@@ -320,7 +320,7 @@ void nr_processULSegment(void* arg) {
Kr_bytes = Kr>>3;
K_bits_F = Kr-ulsch_harq->F;
t_nrLDPC_time_stats procTime;
t_nrLDPC_time_stats procTime = {0};
t_nrLDPC_time_stats* p_procTime = &procTime ;
//start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
@@ -345,6 +345,9 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
n = 0;
k_prime = 0;
rxF_ext_index = 0;
ul_ch0_ext_index = 0;
ul_ch0_index = 0;
if (is_dmrs_symbol == 0) {
//
@@ -406,7 +409,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
#if defined(__x86_64__)||defined(__i386__)
short rb, ch_amp;
unsigned char aatx,aarx;
unsigned char aarx;
__m128i *ul_ch128, ch_amp128;
// Determine scaling amplitude based the symbol
@@ -424,8 +427,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
int off = 0;
#endif
for (aatx=0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) {
for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))];
@@ -454,7 +456,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
}
}
}
}
#endif
}
@@ -471,6 +472,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
short rb;
unsigned char aatx, aarx;
char nb_antennas_ue_tx = 1;
__m128i *ul_ch128, avg128U;
int16_t x = factor2(len);
@@ -482,7 +484,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
int off = 0;
#endif
for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++)
for (aatx = 0; aatx < nb_antennas_ue_tx; aatx++)
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
//clear average level
avg128U = _mm_setzero_si128();
@@ -623,11 +625,12 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
unsigned short rb;
unsigned char aatx,aarx;
char nb_antennas_ue_tx = 1;
__m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
QAM_amp128b = _mm_setzero_si128();
for (aatx=0; aatx<frame_parms->nb_antennas_tx; aatx++) {
for (aatx=0; aatx<nb_antennas_ue_tx; aatx++) {
if (mod_order == 4) {
QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10)
@@ -1163,6 +1166,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
uint32_t nb_re_pusch, bwp_start_subcarrier;
int avgs;
int avg[4];
char nb_antennas_ue_tx = 1;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
@@ -1262,7 +1266,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
avgs = 0;
for (aatx=0;aatx<frame_parms->nb_antennas_tx;aatx++)
for (aatx=0;aatx<nb_antennas_ue_tx;aatx++)
for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
@@ -1280,7 +1284,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
gNB->pusch_vars[ulsch_id]->rxdataF_comp,
(frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL,
(nb_antennas_ue_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL,
frame_parms,
symbol,
dmrs_symbol_flag,
+6 -3
View File
@@ -1604,7 +1604,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
// estimate CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB);
int cqi;
int cqi,bit_left;
if (SNRtimes10 < -640) cqi=0;
else if (SNRtimes10 > 635) cqi=255;
else cqi=(640+SNRtimes10)/5;
@@ -1628,7 +1628,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
uci_pdu->harq.harq_payload[i] = decodedPayload[0] & 255;
decodedPayload[0]>>=8;
}
uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_harq&7))-1);
bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3);
uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<bit_left)-1);
decodedPayload[0] >>= pucch_pdu->bit_len_harq;
}
@@ -1642,6 +1643,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
// csi
if (pucch_pdu->bit_len_csi_part1>0) {
uci_pdu->pduBitmap|=4;
uci_pdu->csi_part1.csi_part1_bit_len=pucch_pdu->bit_len_csi_part1;
int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3;
if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++;
uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes);
@@ -1651,7 +1653,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255;
decodedPayload[0]>>=8;
}
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1);
bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3);
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<bit_left)-1);
decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1;
}
@@ -77,9 +77,9 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
// generate pilot
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
int re_offset = ssb_offset;
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
@@ -277,9 +277,9 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
// generate pilot
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
int re_offset = ssb_offset;
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
@@ -456,12 +456,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
// do ifft of channel estimate
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) {
if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx])
{
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset);
idft(idftsizeidx,
(int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
(int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
(int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset],
(int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1);
}
}
}
@@ -672,7 +672,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
if (ue->high_speed_flag == 0)
ch_offset = ue->frame_parms.ofdm_symbol_size ;
ch_offset = ue->frame_parms.ofdm_symbol_size;
else
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
@@ -690,11 +690,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart;
uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
int8_t delta = get_delta(p, config_type);
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset);
if (config_type == pdsch_dmrs_type1){
nushift = (p>>1)&1;
ue->frame_parms.nushift = nushift;
if (p<4) ue->frame_parms.nushift = nushift;
switch (delta) {
case 0://port 0,1
@@ -734,7 +734,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
}
} else {//pdsch_dmrs_type2
nushift = delta;
ue->frame_parms.nushift = nushift;
if (p<6) ue->frame_parms.nushift = nushift;
switch (delta) {
case 0://port 0,1
fl = filt8_l2;//left interpolation Filter should be fml
+4 -3
View File
@@ -402,11 +402,12 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
c_rb = 0;
for (int rb=0;rb<coreset_nbr_rb;rb++,c_rb++) {
c_rb_by6 = c_rb/6;
// skip zeros in frequency domain bitmap
while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0) {
c_rb+=6;
c_rb_by6 = c_rb/6;
}
c_rb+=6;
c_rb_by6 = c_rb/6;
}
LOG_DDD("c_rb=%d\n",c_rb);
rxF=NULL;
@@ -261,7 +261,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
t_nrLDPC_time_stats procTime;
t_nrLDPC_time_stats procTime = {0};
t_nrLDPC_time_stats* p_procTime =&procTime ;
if (!harq_process) {
@@ -678,7 +678,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
memcpy(harq_process->b+offset,
harq_process->c[r],
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
File diff suppressed because it is too large Load Diff
@@ -289,8 +289,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
proc,
i,
0,
is*fp->samples_per_frame+ue->ssb_offset,
0);
is*fp->samples_per_frame+ue->ssb_offset);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"Calling sss detection (normal CP)\n");
+3 -4
View File
@@ -60,16 +60,15 @@ uint16_t nr_pbch_extract(int **rxdataF,
uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int nushiftmod4 = frame_parms->nushift;
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and
// if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size;
rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size);
AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n",
symbol);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size);
rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
rxF_ext = &rxdataF_ext[aarx][symbol*20*12];
#ifdef DEBUG_PBCH
+287 -88
View File
@@ -244,86 +244,82 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
*********************************************************/
if (mu==1) {
if (fp->N_RB_UL <= 100)
AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL);
else if (fp->N_RB_UL < 137) {
if (fp->threequarter_fs == 0) {
//40 MHz @ 61.44 Ms/s
//50 MHz @ 61.44 Ms/s
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 = 49152;
dftlen = 12288;
if (prach_fmt_id == 3)
dftlen = 12288;
} // 839 sequence
else {
switch (mu){
case 1:
dftlen = 2048;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
dftlen = 3072;
} else { // 839 sequence
dftlen = 512;
}
} else { // threequarter sampling
// 40 MHz @ 46.08 Ms/s
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) {
AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n");
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
dftlen = 36864;
if (prach_fmt_id == 3)
dftlen = 9216;
} else {
switch (mu){
case 1:
dftlen = 1536;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
} // short format
} // 3/4 sampling
} // <=50 MHz BW
else if (fp->N_RB_UL <= 273) {
if (fp->threequarter_fs == 0) {
//80,90,100 MHz @ 122.88 Ms/s
} 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;
}
} else { // threequarter sampling
switch (mu){
case 1:
dftlen = 4096;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
break;
default:
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
}
} else {
AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n");
// 80 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 {
switch (mu){
case 1:
dftlen = 3072;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
}
}
}
else if (mu==3) {
if (fp->threequarter_fs)
@@ -425,15 +421,16 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
uint8_t use_extended_prach_prefix = 0;
if(fp->numerology_index == 0) {
if (prachStartSymbol == 0 || prachStartSymbol == 7)
use_extended_prach_prefix = 1;
use_extended_prach_prefix = 1;
}
else {
if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0)
use_extended_prach_prefix = 1;
use_extended_prach_prefix = 1;
}
if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps
if (fp->threequarter_fs == 0) {
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
@@ -491,13 +488,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (512*12)+Ncp;
}
}
}
else
AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL);
}
else if (fp->N_RB_UL <= 68) {//66 PRB case, 122.88 Msps
if (fp->threequarter_fs == 0) {
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
@@ -555,13 +548,211 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (1024*12)+Ncp;
}
}
break;
default:
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
}
else
AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL);
}
else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s
if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s
Ncp<<=1; //to account for 61.44Mbps
} 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: // 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 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){
@@ -587,7 +778,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
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
} 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
@@ -649,7 +840,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (2048*12)+Ncp;
}
}
} else { // threequarter sampling @ 46.08 Ms/s
break;
case 46080: // threequarter sampling @ 46.08 Ms/s
Ncp = (Ncp*3)/2;
prach2 = prach+(Ncp<<1);
if (prach_sequence_length == 0){
@@ -738,9 +931,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (1536*12)+Ncp;
}
}
}
} else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s
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
@@ -828,7 +1021,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (4096*12)+Ncp;
}
}
} else { // three quarter sampling @ 92.16 Ms/s
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){
@@ -915,6 +1110,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
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);
}
}
@@ -686,11 +686,8 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t nr_slot_rx,
NR_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for single antenna eNB transmission.
@@ -698,67 +695,61 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
@param dl_ch_estimates Channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
@param pmi subband Precoding matrix indicator
@param pmi_ext Extracted PMI for chosen RBs
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param nr_slot_rx Slot number
@param high_speed_flag
@param n_dmrs_cdm_groups
@param frame_parms Pointer to frame descriptor
*/
unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
unsigned short pmi,
unsigned char *pmi_ext,
unsigned char symbol,
uint8_t pilots,
uint8_t config_type,
unsigned short start_rb,
unsigned short nb_pdsch_rb,
unsigned char nr_slot_rx,
uint32_t high_speed_flag,
unsigned short nb_rb_pdsch,
uint8_t n_dmrs_cdm_groups,
NR_DL_FRAME_PARMS *frame_parms,
uint16_t dlDmrsSymbPos);
/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
NR_DL_FRAME_PARMS *frame_parms)
unsigned char symbol
uint8_t pilots,
uint8_t config_type,
unsigned short start_rb,
unsigned short nb_rb_pdsch,
uint8_t n_dmrs_cdm_groups,
uint8_t Nl,
NR_DL_FRAME_PARMS *frame_parms,
uint16_t dlDmrsSymbPos)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for dual antenna eNB transmission.
for the current allocation and for multiple layer antenna gNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_ch_estimates Channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
@param pmi subband Precoding matrix indicator
@param pmi_ext Extracted PMI for chosen RBs
@param rb_alloc RB allocation vector
@param Nl nb of antenna layers
@param symbol Symbol to extract
@param nr_slot_rx Slot index
@param high_speed_flag
@param n_dmrs_cdm_groups
@param frame_parms Pointer to frame descriptor
*/
unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
unsigned short pmi,
unsigned char *pmi_ext,
unsigned char symbol,
uint8_t pilots,
unsigned short start_rb,
unsigned short nb_rb_pdsch,
unsigned char nr_slot_rx,
uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms,
MIMO_mode_t mimo_mode);
unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
unsigned char symbol,
uint8_t pilots,
uint8_t config_type,
unsigned short start_rb,
unsigned short nb_rb_pdsch,
uint8_t n_dmrs_cdm_groups,
uint8_t Nl,
NR_DL_FRAME_PARMS *frame_parms,
uint16_t dlDmrsSymbPos);
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
@@ -812,8 +803,9 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
int32_t **dl_ch_magb,
int32_t **dl_ch_magr,
int32_t **rxdataF_comp,
int32_t **rho,
int32_t ***rho,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t nb_aatx,
uint8_t symbol,
uint8_t start_symbol,
uint8_t first_symbol_flag,
@@ -827,7 +819,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
int **rho,
int ***rho,
unsigned char n_tx,
unsigned char n_rx,
unsigned char mod_order,
@@ -898,6 +890,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
int length,
int start_point);
void nr_dlsch_detection_mrc(int **rxdataF_comp,
int ***rho,
int **dl_ch_mag,
int **dl_ch_magb,
short n_tx,
short n_rx,
unsigned char symbol,
unsigned short nb_rb);
void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
int **rxdataF_comp_i,
int **rho,
@@ -971,6 +972,7 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
*/
void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
int32_t *avg,
uint8_t symbol,
uint32_t len,
@@ -1002,6 +1004,8 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
uint8_t n_rx,
NR_UE_DLSCH_t **dlsch_ue,
uint8_t symbol,
uint8_t start_symbol,
+3 -1
View File
@@ -138,8 +138,10 @@ typedef struct {
typedef struct {
/// Pointers to variables related to DLSCH harq process
NR_DL_gNB_HARQ_t harq_process;
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
/// TX buffers for UE-spec transmission (antenna layers 1,...,4 after to precoding)
int32_t *txdataF[NR_MAX_NB_LAYERS];
/// TX buffers for UE-spec transmission (antenna ports 1000 or 1001,...,1007, before precoding)
int32_t *txdataF_precoding[NR_MAX_NB_LAYERS];
/// Modulated symbols buffer
int32_t *mod_symbs[NR_MAX_NB_CODEWORDS];
/// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers?
+4 -6
View File
@@ -187,7 +187,7 @@ typedef struct {
//! estimated rssi (dBm)
short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX];
//! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][2];
int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][4][4];
//! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
int rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2];
@@ -332,12 +332,10 @@ typedef struct {
int32_t **dl_ch_magb1[8][8];
/// \brief Magnitude of Downlink Channel, first layer (256QAM level).
int32_t **dl_ch_magr0;
/// \brief Cross-correlation of two gNB signals.
/// - first index: rx antenna [0..nb_antennas_rx[
/// \brief Cross-correlation Matrix of the gNB Tx channel signals.
/// - first index: aatx*n_rx+aarx for all aatx=[0..n_tx[ and aarx=[0..nb_rx[
/// - second index: symbol [0..]
int32_t **rho;
/// never used... always send dl_ch_rho_ext instead...
int32_t **rho_i;
int32_t ***rho;
/// \brief Pointers to llr vectors (2 TBs).
/// - first index: ? [0..1] (hard coded)
/// - second index: ? [0..1179743] (hard coded)
+10 -12
View File
@@ -279,13 +279,12 @@ static void *nr_feptx_thread(void *param) {
RU_feptx_t *feptx = (RU_feptx_t *)param;
RU_t *ru;
int aa, slot, start, l, nb_antenna_ports, ret;
int aa, slot, start, l, ret;
int i;
int32_t ***bw;
NR_DL_FRAME_PARMS *fp;
int ofdm_mask_full;
int txdataF_offset;
int32_t *txdataF;
while (!oai_exit) {
ret = 0;
if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
@@ -299,7 +298,6 @@ static void *nr_feptx_thread(void *param) {
l = feptx->symbol;
fp = ru->nr_frame_parms;
start = feptx->symbol;
nb_antenna_ports = feptx->nb_antenna_ports;
ofdm_mask_full = (1<<(ru->nb_tx*2))-1;
if(ru->num_gNB != 0){
@@ -314,16 +312,16 @@ static void *nr_feptx_thread(void *param) {
}
else {
bw = ru->beam_weights[0];
txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset];
for(i=0; i<fp->symbols_per_slot>>1; ++i){
nr_beam_precoding(&txdataF,
nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF,
ru->common.txdataF_BF,
fp,
bw,
slot,
l+i,
aa,
nb_antenna_ports);
ru->nb_log_antennas,
txdataF_offset);//here
}
}
stop_meas(&ru->precoding_stats);
@@ -362,7 +360,8 @@ static void *nr_feptx_thread(void *param) {
slot,
l,
aa,
nb_antenna_ports);
ru->nb_log_antennas,
0);
}
stop_meas(&ru->precoding_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0);
@@ -485,7 +484,8 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
tti_tx,
l,
aa,
ru->nb_log_antennas);
ru->nb_log_antennas,
0);
}// for (aa=0;aa<ru->nb_tx;aa++)
}// for (l=0;l<fp->symbols_per_slot;l++)
}// if (ru->nb_tx == 1)
@@ -520,8 +520,7 @@ void nr_fep0(RU_t *ru, int first_half) {
ru->common.rxdataF[aa],
l,
proc->tti_rx,
ru->N_TA_offset,
0);
ru->N_TA_offset);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0);
@@ -657,8 +656,7 @@ void nr_fep_full(RU_t *ru, int slot) {
ru->common.rxdataF[aa],
l,
proc->tti_rx,
ru->N_TA_offset,
0);
ru->N_TA_offset);
}
}
+5 -15
View File
@@ -189,7 +189,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
if ((frame&127) == 0) dump_pdsch_stats(gNB);
//apply the OFDM symbol rotation here
apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[0][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size);
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[aa][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
}
@@ -349,7 +351,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
int timing_advance_update, cqi;
int sync_pos;
uint16_t mu = gNB->frame_parms.numerology_index;
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
@@ -357,18 +358,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
// pdu->data = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b;
sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC
timing_advance_update = sync_pos * (1 << mu); // scale by the used scs numerology
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
switch (gNB->frame_parms.N_RB_DL) {
case 106: timing_advance_update /= 16; break;
case 217: timing_advance_update /= 32; break;
case 245: timing_advance_update /= 32; break;
case 273: timing_advance_update /= 32; break;
case 66: timing_advance_update /= 12; break;
case 32: timing_advance_update /= 12; break;
default: AssertFatal(0==1,"No case defined for PRB %d to calculate timing_advance_update\n",gNB->frame_parms.N_RB_DL);
}
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
timing_advance_update = sync_pos / bw_scaling;
// put timing advance command in 0..63 range
timing_advance_update += 31;
@@ -499,15 +492,12 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
unsigned char aa;
for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) {
// nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
nr_slot_fep_ul(&gNB->frame_parms,
gNB->common_vars.rxdata[aa],
gNB->common_vars.rxdataF[aa],
symbol,
slot_rx,
0,
0);
}
}
+78 -147
View File
@@ -203,20 +203,15 @@ uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){
}
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t get_bw_scaling(uint16_t nb_rb){
uint16_t bw_scaling;
switch (nb_rb) {
case 32: bw_scaling = 4; break;
case 66: bw_scaling = 8; break;
case 106: bw_scaling = 16; break;
case 217: bw_scaling = 32; break;
case 245: bw_scaling = 32; break;
case 273: bw_scaling = 32; break;
default: abort();
}
return bw_scaling;
// convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second
// 16 * 64 * T_c / (2^mu) * samples_per_second
// = 16 * T_s / (2^mu) * samples_per_second
// = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size)
// = 16 * 1 / 2048 * ofdm_symbol_size
// = 16 * ofdm_symbol_size / 2048
static inline
uint16_t get_bw_scaling(uint16_t ofdm_symbol_size){
return 16 * ofdm_symbol_size / 2048;
}
// UL time alignment procedures:
@@ -234,12 +229,10 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
uint8_t numerology = ue->frame_parms.numerology_index;
uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;
int factor_mu = 1 << numerology;
uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu;
ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling;
LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
__FUNCTION__,
@@ -783,7 +776,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
for (m = s0; m < (s0 +s1); m++) {
if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) {
for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers
for (uint8_t aatx=0; aatx<dlsch0->harq_processes[harq_pid]->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
nr_pdsch_channel_estimation(ue,
proc,
0 /*eNB_id*/,
@@ -838,43 +831,24 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
slot = 1;
start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]);
#endif
// process DLSCH received in first slot
// skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) == 0) {
// process DLSCH received symbols in the slot
// symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function)
if (pdsch == PDSCH || pdsch == SI_PDSCH || pdsch == RA_PDSCH) {
if (nr_rx_pdsch(ue,
proc,
pdsch,
eNB_id,
eNB_id_i,
frame_rx,
nr_slot_rx,
m,
first_symbol_flag,
dual_stream_UE,
i_mod,
dlsch0->current_harq_pid) < 0)
return -1;
}
else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1];
else if (pdsch == PDSCH || pdsch == SI_PDSCH) {
if (nr_rx_pdsch(ue,
proc,
pdsch,
eNB_id,
eNB_id_i,
frame_rx,
nr_slot_rx,
m,
first_symbol_flag,
dual_stream_UE,
i_mod,
dlsch0->current_harq_pid) < 0)
return -1;
}
else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
}
if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]);
proc,
pdsch,
eNB_id,
eNB_id_i,
frame_rx,
nr_slot_rx,
m,
first_symbol_flag,
dual_stream_UE,
i_mod,
dlsch0->current_harq_pid) < 0)
return -1;
} else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]);
#if DISABLE_LOG_X
@@ -884,10 +858,9 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
#endif
#endif
if(first_symbol_flag)
{
proc->first_symbol_available = 1;
}
if(first_symbol_flag) {
proc->first_symbol_available = 1;
}
} // CRNTI active
}
return 0;
@@ -908,35 +881,21 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
int harq_pid = dlsch0->current_harq_pid;
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
int ret=0, ret1=0;
uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX;
NR_UE_PDSCH *pdsch_vars;
uint8_t is_cw0_active = 0;
uint8_t is_cw1_active = 0;
uint8_t dmrs_type, nb_re_dmrs;
uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos);
uint16_t nb_symb_sch = 9;
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind;
uint16_t number_pdus = 1;
// params for UL time alignment procedure
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe;
uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl;
int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d;
uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP
// TODO this should corresponds to the switching time as defined in
// TS 38.133
uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
uint32_t t_subframe = 1; // subframe duration of 1 msec
uint16_t start_symbol;
float tc_factor;
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
uint16_t start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
uint8_t nb_re_dmrs;
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
}
@@ -944,6 +903,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
}
uint8_t is_cw1_active = 0;
if(dlsch1)
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
@@ -1206,53 +1166,29 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
}
// TODO CRC check for CW0
// Check CRC for CW 0
/*if (ret == (1+dlsch0->max_turbo_iterations)) {
*dlsch_errors=*dlsch_errors+1;
if(dlsch0->rnti != 0xffff){
LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
ue->Mod_id,dlsch0->rnti,
harq_pid,frame_rx,nr_slot_rx,
dlsch0->harq_processes[harq_pid]->rvidx,
dlsch0->harq_processes[harq_pid]->round,
dlsch0->harq_processes[harq_pid]->mcs,
dlsch0->harq_processes[harq_pid]->TBS);
}
} else {
if(dlsch0->rnti != 0xffff){
LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
ue->Mod_id,dlsch0->rnti,
harq_pid,frame_rx,nr_slot_rx,
dlsch0->harq_processes[harq_pid]->rvidx,
dlsch0->harq_processes[harq_pid]->round,
dlsch0->harq_processes[harq_pid]->mcs,
dlsch0->harq_processes[harq_pid]->TBS);
}
if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){
int j;
LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
LOG_T(PHY,"\n");
}*/
if (ue->mac_enabled == 1) {
uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL);
/* Time Alignment procedure
// - UE processing capability 1
// - Setting the TA update to be applied after the reception of the TA command
// - Timing adjustment computed according to TS 38.213 section 4.2
// - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
// computed according to sections 5.3 and 6.4 of TS 38.214 */
factor_mu = 1 << numerology;
N_TA_max = 3846 * bw_scaling / factor_mu;
const int numerology = ue->frame_parms.numerology_index;
const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
const int samples_per_subframe = ue->frame_parms.samples_per_subframe;
const int slots_per_frame = ue->frame_parms.slots_per_frame;
const int slots_per_subframe = ue->frame_parms.slots_per_subframe;
const double tc_factor = 1.0 / samples_per_subframe;
const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
const int Ta_max = 3846; // Max value of 12 bits TA Command
const double N_TA_max = Ta_max * bw_scaling * tc_factor;
/* PDSCH decoding time N_1 for processing capability 1 */
int N_1;
if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0)
N_1 = pdsch_N_1_capability_1[numerology][1];
else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available
@@ -1261,12 +1197,12 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
N_1 = pdsch_N_1_capability_1[numerology][3];
/* PUSCH preapration time N_2 for processing capability 1 */
N_2 = pusch_N_2_timing_capability_1[numerology][1];
mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
const int N_2 = pusch_N_2_timing_capability_1[numerology][1];
/* d_1_1 depending on the number of PDSCH symbols allocated */
d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
int d_1_1 = 0;
mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
if (mapping_type_dl == typeA)
if (nb_symb_sch + start_symbol < 7)
d_1_1 = 7 - (nb_symb_sch + start_symbol);
@@ -1281,22 +1217,26 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
/* d_2_1 */
int d_2_1;
mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
if (mapping_type_ul == typeB && start_symbol != 0)
d_2_1 = 0;
else
d_2_1 = 1;
/* d_2_2 */
const double d_2_2 = 0.0; // set to 0 because there is only 1 BWP: TODO this should corresponds to the switching time as defined in TS 38.133
/* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
// N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
if (N_t_2 < d_2_2) N_t_2 = d_2_2;
/* Time alignment procedure */
// N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc
// N_t_1 + N_t_2 + N_TA_max must be in msec
tc_factor = 64 * 0.509 * 10e-7;
ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe);
const double t_subframe = 1.0; // subframe duration of 1 msec
const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe);
if (ul_time_alignment->apply_ta == 1){
ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
@@ -1310,13 +1250,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
}
}
/*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
}*/
// TODO CRC check for CW1
}
}
@@ -1714,15 +1647,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
// looking for pbch only in slot where it is supposed to be
if (slot_ssb) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN);
LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
for (int i=1; i<4; i++) {
nr_slot_fep(ue,
proc,
(ue->symbol_offset+i)%(fp->symbols_per_slot),
nr_slot_rx,
0,
0);
nr_slot_rx);
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
@@ -1753,6 +1685,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
nr_ue_rrc_measurements(ue, proc, nr_slot_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT);
}
}
@@ -1766,18 +1699,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
nr_gold_pdcch(ue, 0, 2);
LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN);
for (uint16_t l=0; l<nb_symb_pdcch; l++) {
#if UE_TIMING_TRACE
start_meas(&ue->ofdm_demod_stats);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
nr_slot_fep(ue,
proc,
l,
nr_slot_rx,
0,
0);
nr_slot_rx);
dci_cnt = 0;
for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
@@ -1795,7 +1726,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
coreset_nb_rb);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
stop_meas(&ue->ofdm_demod_stats);
#endif
@@ -1803,6 +1733,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
if (dci_cnt > 0) {
@@ -1818,6 +1749,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
}
if (dlsch) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN);
uint8_t harq_pid = dlsch->current_harq_pid;
NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
@@ -1836,10 +1768,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
nr_slot_fep(ue,
proc,
m, //to be updated from higher layer
nr_slot_rx,
0,
0);
nr_slot_rx);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT);
}
} else {
LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx);
@@ -1853,7 +1784,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
// do procedures for C-RNTI
int ret_pdsch = 0;
if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
ret_pdsch = nr_ue_pdsch_procedures(ue,
proc,
gNB_id,
@@ -1862,6 +1793,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
NULL);
nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
}
// do procedures for SI-RNTI
@@ -1910,7 +1842,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
// deactivate dlsch once dlsch proc is done
ue->dlsch_p[gNB_id]->active = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
}
+100 -52
View File
@@ -174,7 +174,8 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
void config_common(int Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
);
@@ -205,6 +206,7 @@ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
openair0_config_t openair0_cfg[MAX_CARDS];
void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg);
void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg);
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
@@ -297,7 +299,7 @@ int main(int argc, char **argv)
//uint8_t frame_mod4,num_pdcch_symbols = 0;
SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
SCM_t channel_model = AWGN; // AWGN Rayleigh1 Rayleigh1_anticorr;
NB_UE_INST = 1;
//double pbch_sinr;
@@ -456,7 +458,7 @@ int main(int argc, char **argv)
case 'y':
n_tx=atoi(optarg);
if ((n_tx==0) || (n_tx>2)) {
if ((n_tx==0) || (n_tx>4)) {//extend gNB to support n_tx = 4
printf("Unsupported number of tx antennas %d\n",n_tx);
exit(-1);
}
@@ -466,7 +468,7 @@ int main(int argc, char **argv)
case 'z':
n_rx=atoi(optarg);
if ((n_rx==0) || (n_rx>2)) {
if ((n_rx==0) || (n_rx>4)) {//extend UE to support n_tx = 4
printf("Unsupported number of rx antennas %d\n",n_rx);
exit(-1);
}
@@ -601,7 +603,8 @@ int main(int argc, char **argv)
InitSinLUT();
get_softmodem_params()->phy_test = 1;
get_softmodem_params()->do_ra = 0;
if (snr1set==0)
snr1 = snr0+10;
init_dlsch_tpool(dlsch_threads);
@@ -674,20 +677,26 @@ int main(int argc, char **argv)
rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));
NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
prepare_scc(rrc.carrier.servingcellconfigcommon);
uint64_t ssb_bitmap = 1;
fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
fix_scc(scc,ssb_bitmap);
fill_default_secondaryCellGroup(scc,
secondaryCellGroup,
0,
1,
n_tx,
0);
prepare_scd(scd);
fill_default_secondaryCellGroup(scc,
scd,
secondaryCellGroup,
0,
1,
n_tx,
0);
/* RRC parameter validation for secondaryCellGroup */
fix_scd(scd);
/* -U option modify DMRS */
if(modify_dmrs) {
update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg);
@@ -703,9 +712,9 @@ int main(int argc, char **argv)
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
// common configuration
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
@@ -753,7 +762,7 @@ int main(int argc, char **argv)
gNB2UE = new_channel_desc_scm(n_tx,
n_rx,
channel_model,
fs,
fs/1e6,//sampling frequency in MHz
bw,
30e-9,
0,
@@ -768,28 +777,28 @@ int main(int argc, char **argv)
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
s_re = malloc(2*sizeof(double*));
s_im = malloc(2*sizeof(double*));
r_re = malloc(2*sizeof(double*));
r_im = malloc(2*sizeof(double*));
txdata = malloc(2*sizeof(int*));
for (i=0; i<2; i++) {
s_re = malloc(n_tx*sizeof(double*));
s_im = malloc(n_tx*sizeof(double*));
r_re = malloc(n_rx*sizeof(double*));
r_im = malloc(n_rx*sizeof(double*));
txdata = malloc(n_tx*sizeof(int*));
for (i=0; i<n_tx; i++) {
s_re[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(s_re[i],frame_length_complex_samples*sizeof(double));
s_im[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(s_im[i],frame_length_complex_samples*sizeof(double));
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(txdata[i],frame_length_complex_samples*sizeof(int));
}
for (i=0; i<n_rx; i++) {
r_re[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(r_re[i],frame_length_complex_samples*sizeof(double));
r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(r_im[i],frame_length_complex_samples*sizeof(double));
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(txdata[i],frame_length_complex_samples*sizeof(int));
}
if (pbch_file_fd!=NULL) {
@@ -804,6 +813,7 @@ int main(int argc, char **argv)
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*));
PHY_vars_UE_g[0][0] = UE;
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
UE->frame_parms.nb_antennas_rx = n_rx;
if (run_initial_sync==1) UE->is_synchronized = 0;
else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
@@ -874,7 +884,7 @@ int main(int argc, char **argv)
scheduled_response.CC_id = 0;
scheduled_response.frame = frame;
scheduled_response.slot = slot;
scheduled_response.thread_id = UE_proc.thread_id;
scheduled_response.thread_id = 0;
nr_ue_phy_config_request(&UE_mac->phy_config);
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
@@ -983,9 +993,9 @@ int main(int argc, char **argv)
int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
if (n_trials==1) {
LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
}
int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
@@ -1009,45 +1019,79 @@ int main(int argc, char **argv)
}
if (n_trials==1) {
LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
char filename[100];//LOG_M
for (aa=0;aa<n_tx;aa++) {
sprintf(filename,"txsig%d.m", aa);//LOG_M
LOG_M(filename,"txs", &txdata[aa][tx_offset+frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0],6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples),1,1);
}
}
if (output_fd) {
printf("writing txdata to binary file\n");
fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
}
int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
// if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev));
int txlev[n_tx];
int txlev_sum = 0;
int l_ofdm = 6;
for (aa=0; aa<n_tx; aa++) {
txlev[aa] = signal_energy(&txdata[aa][tx_offset+l_ofdm*frame_parms->ofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
txlev_sum += txlev[aa];
if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum);
}
for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0));
i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0));
i++) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
s_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
s_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
}
}
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
//AWGN
sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
//Compute AWGN variance
sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
sigma2 = pow(10, sigma2_dB/10);
if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
for (aa=0; aa<n_rx; aa++) {
bzero(r_re[aa],frame_length_complex_samples*sizeof(double));
bzero(r_im[aa],frame_length_complex_samples*sizeof(double));
}
// Apply MIMO Channel
if (channel_model != AWGN) multipath_tv_channel(gNB2UE,
s_re,
s_im,
r_re,
r_im,
frame_length_complex_samples,
0);
for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
i++) {
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
for (int aa_rx=0; aa_rx<n_rx; aa_rx++) {
if (channel_model == AWGN) {
// sum up signals from different Tx antennas
r_re[aa_rx][i] = 0;
r_im[aa_rx][i] = 0;
for (aa=0; aa<n_tx; aa++) {
r_re[aa_rx][i] += s_re[aa][i];
r_im[aa_rx][i] += s_im[aa][i];
}
}
// Add Gaussian noise
((short*) UE->common_vars.rxdata[aa_rx])[2*i] = (short) ((r_re[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
((short*) UE->common_vars.rxdata[aa_rx])[2*i+1] = (short) ((r_im[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
/* Add phase noise if enabled */
if (pdu_bit_map & 0x1) {
phase_noise(ts, &((short*) UE->common_vars.rxdata[aa])[2*i],
&((short*) UE->common_vars.rxdata[aa])[2*i+1]);
phase_noise(ts, &((short*) UE->common_vars.rxdata[aa_rx])[2*i],
&((short*) UE->common_vars.rxdata[aa_rx])[2*i+1]);
}
}
}
@@ -1087,10 +1131,10 @@ int main(int argc, char **argv)
available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2);
printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) );
}
for (i = 0; i < available_bits; i++) {
if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) ||
if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) ||
((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0)))
{
if(errors_scrambling == 0) {
@@ -1099,7 +1143,7 @@ int main(int argc, char **argv)
}
errors_scrambling++;
}
}
for (i = 0; i < TBS; i++) {
@@ -1227,12 +1271,16 @@ int main(int argc, char **argv)
}
}*/
for (i = 0; i < 2; i++) {
free_channel_desc_scm(gNB2UE);
for (i = 0; i < n_tx; i++) {
free(s_re[i]);
free(s_im[i]);
free(txdata[i]);
}
for (i = 0; i < n_rx; i++) {
free(r_re[i]);
free(r_im[i]);
free(txdata[i]);
}
free(s_re);
@@ -222,6 +222,7 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL
void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap);
void prepare_scc(NR_ServingCellConfigCommon_t *scc);
void prepare_scd(NR_ServingCellConfig_t *scd);
ngap_gNB_config_t ngap_config;
uint32_t ngap_generate_gNB_id(void) {return 0;}
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
+3 -5
View File
@@ -101,8 +101,8 @@ void nr_phy_config_request_sim_pbchsim(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;
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
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);
if (mu>2) fp->nr_band = 257;
else fp->nr_band = 78;
fp->threequarter_fs= 0;
@@ -698,9 +698,7 @@ int main(int argc, char **argv)
nr_slot_fep(UE,
&proc,
i%frame_parms->symbols_per_slot,
ssb_slot,
0,
0);
ssb_slot);
nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf);
+4 -1
View File
@@ -465,7 +465,10 @@ int main(int argc, char **argv){
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
uint64_t absoluteFrequencyPointA = (mu==1 ? 640000 : 2070833);
uint64_t absoluteFrequencyPointA = to_nrarfcn(frame_parms->nr_band,
frame_parms->dl_CarrierFreq,
frame_parms->numerology_index,
frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index));
uint8_t subframe = slot/frame_parms->slots_per_subframe;
+56 -49
View File
@@ -82,6 +82,7 @@ double cpuf;
//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
@@ -619,8 +620,8 @@ int main(int argc, char **argv)
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx;
//frame_parms->nb_antennas_tx = n_tx;
//frame_parms->nb_antennas_rx = n_rx;
frame_parms->N_RB_DL = N_RB_DL;
frame_parms->N_RB_UL = N_RB_UL;
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
@@ -638,6 +639,7 @@ int main(int argc, char **argv)
rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));
NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
prepare_scc(rrc.carrier.servingcellconfigcommon);
uint64_t ssb_bitmap;
@@ -645,7 +647,10 @@ int main(int argc, char **argv)
fix_scc(scc,ssb_bitmap);
prepare_scd(scd);
fill_default_secondaryCellGroup(scc,
scd,
secondaryCellGroup,
0,
1,
@@ -654,13 +659,16 @@ int main(int argc, char **argv)
// xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
/* RRC parameter validation for secondaryCellGroup */
fix_scd(scd);
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
// common configuration
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
rrc_mac_config_req_gNB(0,0,n_tx,n_rx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
rrc_mac_config_req_gNB(0,0,1,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
@@ -1065,70 +1073,69 @@ int main(int argc, char **argv)
}
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
//nr_fill_ulsch(gNB,frame,slot,pusch_pdu); // Not needed as its its already filled as apart of "nr_schedule_response(Sched_INFO);"
for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
if (input_fd == NULL) {
// set FAPI parameters for UE, put them in the scheduled response and call
nr_ue_scheduled_response(&scheduled_response);
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
///////////
phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
if (n_trials==1) {
LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
}
///////////
////////////////////////////////////////////////////
tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
// set FAPI parameters for UE, put them in the scheduled response and call
nr_ue_scheduled_response(&scheduled_response);
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
///////////
phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
if (n_trials==1) {
LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
}
///////////
////////////////////////////////////////////////////
tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
}
else n_trials = 1;
if (input_fd == NULL ) {
sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
sigma = pow(10,sigma_dB/10);
sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
sigma = pow(10,sigma_dB/10);
if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)frame_parms->ofdm_symbol_size/(12*nb_rb));
if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)
frame_parms->ofdm_symbol_size/(12*nb_rb));
for (i=0; i<slot_length; i++) {
for (int aa=0; aa<1; aa++) {
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
}
}
for (i=0; i<slot_length; i++) {
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
}
}
if (UE2gNB->max_Doppler == 0) {
multipath_channel(UE2gNB,s_re,s_im,r_re,r_im,
slot_length,0,(n_trials==1)?1:0);
} else {
multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im,
2*slot_length,0);
}
for (i=0; i<slot_length; i++) {
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
if (UE2gNB->max_Doppler == 0) {
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0);
} else {
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
}
for (i=0; i<slot_length; i++) {
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
/* Add phase noise if enabled */
if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
&((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
}
}
}
}
}
}
} /*End input_fd */
if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
@@ -48,9 +48,9 @@ void multipath_tv_channel(channel_desc_t *desc,
printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,
desc->max_Doppler);
#endif
tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex));
rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex));
H_t= (double complex ** *) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *));
rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *));
H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
// tv_H_t = (double complex *) malloc(length*sizeof(double complex));
rx_temp= (double complex *) calloc(length,sizeof(double complex));
@@ -63,10 +63,10 @@ void multipath_tv_channel(channel_desc_t *desc,
}
for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
H_t[i] = (double complex **) malloc(length*sizeof(double complex *));
H_t[i] = (double complex **)malloc(desc->nb_taps*sizeof(double complex *));
for(j=0; j<length; j++) {
H_t[i][j] = (double complex *) calloc (desc->nb_taps,sizeof(double complex));
for(j=0; j<desc->nb_taps; j++) {
H_t[i][j] = (double complex *)calloc(length,sizeof(double complex));
}
}
@@ -116,7 +116,7 @@ void multipath_tv_channel(channel_desc_t *desc,
free(rx);
for(i=0; i<desc->nb_rx*desc->nb_tx; i++) {
for(j=0; j<length; j++) {
for(j=0; j<desc->nb_taps; j++) {
free(H_t[i][j]);
}
@@ -131,14 +131,29 @@ void multipath_tv_channel(channel_desc_t *desc,
void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
int i,j,p,l,k;
double *alpha,*phi_rad,pi=acos(-1),*w_Hz;
double *alpha,***phi_rad,pi=acos(-1),***w_Hz;
alpha = (double *)calloc(desc->nb_paths,sizeof(double));
phi_rad = (double *)calloc(desc->nb_paths,sizeof(double));
w_Hz = (double *)calloc(desc->nb_paths,sizeof(double));
phi_rad = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **));
w_Hz = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **));
for(i=0; i<desc->nb_paths; i++) {
w_Hz[i]=desc->max_Doppler*cos(frand_a_b(0,2*pi));
phi_rad[i]=frand_a_b(0,2*pi);
for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
phi_rad[i] = (double **) malloc(desc->nb_taps*sizeof(double *));
w_Hz[i] = (double **) malloc(desc->nb_taps*sizeof(double *));
for(j=0; j<desc->nb_taps; j++) {
phi_rad[i][j] = (double *) malloc(desc->nb_paths*sizeof(double));
w_Hz[i][j] = (double *) malloc(desc->nb_paths*sizeof(double));
}
}
for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
for (j = 0; j<desc->nb_taps; j++) {
for(k=0; k<desc->nb_paths; k++) {
w_Hz[i][j][k] = desc->max_Doppler*cos(frand_a_b(0,2*M_PI));
phi_rad[i][j][k] = frand_a_b(0,2*M_PI);
//printf("w_hz[%d][%d][%d]=f_d*cos(theta) = %f\n",i,j,k,w_Hz[i][j][k]);
//printf("phi_rad[%d][%d][%d] = %f\n",i,j,k,phi_rad[i][j][k]);
}
}
}
if(desc->ricean_factor == 1) {
@@ -153,44 +168,34 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
}
}
/*
// This is the code when we only consider a SISO case
for(i=0;i<length;i++)
{
for(j=0;j<desc->nb_taps;j++)
{
for(p=0;p<desc->nb_paths;p++)
{
H[i][j] += sqrt(desc->amps[j]/2)*alpha[p]*cexp(-I*(2*pi*w_Hz[p]*i*(1/(desc->sampling_rate*1e6))+phi_rad[p]));
}
}
}
for(j=0;j<desc->nb_paths;j++)
{
phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi);
}
*/
// if MIMO
// SISO or MIMO
for (i=0; i<desc->nb_rx; i++) {
for(j=0; j<desc->nb_tx; j++) {
for(k=0; k<length; k++) {
for(l=0; l<desc->nb_taps; l++) {
H[i+(j*desc->nb_rx)][k][l] = 0;
for(k=0; k<desc->nb_taps; k++) {
for(l=0; l<length; l++) {
for(p=0; p<desc->nb_paths; p++) {
H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[l]/2)*alpha[p]*cexp(I*(2*pi*w_Hz[p]*k*(1/(desc->sampling_rate*1e6))+phi_rad[p]));
H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p]));
}
}
}
for(j=0; j<desc->nb_paths; j++) {
phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi);
//printf("H[tx%d][rx%d][k%d] = %f+j%f \n",j,i,k,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0]));
}
}
}
//accumlate the phase
/*for(k=0; k<desc->nb_taps; k++) {
* for(j=0; j<desc->nb_paths; j++) {
* desc->random_phase[k][j] = fmod(2*pi*w_Hz[k][j]*(length-1)*(1/(desc->sampling_rate*1e6))+phi_rad[k][j],2*pi);
* }
* }*/
free(alpha);
for(i=0; i<desc->nb_rx*desc->nb_tx; i++) {
for (j=0; j<desc->nb_taps; j++) {
free(w_Hz[i][j]);
free(phi_rad[i][j]);
}
free(w_Hz[i]);
free(phi_rad[i]);
}
free(w_Hz);
free(phi_rad);
}
@@ -203,7 +208,7 @@ void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t
for(i=0; i<((int)nb_samples-dd); i++) {
for(j=0; j<nb_taps; j++) {
if(i>j)
y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j]));
y[i+dd] += creal(h[j][i])*creal(x[i-j])-cimag(h[j][i])*cimag(x[i-j]) + I*(creal(h[j][i])*cimag(x[i-j])+cimag(h[j][i])*creal(x[i-j]));
}
}
}
+4 -4
View File
@@ -61,7 +61,7 @@ static telnetshell_vardef_t channelmod_vardef[] = {
static double snr_dB=25;
static double sinr_dB=0;
static unsigned int max_chan;
static channel_desc_t** defined_channels;
static channel_desc_t **defined_channels;
void fill_channel_desc(channel_desc_t *chan_desc,
uint8_t nb_tx,
uint8_t nb_rx,
@@ -1185,11 +1185,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
1);
break;
case Rayleigh1:
case Rayleigh1://MIMO Test uses Rayleigh1
nb_taps = 1;
Td = 0;
channel_length = 1;
ricean_factor = 1;
ricean_factor = 0.0;
aoa = .03;
maxDoppler = 0;
fill_channel_desc(chan_desc,nb_tx,
@@ -1632,7 +1632,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
void free_channel_desc_scm(channel_desc_t *ch) {
// Must be made cleanly, a lot of leaks...
defined_channels[ch->chan_idx]=NULL;
if (max_chan != 0) defined_channels[ch->chan_idx]=NULL;
if(ch->free_flags&CHANMODEL_FREE_AMPS)
free(ch->amps);
for (int i = 0; i<ch->nb_tx*ch->nb_rx; i++) {