mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Merge remote-tracking branch 'origin/NR_gNB_sched_improvements' into integration_2024_w43 (!2989)
This MR removes limitations on BWP scheduler operation for which only the information from the first UE of the list was taken into account. To do so, I moved the VRB map check for DL and UL scheduler out of the preprocessor and in the scheduler itself. Closes: #769
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
@@ -389,10 +389,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;
|
||||
@@ -401,25 +403,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)
|
||||
@@ -441,12 +446,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");
|
||||
|
||||
@@ -469,6 +468,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) {
|
||||
@@ -476,35 +483,27 @@ 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) {
|
||||
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) == 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) != 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;
|
||||
@@ -547,7 +546,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,
|
||||
@@ -555,10 +556,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;
|
||||
}
|
||||
|
||||
@@ -570,30 +568,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;
|
||||
}
|
||||
@@ -613,8 +608,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;
|
||||
@@ -650,7 +644,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",
|
||||
@@ -741,11 +735,60 @@ 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;
|
||||
|
||||
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,
|
||||
@@ -779,48 +822,9 @@ 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);
|
||||
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);
|
||||
|
||||
int rbStop = 0;
|
||||
int rbStart = 0;
|
||||
get_start_stop_allocation(mac, iterator->UE, &rbStart, &rbStop);
|
||||
// Freq-demain allocation
|
||||
while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap) != slbitmap)
|
||||
rbStart++;
|
||||
|
||||
uint16_t max_rbSize = 1;
|
||||
|
||||
while (rbStart + max_rbSize <= rbStop && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == 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;
|
||||
@@ -849,8 +853,8 @@ 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++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
|
||||
for (int rb = bwp_start; rb < sched_pdsch->rbSize; rb++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] |= slbitmap;
|
||||
|
||||
remainUEs--;
|
||||
iterator++;
|
||||
@@ -865,45 +869,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++) {
|
||||
// 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
|
||||
|
||||
// if all the pdsch symbols are free
|
||||
if ((rballoc_mask[i]&slbitmap) == 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);
|
||||
|
||||
@@ -916,8 +886,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) {
|
||||
@@ -1092,8 +1061,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;
|
||||
@@ -1207,17 +1177,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;
|
||||
|
||||
@@ -1644,7 +1644,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);
|
||||
@@ -1655,11 +1656,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) != 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",
|
||||
@@ -1671,19 +1673,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) != slbitmap)
|
||||
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
|
||||
rbStart++;
|
||||
int rbSize = 0;
|
||||
while (rbStart + rbSize < bwpSize && (rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap)
|
||||
while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap))
|
||||
rbSize++;
|
||||
uint32_t new_tbs;
|
||||
uint16_t new_rbSize;
|
||||
@@ -1707,7 +1706,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;
|
||||
@@ -1719,7 +1718,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,
|
||||
@@ -1727,10 +1728,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;
|
||||
}
|
||||
|
||||
@@ -1742,11 +1740,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;
|
||||
@@ -1765,8 +1760,8 @@ 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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1782,22 +1777,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) {
|
||||
@@ -1809,9 +1804,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;
|
||||
|
||||
@@ -1823,12 +1815,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",
|
||||
@@ -1857,7 +1853,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) || nr_timer_is_active(&sched_ctrl->transm_interrupt)) {
|
||||
@@ -1896,7 +1892,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,
|
||||
@@ -1908,13 +1904,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) != 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,
|
||||
@@ -1925,18 +1928,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,
|
||||
@@ -1967,8 +1967,8 @@ 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;
|
||||
for (int rb = bwpStart; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= slbitmap;
|
||||
|
||||
remainUEs--;
|
||||
continue;
|
||||
@@ -1986,8 +1986,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++;
|
||||
}
|
||||
|
||||
@@ -2022,7 +2022,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,
|
||||
@@ -2034,14 +2034,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) != 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) == slbitmap)
|
||||
while (rbStart + max_rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + max_rbSize] & slbitmap))
|
||||
max_rbSize++;
|
||||
|
||||
if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) {
|
||||
@@ -2055,13 +2060,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)
|
||||
@@ -2097,23 +2107,28 @@ 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++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap;
|
||||
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 */
|
||||
remainUEs--;
|
||||
@@ -2124,92 +2139,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 = 0; i < bwpSize; i++)
|
||||
rballoc_mask[i] = (i >= st && i <= e)*SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
|
||||
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);
|
||||
|
||||
@@ -2217,13 +2165,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user