diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf index a4d9985dcafa05dfa89b6b3f547b636cf3eeaff2..8d403cf4cea59bf0c7433bb6b16fd30ec1bc71d2 100644 --- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf @@ -236,9 +236,10 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; - pusch_proc_threads = 8; + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf index 1209a6f227f77167d113ae752e892bafbc3ae0f8..05c71c082e4a6d5e91e73e87eb0fa1f14f576110 100644 --- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 33855f2c0eb10c2d4301b57919ed9ea43e0c76d1..df2fd874cafb4fd1806aa2f76e78cf087be6a47b 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -231,10 +231,11 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; + num_cc = 1; + tr_n_preference = "local_mac"; pusch_proc_threads = 6; - } + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } ); RUs = ( diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml index 7ec3a5f1402ceb1d6365c731b6d467235a01ceda..6c11a66d912bd29a94075f7db2819a4a5185ed4a 100644 --- a/ci-scripts/xml_files/fr1_nsa_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml @@ -97,7 +97,7 @@ <desc>Ping: 20pings in 20sec</desc> <id>idefix</id> <ping_args>-c 20</ping_args> - <ping_packetloss_threshold>50</ping_packetloss_threshold> + <ping_packetloss_threshold>1</ping_packetloss_threshold> </testCase> <testCase id="050001"> @@ -105,7 +105,7 @@ <desc>Ping: 100pings in 20sec</desc> <id>idefix</id> <ping_args>-c 100 -i 0.2</ping_args> - <ping_packetloss_threshold>50</ping_packetloss_threshold> + <ping_packetloss_threshold>1</ping_packetloss_threshold> </testCase> <testCase id="070000"> @@ -114,7 +114,7 @@ <iperf_args>-u -b 20M -t 60</iperf_args> <direction>DL</direction> <id>idefix</id> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_packetloss_threshold>3</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> @@ -124,7 +124,7 @@ <iperf_args>-u -b 3M -t 60</iperf_args> <direction>UL</direction> <id>idefix</id> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_packetloss_threshold>1</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index f09d25e6d7525149ab524543874634795b0a5f61..ce09531e78da301902eaf45669d44e55d9fc9821 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -85,6 +85,7 @@ #include "T.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "executables/softmodem-common.h" #include <nfapi/oai_integration/nfapi_pnf.h> #include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h> #include <PHY/NR_ESTIMATION/nr_ul_estimation.h> @@ -534,6 +535,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/ gNB->prach_energy_counter = 0; + gNB->prb_interpolation = get_softmodem_params()->prb_interpolation; } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 24022edc37a115e43e0a2abb351d9b156736d500..76049db8ce8e64b0597830a15b215dcd9dfd8123 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -253,6 +253,7 @@ void init_tpools(uint8_t nun_dlsch_threads) { } static void get_options(void) { + nrUE_params.ofdm_offset_divisor = 8; paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ; int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); config_process_cmdline( cmdline_params,numparams,NULL); @@ -318,8 +319,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ UE->rf_map.card = card_offset; UE->rf_map.chain = CC_id + chain_offset; - LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", - UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction); + LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n", + UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation); // Set FP variables @@ -330,6 +331,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs); + fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor; + } void init_openair0(void) { @@ -487,6 +490,7 @@ int main( int argc, char **argv ) { } init_symbol_rotation(&UE[CC_id]->frame_parms); + init_timeshift_rotation(&UE[CC_id]->frame_parms); init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); #ifdef FR2_TEST diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 6bbb75e55985ac2d9572e48830ce9234aef8972a..9f2a48d6a151e8a1beb26265b3038d133e41e655 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -8,7 +8,8 @@ -#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization" +#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n" +#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument when calling config_get or config_getlist functions */ @@ -29,6 +30,7 @@ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \ + {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \ @@ -60,12 +62,14 @@ {"r" , CONFIG_HLP_PRB_SA, 0, iptr:&(fp->N_RB_DL), defintval:106, TYPE_UINT, 0}, \ {"s" , CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ + {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \ } typedef struct { uint64_t optmask; //mask to store boolean config options + uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization tpool_t Tpool; // thread pool } nrUE_params_t; diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 61e7f32da499b3241816d64b0b91e39413cef967..c6a1eb44e4959f0f4de21f4f949fa5d456b22541 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -72,6 +72,7 @@ extern "C" #define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" #define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n" +#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n" #define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n" //#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation" @@ -119,6 +120,7 @@ extern "C" #define SEND_DMRSSYNC softmodem_params.send_dmrs_sync #define USIM_TEST softmodem_params.usim_test #define USE_256QAM_TABLE softmodem_params.use_256qam_table +#define PRB_INTERPOLATION softmodem_params.prb_interpolation #define NFAPI softmodem_params.nfapi #define NON_STOP softmodem_params.non_stop @@ -153,6 +155,7 @@ extern int usrp_tx_thread; {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ {"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \ + {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \ {"usrp-tx-thread-config",CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \ {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \ @@ -246,6 +249,7 @@ typedef struct { int hw_timing_advance; uint32_t send_dmrs_sync; int use_256qam_table; + int prb_interpolation; uint8_t nfapi; int non_stop; } softmodem_params_t; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index ace934733d8d1130c00fb14200550a96e829858a..32e190679d1ecdd017a3147084c945a844661727 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -459,6 +459,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band); nr_init_frame_parms(gNB_config, fp); + fp->ofdm_offset_divisor = UINT_MAX; gNB->configured = 1; LOG_I(PHY,"gNB configured\n"); } @@ -510,7 +511,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { // } RC.gNB[Mod_id]->configured = 1; + fp->ofdm_offset_divisor = RC.gNB[Mod_id]->ofdm_offset_divisor; init_symbol_rotation(fp); + init_timeshift_rotation(fp); LOG_I(PHY,"gNB %d configured\n",Mod_id); } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index b29d679fe543cbf2f11321624e38d07de47233f5..b60e77e814b41023cfec4f64cda18286058d4de5 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -124,7 +124,7 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch, AssertFatal( pusch, "pusch==0" ); for (int i=0; i<NR_MAX_NB_LAYERS; i++) { - pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); + pusch->txdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t)); } } diff --git a/openair1/PHY/MODULATION/modulation_common.h b/openair1/PHY/MODULATION/modulation_common.h index f550eeca5f6c7f9b483e13c5a44b33eb41f1abd5..1a19bec78c83ea5b2772f91685d6235a0d5a994d 100644 --- a/openair1/PHY/MODULATION/modulation_common.h +++ b/openair1/PHY/MODULATION/modulation_common.h @@ -49,7 +49,7 @@ void PHY_ofdm_mod(int *input, void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms); -void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms); +void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot); void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index e32f6bf575add7a80ad80e60b9938bbccb770471..c81a88ff3075bd6071a8cc02b5230f29f51de7af 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -745,6 +745,23 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { } } +void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) +{ + for (int i = 0; i < fp->ofdm_symbol_size; i++) { + double poff = -i * 2.0 * M_PI * 144.0 / 2048.0 / fp->ofdm_offset_divisor; + double exp_re = cos(poff); + double exp_im = sin(-poff); + fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767); + fp->timeshift_symbol_rotation[i*2+1] = (int16_t)round(exp_im * 32767); + + if (i < 10) + LOG_I(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i, + fp->timeshift_symbol_rotation[i*2], + fp->timeshift_symbol_rotation[i*2+1], + poff); + } +} + 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; diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 547d20952fb4d7e0b5e959535c00088d026af87c..75541a13615ce851db32f45e127c7285e5db971b 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -117,6 +117,8 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); +void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp); + void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, int slot, diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 8cf9f05b9b63acd4bd4bab2e0f0296013a279302..2f075e8218d7da918b8826a6167014aef7e93d95 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -63,20 +63,62 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA } -void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms) +void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot) { - PHY_ofdm_mod(txdataF, // input - txdata, // output - frame_parms->ofdm_symbol_size, - 1, // number of symbols - frame_parms->nb_prefix_samples0, // number of prefix samples - CYCLIC_PREFIX); - PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input - txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, // output - frame_parms->ofdm_symbol_size, - nsymb - 1, - frame_parms->nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); + // This function works only slot wise. For more generic symbol generation refer nr_feptx0() + if (frame_parms->numerology_index != 0) { // case where numerology != 0 + if (!(slot%(frame_parms->slots_per_subframe/2))) { + PHY_ofdm_mod(txdataF, + txdata, + frame_parms->ofdm_symbol_size, + 1, + frame_parms->nb_prefix_samples0, + CYCLIC_PREFIX); + PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, + txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, + frame_parms->ofdm_symbol_size, + nsymb - 1, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } + else { + PHY_ofdm_mod(txdataF, + txdata, + frame_parms->ofdm_symbol_size, + nsymb, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } + } + else { // numerology = 0, longer CP for every 7th symbol + PHY_ofdm_mod(txdataF, + txdata, + frame_parms->ofdm_symbol_size, + 1, + frame_parms->nb_prefix_samples0, + CYCLIC_PREFIX); + PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, + txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, + frame_parms->ofdm_symbol_size, + 6, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + PHY_ofdm_mod(txdataF + 7*frame_parms->ofdm_symbol_size, + txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) + + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, + frame_parms->ofdm_symbol_size, + 1, + frame_parms->nb_prefix_samples0, + CYCLIC_PREFIX); + PHY_ofdm_mod(txdataF + 8*frame_parms->ofdm_symbol_size, + txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) + + 2*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0), + frame_parms->ofdm_symbol_size, + 6, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } + } void PHY_ofdm_mod(int *input, /// pointer to complex input diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 39c730bfac3a5b8c973e9e9643e40acbaf61cee0..f3c8c108dca8d28d36fdac17d0cafd9429e582f3 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -107,7 +107,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, rx_offset += frame_parms->ofdm_symbol_size * symbol; // use OFDM symbol from within 1/8th of the CP to avoid ISI - rx_offset -= nb_prefix_samples / 8; + rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor); #ifdef DEBUG_FEP // if (ue->frame <100) @@ -157,6 +157,15 @@ int nr_slot_fep(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); + + int16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + + multadd_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + shift_rot, + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + 1, + frame_parms->ofdm_symbol_size, + 15); } #ifdef DEBUG_FEP @@ -292,14 +301,15 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, // This is for misalignment issues int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); - unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); - // 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); + unsigned int rxdata_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++) + rxdata_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rxdata_offset += frame_parms->ofdm_symbol_size * symbol; + // use OFDM symbol from within 1/8th of the CP to avoid ISI - rxdata_offset -= nb_prefix_samples / 8; + rxdata_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor); int16_t *rxdata_ptr; @@ -333,9 +343,6 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, (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; } @@ -349,7 +356,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - for (int symbol=0;symbol<nsymb;symbol++) { + for (int symbol=first_symbol;symbol<nsymb;symbol++) { uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; @@ -359,5 +366,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], length, 15); + + int16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + + multadd_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], + shift_rot, + (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], + 1, + length, + 15); } } diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index e942ef2c6b52a57b2b520dd405e98b5d03c65943..57470cf98864fb73643f7c1489b89208d5175e04 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -39,23 +39,22 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) { - int i, aa, max_pos = 0, max_val = 0; - + int 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->nb_prefix_samples / 8; - for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { + const int sync_pos = 0; + + for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { int temp = 0; - for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; - short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + int Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } - if (temp > max_val) { max_pos = i; max_val = temp; @@ -65,7 +64,6 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) if (max_pos > frame_parms->ofdm_symbol_size/2) max_pos = max_pos - frame_parms->ofdm_symbol_size; - return max_pos - sync_pos; } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 8f9a7a5edf9aef3cfa913b0584ead28b9c05e012..960ad826969403ee723b3a88228762798e6b114b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -31,11 +31,13 @@ #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" +#include "executables/softmodem-common.h" //#define DEBUG_CH //#define DEBUG_PUSCH +#define NO_INTERP 1 #define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y))) int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, @@ -187,8 +189,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif //if ((gNB->frame_parms.N_RB_UL&1)==0) { - if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1){ - + if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0){ + LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -212,7 +214,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch, ul_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) @@ -243,7 +245,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch, ul_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("ul_ch addr %p\n",ul_ch); @@ -277,12 +279,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //for (int i= 0; i<16; i++) //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ul_ch+=8; + ul_ch += 8; - for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) { + for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt += 2) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -295,7 +297,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch, ul_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("ul_ch addr %p\n",ul_ch); @@ -315,10 +317,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //for (int i= 0; i<16; i++) //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ul_ch+=8; + ul_ch += 8; } @@ -337,7 +339,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //for (int i= 0; i<8; i++) //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; @@ -353,10 +355,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ul_ch+=8; + ul_ch += 8; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -425,15 +427,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #ifdef DEBUG_PUSCH ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) { - for(uint8_t idxI=0; idxI<16; idxI+=2) { + for(uint8_t idxI=0; idxI<16; idxI += 2) { printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]); } printf("%d\n",idxP); } #endif } - else { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| - + else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && gNB->prb_interpolation == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| + LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation"); // Treat first DMRS specially (left edge) rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; @@ -441,12 +443,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ul_ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - pil+=2; - ul_ch+=2; + pil += 2; + ul_ch += 2; re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size; ch_offset++; - for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt+=6){ + for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt += 6){ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; @@ -456,8 +458,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch[0] = ch_l[0]; ul_ch[1] = ch_l[1]; - pil+=2; - ul_ch+=2; + pil += 2; + ul_ch += 2; ch_offset++; multadd_real_four_symbols_vector_complex_scalar(filt8_ml2, @@ -476,17 +478,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch_r, ul_ch); - //for (int re_idx = 0; re_idx < 8; re_idx+=2) + //for (int re_idx = 0; re_idx < 8; re_idx += 2) //printf("ul_ch = %d + j*%d\n", ul_ch[re_idx], ul_ch[re_idx+1]); - ul_ch+=8; - ch_offset+=4; + ul_ch += 8; + ch_offset += 4; ul_ch[0] = ch_r[0]; ul_ch[1] = ch_r[1]; - pil+=2; - ul_ch+=2; + pil += 2; + ul_ch += 2; ch_offset++; re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size; @@ -502,7 +504,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch[0] = ch_l[0]; ul_ch[1] = ch_l[1]; - ul_ch+=2; + ul_ch += 2; ch_offset++; multadd_real_four_symbols_vector_complex_scalar(filt8_rr1, @@ -518,6 +520,385 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch_128[0] = _mm_slli_epi16 (ul_ch_128[0], 2); } + else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) {// this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a common value for the whole PRB + LOG_D(PHY,"PUSCH estimation DMRS type 1, no Freq-domain interpolation"); + int32_t ch_0, ch_1; + // First PRB + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 6; + ch[1] = ch_1 / 6; + + + + +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch; + ul_ch+=24; +#else + multadd_real_vector_complex_scalar(filt8_avlip0, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip1, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip2, + ch, + ul_ch, + 8); + ul_ch -= 24; +#endif + + for (pilot_cnt=6; pilot_cnt<6*(nb_rb_pusch-1); pilot_cnt += 6) { + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 6; + ch[1] = ch_1 / 6; + +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch; + ul_ch+=24; +#else + ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + ul_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip4, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip5, + ch, + ul_ch, + 8); + ul_ch -= 16; +#endif + } + // Last PRB + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 6; + ch[1] = ch_1 / 6; + +#if NO_INTERP + for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch; + ul_ch+=24; +#else + ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + ul_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip6, + ch, + ul_ch, + 8); +#endif + } + else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB + LOG_D(PHY,"PUSCH estimation DMRS type 2, no Freq-domain interpolation"); + int32_t ch_0, ch_1; + //First PRB + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 4; + ch[1] = ch_1 / 4; + + multadd_real_vector_complex_scalar(filt8_avlip0, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip1, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip2, + ch, + ul_ch, + 8); + ul_ch -= 24; + + for (pilot_cnt=4; pilot_cnt<4*(nb_rb_pusch-1); pilot_cnt += 4) { + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 4; + ch[1] = ch_1 / 4; + + ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + ul_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip4, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip5, + ch, + ul_ch, + 8); + ul_ch -= 16; + } + // Last PRB + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 4; + ch[1] = ch_1 / 4; + + ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + ul_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + ul_ch, + 8); + + ul_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip6, + ch, + ul_ch, + 8); + } +#ifdef DEBUG_PUSCH + ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; + for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) { + for(uint8_t idxI=0; idxI<16; idxI += 2) { + printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]); + } + printf("%d\n",idxP); + } +#endif // Convert to time domain diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 000348ae8728ef2fd2656f86db9ba317c827c5a6..4e2fbd4e715d05639ff011e5833c6247bf277194 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -174,7 +174,11 @@ void rx_nr_prach_ru(RU_t *ru, int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; - int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + int sample_offset_slot; + if (!(slot%(fp->slots_per_subframe/2))) + sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + else + sample_offset_slot = (prachStartSymbol==0?0:prachStartSymbol*(fp->ofdm_symbol_size+fp->nb_prefix_samples)); //to be checked for mu=0; LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 0bace9dbede7fc7b262b99926aed520c84ac25e7..e3b87ff233c3d9bdac5f5d461f2076b60a7aa60f 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1439,7 +1439,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, corr_tmp += corr_re*corr_re + corr_im*corr_im; } // aa loop }// group loop - + LOG_D(PHY,"cw %d, metric %f dB\n",cw,10*log10(corr_tmp)); if (corr_tmp > corr) { corr = corr_tmp; cw_ML=cw; diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c index 990f3101fd181b42686e4faa044fa9af7c788097..65ae28825201321ced5139d9bc785e2284f1f076 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c @@ -239,3 +239,24 @@ short filt8_dcll2[8] = { short filt8_dclh2[8] = { 0,0,0,0,1489,2979,4468,5958}; + +short filt8_avlip0[8] = { +16384,16384,16384,16384,16384,16384,16384,15019}; + +short filt8_avlip1[8] = { +13653,12288,10923,9557,8192,6827,5461,4096}; + +short filt8_avlip2[8] = { +2731,1365,0,0,0,0,0,0}; + +short filt8_avlip3[8] = { +2731,4096,5461,6827,8192,9557,10923,12288}; + +short filt8_avlip4[8] = { +13653,15019,16384,15019,13653,12288,10923,9557}; + +short filt8_avlip5[8] = { +8192,6827,5461,4096,2731,1365,0,0}; + +short filt8_avlip6[8] = { +13653,15019,16384,16384,16384,16384,16384,16384}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index ef6137a07f161e79ab97ea37a2b0061e73f6a4d1..e28736b51daf45dc7c133f1f210d46c89abfd571 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -169,4 +169,17 @@ extern short filt8_dcll2[8]; extern short filt8_dclh2[8]; -#endif \ No newline at end of file +extern short filt8_avlip0[8]; + +extern short filt8_avlip1[8]; + +extern short filt8_avlip2[8]; + +extern short filt8_avlip3[8]; + +extern short filt8_avlip4[8]; + +extern short filt8_avlip5[8]; + +extern short filt8_avlip6[8]; +#endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index a2f824e4686e70226b8e96478b7db1229b7a3053..3908febae9bf2531e941e18777bcd8154b1ede72 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -45,25 +45,23 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, static int max_pos_fil = 0; static int count_max_pos_ok = 0; static int first_time = 1; - int temp = 0, i, aa, max_val = 0, max_pos = 0; - int diff; - short Re,Im,ncoef; + int max_val = 0, max_pos = 0; + const int sync_pos = 0; uint8_t sync_offset = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); - ncoef = 32767 - coef; + short ncoef = 32767 - coef; LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset); - // we only use channel estimates from tx antenna 0 here - for (i = 0; i < frame_parms->nb_prefix_samples; i++) { - temp = 0; + for (int i = 0; i < frame_parms->nb_prefix_samples; i++) { + int temp = 0; - for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; + int Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -73,6 +71,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, } } + if (max_pos > frame_parms->ofdm_symbol_size/2) + max_pos = max_pos - frame_parms->ofdm_symbol_size; + // filter position to reduce jitter if (clear == 1) max_pos_fil = max_pos; @@ -82,61 +83,58 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment //max_pos_fil = max_pos; - diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); - - if (frame_parms->freq_range==nr_FR2) - sync_offset = 2; - else - sync_offset = 0; - - if ( abs(diff) < (SYNCH_HYST+sync_offset) ) - ue->rx_offset = 0; - else - ue->rx_offset = diff; - - if(abs(diff)<5) - count_max_pos_ok ++; - else - count_max_pos_ok = 0; - - //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok); - - if(count_max_pos_ok > 10 && first_time == 1) - { - first_time = 0; - ue->time_sync_cell = 1; - if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) { - LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); - //mac_resynch(); - //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); - ue->UE_mode[0] = PRACH; - ue->prach_resources[gNB_id]->sync_frame = frame; - ue->prach_resources[gNB_id]->init_msg1 = 0; - } else { - ue->UE_mode[0] = PUSCH; - } - } - - if (ue->rx_offset < 0) - ue->rx_offset += frame_parms->samples_per_frame; - - if (ue->rx_offset >= frame_parms->samples_per_frame) - ue->rx_offset -= frame_parms->samples_per_frame; - - - - #ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", - subframe, - diff, - ue->rx_offset, - clear, - max_pos, - max_pos_fil, - temp,max_val, - (frame_parms->nb_prefix_samples>>3)); - #endif //DEBUG_PHY - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); + int diff = max_pos_fil - sync_pos; + + if (frame_parms->freq_range==nr_FR2) + sync_offset = 2; + else + sync_offset = 0; + + if ( abs(diff) < (SYNCH_HYST+sync_offset) ) + ue->rx_offset = 0; + else + ue->rx_offset = diff; + + if(abs(diff)<5) + count_max_pos_ok ++; + else + count_max_pos_ok = 0; + + //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok); + + if(count_max_pos_ok > 10 && first_time == 1) + { + first_time = 0; + ue->time_sync_cell = 1; + if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) { + LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); + //mac_resynch(); + //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); + ue->UE_mode[0] = PRACH; + ue->prach_resources[gNB_id]->sync_frame = frame; + ue->prach_resources[gNB_id]->init_msg1 = 0; + } else { + ue->UE_mode[0] = PUSCH; + } + } + if (ue->rx_offset < 0) + ue->rx_offset += frame_parms->samples_per_frame; + + if (ue->rx_offset >= frame_parms->samples_per_frame) + ue->rx_offset -= frame_parms->samples_per_frame; + +#ifdef DEBUG_PHY + LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n", + subframe, + diff, + ue->rx_offset, + clear, + max_pos, + max_pos_fil, + max_val, + sync_pos); +#endif //DEBUG_PHY + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index e4a82e7021fe1603df0d447d92979aad79f56163..8097b9b3ea12b3d4fa6b6c06941d21ea39b08ea6 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -94,15 +94,15 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - current_ssb->c_re +=ch[0]; - current_ssb->c_im +=ch[1]; + current_ssb->c_re += ch[0]; + current_ssb->c_im += ch[1]; #ifdef DEBUG_CH printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -110,29 +110,29 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - current_ssb->c_re +=ch[0]; - current_ssb->c_im +=ch[1]; + current_ssb->c_re += ch[0]; + current_ssb->c_im += ch[1]; #ifdef DEBUG_CH printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - current_ssb->c_re +=ch[0]; - current_ssb->c_im +=ch[1]; + current_ssb->c_re += ch[0]; + current_ssb->c_im += ch[1]; #ifdef DEBUG_CH printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { + for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) { // if (pilot_cnt == 30) // rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)]; @@ -146,14 +146,14 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - current_ssb->c_re +=ch[0]; - current_ssb->c_im +=ch[1]; + current_ssb->c_re += ch[0]; + current_ssb->c_im += ch[1]; #ifdef DEBUG_CH printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -161,13 +161,13 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - current_ssb->c_re +=ch[0]; - current_ssb->c_im +=ch[1]; + current_ssb->c_re += ch[0]; + current_ssb->c_im += ch[1]; #ifdef DEBUG_CH printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -175,14 +175,14 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - current_ssb->c_re +=ch[0]; - current_ssb->c_im +=ch[1]; + current_ssb->c_re += ch[0]; + current_ssb->c_im += ch[1]; #ifdef DEBUG_CH printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -287,7 +287,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, printf("rxF addr %p\n", rxF); printf("dl_ch addr %p\n",dl_ch); #endif - //if ((ue->frame_parms.N_RB_DL&1)==0) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -301,7 +300,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 16); - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -319,7 +318,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 16); - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -334,12 +333,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 16); - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - dl_ch+=24; + dl_ch += 24; - for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { + for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) { // if (pilot_cnt == 30) // rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)]; @@ -365,7 +364,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, //for (int i= 0; i<8; i++) // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -380,7 +379,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 16); - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -396,10 +395,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 16); - pil+=2; + pil += 2; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - dl_ch+=24; + dl_ch += 24; } @@ -458,8 +457,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } } - //} - } return(0); } @@ -526,111 +523,111 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, printf("dl_ch addr %p\n",dl_ch); #endif // if ((ue->frame_parms.N_RB_DL&1)==0) { - // Treat first 2 pilots specially (left edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + // Treat first 2 pilots specially (left edge) + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 16); - pil+=2; - rxF+=8; - //for (int i= 0; i<8; i++) - //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); + multadd_real_vector_complex_scalar(fl, + ch, + dl_ch, + 16); + pil += 2; + rxF += 8; + //for (int i= 0; i<8; i++) + //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - multadd_real_vector_complex_scalar(fm, - ch, - dl_ch, - 16); - pil+=2; - rxF+=8; + multadd_real_vector_complex_scalar(fm, + ch, + dl_ch, + 16); + pil += 2; + rxF += 8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); + multadd_real_vector_complex_scalar(fr, + ch, + dl_ch, + 16); #ifdef DEBUG_PDCCH - for (int m =0; m<12; m++) - printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); + for (int m =0; m<12; m++) + printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); #endif - pil+=2; - rxF+=8; - dl_ch+=24; - k+=12; + pil += 2; + rxF += 8; + dl_ch += 24; + k += 12; - for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) { + for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt += 3) { - if (k >= ue->frame_parms.ofdm_symbol_size){ - k-=ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];} + if (k >= ue->frame_parms.ofdm_symbol_size){ + k-=ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];} - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 16); + multadd_real_vector_complex_scalar(fl, + ch, + dl_ch, + 16); - //for (int i= 0; i<8; i++) - // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); + //for (int i= 0; i<8; i++) + // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); - pil+=2; - rxF+=8; + pil += 2; + rxF += 8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - multadd_real_vector_complex_scalar(fm, - ch, - dl_ch, - 16); - pil+=2; - rxF+=8; + multadd_real_vector_complex_scalar(fm, + ch, + dl_ch, + 16); + pil += 2; + rxF += 8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); - pil+=2; - rxF+=8; - dl_ch+=24; - k+=12; + multadd_real_vector_complex_scalar(fr, + ch, + dl_ch, + 16); + pil += 2; + rxF += 8; + dl_ch += 24; + k += 12; - } + } - //} + //} } @@ -653,7 +650,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short k; unsigned int pilot_cnt; int16_t ch_l[2],ch_r[2],ch[2],*pil,*rxF,*dl_ch; - int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr; + int16_t *fl=NULL,*fm=NULL,*fr=NULL,*fml=NULL,*fmr=NULL,*fmm=NULL,*fdcl=NULL,*fdcr=NULL,*fdclh=NULL,*fdcrh=NULL, *frl=NULL, *frr=NULL; int ch_offset,symbol_offset; NR_UE_DLSCH_t **dlsch = ue->dlsch[proc->thread_id][gNB_id]; @@ -698,99 +695,97 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, if (p<4) ue->frame_parms.nushift = nushift; switch (delta) { - case 0://port 0,1 - fl = filt8_l0;//left interpolation Filter for DMRS config. 1 - fm = filt8_m0;//left middle interpolation Filter - fr = filt8_r0;//right interpolation Filter - fmm = filt8_mm0;;//middle middle interpolation Filter - fml = filt8_m0;//left middle interpolation Filter - fmr = filt8_mr0;//middle right interpolation Filter - fdcl = filt8_dcl0;//left DC interpolation Filter (even RB) - fdcr = filt8_dcr0;//right DC interpolation Filter (even RB) - fdclh = filt8_dcl0_h;//left DC interpolation Filter (odd RB) - fdcrh = filt8_dcr0_h;//right DC interpolation Filter (odd RB) - frl = NULL; - frr = NULL; - break; - - case 1://port2,3 - fl = filt8_l1; - fm = filt8_m1; - fr = filt8_r1; - fmm = filt8_mm1; - fml = filt8_ml1; - fmr = filt8_m1; - fdcl = filt8_dcl1; - fdcr = filt8_dcr1; - fdclh = filt8_dcl1_h; - fdcrh = filt8_dcr1_h; - frl = NULL; - frr = NULL; - break; - - default: - msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); - return -1; - break; + case 0://port 0,1 + fl = filt8_l0;//left interpolation Filter for DMRS config. 1 + fm = filt8_m0;//left middle interpolation Filter + fr = filt8_r0;//right interpolation Filter + fmm = filt8_mm0;;//middle middle interpolation Filter + fml = filt8_m0;//left middle interpolation Filter + fmr = filt8_mr0;//middle right interpolation Filter + fdcl = filt8_dcl0;//left DC interpolation Filter (even RB) + fdcr = filt8_dcr0;//right DC interpolation Filter (even RB) + fdclh = filt8_dcl0_h;//left DC interpolation Filter (odd RB) + fdcrh = filt8_dcr0_h;//right DC interpolation Filter (odd RB) + frl = NULL; + frr = NULL; + break; + + case 1://port2,3 + fl = filt8_l1; + fm = filt8_m1; + fr = filt8_r1; + fmm = filt8_mm1; + fml = filt8_ml1; + fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + frl = NULL; + frr = NULL; + break; + + default: + LOG_E(PHY,"pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return -1; + break; } } else {//NFAPI_NR_DMRS_TYPE2 nushift = delta; if (p<6) ue->frame_parms.nushift = nushift; switch (delta) { - case 0://port 0,1 - fl = filt8_l2;//left interpolation Filter should be fml - fr = filt8_r2;//right interpolation Filter should be fmr - fm = filt8_l2; - fmm = filt8_r2; - fml = filt8_ml2; - fmr = filt8_mr2; - frl = filt8_rl2; - frr = filt8_rm2; - fdcl = filt8_dcl1; - fdcr = filt8_dcr1; - fdclh = filt8_dcl1_h; - fdcrh = filt8_dcr1_h; - break; - - case 2://port2,3 - fl = filt8_l3; - fm = filt8_m2; - fr = filt8_r3; - fmm = filt8_mm2; - fml = filt8_l2; - fmr = filt8_r2; - frl = filt8_rl3; - frr = filt8_rr3; - fdcl = NULL; - fdcr = NULL; - fdclh = NULL; - fdcrh = NULL; - break; - - default: - msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); - return -1; - break; + case 0://port 0,1 + fl = filt8_l2;//left interpolation Filter should be fml + fr = filt8_r2;//right interpolation Filter should be fmr + fm = filt8_l2; + fmm = filt8_r2; + fml = filt8_ml2; + fmr = filt8_mr2; + frl = filt8_rl2; + frr = filt8_rm2; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + break; + + case 2://port2,3 + fl = filt8_l3; + fm = filt8_m2; + fr = filt8_r3; + fmm = filt8_mm2; + fml = filt8_l2; + fmr = filt8_r2; + frl = filt8_rl3; + frr = filt8_rr3; + fdcl = NULL; + fdcr = NULL; + fdclh = NULL; + fdcrh = NULL; + break; + + default: + LOG_E(PHY,"pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return -1; + break; } } for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)]; + pil = (int16_t *)&pilot[rb_offset*((config_type == NFAPI_NR_DMRS_TYPE1) ? 6:4)]; k = k % ue->frame_parms.ofdm_symbol_size; re_offset = k; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)]; dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); - #ifdef DEBUG_PDSCH printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL); printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); printf("rxF addr %p p %d\n", rxF,p); printf("dl_ch addr %p nushift %d\n",dl_ch,nushift); #endif - - if (config_type == NFAPI_NR_DMRS_TYPE1) { + if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->prb_interpolation == 0) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -804,7 +799,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) @@ -819,7 +814,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("dl_ch addr %p\n",dl_ch); @@ -834,18 +829,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - //for (int i= 0; i<16; i++) - //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); - - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - dl_ch+=8; + dl_ch += 8; - for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pdsch-3); pilot_cnt+=2) { - //if ((pilot_cnt%6)==0) - //dl_ch+=4; - //printf("re_offset %d\n",re_offset); + for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pdsch-3); pilot_cnt += 2) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -857,7 +846,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; @@ -870,10 +859,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - dl_ch+=8; + dl_ch += 8; } @@ -881,7 +870,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -891,7 +880,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //for (int i= 0; i<8; i++) //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; @@ -906,10 +895,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - dl_ch+=8; + dl_ch += 8; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -921,59 +910,59 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - // check if PRB crosses DC and improve estimates around DC - if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { - dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; - uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); - uint16_t idxPil = idxDC/2; - re_offset = k; - pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)]; - pil += (idxPil-2); - dl_ch += (idxDC-4); - dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); - re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - // for proper allignment of SIMD vectors - if((ue->frame_parms.N_RB_DL&1)==0) { - - multadd_real_vector_complex_scalar(fdcl, - ch, - dl_ch-4, - 8); - - pil += 4; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[rb_offset*((config_type == NFAPI_NR_DMRS_TYPE1) ? 6:4)]; + pil += (idxPil-2); + dl_ch += (idxDC-4); + dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - multadd_real_vector_complex_scalar(fdcr, - ch, - dl_ch-4, - 8); - } else { + + // for proper allignment of SIMD vectors + if((ue->frame_parms.N_RB_DL&1) == 0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + dl_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + dl_ch-4, + 8); + } else { - multadd_real_vector_complex_scalar(fdclh, - ch, - dl_ch, - 8); - - pil += 4; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - multadd_real_vector_complex_scalar(fdcrh, - ch, - dl_ch, - 8); + multadd_real_vector_complex_scalar(fdclh, + ch, + dl_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + dl_ch, + 8); + } } - } - } else { //NFAPI_NR_DMRS_TYPE2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| + } else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->prb_interpolation == 0){ //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| // Treat first 4 pilots specially (left edge) ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -984,7 +973,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch_l[0],ch_l[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -1003,13 +992,13 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - pil+=2; + pil += 2; re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -1023,20 +1012,20 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - dl_ch+=12; + dl_ch += 12; dl_ch[0+2*nushift] = ch[0]; dl_ch[1+2*nushift] = ch[1]; dl_ch[2+2*nushift] = ch[0]; dl_ch[3+2*nushift] = ch[1]; - dl_ch+=4; + dl_ch += 4; - for (pilot_cnt=4; pilot_cnt<4*nb_rb_pdsch; pilot_cnt+=4) { + for (pilot_cnt=4; pilot_cnt<4*nb_rb_pdsch; pilot_cnt += 4) { multadd_real_vector_complex_scalar(fml, ch, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -1046,7 +1035,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch_l[0],ch_l[1],pil[0],pil[1]); #endif - pil+=2; + pil += 2; re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -1064,7 +1053,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - dl_ch+=8; + dl_ch += 8; dl_ch[0+2*nushift] = ch[0]; dl_ch[1+2*nushift] = ch[1]; dl_ch[2+2*nushift] = ch[0]; @@ -1075,13 +1064,13 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - pil+=2; + pil += 2; re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - pil+=2; + pil += 2; re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -1099,12 +1088,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); - dl_ch+=12; + dl_ch += 12; dl_ch[0+2*nushift] = ch[0]; dl_ch[1+2*nushift] = ch[1]; dl_ch[2+2*nushift] = ch[0]; dl_ch[3+2*nushift] = ch[1]; - dl_ch+=4; + dl_ch += 4; } // Treat last 2 pilots specially (right edge) @@ -1136,7 +1125,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch_l[1]= dl_ch[1] ; // for proper allignment of SIMD vectors - if((ue->frame_parms.N_RB_DL&1)==0) { + if((ue->frame_parms.N_RB_DL&1) == 0) { dl_ch -= 20; //Interpolate fdcrl1 with ch_r multadd_real_vector_complex_scalar(filt8_dcrl1, @@ -1185,11 +1174,359 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } } } + else if (config_type == NFAPI_NR_DMRS_TYPE1) { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a common value for the whole PRB + int32_t ch_0, ch_1; + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 6; + ch[1] = ch_1 / 6; + + multadd_real_vector_complex_scalar(filt8_avlip0, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip1, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip2, + ch, + dl_ch, + 8); + dl_ch -= 24; + + for (pilot_cnt=6; pilot_cnt<6*(nb_rb_pdsch-1); pilot_cnt += 6) { + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 6; + ch[1] = ch_1 / 6; + dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + dl_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip4, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip5, + ch, + dl_ch, + 8); + dl_ch -= 16; + } + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 6; + ch[1] = ch_1 / 6; + + dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + dl_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip6, + ch, + dl_ch, + 8); + } + else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB + int32_t ch_0, ch_1; + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 4; + ch[1] = ch_1 / 4; + + multadd_real_vector_complex_scalar(filt8_avlip0, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip1, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip2, + ch, + dl_ch, + 8); + dl_ch -= 24; + + for (pilot_cnt=4; pilot_cnt<4*(nb_rb_pdsch-1); pilot_cnt += 4) { + int32_t ch_0, ch_1; + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 4; + ch[1] = ch_1 / 4; + + dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + dl_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip4, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip5, + ch, + dl_ch, + 8); + dl_ch -= 16; + } + + ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15; + ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15; + + pil += 2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = ch_0 / 4; + ch[1] = ch_1 / 4; + + dl_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384 + dl_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384 + + dl_ch += 8; + multadd_real_vector_complex_scalar(filt8_avlip3, + ch, + dl_ch, + 8); + + dl_ch += 16; + multadd_real_vector_complex_scalar(filt8_avlip6, + ch, + dl_ch, + 8); + } #ifdef DEBUG_PDSCH dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pdsch*12/8); idxP++) { - for(uint8_t idxI=0; idxI<16; idxI+=2) { + for(uint8_t idxI=0; idxI<16; idxI += 2) { printf("%d\t%d\t",dl_ch[idxP*16+idxI],dl_ch[idxP*16+idxI+1]); } printf("%d\n",idxP); diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 78c10eca9853c920b6ea298b83ab035fd8b0eeed..aa8588f106f6a4718d50fed7b0f72d768372f7aa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -984,6 +984,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, } } } + pdcch_vars->nb_search_space = 0; return(dci_ind->number_of_dcis); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index f27bf52038843ad0c7cfd5a7655dc61ca67675d4..fb6e7bf6b5da04d2c47c890f7a07e51298cb2c16 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -445,8 +445,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //LOG_I(PHY, "avgs Power per SC is %d\n", avgs); median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx]; } - pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; - //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext, @@ -461,8 +459,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, avgs = cmax(avgs, median[aatx*n_rx + aarx]); } } - pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; } + + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; + //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh); } LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", frame%1024, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index e7cf3c15a913a3127a1516c9a80fc583d09f62b9..24299fd788f9373c39bed13bc9c47bd8d2d5dd96 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -102,7 +102,11 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, ue->X_u); - sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + if (slot % (fp->slots_per_subframe / 2) == 0) + sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + else + sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; + prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot; //printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index fa61b786053f37422d0a8b3ccbcbb00a4492a530..c277a8ffcc2e2b8a6f1b96ad7722776e92ff500d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1044,7 +1044,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); -int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, +int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, + NR_UE_ULSCH_t *ulsch, NR_DL_FRAME_PARMS* frame_parms, uint8_t harq_pid, unsigned int G); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 5733ef6eb3c3595481bdc9757a5877140e70e970..ba5c65ceb71086c01f6505bc4134ad9acfaaeb49 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -215,11 +215,13 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, } -int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, +int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, + NR_UE_ULSCH_t *ulsch, NR_DL_FRAME_PARMS* frame_parms, uint8_t harq_pid, unsigned int G) { + start_meas(&ue->ulsch_encoding_stats); /////////////////////////parameters and variables declaration///////////////////////// /////////// @@ -332,6 +334,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN); + start_meas(&ue->ulsch_segmentation_stats); Kb=nr_segmentation(harq_process->b, harq_process->c, harq_process->B, @@ -340,6 +343,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, pz, &harq_process->F, harq_process->BG); + stop_meas(&ue->ulsch_segmentation_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT); F = harq_process->F; @@ -374,14 +378,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, //for (int i=0;i<68*384;i++) // printf("channel_input[%d]=%d\n",i,channel_input[i]); - int temp_opp = 0; - - if (opp_enabled) { - opp_enabled = 0; - temp_opp = 1; - } - - /*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]); for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ printf("%d \n", harq_process->d[0][cnt]); @@ -397,11 +393,13 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN); + start_meas(&ue->ulsch_ldpc_encoding_stats); for(int j = 0; j < (harq_process->C/8 + 1); j++) { impp.macro_num = j; nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp); } + stop_meas(&ue->ulsch_ldpc_encoding_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT); @@ -412,8 +410,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4); #endif - if (temp_opp) opp_enabled = 1; - /////////// /////////////////////////////////////////////////////////////////////////////// LOG_D(PHY,"setting ndi to %d from pusch_data\n", harq_process->pusch_pdu.pusch_data.new_data_indicator); @@ -449,6 +445,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN); + start_meas(&ue->ulsch_rate_matching_stats); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, harq_process->BG, @@ -460,6 +457,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Kr-F-2*(*pz), harq_process->pusch_pdu.pusch_data.rv_index, E); + stop_meas(&ue->ulsch_rate_matching_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT); @@ -481,10 +479,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, //start_meas(i_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN); + start_meas(&ue->ulsch_interleaving_stats); nr_interleaving_ldpc(E, mod_order, harq_process->e+r_offset, harq_process->f+r_offset); + stop_meas(&ue->ulsch_interleaving_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT); //stop_meas(i_stats); @@ -509,5 +509,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT); + stop_meas(&ue->ulsch_encoding_stats); return(0); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 4ada19ba33108b8aa5804c12020c0edc35c0c1d2..b1addf740a2ee6c668eb03831b1841d1e1877c5e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -159,7 +159,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl); - nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G); + nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G); /////////// //////////////////////////////////////////////////////////////////// @@ -529,7 +529,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, nr_normal_prefix_mod(txdataF[ap], &txdata[ap][tx_offset], 14, - frame_parms); + frame_parms, + slot); } } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index d1fb886341ee5a494862525234fbe6b626eba548..778724218f97813c564b2bed407330624f049598 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -819,6 +819,8 @@ typedef struct PHY_VARS_gNB_s { uint32_t max_peak_val; + /// OFDM symbol offset divisor for UL + uint32_t ofdm_offset_divisor; /// \brief sinr for all subcarriers of the current link (used only for abstraction). /// first index: ? [0..N_RB_DL*12[ double *sinr_dB; @@ -838,6 +840,8 @@ typedef struct PHY_VARS_gNB_s { int **dl_precoder_SgNB[3]; char log2_maxp; /// holds the maximum channel/precoder coefficient + int prb_interpolation; + /// if ==0 enables phy only test mode int mac_enabled; /// counter to average prach energh over first 100 prach opportunities diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 7251dd6a730811f1de0689a87479a1ea708b9980..33322bccb233bf98c2197b5d36bfba6bc03464a2 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -868,7 +868,9 @@ typedef struct { uint32_t perfect_ce; - + // flag to activate PRB based averaging of channel estimates + // when off, defaults to frequency domain interpolation + int prb_interpolation; int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX]; UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX]; @@ -1005,6 +1007,7 @@ typedef struct { time_stats_t ofdm_mod_stats; time_stats_t ulsch_encoding_stats; + time_stats_t ulsch_ldpc_encoding_stats; time_stats_t ulsch_modulation_stats; time_stats_t ulsch_segmentation_stats; time_stats_t ulsch_rate_matching_stats; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 5dca6932ca371559358a0fbf28b5ad8702b66f12..c385d323e3b51e4deddd9a9e5606d8f3c045e00b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -329,6 +329,9 @@ struct NR_DL_FRAME_PARMS { /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211 /// First dimension is for the direction of the link (0 DL, 1 UL) int16_t symbol_rotation[2][224*2]; + /// sequence used to compensate the phase rotation due to timeshifted OFDM symbols + /// First dimenstion is for different CP lengths + int16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); /// shift of pilot position in one RB uint8_t nushift; /// SRS configuration from TS 38.331 RRC @@ -362,6 +365,8 @@ struct NR_DL_FRAME_PARMS { uint8_t ssb_index; /// PBCH polar encoder params t_nrPolar_params pbch_polar_params; + /// OFDM symbol offset divisor for UL + uint32_t ofdm_offset_divisor; }; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 827e986f1b20c9e3bded717c95dc4811811ff523..eb0a4f8cdc3ee46145c7b7e3474d017716163cb0 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -119,6 +119,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { fp->nb_prefix_samples, CYCLIC_PREFIX); slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size; + slot_offsetF += fp->ofdm_symbol_size; } else { PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], @@ -128,6 +129,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { fp->nb_prefix_samples0, CYCLIC_PREFIX); slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size; + slot_offsetF += fp->ofdm_symbol_size; } } } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index ceef0d84c67bc485dbff435ede853c34c69b6e67..0a87a08a56e853d557fd271fd4af24b73cdf53af 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -383,7 +383,13 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048; - timing_advance_update = sync_pos / bw_scaling; + int sync_pos_rounded; + // do some integer rounding to improve TA accuracy + if (sync_pos > 0) + sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1; + else + sync_pos_rounded = sync_pos - (bw_scaling / 2) - 1; + timing_advance_update = sync_pos_rounded / bw_scaling; // put timing advance command in 0..63 range timing_advance_update += 31; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 64be30943a74502046e3cabbf918ad6a61b5f65f..5653e2a2f18f7d385f3a33ad08fd156d1643aef3 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -70,7 +70,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ for (i = 0; i < dl_config->number_pdus; ++i){ AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus); AssertFatal(dl_config->dl_config_list[i].pdu_type<=FAPI_NR_DL_CONFIG_TYPES,"pdu_type %d > 2\n",dl_config->dl_config_list[i].pdu_type); - LOG_D(PHY, "In %s: received 1 DL %s PDU of %d total DL PDUs:\n", __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus); + LOG_D(PHY, "In %s: frame %d slot %d received 1 DL %s PDU of %d total DL PDUs:\n", + __FUNCTION__, scheduled_response->frame, slot, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus); if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) { @@ -227,9 +228,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ break; } } - memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t)); - } } return 0; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index a6a675db8978faebac534552a1cc3ec81efa7acb..4e47eb2865da056251cebf6522f65029984466f4 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -252,7 +252,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling; - LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", + LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", __FUNCTION__, ue->Mod_id, frame_tx, diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index dad6bd388f01506b91be6da1e32b0b767d943728..0886f608a9884e55d3e57518f17115fa965cf0b7 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -413,6 +413,7 @@ int main(int argc, char **argv) uint16_t rbSize = 106; uint8_t mcsIndex = 9; uint8_t dlsch_threads = 0; + int prb_inter = 0; if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[NR_DLSIM] Error, configuration module init failed\n"); } @@ -423,7 +424,7 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) { + while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) { switch (c) { case 'f': scg_fd = fopen(optarg,"r"); @@ -479,14 +480,10 @@ int main(int argc, char **argv) break; - /*case 'i': - interf1=atoi(optarg); + case 'i': + prb_inter=1; break; - case 'j': - interf2=atoi(optarg); - break;*/ - case 'n': n_trials = atoi(optarg); break; @@ -645,7 +642,7 @@ int main(int argc, char **argv) printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n"); printf("-y Number of TX antennas used in gNB\n"); printf("-z Number of RX antennas used in UE\n"); - //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n"); + printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n"); //printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n"); printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); @@ -691,6 +688,7 @@ int main(int argc, char **argv) memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0]; + gNB->ofdm_offset_divisor = UINT_MAX; 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; @@ -911,6 +909,7 @@ int main(int argc, char **argv) UE->if_inst->phy_config_request = nr_ue_phy_config_request; UE->if_inst->dl_indication = nr_ue_dl_indication; UE->if_inst->ul_indication = dummy_nr_ue_ul_indication; + UE->prb_interpolation = prb_inter; UE_mac->if_module = nr_ue_if_module_init(0); @@ -1084,7 +1083,8 @@ int main(int argc, char **argv) nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], &txdata[aa][tx_offset], 14, - frame_parms); + frame_parms, + slot); } } @@ -1319,7 +1319,7 @@ int main(int argc, char **argv) LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); if (UE->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); - LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1); + LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1); write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1); LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0); break; diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c index d02f3fa493e54b8d69690dac55a83af032c8b67e..76f4e826ee6ed740e63933def6c99682f65bdb2e 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c @@ -321,7 +321,7 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint mac->RA_attempt_number++; } -void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ +void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id){ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 80608fd95ba8a40286f31b01694eab762c6cc527..46b42666b58746a5b85a2bff4f97d111645adc07 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -135,7 +135,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band); + fp->ofdm_offset_divisor = UINT_MAX; nr_init_frame_parms(gNB_config, fp); + init_timeshift_rotation(fp); init_symbol_rotation(fp); @@ -431,6 +433,7 @@ int main(int argc, char **argv) RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0]; + gNB->ofdm_offset_divisor = UINT_MAX; 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; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index c889e6dcb994803a39e906429178e2e0991fc3e7..94aea36a670ce960ffcc663080cb48473813b31d 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -504,7 +504,7 @@ int main(int argc, char **argv) unsigned int G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl); if (input_fd == NULL) { - nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G); + nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G); } printf("\n"); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 1e09f6f7ea5a25202304ad3bbf4ed7c663bfeacc..e267c8b6d7410379bdd6ee8a8ec5c58c2472ecb3 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -302,6 +302,7 @@ int main(int argc, char **argv) float effRate; //float eff_tp_check = 0.7; uint8_t snrRun; + int prb_inter = 0; int enable_ptrs = 0; int modify_dmrs = 0; @@ -335,7 +336,7 @@ int main(int argc, char **argv) /* initialize the sin-cos table */ InitSinLUT(); - while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) { + while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) { printf("handling optarg %c\n",c); switch (c) { @@ -427,14 +428,10 @@ int main(int argc, char **argv) break; - /*case 'i': - interf1 = atoi(optarg); - break; + case 'i': + prb_inter=1; + break; - case 'j': - interf2 = atoi(optarg); - break;*/ - case 'k': printf("Setting threequarter_fs_flag\n"); openair0_cfg[0].threequarter_fs= 1; @@ -465,6 +462,14 @@ int main(int argc, char **argv) printf("Setting SNR0 to %f\n", snr0); break; + case 'u': + mu = atoi(optarg); + break; + + case 'w': + start_rb = atoi(optarg); + break; + /* case 't': eff_tp_check = (float)atoi(optarg)/100; @@ -586,13 +591,15 @@ int main(int argc, char **argv) printf("-f Number of frames to simulate\n"); printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); printf("-h This message\n"); - //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n"); //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n"); printf("-m MCS value\n"); printf("-n Number of trials to simulate\n"); printf("-p Use extended prefix mode\n"); printf("-t Delay spread for multipath channel\n"); + printf("-u Set the numerology\n"); + printf("-w Start PRB for PUSCH\n"); //printf("-x Transmission mode (1,2,6 for the moment)\n"); printf("-y Number of TX antennas used in eNB\n"); printf("-z Number of RX antennas used in UE\n"); @@ -633,10 +640,12 @@ int main(int argc, char **argv) if (N_RB_UL >= 217) sampling_frequency = 122.88; else if (N_RB_UL >= 106) sampling_frequency = 61.44; + else if (N_RB_UL >= 32) sampling_frequency = 32.72; else { printf("Need at least 106 PRBs\b"); exit(-1); } if (N_RB_UL == 273) bandwidth = 100; else if (N_RB_UL == 217) bandwidth = 80; else if (N_RB_UL == 106) bandwidth = 40; + else if (N_RB_UL == 32) bandwidth = 50; else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); } if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75; @@ -657,6 +666,7 @@ int main(int argc, char **argv) RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0]; + gNB->ofdm_offset_divisor = UINT_MAX; gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); char tp_param[] = "n"; @@ -669,6 +679,7 @@ int main(int argc, char **argv) gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t)); gNB->UL_INFO.rx_ind.number_of_pdus = 0; gNB->UL_INFO.crc_ind.number_crcs = 0; + gNB->prb_interpolation = prb_inter; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) @@ -801,7 +812,11 @@ int main(int argc, char **argv) nr_scheduled_response_t scheduled_response; fapi_nr_ul_config_request_t ul_config; fapi_nr_tx_request_t tx_req; - + + memset(&scheduled_response, 0, sizeof(scheduled_response)); + memset(&ul_config, 0, sizeof(ul_config)); + memset(&tx_req, 0, sizeof(tx_req)); + uint8_t ptrs_mcs1 = 2; uint8_t ptrs_mcs2 = 4; uint8_t ptrs_mcs3 = 10; @@ -949,9 +964,12 @@ int main(int argc, char **argv) input_fd); if (read_errors==0) exit(1); for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n", - slot_offset, - ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i], - ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]); + slot_offset, + ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i], + ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]); + + mod_order = nr_get_Qm_ul(Imcs, mcs_table); + code_rate = nr_get_code_rate_ul(Imcs, mcs_table); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { @@ -973,6 +991,10 @@ int main(int argc, char **argv) reset_meas(&gNB->ulsch_llr_stats); reset_meas(&gNB->ulsch_channel_compensation_stats); reset_meas(&gNB->ulsch_rbs_extraction_stats); + reset_meas(&UE->ulsch_ldpc_encoding_stats); + reset_meas(&UE->ulsch_rate_matching_stats); + reset_meas(&UE->ulsch_interleaving_stats); + reset_meas(&UE->ulsch_encoding_stats); clear_pusch_stats(gNB); for (trial = 0; trial < n_trials; trial++) { @@ -1165,7 +1187,7 @@ int main(int argc, char **argv) frame_parms->ofdm_symbol_size/(12*nb_rb)); for (i=0; i<slot_length; i++) { - for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) { + for (int aa=0; aa<frame_parms->nb_antennas_tx; 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]); } @@ -1233,6 +1255,8 @@ int main(int argc, char **argv) &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_M("chestF0.m","chF0", &gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + LOG_M("chestT0.m","chT0", + &gNB->pusch_vars[0]->ul_ch_estimates_time[0][0],frame_parms->ofdm_symbol_size,1,1); LOG_M("chestF0_ext.m","chF0_ext", &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); @@ -1350,6 +1374,11 @@ int main(int argc, char **argv) printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation"); printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling"); printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time"); + printStatIndent(&UE->ulsch_encoding_stats,"ULSCH total encoding time"); + printStatIndent2(&UE->ulsch_segmentation_stats,"ULSCH segmentation time"); + printStatIndent2(&UE->ulsch_ldpc_encoding_stats,"ULSCH LDPC encoder time"); + printStatIndent2(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time"); + printStatIndent2(&UE->ulsch_interleaving_stats,"ULSCH interleaving time"); //printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving"); //printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx"); //printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding"); diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index fc2bca19d5e25718e1c464e17da62565d353b541..0306713845b9f302a42a44b5bef53ae61b8030ed 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -47,6 +47,7 @@ #define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" #define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" #define CONFIG_STRING_L1_PUSCH_PROC_THREADS "pusch_proc_threads" +#define CONFIG_STRING_L1_OFDM_OFFSET_DIVISOR "ofdm_offset_divisor" #define CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD "pucch0_dtx_threshold" #define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD "prach_dtx_threshold" #define CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD "pusch_dtx_threshold" @@ -64,7 +65,8 @@ {CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_OFDM_OFFSET_DIVISOR, NULL, 0, uptr:NULL, defuintval:8, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0} \ @@ -79,9 +81,10 @@ #define L1_LOCAL_N_PORTD_IDX 7 #define L1_REMOTE_N_PORTD_IDX 8 #define L1_PUSCH_PROC_THREADS 9 -#define L1_PUCCH0_DTX_THRESHOLD 10 -#define L1_PRACH_DTX_THRESHOLD 11 -#define L1_PUSCH_DTX_THRESHOLD 12 +#define L1_OFDM_OFFSET_DIVISOR 10 +#define L1_PUCCH0_DTX_THRESHOLD 11 +#define L1_PRACH_DTX_THRESHOLD 12 +#define L1_PUSCH_DTX_THRESHOLD 13 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index cf7a7cbef8692f495781e7c5c14740b6f0716175..7e6fd61b0e0aeb23810ae663ca9bbbef5e4243b5 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -573,6 +573,7 @@ void RCconfig_NR_L1(void) { } RC.gNB[j]->pusch_proc_threads = *(L1_ParamList.paramarray[j][L1_PUSCH_PROC_THREADS].uptr); + RC.gNB[j]->ofdm_offset_divisor = *(L1_ParamList.paramarray[j][L1_OFDM_OFFSET_DIVISOR].uptr); RC.gNB[j]->pucch0_thres = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr); RC.gNB[j]->prach_thres = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr); RC.gNB[j]->pusch_thres = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 9296e0892d0402804f2692661b42b8e505ab2913..8a59b3599e65244cc9c402610cc7bff8c8a4d8e8 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -292,8 +292,8 @@ typedef struct { /// Random-access Contention Resolution Timer active flag uint8_t RA_contention_resolution_timer_active; - /// Random-access Contention Resolution Timer count value - uint8_t RA_contention_resolution_cnt; + int RA_contention_resolution_target_frame; + int RA_contention_resolution_target_slot; /// Transmitted UE Contention Resolution Identifier uint8_t cont_res_id[6]; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index bd8d5a21cb555e8a721127556337ee5d627a8327..83ff1d3a9e25176188d615f742d299222bd9b73a 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -363,7 +363,7 @@ void nr_get_prach_resources(module_id_t mod_id, void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id); -void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id); +void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id); void nr_ue_msg2_scheduler(module_id_t mod_id, uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index d485728cbb7aa42e7036ac0101eefa5a2e46f4c2..83784634fcf74b4c7aee68f76ad7c3ce722c9746 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -492,18 +492,27 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint ra->RA_attempt_number++; } -void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ +void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc) ? + RA_config_t *ra = &mac->ra; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc) ? mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; - RA_config_t *ra = &mac->ra; + long mu = (mac->scc) ? + mac->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing : + mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + int subframes_per_slot = nr_slots_per_frame[mu]/10; + + // start contention resolution timer (cnt in slots) + int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1)<<3; + + ra->RA_contention_resolution_target_frame = frameP + (RA_contention_resolution_timer_subframes/10); + ra->RA_contention_resolution_target_slot = (slotP + (RA_contention_resolution_timer_subframes * subframes_per_slot)) % nr_slots_per_frame[mu]; - LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP); + LOG_D(MAC,"In %s: [UE %d] CB-RA: contention resolution timer set in frame.slot %d.%d and expiring in %d.%d\n", + __FUNCTION__, mod_id, frameP, slotP, ra->RA_contention_resolution_target_frame, ra->RA_contention_resolution_target_slot); - // start contention resolution timer - ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8; ra->RA_contention_resolution_timer_active = 1; ra->ra_state = WAIT_CONTENTION_RESOLUTION; @@ -774,20 +783,15 @@ void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame RA_config_t *ra = &mac->ra; if (ra->RA_contention_resolution_timer_active == 1) { - - ra->RA_contention_resolution_cnt--; - - LOG_D(MAC, "In %s: [%d.%d] RA contention resolution timer %d\n", __FUNCTION__, frame, slot, ra->RA_contention_resolution_cnt); - - if (ra->RA_contention_resolution_cnt == 0) { - ra->t_crnti = 0; - ra->RA_active = 0; - ra->RA_contention_resolution_timer_active = 0; - // Signal PHY to quit RA procedure - LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id); - nr_ra_failed(module_id, cc_id, prach_resources, frame, slot); - } - + if (frame >= ra->RA_contention_resolution_target_frame && + slot >= ra->RA_contention_resolution_target_slot) { + ra->t_crnti = 0; + ra->RA_active = 0; + ra->RA_contention_resolution_timer_active = 0; + // Signal PHY to quit RA procedure + LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id); + nr_ra_failed(module_id, cc_id, prach_resources, frame, slot); + } } } @@ -810,7 +814,6 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot); - ra->RA_contention_resolution_cnt = -1; ra->RA_contention_resolution_timer_active = 0; mac->crnti = ra->t_crnti; ra->t_crnti = 0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 9ff0be318c73c86a82f0a87ba033621b0dfc24ed..7f62ee9b3e2534f651ad2953523ecb3eed9226ae 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -182,7 +182,8 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; - rel15->dci_length_options[0] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_TC, rel15->BWPSize, bwp_id); + for (int i = 0; i < rel15->num_dci_options; i++) + rel15->dci_length_options[i] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_TC, rel15->BWPSize, bwp_id); break; case NR_RNTI_SP_CSI: break; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 83133ad32464ef3af782f2ae7cd0624b7f64e4ba..d79c4af7fa94cf6e52ad7b11b92b29e67f4b4675 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -171,7 +171,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, uint16_t ssb_start_subcarrier, uint16_t cell_id) { - LOG_D(MAC,"[L2][MAC] decode mib\n"); + LOG_I(MAC,"[L2][MAC] decode mib\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); mac->physCellId = cell_id; @@ -505,7 +505,10 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15); if ((ret&1) == 1) return -1; - else if (ret == 2) dci->dci_format = NR_UL_DCI_FORMAT_0_0; + else if (ret == 2) { + dci->dci_format = NR_UL_DCI_FORMAT_0_0; + def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format]; + } return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci)); } @@ -2493,9 +2496,10 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; //switch to DCI_0_0 - if (dci_pdu_rel15->format_indicator == 0) + if (dci_pdu_rel15->format_indicator == 0) { + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15); - + } #ifdef DEBUG_EXTRACT_DCI LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); #endif @@ -2691,6 +2695,12 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, pos++; dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + //switch to DCI_0_0 + if (dci_pdu_rel15->format_indicator == 0) { + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; + return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15); + } + if (dci_pdu_rel15->format_indicator == 0) return 1; // discard dci, format indicator not corresponding to dci_format @@ -2829,40 +2839,62 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, break; case NR_RNTI_TC: - /* - // indicating a DL DCI format 1bit - dci_pdu->= (*dci_pdu>>(dci_size-pos)format_indicator&1)<<(dci_size-pos++); - // Freq domain assignment max 16 bit + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu); +#endif + if (dci_pdu_rel15->format_indicator == 1) + return 1; // discard dci, format indicator not corresponding to dci_format fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); - for (int i=0; i<fsize; i++) - dci_pdu->= ((*dci_pdu>>(dci_size-pos)frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); +#endif // Time domain assignment 4bit - for (int i=0; i<4; i++) - dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); +#endif // Frequency hopping flag â€E1 bit - dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)frequency_hopping_flag&1)<<(dci_size-pos++); + pos++; + dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"frequency_hopping %d (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu); +#endif // MCS 5 bit - for (int i=0; i<5; i++) - dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)mcs>>(4-i))&1)<<(dci_size-pos++); + pos+=5; + dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); +#endif // New data indicator 1bit - dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ndi&1)<<(dci_size-pos++); + pos++; + dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); +#endif // Redundancy version 2bit - for (int i=0; i<2; i++) - dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)rv>>(1-i))&1)<<(dci_size-pos++); + pos+=2; + dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); +#endif // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)*dci_pdu>>(dci_size-pos)harq_pid>>(3-i))&1)<<(dci_size-pos++); - + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); +#endif // TPC command for scheduled PUSCH â€E2 bits - for (int i=0; i<2; i++) - dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)tpc>>(1-i))&1)<<(dci_size-pos++); - */ - // UL/SUL indicator â€E1 bit - /* - commented for now (RK): need to get this information from BWP descriptor - if (cfg->pucch_config.pucch_GroupHopping.value) - dci_pdu->= ((uint64_t)dci_pdu_rel15->ul_sul_indicator&1)<<(dci_size-pos++); - */ + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; +#ifdef DEBUG_EXTRACT_DCI + LOG_I(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); +#endif break; } @@ -3278,7 +3310,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, #endif */ - LOG_I(MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); + LOG_D(MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); break; case DL_SCH_LCID_CON_RES_ID: diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 0e1f83863aabef5ed71f6148922c7b9fe40946a4..f3a2496ce3e4a7ae48c0ad0d7f4e266c4d2688ba 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -879,7 +879,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in nr_dcireq_t dcireq; if(mac->cg != NULL){ // we have a cg - dcireq.module_id = mod_id; dcireq.gNB_index = gNB_index; dcireq.cc_id = cc_id; @@ -896,8 +895,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in // this is for Msg2/Msg4 if (mac->ra.ra_state >= WAIT_RAR) { fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; - rel15->num_dci_options = 1; + rel15->num_dci_options = mac->ra.ra_state == WAIT_RAR ? 1 : 2; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; + if (mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) + rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_0; // msg3 retransmission config_dci_pdu(mac, rel15, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC , -1); fill_dci_search_candidates(mac->ra.ss, rel15); dl_config->number_pdus = 1; @@ -979,11 +980,15 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in tx_req.tx_request_body[0].pdu_index = j; tx_req.tx_request_body[0].pdu = ulsch_input_buffer; + if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){ + LOG_I(NR_MAC,"[RAPROC] RA-Msg3 retransmitted\n"); + // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); + } if (ra->ra_state == WAIT_RAR && !ra->cfra){ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n"); - nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index); + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } - } } @@ -1015,7 +1020,6 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, int delta = 0; NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; - // Get the numerology to calculate the Tx frame and slot int mu = ubwp ? ubwp->bwp_Common->genericParameters.subcarrierSpacing : diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e206d877df11a09134538ba05ae2b809929a8450..3c128c6dbf50b383eb9488712c92888e6cd94cf6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -653,34 +653,229 @@ void nr_initiate_ra_proc(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } - void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) - { - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - - start_meas(&mac->schedule_ra); - for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - NR_RA_t *ra = &cc->ra[i]; - LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); - switch (ra->state) { - case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); - break; - case Msg4: - nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra); - break; - case WAIT_Msg4_ACK: - nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); - break; - default: - break; - } +void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { + + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + + start_meas(&mac->schedule_ra); + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); + switch (ra->state) { + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); + break; + case Msg3_retransmission: + nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra); + break; + case Msg4: + nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra); + break; + case WAIT_Msg4_ACK: + nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); + break; + default: + break; + } + } + } + stop_meas(&mac->schedule_ra); +} + + +void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) { + + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + + NR_BWP_Uplink_t *ubwp = ra->CellGroup ? + ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1] : + NULL; + + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ? + ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + + int mu = ubwp ? + ubwp->bwp_Common->genericParameters.subcarrierSpacing : + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + + uint8_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; + + const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); + const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; + + if (is_xlsch_in_slot(RC.nrmac[module_idP]->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) { + // beam association for FR2 + int16_t *tdd_beam_association = nr_mac->tdd_beam_association; + if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { + uint8_t tdd_period_slot = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0)) + tdd_period_slot++; + int num_tdd_period = sched_slot/tdd_period_slot; + if((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=ra->beam_id)) + return; // can't schedule retransmission in this slot + else + tdd_beam_association[num_tdd_period] = ra->beam_id; + } + + int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + int fh = 0; + int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; + + if (ra->CellGroup) { + AssertFatal(ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; + scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0; + if ((bwpStart < act_bwp_start) || (bwpSize > act_bwp_size)) + bwpStart = act_bwp_start; + } + uint16_t *vrb_map_UL = + &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; + + int rbStart = 0; + for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (bwpSize - ra->msg3_nb_rb)); i++) { + if (vrb_map_UL[rbStart + bwpStart + i]) { + rbStart += i; + i = 0; } } - stop_meas(&mac->schedule_ra); + if (rbStart > (bwpSize - ra->msg3_nb_rb)) { + // cannot find free vrb_map for msg3 retransmission in this slot + return; + } + + LOG_I(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d Scheduling retransmission of Msg3 in (%d,%d)\n", + module_idP, frame, slot, CC_id, sched_frame, sched_slot); + + nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][sched_slot]; + AssertFatal(future_ul_tti_req->SFN == sched_frame + && future_ul_tti_req->Slot == sched_slot, + "future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n", + future_ul_tti_req->SFN, + future_ul_tti_req->Slot, + sched_frame, + sched_slot); + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; + memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); + + fill_msg3_pusch_pdu(pusch_pdu, scc, + ra->msg3_round, + startSymbolAndLength, + ra->rnti, scs, + bwpSize, bwpStart, + mappingtype, fh, + rbStart, ra->msg3_nb_rb); + future_ul_tti_req->n_pdus += 1; + + // generation of DCI 0_0 to schedule msg3 retransmission + NR_SearchSpace_t *ss = ra->ra_ss; + NR_BWP_Downlink_t *bwp = NULL; + NR_ControlResourceSet_t *coreset = NULL; + + NR_BWP_t *genericParameters = NULL; + if (ra->CellGroup && + ra->CellGroup->spCellConfig && + ra->CellGroup->spCellConfig->spCellConfigDedicated && + ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList && + ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]) { + bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + genericParameters = &bwp->bwp_Common->genericParameters; + } + else { + genericParameters= &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; + } + + if (*ss->controlResourceSetId == 0) + coreset = nr_mac->sched_ctrlCommon->coreset; // this is coreset 0 + else + coreset = get_coreset(scc, bwp, ss, NR_SearchSpace__searchSpaceType_PR_common); + AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n"); + + nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id]; + + const int coresetid = coreset->controlResourceSetId; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid]; + if (!pdcch_pdu_rel15) { + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus]; + memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t)); + ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; + ul_dci_req->numPdus += 1; + nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL); + nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15; + } + + uint8_t aggregation_level; + uint8_t nr_of_candidates; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); + int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level, 0, 0, nr_of_candidates); + if (CCEIndex < 0) { + LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); + return; + } + + // Fill PDCCH DL DCI PDU + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; + pdcch_pdu_rel15->numDlDci++; + dci_pdu->RNTI = ra->rnti; + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + dci_pdu->AggregationLevel = aggregation_level; + dci_pdu->CceIndex = CCEIndex; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + dci_pdu_rel15_t uldci_payload; + memset(&uldci_payload, 0, sizeof(uldci_payload)); + + config_uldci(ubwp, + scc, + pusch_pdu, + &uldci_payload, + NR_UL_DCI_FORMAT_0_0, + ra->Msg3_tda_id, + ra->msg3_TPC, + 0, // not used in format 0_0 + ra->bwp_id); + + fill_dci_pdu_rel15(scc, + ra->CellGroup, + dci_pdu, + &uldci_payload, + NR_UL_DCI_FORMAT_0_0, + NR_RNTI_TC, + pusch_pdu->bwp_size, + ra->bwp_id); + + // Mark the corresponding RBs as used + for (int rb = 0; rb < ra->msg3_nb_rb; rb++) { + vrb_map_UL[rbStart + bwpStart + rb] = 1; + } + + // reset state to wait msg3 + ra->state = WAIT_Msg3; + ra->Msg3_frame = sched_frame; + ra->Msg3_slot = sched_slot; + } +} + void nr_get_Msg3alloc(module_id_t module_id, int CC_id, NR_ServingCellConfigCommon_t *scc, @@ -690,45 +885,45 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_RA_t *ra, int16_t *tdd_beam_association) { - // msg3 is schedulend in mixed slot in the following TDD period - - uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes - - int mu = ubwp ? - ubwp->bwp_Common->genericParameters.subcarrierSpacing : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; - int StartSymbolIndex = 0; - int NrOfSymbols = 0; - int startSymbolAndLength = 0; - int temp_slot = 0; - ra->Msg3_tda_id = 16; // initialization to a value above limit - - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ? - ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - - uint8_t k2 = 0; - for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) { - startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); - // we want to transmit in the uplink symbols of mixed slot - if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) { - k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2; - temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 - ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; - if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) { - ra->Msg3_tda_id = i; - break; - } + // msg3 is scheduled in mixed slot in the following TDD period + + uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes + + int mu = ubwp ? + ubwp->bwp_Common->genericParameters.subcarrierSpacing : + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + int StartSymbolIndex = 0; + int NrOfSymbols = 0; + int startSymbolAndLength = 0; + int temp_slot = 0; + ra->Msg3_tda_id = 16; // initialization to a value above limit + + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ? + ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + + uint8_t k2 = 0; + for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) { + startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); + // we want to transmit in the uplink symbols of mixed slot + if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) { + k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2; + temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 + ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; + if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) { + ra->Msg3_tda_id = i; + break; } } + } - AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); + AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); - if (nr_slots_per_frame[mu]>temp_slot) - ra->Msg3_frame = current_frame; - else - ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024; + if (nr_slots_per_frame[mu]>temp_slot) + ra->Msg3_frame = current_frame; + else + ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024; // beam association for FR2 if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { @@ -750,7 +945,7 @@ void nr_get_Msg3alloc(module_id_t module_id, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - /* search msg3_nb_rb free RBs */ + /* search msg3_nb_rb free RBs */ int rbSize = 0; int rbStart = 0; while (rbSize < msg3_nb_rb) { @@ -768,6 +963,75 @@ void nr_get_Msg3alloc(module_id_t module_id, ra->msg3_first_rb = rbStart; } + +void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, + NR_ServingCellConfigCommon_t *scc, + int round, + int startSymbolAndLength, + rnti_t rnti, int scs, + int bwp_size, int bwp_start, + int mappingtype, int fh, + int msg3_first_rb, int msg3_nb_rb) { + + + int start_symbol_index,nr_of_symbols; + SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols); + + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = rnti; + pusch_pdu->handle = 0; + pusch_pdu->bwp_start = bwp_start; + pusch_pdu->bwp_size = bwp_size; + pusch_pdu->subcarrier_spacing = scs; + pusch_pdu->cyclic_prefix = 0; + pusch_pdu->mcs_index = 0; + pusch_pdu->mcs_table = 0; + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) + pusch_pdu->transform_precoding = 1; + else + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = *scc->physCellId; + pusch_pdu->nrOfLayers = 1; + pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position); + LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos); + pusch_pdu->dmrs_config_type = 0; + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. + pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. + pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used + pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 + pusch_pdu->resource_alloc = 1; //type 1 + + pusch_pdu->rb_start = msg3_first_rb; + if (msg3_nb_rb > pusch_pdu->bwp_size) + AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); + else + pusch_pdu->rb_size = msg3_nb_rb; + pusch_pdu->vrb_to_prb_mapping = 0; + + pusch_pdu->frequency_hopping = fh; + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + //Resource Allocation in time domain + pusch_pdu->start_symbol_index = start_symbol_index; + pusch_pdu->nr_of_symbols = nr_of_symbols; + //Optional Data only included if indicated in pduBitmap + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round]; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 1; + pusch_pdu->pusch_data.num_cb = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + 12, // nb dmrs set for no data in dmrs symbol + 0, //nb_rb_oh + 0, // to verify tb scaling + pusch_pdu->nrOfLayers)>>3; + +} + void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) { gNB_MAC_INST *mac = RC.nrmac[module_idP]; @@ -790,7 +1054,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t vrb_map_UL[i + ra->msg3_first_rb] = 1; } - LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot]; AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame @@ -804,7 +1068,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); - future_ul_tti_req->n_pdus += 1; + int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int abwp_size = ibwp_size; @@ -837,67 +1101,20 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t ra->msg3_round, ra->rnti); - int start_symbol_index,nr_of_symbols; - SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols); - - pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - pusch_pdu->rnti = ra->rnti; - pusch_pdu->handle = 0; - + int bwp_start; if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) - pusch_pdu->bwp_start = abwp_start; + bwp_start = abwp_start; else - pusch_pdu->bwp_start = ibwp_start; - pusch_pdu->bwp_size = ibwp_size; - pusch_pdu->subcarrier_spacing = scs; - pusch_pdu->cyclic_prefix = 0; - pusch_pdu->mcs_index = 0; - pusch_pdu->mcs_table = 0; - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - pusch_pdu->transform_precoding = 1; - else - pusch_pdu->transform_precoding = 0; - pusch_pdu->data_scrambling_id = *scc->physCellId; - pusch_pdu->nrOfLayers = 1; - - pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position); - LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos); - - pusch_pdu->dmrs_config_type = 0; - pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. - pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. - pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used - pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 - pusch_pdu->resource_alloc = 1; //type 1 - //pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211 - pusch_pdu->rb_start = ra->msg3_first_rb; - if (ra->msg3_nb_rb > pusch_pdu->bwp_size) - AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); - else - pusch_pdu->rb_size = ra->msg3_nb_rb; - pusch_pdu->vrb_to_prb_mapping = 0; - - pusch_pdu->frequency_hopping = fh; - //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] - pusch_pdu->uplink_frequency_shift_7p5khz = 0; - //Resource Allocation in time domain - pusch_pdu->start_symbol_index = start_symbol_index; - pusch_pdu->nr_of_symbols = nr_of_symbols; - //Optional Data only included if indicated in pduBitmap - pusch_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213 - pusch_pdu->pusch_data.harq_process_id = 0; - pusch_pdu->pusch_data.new_data_indicator = 1; // new data - pusch_pdu->pusch_data.num_cb = 0; - pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order, - pusch_pdu->target_code_rate, - pusch_pdu->rb_size, - pusch_pdu->nr_of_symbols, - 12, // nb dmrs set for no data in dmrs symbol - 0, //nb_rb_oh - 0, // to verify tb scaling - pusch_pdu->nrOfLayers = 1)>>3; + bwp_start = ibwp_start; + + fill_msg3_pusch_pdu(pusch_pdu,scc, + ra->msg3_round, + startSymbolAndLength, + ra->rnti, scs, + ibwp_size, bwp_start, + mappingtype, fh, + ra->msg3_first_rb, ra->msg3_nb_rb); + future_ul_tti_req->n_pdus += 1; // calling function to fill rar message nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); @@ -1479,6 +1696,9 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } } + T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti), + T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->tb, harq->tb_size)); + // DL TX request nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e0e387954b0c18815a695a503d56b3627d5c7fff..42315236c8b5f46a61bf25fd5d463d4306aad0b0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -604,6 +604,7 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, uint8_t tpc, int n_ubwp, int bwp_id) { + const int bw = NRRIV2BW(ubwp ? ubwp->bwp_Common->genericParameters.locationAndBandwidth : scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); @@ -1395,41 +1396,53 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, break; case NFAPI_NR_RNTI_TC: - // indicating a DL DCI format 1bit - *dci_pdu |= (dci_pdu_rel15->format_indicator & 1) << (dci_size - pos++); + // indicating a UL DCI format 1bit + pos=1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos); // Freq domain assignment max 16 bit fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1)); - for (int i = 0; i < fsize; i++) - *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val >> (fsize - i - 1)) & 1) << (dci_size - pos++); + pos+=fsize; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos); // Time domain assignment 4bit - for (int i = 0; i < 4; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val >> (3 - i)) & 1) << (dci_size - pos++); + pos += 4; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val & ((1 << 4) - 1)) << (dci_size - pos); // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 1) << (dci_size - pos++); + pos++; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 1) << (dci_size - pos); // MCS 5 bit - for (int i = 0; i < 5; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs >> (4 - i)) & 1) << (dci_size - pos++); + pos+=5; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos); // New data indicator 1bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos++); + pos++; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos); // Redundancy version 2bit - for (int i = 0; i < 2; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv >> (1 - i)) & 1) << (dci_size - pos++); + pos+=2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv & 0x3) << (dci_size - pos); // HARQ process number 4bit - for (int i = 0; i < 4; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->harq_pid >> (3 - i)) & 1) << (dci_size - pos++); - // TPC command for scheduled PUSCH – 2 bits - for (int i = 0; i < 2; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc >> (1 - i)) & 1) << (dci_size - pos++); + pos+=4; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos); // Padding bits for (int a = pos; a < 32; a++) *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++); // UL/SUL indicator – 1 bit - /* - commented for now (RK): need to get this information from BWP descriptor - if (cfg->pucch_config.pucch_GroupHopping.value) + /* commented for now (RK): need to get this from BWP descriptor + if (cfg->pucch_config.pucch_GroupHopping.value) *dci_pdu |= - ((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&1)<<(dci_size-pos++); + ((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&1)<<(dci_size-pos++); */ + LOG_D(NR_MAC,"N_RB = %i\n", N_RB); + LOG_D(NR_MAC,"dci_size = %i\n", dci_size); + LOG_D(NR_MAC,"fsize = %i\n", fsize); + LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->frequency_hopping_flag.val = %i\n", dci_pdu_rel15->frequency_hopping_flag.val); + LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(NR_MAC,"dci_pdu_rel15->ndi = %i\n", dci_pdu_rel15->ndi); + LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid); + LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc); + LOG_D(NR_MAC,"dci_pdu_rel15->padding = %i\n", dci_pdu_rel15->padding); + break; } break; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9a3469f7d4cc50acad6c89d9469fd26aba33d771..dfd63671b47bf5b8215ae916b6c0af5c877fe08c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -526,19 +526,26 @@ void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid) sched_ctrl->sched_ul_bytes = 0; } -void handle_nr_ul_harq(module_id_t mod_id, +void handle_nr_ul_harq(const int CC_idP, + module_id_t mod_id, frame_t frame, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu) { + gNB_MAC_INST *gNB_mac = RC.nrmac[mod_id]; int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti); if (UE_id < 0) { + for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { + NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; + if (ra->state >= WAIT_Msg3 && + ra->rnti == crc_pdu->rnti) + return; + } LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti); return; } NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - int8_t harq_pid = sched_ctrl->feedback_ul_harq.head; while (crc_pdu->harq_id != harq_pid || harq_pid < 0) { LOG_W(NR_MAC, @@ -601,6 +608,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi){ + gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; NR_UE_info_t *UE_info = &gNB_mac->UE_info; @@ -799,9 +807,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (ra->state != WAIT_Msg3) continue; - LOG_W(NR_MAC, "Random Access %i failed at state %i (state is not WAIT_Msg3)\n", i, ra->state); - nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + if( (frameP!=ra->Msg3_frame) || (slotP!=ra->Msg3_slot)) + continue; + + if (ra->msg3_round >= MAX_HARQ_ROUNDS - 1) { + LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state); + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + return; + } + + LOG_W(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); + ra->msg3_round++; + ra->state = Msg3_retransmission; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 2e0d6f43a5302b01a03ffc024b39f37a8058a898..588fd31247fd74a2785b2be4805d36c74a79bdd1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -126,6 +126,8 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_RA_t *ra, int16_t *tdd_beam_association); +void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); + /* \brief Function in gNB to fill RAR pdu when requested by PHY. @param ra Instance of RA resources of gNB @param dlsch_buffer Pointer to RAR input buffer @@ -136,6 +138,15 @@ void nr_fill_rar(uint8_t Mod_idP, uint8_t * dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu); +void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, + NR_ServingCellConfigCommon_t *scc, + int round, + int startSymbolAndLength, + rnti_t rnti, int scs, + int bwp_size, int bwp_start, + int mappingtype, int fh, + int msg3_first_rb, int msg3_nb_rb); + void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); @@ -391,7 +402,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint8_t ul_cqi, const uint16_t rssi); -void handle_nr_ul_harq(module_id_t mod_id, +void handle_nr_ul_harq(const int CC_idP, + module_id_t mod_id, frame_t frame, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 6b77e1859bd5b294d1b97c57dd65b48654e4bd48..804ddec52ec0fbec89b6df576bab339976aba787 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -93,8 +93,9 @@ typedef enum { RA_IDLE = 0, Msg2 = 1, WAIT_Msg3 = 2, - Msg4 = 3, - WAIT_Msg4_ACK = 4 + Msg3_retransmission = 3, + Msg4 = 4, + WAIT_Msg4_ACK = 5 } RA_gNB_state_t; typedef struct NR_preamble_ue { diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 58a477aa36ad1e5ac9b1fa04e12161d10e1f0917..cb5bef5ab0ed7e76648d75f16e7646fefecf7ed1 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -182,7 +182,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) rx->timing_advance, rx->ul_cqi, rx->rssi); - handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc); + handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc); break; } // for (j=0;j<UL_info->crc_ind.number_crcs;j++) } // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf index ef171bf0a9748041308c13fc3c32007a81d4d32f..0fd0dd455156bd98aaeebc6fa742a3b347bf423b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf @@ -234,8 +234,10 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 360b75c67df50642b9f8487fca656523f533e12e..2c97e2cad35c3a116a97769ee07393f3ec1f7e66 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -218,8 +218,10 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index e018aef006ec0f5c9165dc56f19885f517f7c6d3..3ec84d34cec730e85ff9d843f9f62942b40f0714 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -216,8 +216,10 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index 834060b071731f9df400830291adffe6f81dab5b..90ae80fb8d0481f51c127223e2d33081bbb01bb1 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -235,6 +235,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf index 2028f405527468ba66ad4cbc5949b0099d422e6d..cd57096e006929ee6369727fb6383ab6eb24de1e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf index 35c4924ba1c1f491a8254bc83fb29c3f494f524b..5230fa91ef2f2e30ea84b0ddb7c8ca8b0c3970ee 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf index aa61153c93c3e5a87a4735ba4e3aa21c782440f0..51b252e1a49f0d5e1ce0204959cfb7ba5acb2def 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -231,8 +231,10 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf index d08234ab1678ba1e0a8e6c7d71f7aaff1f88e953..5530f33d6559d42fa3d78dd996aa21869c9f2335 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf @@ -269,6 +269,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf index f22d5f781f22d398e8fb80789f92f07c65740196..1cd08ec115d48e1c1d48e2a345a75db48592c5d3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -215,8 +215,10 @@ MACRLCs = ( L1s = ( { - num_cc = 1; - tr_n_preference = "local_mac"; + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index b57cb00779d41a7e2224fbb88b2d25dba8fc9c42..8a5fbb740f97f7420441adae959791ade2ec9e84 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -218,6 +218,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index 862185835e3dc7abd7cd306d95d345bed3144b35..705fa277e03a93c95de22fafdef6029dc6edecd4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 335c3d9f0b5aae258d9d9494d133070c5caef658..7d8b80f83c30334f9b61bb5c8fcf41da64fc150b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -230,11 +230,12 @@ MACRLCs = ( ); L1s = ( - { - num_cc = 1; - tr_n_preference = "local_mac"; - pusch_proc_threads = 8; - } + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } ); RUs = ( diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index bf75edc360e56a0130fc99177694617ef4def640..a1a49724703206dd2bfa66e44f7b06724f699011 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -214,11 +214,12 @@ MACRLCs = ( ); L1s = ( - { - num_cc = 1; - tr_n_preference = "local_mac"; - pusch_proc_threads = 8; - } + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } ); RUs = ( diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf index b4f40d2205d0c7b29b75572647962b5d30d1c59c..44d238bce242dae4829a465fe7d9d67d923f18a0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf index 639b11828ba98cb07b9257507310aa228e8e6925..a4df8399eadd61f4eb359b98b2a41700317ab99f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf index b93b530bed6f9deaf1d6be4e9b433de33613d93b..2899f6982d19101c2437ef602f6ff6f0cd028c55 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf @@ -219,6 +219,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 50276c32897ab2fd805981f17922303ce43b5868..2b646fcacd578177ac402289ed019770dd941ab2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -214,11 +214,12 @@ MACRLCs = ( ); L1s = ( - { - num_cc = 1; - tr_n_preference = "local_mac"; - pusch_proc_threads = 8; - } + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } ); RUs = ( diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 7d21dce681162e31336431a27f33b8d1aaea3f71..95b05f320b89171808bbe1d621852ad615a0bf55 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -235,6 +235,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf index 463b7d6d069ab77be97605b08acc4ea7eedd446e..f7546cde792b591721ed5e9c96712bd4b0e265e3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf @@ -251,6 +251,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 9c435f278f51998107fd0d2d8359429eb25c0138..3fd543f70fcdb8d61dd1d18bc6b4e7592e6f27ef 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -241,6 +241,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 299d15e03c3d2c3c370270a88a0b44d4b7758fbd..e69607ee574213875a3b76bb7a6a16f65ab50d55 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -241,6 +241,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; pusch_proc_threads = 8; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } );