diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index b631192dc3..7f983ea814 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1756,6 +1756,7 @@ set(PHY_SRC_UE set(PHY_NR_SRC_COMMON ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c ) set(PHY_NR_SRC @@ -1826,7 +1827,6 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/ ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_prach.c - ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c 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 78502d7d7e..d5d70cf8b3 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 @@ -358,7 +358,6 @@ typedef struct { uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559 nfapi_nr_ue_ul_beamforming_t beamforming; - fapi_nr_ul_srs_parms_v4 srs_parms_v4; } fapi_nr_ul_config_srs_pdu; typedef struct { diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 1efa86a841..5356888f44 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -195,6 +195,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value); + gNB->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); + gNB->nr_srs_info->srs_generated_signal = (int32_t*)malloc16_clear(NR_NB_SC_PER_RB*NR_MAX_NB_RB*sizeof(int32_t)); + gNB->nr_srs_info->srs_received_signal = (int32_t*)malloc16_clear(NR_NB_SC_PER_RB*NR_MAX_NB_RB*sizeof(int32_t)); + + generate_ul_reference_signal_sequences(SHRT_MAX); + /* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */ generate_lowpapr_typ1_refsig_sequences(SHRT_MAX); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index df0dddcda9..66b0ab3646 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -323,6 +323,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS)); srs_vars[gNB_id]->active = false; + ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); + ue->nr_srs_info->srs_generated_signal = (int32_t*)malloc16_clear(NR_NB_SC_PER_RB*NR_MAX_NB_RB*sizeof(int32_t)); + ue->nr_srs_info->srs_received_signal = (int32_t*)malloc16_clear(NR_NB_SC_PER_RB*NR_MAX_NB_RB*sizeof(int32_t)); if (abstraction_flag == 0) { for (th_id=0; th_id +#include #include #include #include @@ -40,6 +40,8 @@ #include "T.h" +//#define SRS_DEBUG + NR_gNB_SRS_t *new_gNB_srs(void){ NR_gNB_SRS_t *srs; srs = (NR_gNB_SRS_t *)malloc16(sizeof(NR_gNB_SRS_t)); @@ -86,6 +88,42 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, memcpy((void*)&srs->srs_pdu, (void*)srs_pdu, sizeof(nfapi_nr_srs_pdu_t)); } -void nr_get_srs_signal(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_srs_pdu_t *srs_pdu) { - LOG_W(NR_PHY, "(%d.%d) nr_get_srs_signal is not implemented yet!\n", frame,slot); +int nr_get_srs_signal(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_srs_pdu_t *srs_pdu, + nr_srs_info_t *nr_srs_info, + int32_t *srs_received_signal) { + + if(nr_srs_info->n_symbs==0) { + LOG_E(NR_PHY, "nr_srs_info was not generated yet!\n"); + return -1; + } + + int32_t **rxdataF = gNB->common_vars.rxdataF; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + + uint16_t n_symbols = (slot&3)*frame_parms->symbols_per_slot; // number of symbols until this slot + uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot + uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size; + + int32_t *rx_signal; + for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + rx_signal = &rxdataF[ant][symbol_offset + frame_parms->first_carrier_offset]; + + for(int sc_idx = 0; sc_idx < nr_srs_info->n_symbs; sc_idx++) { + srs_received_signal[nr_srs_info->subcarrier_idx[sc_idx] + frame_parms->first_carrier_offset] = rx_signal[nr_srs_info->subcarrier_idx[sc_idx]]; + +#ifdef SRS_DEBUG + if(nr_srs_info->subcarrier_idx[sc_idx]%12 == 0) { + LOG_I(NR_PHY,"::::::::::::: %i :::::::::::::\n", nr_srs_info->subcarrier_idx[sc_idx]/12); + } + LOG_I(NR_PHY,"(%i) \t%i\t%i\n", + nr_srs_info->subcarrier_idx[sc_idx], + srs_received_signal[nr_srs_info->subcarrier_idx[sc_idx] + frame_parms->first_carrier_offset]&0xFFFF, + (srs_received_signal[nr_srs_info->subcarrier_idx[sc_idx] + frame_parms->first_carrier_offset]>>16)&0xFFFF); +#endif + } + } + return 0; } \ No newline at end of file diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 7552f373d3..9d74795937 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -74,11 +74,13 @@ * - no antenna switching* * *********************************************************************/ -int generate_srs_nr(fapi_nr_ul_config_srs_pdu *srs_config_pdu, - NR_DL_FRAME_PARMS *frame_parms, - int32_t *txptr, - int16_t amp, - UE_nr_rxtx_proc_t *proc) +int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, + NR_DL_FRAME_PARMS *frame_parms, + int32_t *txptr, + nr_srs_info_t *nr_srs_info, + int16_t amp, + int frame_number, + int slot_number) { uint8_t n_SRS_cs_max; uint8_t u; @@ -94,9 +96,6 @@ int generate_srs_nr(fapi_nr_ul_config_srs_pdu *srs_config_pdu, uint8_t N_b; uint8_t k_0_overbar_p; - int frame_number = proc->frame_tx; - int slot_number = proc->nr_slot_tx; - // get parameters from srs_config_pdu uint8_t B_SRS = srs_config_pdu->bandwidth_index; uint8_t C_SRS = srs_config_pdu->config_index; @@ -117,6 +116,10 @@ int generate_srs_nr(fapi_nr_ul_config_srs_pdu *srs_config_pdu, uint8_t l0 = N_SYMB_SLOT - 1 - l_offset; // starting position in the time domain uint8_t k_0_p; // frequency domain starting position + if(nr_srs_info) { + nr_srs_info->n_symbs = 0; + } + #ifdef SRS_DEBUG LOG_I(NR_PHY,"Frame = %i, slot = %i\n", frame_number, slot_number); LOG_I(NR_PHY,"B_SRS = %i\n", B_SRS); @@ -369,6 +372,11 @@ int generate_srs_nr(fapi_nr_ul_config_srs_pdu *srs_config_pdu, txptr[subcarrier+ofdm_symbol*frame_parms->ofdm_symbol_size] = (real_amp & 0xFFFF) + ((imag_amp<<16)&0xFFFF0000); + if(nr_srs_info) { + nr_srs_info->subcarrier_idx[nr_srs_info->n_symbs] = subcarrier+ofdm_symbol*frame_parms->ofdm_symbol_size-frame_parms->first_carrier_offset; + nr_srs_info->n_symbs++; + } + #ifdef SRS_DEBUG if( (subcarrier+ofdm_symbol*frame_parms->ofdm_symbol_size-frame_parms->first_carrier_offset)%12 == 0 ) { LOG_I(NR_PHY,"------------ %i ------------\n", @@ -417,7 +425,7 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gN } ue->srs_vars[0]->active = false; - fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ue->srs_vars[0]->srs_config_pdu; + nfapi_nr_srs_pdu_t *srs_config_pdu = (nfapi_nr_srs_pdu_t*)&ue->srs_vars[0]->srs_config_pdu; #ifdef SRS_DEBUG LOG_I(NR_PHY,"Frame = %i, slot = %i\n", proc->frame_tx, proc->nr_slot_tx); @@ -452,7 +460,8 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gN uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12; uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((proc->nr_slot_tx*nsymb)+(nsymb-1)); - if (generate_srs_nr(srs_config_pdu, frame_parms, &ue->common_vars.txdataF[gNB_id][symbol_offset], txptr, proc) == 0) { + if (generate_srs_nr(srs_config_pdu, frame_parms, &ue->common_vars.txdataF[gNB_id][symbol_offset], ue->nr_srs_info, + txptr, proc->frame_tx, proc->nr_slot_tx) == 0) { return 0; } else { return -1; diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index 5abf064fef..e43bbe4934 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -136,15 +136,19 @@ EXTERN const uint16_t srs_periodicity[SRS_PERIODICITY] /** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 38.211 6.4.1.4 Sounding reference signal @param frame_parms NR DL Frame parameters @param txdataF pointer to the frequency domain TX signal + @param nr_srs_info pointer to the srs info structure @param amp amplitude of generated signal - @param proc pointer to the transmit parameters + @param frame_number frame number + @param slot_number slot number @returns 0 on success -1 on error with message */ -int generate_srs_nr(fapi_nr_ul_config_srs_pdu *srs_config_pdu, +int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, int32_t *txptr, + nr_srs_info_t *nr_srs_info, int16_t amp, - UE_nr_rxtx_proc_t *proc); + int frame_number, + int slot_number); /** \brief This function checks for periodic srs if srs should be transmitted in this slot * @param p_SRS_Resource pointer to active resource diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index ab0ccaf833..170011c507 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -794,6 +794,9 @@ typedef struct PHY_VARS_gNB_s { NR_gNB_UCI_STATS_t uci_stats[NUMBER_OF_NR_UCI_STATS_MAX]; t_nrPolar_params *uci_polarParams; + /// SRS variables + nr_srs_info_t *nr_srs_info; + uint8_t pbch_configured; char gNB_generate_rar; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index fe2f91c706..2f33fb5c2b 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -973,6 +973,8 @@ typedef struct { /// PUSCH contention-based access vars PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola + /// SRS variables + nr_srs_info_t *nr_srs_info; //#if defined(UPGRADE_RAT_NR) #if 1 diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index c385d323e3..85902403b8 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -240,6 +240,13 @@ typedef struct { uint8_t init_msg1; } NR_PRACH_RESOURCES_t; +typedef struct { + uint16_t n_symbs; + uint16_t subcarrier_idx[6*NR_MAX_NB_RB]; + int32_t *srs_generated_signal; + int32_t *srs_received_signal; +} nr_srs_info_t; + typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index c9058d471b..e07b1c6069 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -33,6 +33,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/INIT/phy_init.h" #include "PHY/MODULATION/nr_modulation.h" +#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h" #include "T.h" #include "executables/softmodem-common.h" @@ -792,9 +793,17 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { NR_gNB_SRS_t *srs = gNB->srs[i]; if (srs) { if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) { + LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i); + nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; - nr_get_srs_signal(gNB,frame_rx,slot_rx,srs_pdu); + + // At least currently, the configuration is constant, so it is enough to generate the sequence just once. + if(gNB->nr_srs_info->n_symbs==0) { + generate_srs_nr(srs_pdu, &gNB->frame_parms, gNB->nr_srs_info->srs_generated_signal, gNB->nr_srs_info, AMP, frame_rx, slot_rx); + } + + nr_get_srs_signal(gNB,frame_rx,slot_rx,srs_pdu, gNB->nr_srs_info, gNB->nr_srs_info->srs_received_signal); srs->active = 0; } }