diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 7d56f8b410..2246fcdde1 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -419,15 +419,13 @@ void init_nr_transport(PHY_VARS_gNB *gNB) buffer_ul_slots = (nb_ul_slots_period < slot_ahead) ? nb_ul_slots_period : slot_ahead; gNB->max_nb_pusch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1; - gNB->max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot int max_nb_pucch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1; gNB->pucch_queue = spsc_q_alloc(max_nb_pucch, sizeof(NR_gNB_PUCCH_job_t)); gNB->pusch_queue = spsc_q_alloc(gNB->max_nb_pusch, sizeof(NR_gNB_PUSCH_job_t)); - gNB->srs = (NR_gNB_SRS_t *)malloc16(gNB->max_nb_srs * sizeof(NR_gNB_SRS_t)); - for (int i = 0; i < gNB->max_nb_srs; i++) - gNB->srs[i].active = 0; + int max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot + gNB->srs_queue = spsc_q_alloc(max_nb_srs, sizeof(NR_gNB_SRS_job_t)); gNB->ulsch = (NR_gNB_ULSCH_t *)malloc16(gNB->max_nb_pusch * sizeof(NR_gNB_ULSCH_t)); for (int i = 0; i < gNB->max_nb_pusch; i++) { @@ -446,7 +444,7 @@ void reset_nr_transport(PHY_VARS_gNB *gNB) spsc_q_free(&gNB->pucch_queue); spsc_q_free(&gNB->pusch_queue); - free(gNB->srs); + spsc_q_free(&gNB->srs_queue); for (int i = 0; i < gNB->max_nb_pusch; i++) free_gNB_ulsch(&gNB->ulsch[i], fp->N_RB_UL); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 54acd23351..32efa979cc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -209,7 +209,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB, uint8_t N_ap, uint8_t N_symb_SRS, uint16_t ofdm_symbol_size, - const NR_gNB_SRS_t *srs, + const NR_gNB_SRS_job_t *srs, int *srs_est, int8_t *snr, c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS], diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 96695909a9..b0436cb2d7 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -29,31 +29,21 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu) { - bool found = false; - for (int i = 0; i < gNB->max_nb_srs; i++) { - NR_gNB_SRS_t *srs = &gNB->srs[i]; - if (srs->active == false) { - found = true; - srs->frame = frame; - srs->slot = slot; - srs->active = true; - srs->beam_nb = 0; - if (gNB->common_vars.beam_id) { - const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position; - int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols); - int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - srs->beam_nb = beam_index_allocation(gNB->enable_analog_das, - fapi_beam_idx, - &gNB->common_vars, - slot, - gNB->frame_parms.symbols_per_slot, - bitmap); - } - memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t)); - break; - } + NR_gNB_SRS_job_t srs = {.frame = frame, .slot = slot, .srs_pdu = *srs_pdu}; + if (gNB->common_vars.beam_id) { + const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position; + int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols); + int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; + srs.beam_nb = beam_index_allocation(gNB->enable_analog_das, + fapi_beam_idx, + &gNB->common_vars, + slot, + gNB->frame_parms.symbols_per_slot, + bitmap); } - AssertFatal(found, "SRS list is full\n"); + bool found = spsc_q_put(&gNB->srs_queue, &srs, sizeof(srs)); + if (!found) + LOG_W(NR_PHY, "SRS list is full: dropping SRS UE %04x\n", srs_pdu->rnti); } int nr_get_srs_signal(PHY_VARS_gNB *gNB, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 20e820a298..479a214418 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -208,7 +208,6 @@ typedef struct { } NR_gNB_PUCCH_job_t; typedef struct { - bool active; // identifier for concurrent beams int beam_nb; /// Frame where current SRS pdu was received @@ -217,7 +216,7 @@ typedef struct { uint32_t slot; /// ULSCH PDU nfapi_nr_srs_pdu_t srs_pdu; -} NR_gNB_SRS_t; +} NR_gNB_SRS_job_t; typedef struct { /// \brief Pointers (dynamic) to the received data in the frequency domain. @@ -375,7 +374,6 @@ typedef struct PHY_VARS_gNB_s { nfapi_nr_ul_tti_request_t UL_tti_req; - int max_nb_srs; int max_nb_pdsch; int max_nb_pusch; @@ -387,7 +385,7 @@ typedef struct PHY_VARS_gNB_s { NR_gNB_PUSCH *pusch_vars; spsc_q_t pucch_queue; spsc_q_t pusch_queue; - NR_gNB_SRS_t *srs; + spsc_q_t srs_queue; NR_gNB_ULSCH_t *ulsch; NR_gNB_PHY_STATS_t phy_stats[MAX_MOBILES_PER_GNB]; t_nrPolar_params **polarParams; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 3c9f3fcf02..f9a1100724 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -536,7 +536,9 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, const NR_gNB_PUCCH_job_t *pucch, int n_pucch, const NR_gNB_PUSCH_job_t *pusch, - int n_pusch) + int n_pusch, + const NR_gNB_SRS_job_t *srs, + int n_srs) { for (int symbol = 0; symbol < 14; symbol++) { for (int m = 0; m < 9; m++) { @@ -581,11 +583,8 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, } } - for (int i = 0; i < gNB->max_nb_srs; i++) { - NR_gNB_SRS_t *srs = &gNB->srs[i]; - if (!(srs && srs->active && srs->frame == now.f && srs->slot == now.s)) - continue; - nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; + for (int i = 0; i < n_srs; i++) { + const nfapi_nr_srs_pdu_t *srs_pdu = &srs[i].srs_pdu; const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position; for (int symbol = 0; symbol < (1 << srs_pdu->num_symbols); symbol++) { for (int rb = srs_pdu->bwp_start; rb < (srs_pdu->bwp_start + srs_pdu->bwp_size); rb++) { @@ -703,7 +702,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB, uint8_t N_ap, uint8_t N_symb_SRS, uint16_t ofdm_symbol_size, - const NR_gNB_SRS_t *srs, + const NR_gNB_SRS_job_t *srs, int *srs_est, int8_t *snr, c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS], @@ -875,7 +874,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB, return nr_srs_info; } -static void handle_srs(fsn_t now, PHY_VARS_gNB *gNB, const NR_gNB_SRS_t *srs, nfapi_nr_srs_indication_pdu_t *srs_indication) +static void handle_srs(fsn_t now, PHY_VARS_gNB *gNB, const NR_gNB_SRS_job_t *srs, nfapi_nr_srs_indication_pdu_t *srs_indication) { const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; const uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; @@ -1137,6 +1136,25 @@ static bool get_current_pusch(const void *data, void *user) return fsn_equal(t, *now); } +static bool drop_old_srs(const void *data, void *user) +{ + const NR_gNB_SRS_job_t *srs = data; + const fsn_t *now = user; + const fsn_t t = {srs->frame, srs->slot, now->mu}; + bool drop = fsn_in_the_past(t, *now); + if (drop) + LOG_E(NR_PHY, "%4d.%2d SRS job for UE %04x is in the past (%4d.%2d)\n", now->f, now->s, srs->srs_pdu.rnti, t.f, t.s); + return drop; +} + +static bool get_current_srs(const void *data, void *user) +{ + const NR_gNB_SRS_job_t *srs = data; + const fsn_t *now = user; + const fsn_t t = {srs->frame, srs->slot, now->mu}; + return fsn_equal(t, *now); +} + static int find_nr_ulsch_idx(PHY_VARS_gNB *gNB, uint16_t rnti, int pid) { AssertFatal(gNB != NULL, "gNB is null\n"); @@ -1201,6 +1219,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N NR_gNB_PUSCH_job_t pusch[MAX_UL_PDUS_PER_SLOT]; int n_pusch_jobs = spsc_q_get_while(&gNB->pusch_queue, get_current_pusch, &now, pusch, sizeof(*pusch), MAX_UL_PDUS_PER_SLOT); + spsc_q_drop_while(&gNB->srs_queue, drop_old_srs, &now); + NR_gNB_SRS_job_t srs[MAX_NUM_NR_SRS_PDUS]; + int n_srs = spsc_q_get_while(&gNB->srs_queue, get_current_srs, &now, srs, sizeof(*srs), MAX_NUM_NR_SRS_PDUS); + LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); { // Mask of occupied RBs, per symbol and PRB @@ -1208,7 +1230,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N nfapi_nr_max_num_of_symbol_per_slot_t *slot_conf = NULL; if (frame_parms->frame_type == TDD) slot_conf = gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list; - fill_ul_rb_mask(gNB, now, rb_mask_ul, slot_conf, pucch, n_pucch, pusch, n_pusch_jobs); + fill_ul_rb_mask(gNB, now, rb_mask_ul, slot_conf, pucch, n_pucch, pusch, n_pusch_jobs, srs, n_srs); int first_symb = 0, num_symb = 0; if (frame_parms->frame_type == TDD) @@ -1273,22 +1295,13 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N if (gNB->max_nb_pusch == 1) stop_meas(&gNB->ulsch_decoding_stats); - for (int i = 0; i < gNB->max_nb_srs; i++) { - NR_gNB_SRS_t *srs = &gNB->srs[i]; - if (!(srs && srs->active && srs->frame == frame_rx && srs->slot == slot_rx)) - continue; - LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i); - + UL_INFO->srs_ind.sfn = frame_rx; + UL_INFO->srs_ind.slot = slot_rx; + UL_INFO->srs_ind.pdu_list = UL_INFO->srs_pdu_list; + UL_INFO->srs_ind.number_of_pdus = n_srs; + for (int i = 0; i < n_srs; ++i) { start_meas(&gNB->rx_srs_stats); - - UL_INFO->srs_ind.sfn = frame_rx; - UL_INFO->srs_ind.slot = slot_rx; - UL_INFO->srs_ind.pdu_list = UL_INFO->srs_pdu_list; - nfapi_nr_srs_indication_pdu_t *srs_indication = UL_INFO->srs_pdu_list + UL_INFO->srs_ind.number_of_pdus++; - - handle_srs(now, gNB, srs, srs_indication); - - srs->active = false; + handle_srs(now, gNB, &srs[i], &UL_INFO->srs_ind.pdu_list[i]); stop_meas(&gNB->rx_srs_stats); } diff --git a/openair1/SIMULATION/NR_PHY/srssim.c b/openair1/SIMULATION/NR_PHY/srssim.c index 144bce1ab9..0ab34dac47 100644 --- a/openair1/SIMULATION/NR_PHY/srssim.c +++ b/openair1/SIMULATION/NR_PHY/srssim.c @@ -435,11 +435,7 @@ int main(int argc, char *argv[]) .beamforming.num_prgs = m_SRS[srs_pdu.config_index], .beamforming.prg_size = 1}; - gNB->srs->srs_pdu = srs_pdu; - gNB->srs->active = true; - gNB->srs->beam_nb = 0; - gNB->srs->frame = frame; - gNB->srs->slot = slot; + NR_gNB_SRS_job_t srs_job = {.frame = frame, .slot = slot, .srs_pdu = srs_pdu}; // Configure SRS parameters at UE fapi_nr_ul_config_srs_pdu srs_config_pdu = {.rnti = srs_pdu.rnti, @@ -559,10 +555,9 @@ int main(int argc, char *argv[]) //----------- UE RX SRS procedures --------------------- start_meas(&gNB->rx_srs_stats); - NR_gNB_SRS_t *srs = &gNB->srs[0]; - uint8_t N_symb_SRS = 1 << srs->srs_pdu.num_symbols; - uint8_t N_ap = 1 << srs->srs_pdu.num_ant_ports; - int16_t snr_per_rb[srs->srs_pdu.bwp_size]; + uint8_t N_symb_SRS = 1 << srs_pdu.num_symbols; + uint8_t N_ap = 1 << srs_pdu.num_ant_ports; + int16_t snr_per_rb[srs_pdu.bwp_size]; uint16_t timing_advance_offset; int16_t timing_advance_offset_nsec[n_rx]; int srs_est; @@ -576,7 +571,7 @@ int main(int argc, char *argv[]) N_ap, N_symb_SRS, ofdm_symbol_size, - srs, + &srs_job, &srs_est, &snr, srs_estimated_channel_freq,