diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 7161125f89..f0da3db241 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -236,7 +236,8 @@ void rx_func(void *param) gNB->common_vars.rxdataF[aa], slot_rx, 0, - gNB->frame_parms.Ncp==EXTENDED?12:14); + gNB->frame_parms.Ncp == EXTENDED ? 12 : 14, + link_type_ul); } } phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 18eacbff86..7896e57145 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -128,6 +128,7 @@ int dumpframe = 0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +uint64_t sidelink_frequency[MAX_NUM_CCs][4]; int rx_input_level_dBm; #if MAX_NUM_CCs == 1 @@ -317,7 +318,7 @@ void init_openair0(void) { NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms; for (card=0; cardthreequarter_fs; openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3; @@ -346,6 +347,12 @@ void init_openair0(void) { nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier); nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off); + + if (get_softmodem_params()->sl_mode == 2) { + nr_get_carrier_frequencies_sl(PHY_vars_UE_g[0][0], &sl_carrier); + nr_rf_card_config_freq(&openair0_cfg[card], sl_carrier, sl_carrier, freq_off); + } + nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off); openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 99c97eae28..418373ccb4 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -60,6 +60,7 @@ {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&(nrUE_params.chest_freq), .defintval=0, TYPE_INT, 0}, \ {"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(nrUE_params.chest_time), .defintval=0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \ + {"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000,TYPE_UINT64,0}, \ } // clang-format on diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index b8f7e6ff62..1f37c9bdea 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -58,6 +58,7 @@ extern "C" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" #define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n" #define CONFIG_HLP_SA "run gNB in standalone mode\n" +#define CONFIG_HLP_SL_MODE "sets the NR sidelink mode (0: not in sidelink mode, 1: in-coverage/gNB, 2: out-of-coverage/no gNB)" #define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n" #define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" #define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" @@ -67,6 +68,7 @@ extern "C" #define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" #define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" #define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n" +#define CONFIG_HLP_SLF "Set the sidelink frequency for all component carriers\n" #define CONFIG_HLP_CHOFF "Channel id offset\n" #define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" #define CONFIG_HLP_SOFTS_QT "Enable soft scope and L1 and L2 stats (QT)\n" @@ -115,6 +117,7 @@ extern "C" #define PHY_TEST softmodem_params.phy_test #define DO_RA softmodem_params.do_ra #define SA softmodem_params.sa +#define SL_MODE softmodem_params.sl_mode #define WAIT_FOR_SYNC softmodem_params.wait_for_sync #define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag #define CHAIN_OFFSET softmodem_params.chain_offset @@ -146,6 +149,7 @@ extern int usrp_tx_thread; {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, .iptr=&PHY_TEST, .defintval=0, TYPE_INT, 0}, \ {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \ {"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \ + {"sl-mode", CONFIG_HLP_SL_MODE, 0, .u8ptr=&SL_MODE, .defintval=0, TYPE_UINT8, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, .u8ptr=&USIM_TEST, .defintval=0, TYPE_UINT8, 0}, \ {"clock-source", CONFIG_HLP_CLK, 0, .uptr=&CLOCK_SOURCE, .defintval=0, TYPE_UINT, 0}, \ {"time-source", CONFIG_HLP_TME, 0, .uptr=&TIMING_SOURCE, .defintval=0, TYPE_UINT, 0}, \ @@ -214,6 +218,7 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ { .s3a = { config_checkstr_assign_integer, \ {"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ @@ -308,6 +313,7 @@ typedef struct { int phy_test; int do_ra; int sa; + uint8_t sl_mode; uint8_t usim_test; int emulate_rf; int wait_for_sync; //eNodeB only diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index a425d6b0f5..216c3f6a2f 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -560,7 +560,9 @@ typedef struct { typedef struct { uint16_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + uint16_t sl_bandwidth; //Carrier bandwidth for SL in MHz [38.101, sec 5.3.5] Values: 10, 20, 30, and 40 uint32_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + uint32_t sl_frequency; //Absolute frequency of SL point A in KHz [38.331, sec6.3.5 and 38.211 sec 8.2.7] uint16_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699 uint16_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used uint16_t num_tx_ant;//Number of Tx antennas @@ -568,6 +570,7 @@ typedef struct uint32_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 uint16_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699 uint16_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used + uint16_t sl_grid_size[5]; uint16_t num_rx_ant;// uint8_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index ce984759ba..c444440451 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -22,6 +22,7 @@ #include "nr_phy_init.h" #include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log.h" +#include "executables/softmodem-common.h" /// Subcarrier spacings in Hz indexed by numerology index static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; @@ -41,6 +42,18 @@ static const int nr_ssb_table[48][3] = { {93, 15, nr_ssb_type_A}, {94, 15, nr_ssb_type_A}, {96, 30, nr_ssb_type_C}}; void set_Lmax(NR_DL_FRAME_PARMS *fp) { + if (get_softmodem_params()->sl_mode == 2) { + int sl_NumSSB_WithinPeriod = 1; //TODO: Needs to be updated from RRC parameters + int sl_TimeOffsetSSB = 1; //TODO: Needs to be updated from RRC parameters + int sl_TimeInterval = 1; //TODO: Needs to be updated from RRC parameters + if ((sl_NumSSB_WithinPeriod == 4) && ((sl_TimeOffsetSSB % fp->slots_per_frame) + 3 * sl_TimeInterval < NR_NUMBER_OF_SUBFRAMES_PER_FRAME * 2)) + fp->Lmax = 4; + else if ((sl_NumSSB_WithinPeriod == 2) && ((sl_TimeOffsetSSB % fp->slots_per_frame) + sl_TimeInterval < NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) + fp->Lmax = 2; + else + fp->Lmax = 1; + return; + } // definition of Lmax according to ts 38.213 section 4.1 if (fp->dl_CarrierFreq < 6e9) { if(fp->frame_type && (fp->ssb_type==2)) @@ -151,6 +164,9 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) fp->ofdm_symbol_size <<= 1; fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2); + // TODO: Temporarily setting fp->first_carrier_offset = 0 for SL until MAC is developed + if (get_softmodem_params()->sl_mode == 2) + fp->first_carrier_offset = 0; fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9; fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu)); LOG_W(PHY,"Init: N_RB_DL %d, first_carrier_offset %d, nb_prefix_samples %d,nb_prefix_samples0 %d, ofdm_symbol_size %d\n", @@ -283,12 +299,18 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, LOG_D(PHY,"dl_bw_kHz %lu\n",dl_bw_khz); LOG_D(PHY,"dl_CarrierFreq %lu\n",fp->dl_CarrierFreq); + if (get_softmodem_params()->sl_mode == 2) { + uint64_t sl_bw_khz = (12 * config->carrier_config.sl_grid_size[config->ssb_config.scs_common]) * (15 << config->ssb_config.scs_common); + fp->sl_CarrierFreq = ((sl_bw_khz >> 1) + config->carrier_config.sl_frequency) * 1000; + } + uint64_t ul_bw_khz = (12*config->carrier_config.ul_grid_size[config->ssb_config.scs_common])*(15<ssb_config.scs_common); fp->ul_CarrierFreq = ((ul_bw_khz>>1) + config->carrier_config.uplink_frequency)*1000 ; fp->numerology_index = config->ssb_config.scs_common; fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index]; fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index]; + fp->N_RB_SL = config->carrier_config.sl_grid_size[fp->numerology_index]; fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index); int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index); @@ -307,8 +329,8 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, AssertFatal(fp->numerology_index == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, fp->numerology_index); fp->Ncp = Ncp; - - set_scs_parameters(fp, fp->numerology_index, fp->N_RB_DL); + int N_RB = (get_softmodem_params()->sl_mode == 2) ? fp->N_RB_SL : fp->N_RB_DL; + set_scs_parameters(fp, fp->numerology_index, N_RB); fp->slots_per_frame = 10* fp->slots_per_subframe; fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats @@ -332,6 +354,10 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, } fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco); + // TODO: Temporarily setting fp->ssb_start_subcarrier = 0 for SL until MAC is developed + if (get_softmodem_params()->sl_mode == 2) { + fp->ssb_start_subcarrier = 0; + } set_Lmax(fp); fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; @@ -381,6 +407,11 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink } +void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band) { + LOG_D(NR_PHY, "SL init parameters. SL freq %lu\n", sidelink_frequency); + frame_parms->sl_CarrierFreq = sidelink_frequency; + frame_parms->nr_band = nr_band; +} void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) { diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index 4c035d13d8..d025a3555f 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -29,6 +29,7 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb); int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band); void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band); +void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB); void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB); void init_nr_ue_transport(PHY_VARS_NR_UE *ue); diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 420cf07e3d..99986725c0 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -58,7 +58,8 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, unsigned char symbol, int sample_offset, bool pbch_decoded, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], + int link_type); int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, unsigned char l, diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 40ef403041..310b2f0e75 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -21,6 +21,7 @@ #include "nr_modulation.h" #include "PHY/NR_REFSIG/nr_mod_table.h" +#include "executables/softmodem-common.h" //Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j const char nr_W_1l_2p[6][2][1] = { @@ -599,6 +600,7 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { uint64_t dl_CarrierFreq = fp->dl_CarrierFreq; uint64_t ul_CarrierFreq = fp->ul_CarrierFreq; + uint64_t sl_CarrierFreq = fp->sl_CarrierFreq; double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq}; const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10; @@ -612,6 +614,10 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { double f0 = f[ll]; LOG_D(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb); c16_t *symbol_rotation = fp->symbol_rotation[ll]; + if (get_softmodem_params()->sl_mode == 2) { + f0 = (double)sl_CarrierFreq; + symbol_rotation = fp->symbol_rotation[link_type_sl]; + } double tl = 0.0; double poff = 0.0; diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 66d97980ab..09f6c94d2c 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -112,7 +112,8 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, c16_t* txdata, int slot, int first_symbol, - int nsymb); + int nsymb, + int link_type); void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); @@ -122,7 +123,8 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, c16_t *rxdataF, int slot, int first_symbol, - int nsymb); + int nsymb, + int link_type); /*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5 @param[in] datatx_F_precoding, Pointer to n_layers*re data array diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index a15708305a..16238257d1 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -33,6 +33,7 @@ This section deals with basic functions for OFDM Modulation. #include "PHY/defs_eNB.h" #include "PHY/defs_gNB.h" #include "PHY/impl_defs_top.h" +#include "PHY/impl_defs_nr.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "modulation_common.h" @@ -337,11 +338,13 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, c16_t *txdataF, int slot, int first_symbol, - int nsymb) + int nsymb, + int link_type) { int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot; - c16_t *symbol_rotation = fp->symbol_rotation[0] + symb_offset; + c16_t *symbol_rotation = fp->symbol_rotation[link_type] + symb_offset; + int N_RB = (link_type == link_type_sl) ? fp->N_RB_SL : fp->N_RB_DL; for (int sidx = first_symbol; sidx < first_symbol + nsymb; sidx++) { c16_t *this_rotation = symbol_rotation + sidx; @@ -354,20 +357,20 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, this_rotation->r, this_rotation->i); - if (fp->N_RB_DL & 1) { + if (N_RB & 1) { rotate_cpx_vector(this_symbol, this_rotation, this_symbol, - (fp->N_RB_DL + 1) * 6, 15); + (N_RB + 1) * 6, 15); rotate_cpx_vector(this_symbol + fp->first_carrier_offset - 6, this_rotation, this_symbol + fp->first_carrier_offset - 6, - (fp->N_RB_DL + 1) * 6, 15); + (N_RB + 1) * 6, 15); } else { rotate_cpx_vector(this_symbol, this_rotation, this_symbol, - fp->N_RB_DL * 6, 15); + N_RB * 6, 15); rotate_cpx_vector(this_symbol + fp->first_carrier_offset, this_rotation, this_symbol + fp->first_carrier_offset, - fp->N_RB_DL * 6, 15); + N_RB * 6, 15); } } } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index dee8253388..43d7be3fa3 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -150,7 +150,8 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, unsigned char symbol, int sample_offset, bool pbch_decoded, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], + int link_type) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; @@ -230,7 +231,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, stop_meas(&ue->rx_dft_stats); int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - c16_t rot2 = frame_parms->symbol_rotation[0][symbol + symb_offset]; + c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset]; rot2.i=-rot2.i; #ifdef DEBUG_FEP @@ -314,14 +315,15 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, c16_t *rxdataF, int slot, int first_symbol, - int nsymb) + int nsymb, + int link_type) { int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; for (int symbol=first_symbol;symbolsymbol_rotation[1][symbol + symb_offset]; + c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset]; rot2.i=-rot2.i; LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,rot2.r,rot2.i); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index d2ecc56177..5a475b84ae 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -300,7 +300,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, i, is * fp->samples_per_frame + ue->ssb_offset, false, - rxdataF); + rxdataF, + link_type_dl); #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"Calling sss detection (normal CP)\n"); @@ -534,7 +535,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, l, // the UE PHY has no notion of the symbols to be monitored in the search space is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset, true, - rxdataF); + rxdataF, + link_type_dl); nr_pdcch_channel_estimation(ue, proc, @@ -560,7 +562,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, m, is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset, true, - rxdataF); + rxdataF, + link_type_dl); } uint8_t nb_re_dmrs; 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 b20dbf8483..cb777c3515 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -330,6 +330,14 @@ void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_Carrier, uint64_t *ul_Carrier); +/*! + \brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter + @param ue Pointer to PHY UE + @param sl_Carrier Pointer to SL carrier to be set +*/ +void nr_get_carrier_frequencies_sl(PHY_VARS_NR_UE *ue, + uint64_t *sl_Carrier); + /*! \brief This function sets the OAI RF card rx/tx params @param openair0_cfg Pointer OAI config for a specific card @@ -347,6 +355,10 @@ void nr_rf_card_config_freq(openair0_config_t *openair0_cfg, uint64_t dl_Carrier, int freq_offset); +void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue, + openair0_config_t *openair0_cfg, + int freq_offset); + void nr_pdcch_unscrambling(int16_t *z, uint16_t scrambling_RNTI, uint32_t length, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c index 80b803779d..1bc4d42c26 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -47,6 +47,16 @@ void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64 } +void nr_get_carrier_frequencies_sl(PHY_VARS_NR_UE *ue, uint64_t *sl_carrier) { + + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + if (ue->if_freq!=0) { + *sl_carrier = ue->if_freq; + } else { + *sl_carrier = fp->sl_CarrierFreq; + } +} + void nr_rf_card_config_gain(openair0_config_t *openair0_cfg, double rx_gain_off){ @@ -113,3 +123,18 @@ void nr_rf_card_config_freq(openair0_config_t *openair0_cfg, } } + + +void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue, openair0_config_t *openair0_cfg, int freq_offset) { + + for (int i = 0; i < openair0_cfg->rx_num_channels; i++) { + openair0_cfg->rx_gain[ue->rf_map.chain + i] = ue->rx_total_gain_dB; + if (ue->UE_scan_carrier == 1) { + if (freq_offset >= 0) + openair0_cfg->rx_freq[ue->rf_map.chain + i] += abs(freq_offset); + else + openair0_cfg->rx_freq[ue->rf_map.chain + i] -= abs(freq_offset); + freq_offset=0; + } + } +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 1a52d3edd9..186ec58d4d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -617,7 +617,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, for(ap = 0; ap < n_antenna_ports; ap++) { for (int s=0;sofdm_symbol_size * s]; - c16_t rot=frame_parms->symbol_rotation[1][s + symb_offset]; + c16_t rot=frame_parms->symbol_rotation[link_type_ul][s + symb_offset]; LOG_D(PHY,"rotating txdataF symbol %d (%d) => (%d.%d)\n", s, s + symb_offset, diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 8d9de8976d..e8dba45f2b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -147,6 +147,8 @@ struct NR_DL_FRAME_PARMS { int N_RB_DL; /// Number of resource blocks (RB) in UL int N_RB_UL; + /// Number of resource blocks (RB) in SL + int N_RB_SL; /// total Number of Resource Block Groups: this is ceil(N_PRB/P) uint8_t N_RBG; /// Total Number of Resource Block Groups SubSets: this is P @@ -157,6 +159,8 @@ struct NR_DL_FRAME_PARMS { uint64_t dl_CarrierFreq; /// UL carrier frequency uint64_t ul_CarrierFreq; + /// SL carrier frequency + uint64_t sl_CarrierFreq; /// TX attenuation uint32_t att_tx; /// RX attenuation @@ -216,8 +220,8 @@ struct NR_DL_FRAME_PARMS { /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) lte_prefix_type_t Ncp; /// 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) - c16_t symbol_rotation[2][224]; + /// First dimension is for the direction of the link (0 DL, 1 UL, 2 SL) + c16_t symbol_rotation[3][224]; /// sequence used to compensate the phase rotation due to timeshifted OFDM symbols /// First dimenstion is for different CP lengths c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index afbe6830f5..316446bf7a 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -101,6 +101,12 @@ SystemInformationBlockType1_nr_t; #define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */ +enum nr_Link { + link_type_dl, + link_type_ul, + link_type_sl, +}; + typedef enum { ms0p5 = 500, /* duration is given in microsecond */ ms0p625 = 625, diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h index 98765730bb..2c4679dddd 100644 --- a/openair1/PHY/phy_extern_nr_ue.h +++ b/openair1/PHY/phy_extern_nr_ue.h @@ -25,5 +25,9 @@ #include "PHY/defs_nr_UE.h" extern PHY_VARS_NR_UE ***PHY_vars_UE_g; +extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +extern uint64_t sidelink_frequency[MAX_NUM_CCs][4]; + #endif /*__PHY_EXTERN_H__ */ diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 0e8e2cfd56..39e360c79c 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -222,7 +222,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, //apply the OFDM symbol rotation here for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { - apply_nr_rotation(fp, &gNB->common_vars.txdataF[aa][txdataF_offset], slot, 0, fp->Ncp == EXTENDED ? 12 : 14); + apply_nr_rotation(fp, &gNB->common_vars.txdataF[aa][txdataF_offset], slot, 0, fp->Ncp == EXTENDED ? 12 : 14, link_type_dl); T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0), T_INT(frame), T_INT(slot), diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ac9b2e3bec..d5930c0c23 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -652,7 +652,8 @@ int main(int argc, char **argv) gNB->common_vars.txdataF[aa], slot, 0, - 12); + 12, + link_type_dl); PHY_ofdm_mod((int *)gNB->common_vars.txdataF[aa], (int *)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], @@ -665,7 +666,8 @@ int main(int argc, char **argv) gNB->common_vars.txdataF[aa], slot, 0, - 14); + 14, + link_type_dl); /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index f4072b495a..3938eef12d 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -80,7 +80,10 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) { } /* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ uint64_t get_softmodem_optmask(void) {return 0;} -softmodem_params_t *get_softmodem_params(void) {return 0;} +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) { + return &softmodem_params; +} //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; @@ -138,7 +141,7 @@ int NB_UE_INST = 1; int main(int argc, char **argv){ char c; - + get_softmodem_params()->sl_mode = 0; double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw; int i, l, aa, aarx, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index fa49008adb..3ced917cac 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -48,6 +48,7 @@ #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "executables/nr-uesoftmodem.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "executables/softmodem-common.h" THREAD_STRUCT thread_struct; PHY_VARS_gNB *gNB; @@ -67,7 +68,10 @@ const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}}; uint64_t get_softmodem_optmask(void) {return 0;} -softmodem_params_t *get_softmodem_params(void) {return 0;} +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) { + return &softmodem_params; +} void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 835ba9ef99..66460e7a63 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1276,7 +1276,8 @@ int main(int argc, char **argv) gNB->common_vars.rxdataF[aa], slot, 0, - gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); + gNB->frame_parms.Ncp == EXTENDED ? 12 : 14, + link_type_ul); } ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);