From bfd9671626b11150a880e4855d5ebe52d9b6516e Mon Sep 17 00:00:00 2001 From: francescomani <francesco.mani@eurecom.fr> Date: Mon, 20 Sep 2021 19:32:19 +0200 Subject: [PATCH] fixes in acknack scheduling --- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 4 +- openair1/SCHED_NR/fapi_nr_l1.c | 3 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 9 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 16 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 105 +++++++++++------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 7 files changed, 84 insertions(+), 56 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 2a1556f432..34c0f6cdbf 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -446,8 +446,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2); uci_pdu->harq->harq_list[1].harq_value = index&0x01; uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01; - LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d, xrt_mag %d xrt_mag_next %d\n", - frame,slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dBtimes10,xrtmag_next_dBtimes10); + LOG_I(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d, xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d\n", + frame,slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); uci_pdu->sr->sr_indication = (index>3) ? 1 : 0; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index ad78dbf355..b2a802ab08 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -104,8 +104,7 @@ void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu) { - if(pdcch_pdu->pdcch_pdu_rel15.CoreSetType==1) - LOG_I(PHY,"Frame %d, Slot %d: DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, pdcch_pdu->pdcch_pdu_rel15.numDlDci); + LOG_D(PHY,"Frame %d, Slot %d: DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, pdcch_pdu->pdcch_pdu_rel15.numDlDci); // copy dci configuration into gNB structure // gNB->pdcch_pdu = pdcch_pdu; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9b78bdf57c..e779f5eab6 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -164,11 +164,10 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, gNB->Mod_id,frame,slot,pdcch_pdu_id,ul_pdcch_pdu_id); if (pdcch_pdu_id >= 0 || ul_pdcch_pdu_id >= 0) { - if(gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.CoreSetType==1) - LOG_I(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n", - gNB->Mod_id, frame, slot, - gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci, - gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci); + LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n", + gNB->Mod_id, frame, slot, + gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci, + gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 5a7e5c2260..8ae2a5d6dc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1074,7 +1074,7 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; // PDSCH to HARQ TI dci_payload.antenna_ports.val = ps->dmrs_ports_id; dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; - LOG_I(NR_MAC, + LOG_D(NR_MAC, "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d\n", frame, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index ac017f6a67..0fb06dfb4e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2090,6 +2090,7 @@ void get_pdsch_to_harq_feedback(int Mod_idP, int UE_id, int bwp_id, NR_SearchSpace__searchSpaceType_PR ss_type, + int *max_fb_time, uint8_t *pdsch_to_harq_feedback) { NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; @@ -2127,8 +2128,11 @@ void get_pdsch_to_harq_feedback(int Mod_idP, // common search type uses DCI format 1_0 if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { - for (int i=0; i<8; i++) + for (int i=0; i<8; i++) { pdsch_to_harq_feedback[i] = i+1; + if(pdsch_to_harq_feedback[i]>*max_fb_time) + *max_fb_time = pdsch_to_harq_feedback[i]; + } } else { @@ -2150,14 +2154,20 @@ void get_pdsch_to_harq_feedback(int Mod_idP, if (ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) { - for (int i=0; i<8; i++) + for (int i=0; i<8; i++) { pdsch_to_harq_feedback[i] = i+1; + if(pdsch_to_harq_feedback[i]>*max_fb_time) + *max_fb_time = pdsch_to_harq_feedback[i]; + } } else { AssertFatal(ubwpd!=NULL,"ubwpd shouldn't be null here\n"); if(ubwpd->pucch_Config->choice.setup->dl_DataToUL_ACK != NULL) { - for (int i=0; i<8; i++) + for (int i=0; i<8; i++) { pdsch_to_harq_feedback[i] = *ubwpd->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[i]; + if(pdsch_to_harq_feedback[i]>*max_fb_time) + *max_fb_time = pdsch_to_harq_feedback[i]; + } } else AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index c17641b2fb..3710c25af2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1169,12 +1169,11 @@ int nr_acknack_scheduling(int mod_id, frame_t frame, sub_frame_t slot, int r_pucch, - int is_common) -{ + int is_common) { + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; - const int nr_ulmix_slots = tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols != 0); const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0; const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots; const int first_ul_slot_tdd = tdd->nrofDownlinkSlots + nr_slots_period * (slot / nr_slots_period); @@ -1195,7 +1194,7 @@ int nr_acknack_scheduling(int mod_id, * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */ NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; - LOG_D(NR_MAC,"pucch_acknak %d.%d Trying to allocate pucch, current DAI %d\n",frame,slot,pucch->dai_c); + LOG_I(NR_MAC,"pucch_acknak %d.%d Trying to allocate pucch, current DAI %d\n",frame,slot,pucch->dai_c); pucch->r_pucch=r_pucch; AssertFatal(pucch->csi_bits == 0, "%s(): csi_bits %d in sched_pucch[0]\n", @@ -1207,11 +1206,14 @@ int nr_acknack_scheduling(int mod_id, * the same slot again */ const int f = pucch->frame; const int s = pucch->ul_slot; - LOG_D(NR_MAC,"pucch_acknak : %d.%d DAI = 2 pucch currently in %d.%d, advancing by 1 slot\n",frame,slot,f,s); + LOG_I(NR_MAC,"pucch_acknak : %d.%d DAI = 2 pucch currently in %d.%d, advancing by 1 slot\n",frame,slot,f,s); nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id); memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; - pucch->ul_slot = (s + 1) % n_slots_frame; + if((s + 1) == nr_slots_period) + pucch->ul_slot = (s + 1 + first_ul_slot_tdd) % n_slots_frame; + else + pucch->ul_slot = (s + 1) % n_slots_frame; // we assume that only two indices over the array sched_pucch exist csi_pucch = &sched_ctrl->sched_pucch[1]; // skip the CSI PUCCH if it is present and if in the next frame/slot @@ -1223,19 +1225,15 @@ int nr_acknack_scheduling(int mod_id, && !csi_pucch->simultaneous_harqcsi) { nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); memset(csi_pucch, 0, sizeof(*csi_pucch)); - pucch->frame = s >= n_slots_frame - 2 ? (f + 1) % 1024 : f; - pucch->ul_slot = (s + 2) % n_slots_frame; + pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; + if((s + 1) == nr_slots_period) + pucch->ul_slot = (s + 1 + first_ul_slot_tdd) % n_slots_frame; + else + pucch->ul_slot = (s + 1) % n_slots_frame; } } LOG_D(NR_MAC,"pucch_acknak 1. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n",frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c); - /* if the UE's next PUCCH occasion is after the possible UL slots (within the - * same frame) or wrapped around to the next frame, then we assume there is - * no possible PUCCH allocation anymore */ - if ((pucch->frame == frame - && (pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots)) - || (pucch->frame == frame + 1)) - return -1; // this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP NR_CellGroupConfig_t *cg = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]; @@ -1253,15 +1251,14 @@ int nr_acknack_scheduling(int mod_id, int bwp_Id = 0; if (sched_ctrl->active_ubwp) bwp_Id = sched_ctrl->active_ubwp->bwp_Id; - get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, pdsch_to_harq_feedback); - + int max_fb_time = 0; + get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback); + int max_absslot = frame*n_slots_frame + slot + max_fb_time; LOG_D(NR_MAC,"pucch_acknak 1b. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n",frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c); /* there is a HARQ. Check whether we can use it for this ACKNACK */ if (pucch->dai_c > 0) { /* this UE already has a PUCCH occasion */ - DevAssert(pucch->frame == frame); - // Find the right timing_indicator value. int i = 0; while (i < 8) { @@ -1278,48 +1275,67 @@ int nr_acknack_scheduling(int mod_id, nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id); memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; - pucch->ul_slot = (s + 1) % n_slots_frame; + if((s + 1) == nr_slots_period) + pucch->ul_slot = (s + 1 + first_ul_slot_tdd) % n_slots_frame; + else + pucch->ul_slot = (s + 1) % n_slots_frame; return nr_acknack_scheduling(mod_id, UE_id, frame, slot, r_pucch,is_common); } pucch->timing_indicator = i; pucch->dai_c++; // retain old resource indicator, and we are good - LOG_D(NR_MAC,"pucch_acknak : %d.%d. DAI > 0, pucch allocated for %d.%d\n",frame,slot,pucch->frame,pucch->ul_slot); + LOG_D(NR_MAC,"pucch_acknak : %d.%d. DAI > 0, pucch allocated for %d.%d (index %d)\n",frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator); return 0; } LOG_D(NR_MAC,"pucch_acknak : %d.%d DAI = 0, looking for new pucch occasion\n",frame,slot); /* we need to find a new PUCCH occasion */ - /* if time information is outdated (e.g., last PUCCH occasion in last frame), - * set to first possible UL occasion in this frame. Note that if such UE is - * scheduled a lot and used all AckNacks, pucch->frame might have been - * wrapped around to next frame */ - if (frame != pucch->frame || pucch->ul_slot < first_ul_slot_tdd) { + /*Inizialization of timing information*/ + if (pucch->frame == 0 && pucch->ul_slot == 0) { AssertFatal(pucch->sr_flag + pucch->dai_c == 0, "expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n", UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot); - AssertFatal(frame + 1 != pucch->frame, - "frame wrap around not handled in %s() yet\n", - __func__); pucch->frame = frame; - pucch->ul_slot = first_ul_slot_tdd; + pucch->ul_slot = first_ul_slot_tdd + (slot/nr_slots_period); } - // advance ul_slot if it is not reachable by UE - int pucch_slot,ind_found=-1; - for (int i=0;i<8;i++) { - pucch_slot = slot + pdsch_to_harq_feedback[i]; - if ((pucch_slot%nr_slots_period) >= tdd->nrofDownlinkSlots) { - pucch->ul_slot = max(pucch->ul_slot, pucch_slot); - ind_found=i; - break; + // Find the right timing_indicator value. + int ind_found = -1; + // while we are within the feedback limits and it has not been + while ((pucch->frame*n_slots_frame + pucch->ul_slot) <= max_absslot) { + if (ind_found!=-1) + break; + int i = 0; + while (i < 8) { + LOG_D(NR_MAC,"pdsch_to_harq_feedback[%d] = %d (pucch->ul_slot %d - slot %d)\n", + i,pdsch_to_harq_feedback[i],pucch->ul_slot,slot); + if (pdsch_to_harq_feedback[i] == pucch->ul_slot - slot) { + ind_found = i; + break; + } + ++i; } + // advance to the next ul slot + const int f = pucch->frame; + const int s = pucch->ul_slot; + pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; + if((s + 1) == nr_slots_period) + pucch->ul_slot = (s + 1 + first_ul_slot_tdd) % n_slots_frame; + else + pucch->ul_slot = (s + 1) % n_slots_frame; + } + if (ind_found==-1) { + LOG_W(NR_MAC, + "%4d.%2d could not find pdsch_to_harq_feedback for UE %d: earliest " + "ack slot %d\n", + frame, + slot, + UE_id, + pucch->ul_slot); + return -1; } - if (pucch->ul_slot >= n_slots_frame) pucch->frame++; - pucch->ul_slot = pucch->ul_slot % n_slots_frame; - AssertFatal(ind_found!=-1,"couldn't find a valid UL_ACK slot for PUCCH, shouldn't happen\n"); // is there already CSI in this slot? csi_pucch = &sched_ctrl->sched_pucch[1]; @@ -1340,7 +1356,10 @@ int nr_acknack_scheduling(int mod_id, const int s = pucch->ul_slot; memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; - pucch->ul_slot = (s + 1) % n_slots_frame; + if((s + 1) == nr_slots_period) + pucch->ul_slot = (s + 1 + first_ul_slot_tdd) % n_slots_frame; + else + pucch->ul_slot = (s + 1) % n_slots_frame; return nr_acknack_scheduling(mod_id, UE_id, frame, slot, r_pucch,is_common); } // multiplexing harq and csi in a pucch @@ -1353,7 +1372,7 @@ int nr_acknack_scheduling(int mod_id, pucch->timing_indicator = ind_found; // index in the list of timing indicators - LOG_D(NR_MAC,"pucch_acknak 2. DAI 0 DL %d.%d, UL_ACK %d.%d (index %d)\n",frame,slot,pucch->frame,pucch->ul_slot,ind_found); + LOG_D(NR_MAC,"pucch_acknak 2. DAI 0 DL %d.%d, UL_ACK %d.%d (index %d)\n",frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator); pucch->dai_c++; pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index ea5bed9ca9..321476d513 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -212,6 +212,7 @@ void get_pdsch_to_harq_feedback(int Mod_idP, int UE_id, int bwp_id, NR_SearchSpace__searchSpaceType_PR ss_type, + int *max_fb_time, uint8_t *pdsch_to_harq_feedback); void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, -- 2.26.2