diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 4efb04a873..655fce5761 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -383,6 +383,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (slot == 0) nr_csi_meas_reporting(module_idP, frame, slot); + // Schedule SRS: check in slot 0 for the whole frame + if (slot == 0) + nr_schedule_srs(module_idP, frame); + // This schedule RA procedure if not in phy_test mode // Otherwise already consider 5G already connected if (get_softmodem_params()->phy_test == 0) { @@ -397,8 +401,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nr_schedule_pucch(module_idP, frame, slot); - nr_schedule_srs(module_idP, frame, slot); - stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 7387bfe698..32ef22879e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1961,6 +1961,11 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG sched_ctrl->pucch_consecutive_dtx_cnt = 0; sched_ctrl->pusch_consecutive_dtx_cnt = 0; sched_ctrl->ul_failure = 0; + + sched_ctrl->sched_srs.frame = -1; + sched_ctrl->sched_srs.slot = -1; + sched_ctrl->sched_srs.srs_scheduled = false; + /* set illegal time domain allocation to force recomputation of all fields */ sched_ctrl->pdsch_semi_static.time_domain_allocation = -1; sched_ctrl->pusch_semi_static.time_domain_allocation = -1; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 2a0429614e..3ef234a2ed 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -101,13 +101,12 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR * * PARAMETERS : module id * frame number for possible SRS reception -* slot number for possible SRS reception * * DESCRIPTION : It informs the PHY layer that has an SRS to receive. * Only for periodic scheduling yet. * *********************************************************************/ -void nr_schedule_srs(int module_id, frame_t frame, sub_frame_t slot) { +void nr_schedule_srs(int module_id, frame_t frame) { gNB_MAC_INST *nrmac = RC.nrmac[module_id]; NR_UE_info_t *UE_info = &nrmac->UE_info; @@ -120,6 +119,10 @@ void nr_schedule_srs(int module_id, frame_t frame, sub_frame_t slot) { NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + sched_ctrl->sched_srs.frame = -1; + sched_ctrl->sched_srs.slot = -1; + sched_ctrl->sched_srs.srs_scheduled = false; + if(!UE_info->active[UE_id]) { continue; } @@ -170,10 +173,13 @@ void nr_schedule_srs(int module_id, frame_t frame, sub_frame_t slot) { int n_slots_frame = nr_slots_per_frame[ubwp.subcarrierSpacing]; - // Check if UE transmitted the SRS here - if ((frame * n_slots_frame + slot - offset) % period == 0) { - LOG_D(NR_MAC,"(%d.%d) Scheduling SRS reception\n", frame, slot); - nr_fill_nfapi_srs(module_id, CC_id, UE_id, slot, srs_resource); + // Check if UE will transmit the SRS in this frame + if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) { + LOG_D(NR_MAC,"(%d.%d) Scheduling SRS reception\n", frame, offset%n_slots_frame); + nr_fill_nfapi_srs(module_id, CC_id, UE_id, offset%n_slots_frame, srs_resource); + sched_ctrl->sched_srs.frame = frame; + sched_ctrl->sched_srs.slot = offset%n_slots_frame; + sched_ctrl->sched_srs.srs_scheduled = true; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9a6fa32b5f..d0e66c8b00 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1274,6 +1274,15 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t if (sched_ctrl->active_ubwp==NULL && is_mixed_slot) return false; + // Avoid slots with the SRS + const NR_list_t *UE_list = &UE_info->list; + for (int UE_idx = UE_list->head; UE_idx >= 0; UE_idx = UE_list->next[UE_idx]) { + NR_sched_srs_t sched_srs = UE_info->UE_sched_ctrl[UE_idx].sched_srs; + if(sched_srs.srs_scheduled && sched_srs.frame==sched_frame && sched_srs.slot==sched_slot) { + return false; + } + } + sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { @@ -1513,7 +1522,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); future_ul_tti_req->n_pdus += 1; - LOG_D(NR_MAC, "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tto_req %d.%d\n", frame, slot, + LOG_D(NR_MAC, "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tti_req %d.%d\n", frame, slot, sched_pusch->frame,sched_pusch->slot,future_ul_tti_req->SFN,future_ul_tti_req->Slot); pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index b0aaf95722..e0efbd4afe 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -190,7 +190,7 @@ void nr_schedule_pucch(int Mod_idP, frame_t frameP, sub_frame_t slotP); -void nr_schedule_srs(int module_id, frame_t frame, sub_frame_t slot); +void nr_schedule_srs(int module_id, frame_t frame); void nr_csirs_scheduling(int Mod_idP, frame_t frame, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 27f42f4b1d..46674dfaa5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -360,6 +360,12 @@ typedef struct NR_sched_pusch { int time_domain_allocation; } NR_sched_pusch_t; +typedef struct NR_sched_srs { + int frame; + int slot; + bool srs_scheduled; +} NR_sched_srs_t; + /* PDSCH semi-static configuratio: as long as the TDA/DMRS/mcsTable remains the * same, there is no need to recalculate all S/L or DMRS-related parameters * over and over again. Hence, we store them in this struct for easy @@ -546,9 +552,12 @@ typedef struct { /// PUSCH semi-static configuration: is not cleared across TTIs NR_pusch_semi_static_t pusch_semi_static; - /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI + /// Sched PUSCH: scheduling decisions, copied into HARQ and cleared every TTI NR_sched_pusch_t sched_pusch; + /// Sched SRS: scheduling decisions + NR_sched_srs_t sched_srs; + /// uplink bytes that are currently scheduled int sched_ul_bytes; /// estimation of the UL buffer size