From 3add5761955747e7c87a3d67c92df0082f512a27 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 17 Oct 2024 14:56:37 +0200 Subject: [PATCH 1/5] remove use of VRB map bitwise not in dlsch and ulsch preprocessor --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 26 +++++++------------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 22 ++++++++-------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index af2a2b24e7..7314ff32d7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -477,7 +477,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, rbSize = 0; const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); - while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) rbStart++; if (rbStart >= rbStop) { @@ -488,9 +488,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, return false; } - while (rbStart + rbSize <= rbStop && - (rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap && - rbSize < retInfo->rbSize) + while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize) rbSize++; } } else { @@ -502,10 +500,10 @@ static bool allocate_dl_retransmission(module_id_t module_id, layers); const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols); - while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) rbStart++; - while (rbStart + rbSize <= rbStop && (rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap) + while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap)) rbSize++; uint32_t new_tbs; @@ -594,7 +592,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); + rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); return true; } @@ -810,12 +808,12 @@ static void pf_dl(module_id_t module_id, int rbStart = 0; get_start_stop_allocation(mac, iterator->UE, &rbStart, &rbStop); // Freq-demain allocation - while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) rbStart++; uint16_t max_rbSize = 1; - while (rbStart + max_rbSize <= rbStop && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == slbitmap) + while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize] & slbitmap)) max_rbSize++; sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, @@ -851,7 +849,7 @@ static void pf_dl(module_id_t module_id, n_rb_sched -= sched_pdsch->rbSize; for (int rb = 0; rb < sched_pdsch->rbSize; rb++) - rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap; + rballoc_mask[rb + sched_pdsch->rbStart] |= slbitmap; remainUEs--; iterator++; @@ -891,14 +889,10 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_ int n_rb_sched = 0; for (int i = 0; i < bwpSize; i++) { - // calculate mask: init with "NOT" vrb_map: - // if any RB in vrb_map is blocked (1), the current RBG will be 0 - rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols - + rballoc_mask[i] = vrb_map[i + BWPStart]; // if all the pdsch symbols are free - if ((rballoc_mask[i]&slbitmap) == slbitmap) { + if (!(rballoc_mask[i] & slbitmap)) n_rb_sched++; - } } /* Retrieve amount of data to send for this UE */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 4599349a04..84d80bc930 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1655,7 +1655,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) { /* Check the resource is enough for retransmission */ const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) rbStart++; if (rbStart + retInfo->rbSize > bwpSize) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n", @@ -1676,10 +1676,10 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, /* the retransmission will use a different time domain allocation, check * that we have enough resources */ const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) rbStart++; int rbSize = 0; - while (rbStart + rbSize < bwpSize && (rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap) + while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + rbSize] & slbitmap)) rbSize++; uint32_t new_tbs; uint16_t new_rbSize; @@ -1762,7 +1762,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, /* Mark the corresponding RBs as used */ n_rb_sched -= sched_pusch->rbSize; for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); return true; } @@ -1907,7 +1907,7 @@ static void pf_ul(module_id_t module_id, LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", min_rb, rbStart, sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data); const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) rbStart++; if (rbStart + min_rb >= bwpSize) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate continuous UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", @@ -1964,7 +1964,7 @@ static void pf_ul(module_id_t module_id, /* Mark the corresponding RBs as used */ n_rb_sched -= sched_pusch->rbSize; for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap; + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= slbitmap; remainUEs--; continue; @@ -2033,11 +2033,11 @@ static void pf_ul(module_id_t module_id, int rbStart = 0; const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); const uint16_t bwpSize = current_BWP->BWPSize; - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) + while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) rbStart++; sched_pusch->rbStart = rbStart; uint16_t max_rbSize = 1; - while (rbStart + max_rbSize < bwpSize && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == slbitmap) + while (rbStart + max_rbSize < bwpSize && !(rballoc_mask[rbStart + max_rbSize] & slbitmap)) max_rbSize++; if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) { @@ -2109,7 +2109,7 @@ static void pf_ul(module_id_t module_id, n_rb_sched -= sched_pusch->rbSize; for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap; + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= slbitmap; /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; @@ -2202,8 +2202,8 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_ uint16_t rballoc_mask[bwpSize]; /* Calculate mask: if any RB in vrb_map_UL is blocked (1), the current RB will be 0 */ - for (int i = 0; i < bwpSize; i++) - rballoc_mask[i] = (i >= st && i <= e)*SL_to_bitmap(startSymbolIndex, nrOfSymbols); + for (int i = st; i < e; i++) + rballoc_mask[i] = vrb_map_UL[bwpStart + i]; int bw = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; int average_agg_level = 4; // TODO find a better estimation From 38a05d8aada1847e499e87ce5430b7df985fe5bd Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 25 Sep 2024 15:40:35 +0200 Subject: [PATCH 2/5] making DLSCH preprocessor agnostic to UEs BWP and TDA --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 167 +++++++----------- 2 files changed, 63 insertions(+), 108 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index a1b9b5b283..321ff3028b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -250,8 +250,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol); - nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, - (int16_t *)mod_dmrs); // Qm = 2 as DMRS is QPSK modulated + // Qm = 2 as DMRS is QPSK modulated + nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); #ifdef DEBUG_DLSCH printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l_symbol, n_dmrs, dmrs_Type); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7314ff32d7..5faa5d3c13 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -52,8 +52,8 @@ #define WORD 32 //#define SIZE_OF_POINTER sizeof (void *) -int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) { - +int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) +{ /* we assume that this function is mutex-protected from outside */ const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n"); @@ -390,10 +390,12 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) UE->mac_stats.dl.errors++; } -static void get_start_stop_allocation(gNB_MAC_INST *mac, - NR_UE_info_t *UE, - int *rbStart, - int *rbStop) +typedef struct { + int bwpStart; + int bwpSize; +} dl_bwp_info_t; + +static dl_bwp_info_t get_bwp_start_size(gNB_MAC_INST *mac, NR_UE_info_t *UE) { NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -402,25 +404,28 @@ static void get_start_stop_allocation(gNB_MAC_INST *mac, // in which case the size of CORESET 0 shall be used if CORESET 0 is configured for the cell // and the size of initial DL bandwidth part shall be used if CORESET 0 is not configured for the cell. // TS 38.214 Section 5.1.2.2.2 - *rbStop = dl_bwp->BWPSize - 1; - *rbStart = 0; // start wrt BWPstart + dl_bwp_info_t bwp_info; + bwp_info.bwpSize = dl_bwp->BWPSize; + bwp_info.bwpStart = dl_bwp->BWPStart; if (sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common && dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) { if (mac->cset0_bwp_size != 0) { - *rbStart = mac->cset0_bwp_start; - *rbStop = *rbStart + mac->cset0_bwp_size - 1; + bwp_info.bwpStart = mac->cset0_bwp_start; + bwp_info.bwpSize = mac->cset0_bwp_size; } else { - *rbStart = UE->sc_info.initial_dl_BWPStart; - *rbStop = *rbStart + UE->sc_info.initial_dl_BWPSize - 1; + // TODO this is not entirely correct + // start would be the start of CORESET not of the initial BWP + bwp_info.bwpStart = UE->sc_info.initial_dl_BWPStart; + bwp_info.bwpSize = UE->sc_info.initial_dl_BWPSize; } } + return bwp_info; } static bool allocate_dl_retransmission(module_id_t module_id, frame_t frame, sub_frame_t slot, - uint16_t *rballoc_mask, int *n_rb_sched, NR_UE_info_t *UE, int current_harq_pid) @@ -442,12 +447,6 @@ static bool allocate_dl_retransmission(module_id_t module_id, int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index; const int coresetid = sched_ctrl->coreset->controlResourceSetId; - - int rbStop = 0; - int rbStart = 0; - get_start_stop_allocation(nr_mac, UE, &rbStart, &rbStop); - - int rbSize = 0; const int tda = get_dl_tda(nr_mac, scc, slot); AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n"); @@ -470,6 +469,14 @@ static bool allocate_dl_retransmission(module_id_t module_id, reuse_old_tda ? "reuse" : "do not reuse", layers == retInfo->nrOfLayers ? "same" : "different"); + // TODO assuming beam 0 for now + uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[0]; + + dl_bwp_info_t bwp_info = get_bwp_start_size(nr_mac, UE); + int rbStart = bwp_info.bwpStart; + int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1; + int rbSize = 0; + if (reuse_old_tda && layers == retInfo->nrOfLayers) { /* Check that there are enough resources for retransmission */ while (rbSize < retInfo->rbSize) { @@ -481,23 +488,17 @@ static bool allocate_dl_retransmission(module_id_t module_id, rbStart++; if (rbStart >= rbStop) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", - UE->rnti, - frame, - slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot); return false; } - while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize) + while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize) rbSize++; } } else { /* the retransmission will use a different time domain allocation, check * that we have enough resources */ - NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, - dl_bwp, - &temp_tda, - layers); + NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers); const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols); while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) @@ -546,7 +547,9 @@ static bool allocate_dl_retransmission(module_id_t module_id, /* Find a free CCE */ int CCEIndex = get_cce_index(nr_mac, - CC_id, slot, UE->rnti, + CC_id, + slot, + UE->rnti, &sched_ctrl->aggregation_level, beam, sched_ctrl->search_space, @@ -554,10 +557,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, &sched_ctrl->sched_pdcch, false); if (CCEIndex<0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", - UE->rnti, - frame, - slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot); return false; } @@ -569,30 +569,27 @@ static bool allocate_dl_retransmission(module_id_t module_id, int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, beam, r_pucch, 0); if (alloc < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", - UE->rnti, - frame, - slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", UE->rnti, frame, slot); return false; } } sched_ctrl->cce_index = CCEIndex; fill_pdcch_vrb_map(nr_mac, - /* CC_id = */ 0, + CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam); /* just reuse from previous scheduling opportunity, set new start RB */ sched_ctrl->sched_pdsch = *retInfo; - sched_ctrl->sched_pdsch.rbStart = rbStart; + sched_ctrl->sched_pdsch.rbStart = rbStart - bwp_info.bwpStart; sched_ctrl->sched_pdsch.pucch_allocation = alloc; /* retransmissions: directly allocate */ *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; - for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); + for (int rb = rbStart; rb < sched_ctrl->sched_pdsch.rbSize; rb++) + rballoc_mask[rb] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); return true; } @@ -612,8 +609,7 @@ static void pf_dl(module_id_t module_id, sub_frame_t slot, NR_UE_info_t **UE_list, int max_num_ue, - int n_rb_sched, - uint16_t *rballoc_mask) + int n_rb_sched) { gNB_MAC_INST *mac = RC.nrmac[module_id]; NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; @@ -649,7 +645,7 @@ static void pf_dl(module_id_t module_id, /* retransmission */ if (sched_pdsch->dl_harq_pid >= 0) { /* Allocate retransmission */ - bool r = allocate_dl_retransmission(module_id, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pdsch->dl_harq_pid); + bool r = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched, UE, sched_pdsch->dl_harq_pid); if (!r) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", @@ -744,7 +740,9 @@ static void pf_dl(module_id_t module_id, int beam = 0; int CCEIndex = get_cce_index(mac, - CC_id, slot, iterator->UE->rnti, + CC_id, + slot, + iterator->UE->rnti, &sched_ctrl->aggregation_level, beam, sched_ctrl->search_space, @@ -778,12 +776,7 @@ static void pf_dl(module_id_t module_id, } sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(mac, - /* CC_id = */ 0, - &sched_ctrl->sched_pdcch, - CCEIndex, - sched_ctrl->aggregation_level, - beam); + fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam); /* MCS has been set above */ sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); @@ -804,22 +797,22 @@ static void pf_dl(module_id_t module_id, const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); - int rbStop = 0; - int rbStart = 0; - get_start_stop_allocation(mac, iterator->UE, &rbStart, &rbStop); + // TODO assuming beam 0 for now + uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[0]; + dl_bwp_info_t bwp_info = get_bwp_start_size(mac, iterator->UE); + int rbStart = 0; // WRT BWP start + int rbStop = bwp_info.bwpSize - 1; + int bwp_start = bwp_info.bwpStart; // Freq-demain allocation - while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) + while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap)) rbStart++; uint16_t max_rbSize = 1; - while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize] & slbitmap)) + while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize + bwp_start] & slbitmap)) max_rbSize++; - sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, - dl_bwp, - tda_info, - sched_pdsch->nrOfLayers); + sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, tda_info, sched_pdsch->nrOfLayers); sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->pucch_allocation = alloc; @@ -848,7 +841,7 @@ static void pf_dl(module_id_t module_id, /* transmissions: directly allocate */ n_rb_sched -= sched_pdsch->rbSize; - for (int rb = 0; rb < sched_pdsch->rbSize; rb++) + for (int rb = bwp_start; rb < sched_pdsch->rbSize; rb++) rballoc_mask[rb + sched_pdsch->rbStart] |= slbitmap; remainUEs--; @@ -864,41 +857,11 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_ return; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; - const int CC_id = 0; - /* Get bwpSize and TDAfrom the first UE */ - /* This is temporary and it assumes all UEs have the same BWP and TDA*/ - NR_UE_info_t *UE=UE_info->list[0]; - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); - int startSymbolIndex, nrOfSymbols; - const int coresetid = sched_ctrl->coreset->controlResourceSetId; - const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = - get_dl_tdalist(current_BWP, coresetid, sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_); - AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - - const uint16_t bwpSize = current_BWP->BWPSize; - const uint16_t BWPStart = current_BWP->BWPStart; - - const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols); - // TODO improve handling of beam in vrb_map (for now just using 0) - uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map[0]; - uint16_t rballoc_mask[bwpSize]; - int n_rb_sched = 0; - - for (int i = 0; i < bwpSize; i++) { - rballoc_mask[i] = vrb_map[i + BWPStart]; - // if all the pdsch symbols are free - if (!(rballoc_mask[i] & slbitmap)) - n_rb_sched++; - } + int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; /* Retrieve amount of data to send for this UE */ nr_store_dlsch_buffer(module_id, frame, slot); - int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; int average_agg_level = 4; // TODO find a better estimation int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); @@ -911,8 +874,7 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_ slot, UE_info->list, max_sched_ues, - n_rb_sched, - rballoc_mask); + bw); // we set the whole BW as max number } nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { @@ -1087,8 +1049,9 @@ void nr_schedule_ue_spec(module_id_t module_id, const int pduindex = gNB_mac->pdu_index[CC_id]++; pdsch_pdu->pduIndex = pduindex; - pdsch_pdu->BWPSize = current_BWP->BWPSize; - pdsch_pdu->BWPStart = current_BWP->BWPStart; + dl_bwp_info_t bwp_info = get_bwp_start_size(gNB_mac, UE); + pdsch_pdu->BWPSize = bwp_info.bwpSize; + pdsch_pdu->BWPStart = bwp_info.bwpStart; pdsch_pdu->SubcarrierSpacing = current_BWP->scs; pdsch_pdu->CyclicPrefix = current_BWP->cyclicprefix ? *current_BWP->cyclicprefix : 0; @@ -1202,17 +1165,9 @@ void nr_schedule_ue_spec(module_id_t module_id, AssertFatal(pdsch_Config == NULL || pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, "Only frequency resource allocation type 1 is currently supported\n"); - - // For a PDSCH scheduled with a DCI format 1_0 in any type of PDCCH common search space, regardless of which - // bandwidth part is the active bandwidth part, RB numbering starts from the lowest RB of the CORESET in which the - // DCI was received; otherwise RB numbering starts from the lowest RB in the determined downlink bandwidth part. - // TS 38.214 Section 5.1.2.2.2 - int rbStop = 0; - int rbStart = 0; - get_start_stop_allocation(gNB_mac, UE, &rbStart, &rbStop); dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize, - pdsch_pdu->rbStart - rbStart, - rbStop - rbStart + 1); + pdsch_pdu->rbStart, + pdsch_pdu->BWPSize); dci_payload.format_indicator = 1; dci_payload.time_domain_assignment.val = sched_pdsch->time_domain_allocation; dci_payload.mcs = sched_pdsch->mcs; From c8387d706cbd7b0f4905b718bb4c84996e412966 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 26 Sep 2024 10:05:25 +0200 Subject: [PATCH 3/5] making ULSCH preprocessor agnostic to UEs BWP and TDA --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 238 +++++++----------- 1 file changed, 90 insertions(+), 148 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 84d80bc930..2149386399 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1640,7 +1640,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; int rbStart = 0; // wrt BWP start - const uint16_t bwpSize = ul_bwp->BWPSize; + const uint32_t bwpSize = ul_bwp->BWPSize; + const uint32_t bwpStart = ul_bwp->BWPStart; const uint8_t nrOfLayers = retInfo->nrOfLayers; LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); LOG_D(NR_MAC,"tbs %d\n",retInfo->tb_size); @@ -1651,11 +1652,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, tda); if (!tda_info.valid_tda) return false; + bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == tda_info.startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= tda_info.nrOfSymbols); if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) { /* Check the resource is enough for retransmission */ const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) + while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) rbStart++; if (rbStart + retInfo->rbSize > bwpSize) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n", @@ -1667,19 +1669,16 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, bwpSize); return false; } - LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); + LOG_D(NR_MAC, "Retransmission keeping TDA %d and TBS %d\n", tda, retInfo->tb_size); } else { - NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, - ul_bwp, - &tda_info, - nrOfLayers); + NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, &tda_info, nrOfLayers); /* the retransmission will use a different time domain allocation, check * that we have enough resources */ const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) + while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) rbStart++; int rbSize = 0; - while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + rbSize] & slbitmap)) + while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap)) rbSize++; uint32_t new_tbs; uint16_t new_rbSize; @@ -1703,7 +1702,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, retInfo->tb_size); return false; /* the maximum TBsize we might have is smaller than what we need */ } - LOG_D(NR_MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs); + LOG_D(NR_MAC, "Retransmission with TDA %d->%d and TBS %d -> %d\n", retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs); /* we can allocate it. Overwrite the time_domain_allocation, the number * of RBs, and the new TB size. The rest is done below */ retInfo->tb_size = new_tbs; @@ -1715,7 +1714,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, /* Find a free CCE */ int CCEIndex = get_cce_index(nrmac, - CC_id, slot, UE->rnti, + CC_id, + slot, + UE->rnti, &sched_ctrl->aggregation_level, 0, // TODO use beam index sched_ctrl->search_space, @@ -1723,10 +1724,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, &sched_ctrl->sched_pdcch, false); if (CCEIndex<0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", - UE->rnti, - frame, - slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot); return false; } @@ -1738,11 +1736,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, sched_ctrl->aggregation_level, 0); // TODO use beam index when implemented - /* frame/slot in sched_pusch has been set previously. In the following, we - * overwrite the information in the retransmission information before storing - * as the new scheduling instruction */ - retInfo->frame = sched_ctrl->sched_pusch.frame; - retInfo->slot = sched_ctrl->sched_pusch.slot; + retInfo->frame = (frame + (slot + tda_info.k2) / nr_slots_per_frame[ul_bwp->scs]) % MAX_FRAME_NUMBER; + retInfo->slot = (slot + tda_info.k2) % nr_slots_per_frame[ul_bwp->scs]; /* Get previous PSUCH field info */ sched_ctrl->sched_pusch = *retInfo; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; @@ -1761,7 +1756,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, /* Mark the corresponding RBs as used */ n_rb_sched -= sched_pusch->rbSize; - for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + for (int rb = bwpStart; rb < sched_ctrl->sched_pusch.rbSize; rb++) rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); return true; } @@ -1778,22 +1773,22 @@ static int comparator(const void *p, const void *q) { static void pf_ul(module_id_t module_id, frame_t frame, - sub_frame_t slot, + int slot, + frame_t sched_frame, + int sched_slot, NR_UE_info_t *UE_list[], int max_num_ue, - int n_rb_sched, - uint16_t *rballoc_mask) + int n_rb_sched) { - const int CC_id = 0; gNB_MAC_INST *nrmac = RC.nrmac[module_id]; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; - + const int min_rb = nrmac->min_grant_prb; // UEs that could be scheduled UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0}; int remainUEs = max_num_ue; - int curUE=0; + int curUE = 0; /* Loop UE_list to calculate throughput and coeff */ UE_iterator(UE_list, UE) { @@ -1805,9 +1800,6 @@ static void pf_ul(module_id_t module_id, LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; - int rbStart = 0; // wrt BWP start - - const uint16_t bwpSize = current_BWP->BWPSize; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul; @@ -1819,12 +1811,16 @@ static void pf_ul(module_id_t module_id, if(remainUEs == 0) continue; + const int index = ul_buffer_index(sched_frame, sched_slot, current_BWP->scs, nrmac->vrb_map_UL_size); + // TODO improve handling of beam in vrb_map (for now just using 0) + uint16_t *rballoc_mask = &nrmac->common_channels[CC_id].vrb_map_UL[0][index * MAX_BWP_SIZE]; + /* Check if retransmission is necessary */ sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n",UE->rnti,sched_pusch->ul_harq_pid); if (sched_pusch->ul_harq_pid >= 0) { /* Allocate retransmission*/ - const int tda = get_ul_tda(nrmac, scc, sched_pusch->frame, sched_pusch->slot); + const int tda = get_ul_tda(nrmac, scc, sched_frame, sched_slot); bool r = allocate_ul_retransmission(nrmac, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pusch->ul_harq_pid, scc, tda); if (!r) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UL retransmission could not be allocated\n", @@ -1853,7 +1849,7 @@ static void pf_ul(module_id_t module_id, const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes); /* preprocessor computed sched_frame/sched_slot */ - const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity); + const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_frame, sched_slot, nrmac->ulsch_max_frame_inactivity); LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no"); if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) { @@ -1892,7 +1888,7 @@ static void pf_ul(module_id_t module_id, } sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1; - sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_pusch->frame, sched_pusch->slot); + sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_frame, sched_slot); sched_pusch->tda_info = get_ul_tda_info(current_BWP, sched_ctrl->coreset->controlResourceSetId, sched_ctrl->search_space->searchSpaceType->present, @@ -1904,13 +1900,20 @@ static void pf_ul(module_id_t module_id, &sched_pusch->tda_info, sched_pusch->nrOfLayers); - LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", - min_rb, rbStart, sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data); + int rbStart = 0; // wrt BWP start + LOG_D(NR_MAC, + "Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", + min_rb, + rbStart, + sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data); + const uint32_t bwpSize = current_BWP->BWPSize; + const uint32_t bwpStart = current_BWP->BWPStart; const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) + while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) rbStart++; if (rbStart + min_rb >= bwpSize) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate continuous UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", + LOG_D(NR_MAC, + "[UE %04x][%4d.%2d] could not allocate continuous UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", UE->rnti, frame, slot, @@ -1921,18 +1924,15 @@ static void pf_ul(module_id_t module_id, } sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(nrmac, - CC_id, - &sched_ctrl->sched_pdcch, - CCEIndex, - sched_ctrl->aggregation_level, - 0); // TODO use beam index); + fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, 0); // TODO use beam index NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs); update_ul_ue_R_Qm(sched_pusch->mcs, current_BWP->mcs_table, current_BWP->pusch_Config, &sched_pusch->R, &sched_pusch->Qm); sched_pusch->rbStart = rbStart; sched_pusch->rbSize = min_rb; + sched_pusch->frame = sched_frame; + sched_pusch->slot = sched_slot; sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, sched_pusch->R, sched_pusch->rbSize, @@ -1963,7 +1963,7 @@ static void pf_ul(module_id_t module_id, /* Mark the corresponding RBs as used */ n_rb_sched -= sched_pusch->rbSize; - for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + for (int rb = bwpStart; rb < sched_ctrl->sched_pusch.rbSize; rb++) rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= slbitmap; remainUEs--; @@ -1982,8 +1982,8 @@ static void pf_ul(module_id_t module_id, UE->ul_thr_ue, tbs, coeff_ue); - UE_sched[curUE].coef=coeff_ue; - UE_sched[curUE].UE=UE; + UE_sched[curUE].coef = coeff_ue; + UE_sched[curUE].UE = UE; curUE++; } @@ -2018,7 +2018,7 @@ static void pf_ul(module_id_t module_id, NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1; - sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_pusch->frame, sched_pusch->slot); + sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_frame, sched_slot); sched_pusch->tda_info = get_ul_tda_info(current_BWP, sched_ctrl->coreset->controlResourceSetId, sched_ctrl->search_space->searchSpaceType->present, @@ -2030,14 +2030,19 @@ static void pf_ul(module_id_t module_id, &sched_pusch->tda_info, sched_pusch->nrOfLayers); + const int index = ul_buffer_index(sched_frame, sched_slot, current_BWP->scs, nrmac->vrb_map_UL_size); + // TODO improve handling of beam in vrb_map (for now just using 0) + uint16_t *rballoc_mask = &nrmac->common_channels[CC_id].vrb_map_UL[0][index * MAX_BWP_SIZE]; + int rbStart = 0; const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); - const uint16_t bwpSize = current_BWP->BWPSize; - while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap)) + const uint32_t bwpSize = current_BWP->BWPSize; + const uint32_t bwpStart = current_BWP->BWPStart; + while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) rbStart++; sched_pusch->rbStart = rbStart; uint16_t max_rbSize = 1; - while (rbStart + max_rbSize < bwpSize && !(rballoc_mask[rbStart + max_rbSize] & slbitmap)) + while (rbStart + max_rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + max_rbSize] & slbitmap)) max_rbSize++; if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) { @@ -2051,13 +2056,18 @@ static void pf_ul(module_id_t module_id, iterator++; continue; } else - LOG_D(NR_MAC, "allocating UL data for RNTI %04x (rbStart %d, min_rb %d, max_rbSize %d, bwpSize %d)\n", iterator->UE->rnti, rbStart, min_rb, max_rbSize, bwpSize); + LOG_D(NR_MAC, + "allocating UL data for RNTI %04x (rbStart %d, min_rb %d, max_rbSize %d, bwpSize %d)\n", + iterator->UE->rnti, + rbStart, + min_rb, + max_rbSize, + bwpSize); /* Calculate the current scheduling bytes */ const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0); /* adjust rbSize and MCS according to PHR and BPRE */ - if(sched_ctrl->pcmax!=0 || - sched_ctrl->ph!=0) // verify if the PHR related parameter have been initialized + if(sched_ctrl->pcmax != 0 || sched_ctrl->ph != 0) // verify if the PHR related parameter have been initialized nr_ue_max_mcs_min_rb(current_BWP->scs, sched_ctrl->ph, sched_pusch, current_BWP, min_rb, B, &max_rbSize, &sched_pusch->mcs); if (sched_pusch->mcs < sched_ctrl->ul_bler_stats.mcs) @@ -2093,22 +2103,27 @@ static void pf_ul(module_id_t module_id, sched_pusch->rbSize = rbSize; sched_pusch->tb_size = TBS; - LOG_D(NR_MAC,"rbSize %d (max_rbSize %d), TBS %d, est buf %d, sched_ul %d, B %d, CCE %d, num_dmrs_symb %d, N_PRB_DMRS %d\n", - rbSize, max_rbSize,sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B, - sched_ctrl->cce_index,sched_pusch->dmrs_info.num_dmrs_symb,sched_pusch->dmrs_info.N_PRB_DMRS); + sched_pusch->frame = sched_frame; + sched_pusch->slot = sched_slot; + LOG_D(NR_MAC, + "rbSize %d (max_rbSize %d), TBS %d, est buf %d, sched_ul %d, B %d, CCE %d, num_dmrs_symb %d, N_PRB_DMRS %d\n", + rbSize, + max_rbSize, + sched_pusch->tb_size, + sched_ctrl->estimated_ul_buffer, + sched_ctrl->sched_ul_bytes, + B, + sched_ctrl->cce_index, + sched_pusch->dmrs_info.num_dmrs_symb, + sched_pusch->dmrs_info.N_PRB_DMRS); /* Mark the corresponding RBs as used */ sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(nrmac, - CC_id, - &sched_ctrl->sched_pdcch, - CCEIndex, - sched_ctrl->aggregation_level, - 0); // TODO use beam index); + fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, 0); // TODO use beam index n_rb_sched -= sched_pusch->rbSize; - for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + for (int rb = bwpStart; rb < sched_ctrl->sched_pusch.rbSize; rb++) rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= slbitmap; /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ @@ -2120,92 +2135,25 @@ static void pf_ul(module_id_t module_id, static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) { gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; - NR_COMMON_channels_t *cc = nr_mac->common_channels; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_ServingCellConfigCommonSIB_t *scc_sib1 = sib1 ? sib1->servingCellConfigCommon : NULL; - - AssertFatal(scc || scc_sib1, "We need one serving cell config common\n"); - // no UEs if (nr_mac->UE_info.list[0] == NULL) return false; - const int CC_id = 0; - - /* Get the K2 for first UE to compute offset. The other UEs are guaranteed to - * have the same K2 (we don't support multiple/different K2s via different - * TDAs yet). If the TDA is negative, it means that there is no UL slot to - * schedule now (slot + k2 is not UL slot) */ - NR_UE_sched_ctrl_t *sched_ctrl = &nr_mac->UE_info.list[0]->UE_sched_ctrl; - NR_UE_UL_BWP_t *current_BWP = &nr_mac->UE_info.list[0]->current_UL_BWP; - int mu = current_BWP->scs; - const int temp_tda = get_ul_tda(nr_mac, scc, frame, slot); - NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = get_ul_tdalist(current_BWP, - sched_ctrl->coreset->controlResourceSetId, - sched_ctrl->search_space->searchSpaceType->present, - TYPE_C_RNTI_); - int K2 = get_K2(tdaList, temp_tda, mu, scc); - const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER; - const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; - const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot); - if (tda < 0) - return false; - DevAssert(K2 == get_K2(tdaList, tda, mu, scc)); - + NR_COMMON_channels_t *cc = nr_mac->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; + NR_ServingCellConfigCommonSIB_t *scc_sib1 = sib1 ? sib1->servingCellConfigCommon : NULL; + AssertFatal(scc || scc_sib1, "We need one serving cell config common\n"); + const int slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + // TODO we assume the same K2 for all UEs + const int K2 = nr_mac->radio_config.minRXTXTIME + get_NTN_Koffset(scc); + const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER; + const int sched_slot = (slot + K2) % slots_frame; if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) return false; - sched_ctrl->sched_pusch.slot = sched_slot; - sched_ctrl->sched_pusch.frame = sched_frame; - UE_iterator(nr_mac->UE_info.list, UE2) { - NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl; - AssertFatal(K2 == get_K2(tdaList, tda, mu, scc), - "Different K2, %d(UE%d) != %ld(UE%04x)\n", - K2, 0, get_K2(tdaList, tda, mu, scc), UE2->rnti); - sched_ctrl->sched_pusch.slot = sched_slot; - sched_ctrl->sched_pusch.frame = sched_frame; - } - - /* Change vrb_map_UL to rballoc_mask: check which symbols per RB (in - * vrb_map_UL) overlap with the "default" tda and exclude those RBs. - * Calculate largest contiguous RBs */ - const int index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); - // TODO improve handling of beam in vrb_map (for now just using 0) - uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[0][index * MAX_BWP_SIZE]; - - const uint16_t bwpSize = current_BWP->BWPSize; - const uint16_t bwpStart = current_BWP->BWPStart; - - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; - int startSymbolIndex, nrOfSymbols; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - const uint16_t symb = SL_to_bitmap(startSymbolIndex, nrOfSymbols); - - int st = 0, e = 0, len = 0; - - for (int i = 0; i < bwpSize; i++) { - while ((vrb_map_UL[bwpStart + i] & symb) != 0 && i < bwpSize) - i++; - st = i; - while ((vrb_map_UL[bwpStart + i] & symb) == 0 && i < bwpSize) - i++; - if (i - st > len) { - len = i - st; - e = i - 1; - } - } - st = e - len + 1; - - LOG_D(NR_MAC,"UL %d.%d : start_prb %d, end PRB %d\n",frame,slot,st,e); - - uint16_t rballoc_mask[bwpSize]; - - /* Calculate mask: if any RB in vrb_map_UL is blocked (1), the current RB will be 0 */ - for (int i = st; i < e; i++) - rballoc_mask[i] = vrb_map_UL[bwpStart + i]; - int bw = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + int average_agg_level = 4; // TODO find a better estimation int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); @@ -2213,13 +2161,7 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_ max_sched_ues = min(max_sched_ues, MAX_DCI_CORESET); /* proportional fair scheduling algorithm */ - pf_ul(module_id, - frame, - slot, - nr_mac->UE_info.list, - max_sched_ues, - len, - rballoc_mask); + pf_ul(module_id, frame, slot, sched_frame, sched_slot, nr_mac->UE_info.list, max_sched_ues, bw); return true; } From 62301e9eef0b439598b667d3bab6305bace83427 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 15 Oct 2024 14:51:27 +0200 Subject: [PATCH 4/5] remove bf_weights from 2step RA config file --- .../CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf index 45dbf2197f..d59dca9384 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.106PRB.usrpb210.RA_2-Step.conf @@ -226,8 +226,6 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; clock_src = "internal"; } ); From ad9b91627c5894a145b41a8f62de88bf9194862b Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Tue, 1 Oct 2024 12:46:52 +0100 Subject: [PATCH 5/5] Prevent DLSCH scheduler to allocate PRBs outside of current BWP --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 5faa5d3c13..57b2356f52 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -736,6 +736,53 @@ static void pf_dl(module_id_t module_id, NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; + /* MCS has been set above */ + sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); + AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); + + const int coresetid = sched_ctrl->coreset->controlResourceSetId; + sched_pdsch->tda_info = get_dl_tda_info(dl_bwp, + sched_ctrl->search_space->searchSpaceType->present, + sched_pdsch->time_domain_allocation, + scc->dmrs_TypeA_Position, + 1, + TYPE_C_RNTI_, + coresetid, + false); + AssertFatal(sched_pdsch->tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n"); + + NR_tda_info_t *tda_info = &sched_pdsch->tda_info; + + const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); + + // TODO assuming beam 0 for now + uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[0]; + dl_bwp_info_t bwp_info = get_bwp_start_size(mac, iterator->UE); + int rbStart = 0; // WRT BWP start + int rbStop = bwp_info.bwpSize - 1; + int bwp_start = bwp_info.bwpStart; + // Freq-demain allocation + while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap)) + rbStart++; + + uint16_t max_rbSize = 1; + + while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize + bwp_start] & slbitmap)) + max_rbSize++; + + if (max_rbSize < min_rbSize) { + LOG_D(NR_MAC, + "(%d.%d) Cannot schedule RNTI %04x, rbStart %d, rbSize %d, rbStop %d\n", + frame, + slot, + rnti, + rbStart, + max_rbSize, + rbStop); + iterator++; + continue; + } + // TODO properly set the beam index (currently only done for RA) int beam = 0; @@ -778,40 +825,6 @@ static void pf_dl(module_id_t module_id, sched_ctrl->cce_index = CCEIndex; fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam); - /* MCS has been set above */ - sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); - AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); - - const int coresetid = sched_ctrl->coreset->controlResourceSetId; - sched_pdsch->tda_info = get_dl_tda_info(dl_bwp, - sched_ctrl->search_space->searchSpaceType->present, - sched_pdsch->time_domain_allocation, - scc->dmrs_TypeA_Position, - 1, - TYPE_C_RNTI_, - coresetid, - false); - AssertFatal(sched_pdsch->tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n"); - - NR_tda_info_t *tda_info = &sched_pdsch->tda_info; - - const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); - - // TODO assuming beam 0 for now - uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[0]; - dl_bwp_info_t bwp_info = get_bwp_start_size(mac, iterator->UE); - int rbStart = 0; // WRT BWP start - int rbStop = bwp_info.bwpSize - 1; - int bwp_start = bwp_info.bwpStart; - // Freq-demain allocation - while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap)) - rbStart++; - - uint16_t max_rbSize = 1; - - while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize + bwp_start] & slbitmap)) - max_rbSize++; - sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, tda_info, sched_pdsch->nrOfLayers); sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);