Commit 26fa3300 authored by Robert Schmidt's avatar Robert Schmidt

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
parents 39f00692 ad9b9162
...@@ -250,8 +250,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) ...@@ -250,8 +250,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
const uint32_t *gold = const uint32_t *gold =
nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol); 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, // Qm = 2 as DMRS is QPSK modulated
(int16_t *)mod_dmrs); // 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 #ifdef DEBUG_DLSCH
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l_symbol, n_dmrs, dmrs_Type); printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l_symbol, n_dmrs, dmrs_Type);
......
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
#define WORD 32 #define WORD 32
//#define SIZE_OF_POINTER sizeof (void *) //#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 */ /* 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; 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"); 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) ...@@ -389,10 +389,12 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid)
UE->mac_stats.dl.errors++; UE->mac_stats.dl.errors++;
} }
static void get_start_stop_allocation(gNB_MAC_INST *mac, typedef struct {
NR_UE_info_t *UE, int bwpStart;
int *rbStart, int bwpSize;
int *rbStop) } 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_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; 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, ...@@ -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 // 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. // 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 // TS 38.214 Section 5.1.2.2.2
*rbStop = dl_bwp->BWPSize - 1; dl_bwp_info_t bwp_info;
*rbStart = 0; // start wrt BWPstart bwp_info.bwpSize = dl_bwp->BWPSize;
bwp_info.bwpStart = dl_bwp->BWPStart;
if (sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common && if (sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common &&
dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) { dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) {
if (mac->cset0_bwp_size != 0) { if (mac->cset0_bwp_size != 0) {
*rbStart = mac->cset0_bwp_start; bwp_info.bwpStart = mac->cset0_bwp_start;
*rbStop = *rbStart + mac->cset0_bwp_size - 1; bwp_info.bwpSize = mac->cset0_bwp_size;
} }
else { else {
*rbStart = UE->sc_info.initial_dl_BWPStart; // TODO this is not entirely correct
*rbStop = *rbStart + UE->sc_info.initial_dl_BWPSize - 1; // 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, static bool allocate_dl_retransmission(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot, sub_frame_t slot,
uint16_t *rballoc_mask,
int *n_rb_sched, int *n_rb_sched,
NR_UE_info_t *UE, NR_UE_info_t *UE,
int current_harq_pid) int current_harq_pid)
...@@ -441,12 +446,6 @@ static bool allocate_dl_retransmission(module_id_t module_id, ...@@ -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; int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index;
const int coresetid = sched_ctrl->coreset->controlResourceSetId; 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); const int tda = get_dl_tda(nr_mac, scc, slot);
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n"); 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, ...@@ -469,6 +468,14 @@ static bool allocate_dl_retransmission(module_id_t module_id,
reuse_old_tda ? "reuse" : "do not reuse", reuse_old_tda ? "reuse" : "do not reuse",
layers == retInfo->nrOfLayers ? "same" : "different"); 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) { if (reuse_old_tda && layers == retInfo->nrOfLayers) {
/* Check that there are enough resources for retransmission */ /* Check that there are enough resources for retransmission */
while (rbSize < retInfo->rbSize) { while (rbSize < retInfo->rbSize) {
...@@ -476,35 +483,27 @@ static bool allocate_dl_retransmission(module_id_t module_id, ...@@ -476,35 +483,27 @@ static bool allocate_dl_retransmission(module_id_t module_id,
rbSize = 0; rbSize = 0;
const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); 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++; rbStart++;
if (rbStart >= rbStop) { if (rbStart >= rbStop) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
UE->rnti,
frame,
slot);
return false; return false;
} }
while (rbStart + rbSize <= rbStop && while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize)
(rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap &&
rbSize < retInfo->rbSize)
rbSize++; rbSize++;
} }
} else { } else {
/* the retransmission will use a different time domain allocation, check /* the retransmission will use a different time domain allocation, check
* that we have enough resources */ * that we have enough resources */
NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers);
dl_bwp,
&temp_tda,
layers);
const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols); 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++; rbStart++;
while (rbStart + rbSize <= rbStop && (rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap) while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap))
rbSize++; rbSize++;
uint32_t new_tbs; uint32_t new_tbs;
...@@ -547,7 +546,9 @@ static bool allocate_dl_retransmission(module_id_t module_id, ...@@ -547,7 +546,9 @@ static bool allocate_dl_retransmission(module_id_t module_id,
/* Find a free CCE */ /* Find a free CCE */
int CCEIndex = get_cce_index(nr_mac, int CCEIndex = get_cce_index(nr_mac,
CC_id, slot, UE->rnti, CC_id,
slot,
UE->rnti,
&sched_ctrl->aggregation_level, &sched_ctrl->aggregation_level,
beam, beam,
sched_ctrl->search_space, sched_ctrl->search_space,
...@@ -555,10 +556,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, ...@@ -555,10 +556,7 @@ static bool allocate_dl_retransmission(module_id_t module_id,
&sched_ctrl->sched_pdcch, &sched_ctrl->sched_pdcch,
false); false);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot);
UE->rnti,
frame,
slot);
return false; return false;
} }
...@@ -570,30 +568,27 @@ static bool allocate_dl_retransmission(module_id_t module_id, ...@@ -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); 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); alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, beam, r_pucch, 0);
if (alloc < 0) { if (alloc < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", UE->rnti, frame, slot);
UE->rnti,
frame,
slot);
return false; return false;
} }
} }
sched_ctrl->cce_index = CCEIndex; sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nr_mac, fill_pdcch_vrb_map(nr_mac,
/* CC_id = */ 0, CC_id,
&sched_ctrl->sched_pdcch, &sched_ctrl->sched_pdcch,
CCEIndex, CCEIndex,
sched_ctrl->aggregation_level, sched_ctrl->aggregation_level,
beam); beam);
/* just reuse from previous scheduling opportunity, set new start RB */ /* just reuse from previous scheduling opportunity, set new start RB */
sched_ctrl->sched_pdsch = *retInfo; 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; sched_ctrl->sched_pdsch.pucch_allocation = alloc;
/* retransmissions: directly allocate */ /* retransmissions: directly allocate */
*n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++) for (int rb = rbStart; 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] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
return true; return true;
} }
...@@ -613,8 +608,7 @@ static void pf_dl(module_id_t module_id, ...@@ -613,8 +608,7 @@ static void pf_dl(module_id_t module_id,
sub_frame_t slot, sub_frame_t slot,
NR_UE_info_t **UE_list, NR_UE_info_t **UE_list,
int max_num_ue, int max_num_ue,
int n_rb_sched, int n_rb_sched)
uint16_t *rballoc_mask)
{ {
gNB_MAC_INST *mac = RC.nrmac[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
...@@ -650,7 +644,7 @@ static void pf_dl(module_id_t module_id, ...@@ -650,7 +644,7 @@ static void pf_dl(module_id_t module_id,
/* retransmission */ /* retransmission */
if (sched_pdsch->dl_harq_pid >= 0) { if (sched_pdsch->dl_harq_pid >= 0) {
/* Allocate retransmission */ /* 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) { if (!r) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", 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, ...@@ -741,11 +735,60 @@ static void pf_dl(module_id_t module_id,
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; 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) // TODO properly set the beam index (currently only done for RA)
int beam = 0; int beam = 0;
int CCEIndex = get_cce_index(mac, int CCEIndex = get_cce_index(mac,
CC_id, slot, iterator->UE->rnti, CC_id,
slot,
iterator->UE->rnti,
&sched_ctrl->aggregation_level, &sched_ctrl->aggregation_level,
beam, beam,
sched_ctrl->search_space, sched_ctrl->search_space,
...@@ -779,48 +822,9 @@ static void pf_dl(module_id_t module_id, ...@@ -779,48 +822,9 @@ static void pf_dl(module_id_t module_id,
} }
sched_ctrl->cce_index = CCEIndex; sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(mac, fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam);
/* CC_id = */ 0,
&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) sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, tda_info, sched_pdsch->nrOfLayers);
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->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->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
sched_pdsch->pucch_allocation = alloc; sched_pdsch->pucch_allocation = alloc;
...@@ -849,8 +853,8 @@ static void pf_dl(module_id_t module_id, ...@@ -849,8 +853,8 @@ static void pf_dl(module_id_t module_id,
/* transmissions: directly allocate */ /* transmissions: directly allocate */
n_rb_sched -= sched_pdsch->rbSize; 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; rballoc_mask[rb + sched_pdsch->rbStart] |= slbitmap;
remainUEs--; remainUEs--;
iterator++; iterator++;
...@@ -865,45 +869,11 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_ ...@@ -865,45 +869,11 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
return; return;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
const int CC_id = 0; int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
/* 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++;
}
}
/* Retrieve amount of data to send for this UE */ /* Retrieve amount of data to send for this UE */
nr_store_dlsch_buffer(module_id, frame, slot); 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 average_agg_level = 4; // TODO find a better estimation
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); 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_ ...@@ -916,8 +886,7 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
slot, slot,
UE_info->list, UE_info->list,
max_sched_ues, max_sched_ues,
n_rb_sched, bw); // we set the whole BW as max number
rballoc_mask);
} }
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { 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, ...@@ -1092,8 +1061,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
const int pduindex = gNB_mac->pdu_index[CC_id]++; const int pduindex = gNB_mac->pdu_index[CC_id]++;
pdsch_pdu->pduIndex = pduindex; pdsch_pdu->pduIndex = pduindex;
pdsch_pdu->BWPSize = current_BWP->BWPSize; dl_bwp_info_t bwp_info = get_bwp_start_size(gNB_mac, UE);
pdsch_pdu->BWPStart = current_BWP->BWPStart; pdsch_pdu->BWPSize = bwp_info.bwpSize;
pdsch_pdu->BWPStart = bwp_info.bwpStart;
pdsch_pdu->SubcarrierSpacing = current_BWP->scs; pdsch_pdu->SubcarrierSpacing = current_BWP->scs;
pdsch_pdu->CyclicPrefix = current_BWP->cyclicprefix ? *current_BWP->cyclicprefix : 0; pdsch_pdu->CyclicPrefix = current_BWP->cyclicprefix ? *current_BWP->cyclicprefix : 0;
...@@ -1207,17 +1177,9 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -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, AssertFatal(pdsch_Config == NULL || pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
"Only frequency resource allocation type 1 is currently supported\n"); "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, dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize,
pdsch_pdu->rbStart - rbStart, pdsch_pdu->rbStart,
rbStop - rbStart + 1); pdsch_pdu->BWPSize);
dci_payload.format_indicator = 1; dci_payload.format_indicator = 1;
dci_payload.time_domain_assignment.val = sched_pdsch->time_domain_allocation; dci_payload.time_domain_assignment.val = sched_pdsch->time_domain_allocation;
dci_payload.mcs = sched_pdsch->mcs; dci_payload.mcs = sched_pdsch->mcs;
......
...@@ -1644,7 +1644,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1644,7 +1644,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
int rbStart = 0; // wrt BWP start 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; 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,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda);
LOG_D(NR_MAC,"tbs %d\n",retInfo->tb_size); LOG_D(NR_MAC,"tbs %d\n",retInfo->tb_size);
...@@ -1655,11 +1656,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1655,11 +1656,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
tda); tda);
if (!tda_info.valid_tda) if (!tda_info.valid_tda)
return false; return false;
bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == tda_info.startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= tda_info.nrOfSymbols); 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) { if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) {
/* Check the resource is enough for retransmission */ /* Check the resource is enough for retransmission */
const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); 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++; rbStart++;
if (rbStart + retInfo->rbSize > bwpSize) { 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", 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, ...@@ -1671,19 +1673,16 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
bwpSize); bwpSize);
return false; 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 { } else {
NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, &tda_info, nrOfLayers);
ul_bwp,
&tda_info,
nrOfLayers);
/* the retransmission will use a different time domain allocation, check /* the retransmission will use a different time domain allocation, check
* that we have enough resources */ * that we have enough resources */
const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); 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++; rbStart++;
int rbSize = 0; int rbSize = 0;
while (rbStart + rbSize < bwpSize && (rballoc_mask[rbStart + rbSize] & slbitmap) == slbitmap) while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap))
rbSize++; rbSize++;
uint32_t new_tbs; uint32_t new_tbs;
uint16_t new_rbSize; uint16_t new_rbSize;
...@@ -1707,7 +1706,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1707,7 +1706,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
retInfo->tb_size); retInfo->tb_size);
return false; /* the maximum TBsize we might have is smaller than what we need */ 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 /* we can allocate it. Overwrite the time_domain_allocation, the number
* of RBs, and the new TB size. The rest is done below */ * of RBs, and the new TB size. The rest is done below */
retInfo->tb_size = new_tbs; retInfo->tb_size = new_tbs;
...@@ -1719,7 +1718,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1719,7 +1718,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
/* Find a free CCE */ /* Find a free CCE */
int CCEIndex = get_cce_index(nrmac, int CCEIndex = get_cce_index(nrmac,
CC_id, slot, UE->rnti, CC_id,
slot,
UE->rnti,
&sched_ctrl->aggregation_level, &sched_ctrl->aggregation_level,
0, // TODO use beam index 0, // TODO use beam index
sched_ctrl->search_space, sched_ctrl->search_space,
...@@ -1727,10 +1728,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1727,10 +1728,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
&sched_ctrl->sched_pdcch, &sched_ctrl->sched_pdcch,
false); false);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot);
UE->rnti,
frame,
slot);
return false; return false;
} }
...@@ -1742,11 +1740,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1742,11 +1740,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
sched_ctrl->aggregation_level, sched_ctrl->aggregation_level,
0); // TODO use beam index when implemented 0); // TODO use beam index when implemented
/* frame/slot in sched_pusch has been set previously. In the following, we retInfo->frame = (frame + (slot + tda_info.k2) / nr_slots_per_frame[ul_bwp->scs]) % MAX_FRAME_NUMBER;
* overwrite the information in the retransmission information before storing retInfo->slot = (slot + tda_info.k2) % nr_slots_per_frame[ul_bwp->scs];
* as the new scheduling instruction */
retInfo->frame = sched_ctrl->sched_pusch.frame;
retInfo->slot = sched_ctrl->sched_pusch.slot;
/* Get previous PSUCH field info */ /* Get previous PSUCH field info */
sched_ctrl->sched_pusch = *retInfo; sched_ctrl->sched_pusch = *retInfo;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
...@@ -1765,8 +1760,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, ...@@ -1765,8 +1760,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
/* Mark the corresponding RBs as used */ /* Mark the corresponding RBs as used */
n_rb_sched -= sched_pusch->rbSize; 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); rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols);
return true; return true;
} }
...@@ -1782,22 +1777,22 @@ static int comparator(const void *p, const void *q) { ...@@ -1782,22 +1777,22 @@ static int comparator(const void *p, const void *q) {
static void pf_ul(module_id_t module_id, static void pf_ul(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot, int slot,
frame_t sched_frame,
int sched_slot,
NR_UE_info_t *UE_list[], NR_UE_info_t *UE_list[],
int max_num_ue, int max_num_ue,
int n_rb_sched, int n_rb_sched)
uint16_t *rballoc_mask)
{ {
const int CC_id = 0; const int CC_id = 0;
gNB_MAC_INST *nrmac = RC.nrmac[module_id]; gNB_MAC_INST *nrmac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
const int min_rb = nrmac->min_grant_prb; const int min_rb = nrmac->min_grant_prb;
// UEs that could be scheduled // UEs that could be scheduled
UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0}; UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
int remainUEs = max_num_ue; int remainUEs = max_num_ue;
int curUE=0; int curUE = 0;
/* Loop UE_list to calculate throughput and coeff */ /* Loop UE_list to calculate throughput and coeff */
UE_iterator(UE_list, UE) { UE_iterator(UE_list, UE) {
...@@ -1809,9 +1804,6 @@ static void pf_ul(module_id_t module_id, ...@@ -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); 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; 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; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul; const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
...@@ -1823,12 +1815,16 @@ static void pf_ul(module_id_t module_id, ...@@ -1823,12 +1815,16 @@ static void pf_ul(module_id_t module_id,
if(remainUEs == 0) if(remainUEs == 0)
continue; 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 */ /* Check if retransmission is necessary */
sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; 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); 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) { if (sched_pusch->ul_harq_pid >= 0) {
/* Allocate retransmission*/ /* 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); bool r = allocate_ul_retransmission(nrmac, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pusch->ul_harq_pid, scc, tda);
if (!r) { if (!r) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UL retransmission could not be allocated\n", 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, ...@@ -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); const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
/* preprocessor computed sched_frame/sched_slot */ /* 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"); 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)) { 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, ...@@ -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->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_pusch->tda_info = get_ul_tda_info(current_BWP,
sched_ctrl->coreset->controlResourceSetId, sched_ctrl->coreset->controlResourceSetId,
sched_ctrl->search_space->searchSpaceType->present, sched_ctrl->search_space->searchSpaceType->present,
...@@ -1908,13 +1904,20 @@ static void pf_ul(module_id_t module_id, ...@@ -1908,13 +1904,20 @@ static void pf_ul(module_id_t module_id,
&sched_pusch->tda_info, &sched_pusch->tda_info,
sched_pusch->nrOfLayers); sched_pusch->nrOfLayers);
LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", int rbStart = 0; // wrt BWP start
min_rb, rbStart, sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data); 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); 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++; rbStart++;
if (rbStart + min_rb >= bwpSize) { 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, UE->rnti,
frame, frame,
slot, slot,
...@@ -1925,18 +1928,15 @@ static void pf_ul(module_id_t module_id, ...@@ -1925,18 +1928,15 @@ static void pf_ul(module_id_t module_id,
} }
sched_ctrl->cce_index = CCEIndex; sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nrmac, fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, 0); // TODO use beam index
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; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs); 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); 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->rbStart = rbStart;
sched_pusch->rbSize = min_rb; 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->tb_size = nr_compute_tbs(sched_pusch->Qm,
sched_pusch->R, sched_pusch->R,
sched_pusch->rbSize, sched_pusch->rbSize,
...@@ -1967,8 +1967,8 @@ static void pf_ul(module_id_t module_id, ...@@ -1967,8 +1967,8 @@ static void pf_ul(module_id_t module_id,
/* Mark the corresponding RBs as used */ /* Mark the corresponding RBs as used */
n_rb_sched -= sched_pusch->rbSize; 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; rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] |= slbitmap;
remainUEs--; remainUEs--;
continue; continue;
...@@ -1986,8 +1986,8 @@ static void pf_ul(module_id_t module_id, ...@@ -1986,8 +1986,8 @@ static void pf_ul(module_id_t module_id,
UE->ul_thr_ue, UE->ul_thr_ue,
tbs, tbs,
coeff_ue); coeff_ue);
UE_sched[curUE].coef=coeff_ue; UE_sched[curUE].coef = coeff_ue;
UE_sched[curUE].UE=UE; UE_sched[curUE].UE = UE;
curUE++; curUE++;
} }
...@@ -2022,7 +2022,7 @@ static void pf_ul(module_id_t module_id, ...@@ -2022,7 +2022,7 @@ static void pf_ul(module_id_t module_id,
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1; 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_pusch->tda_info = get_ul_tda_info(current_BWP,
sched_ctrl->coreset->controlResourceSetId, sched_ctrl->coreset->controlResourceSetId,
sched_ctrl->search_space->searchSpaceType->present, sched_ctrl->search_space->searchSpaceType->present,
...@@ -2034,14 +2034,19 @@ static void pf_ul(module_id_t module_id, ...@@ -2034,14 +2034,19 @@ static void pf_ul(module_id_t module_id,
&sched_pusch->tda_info, &sched_pusch->tda_info,
sched_pusch->nrOfLayers); 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; int rbStart = 0;
const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols);
const uint16_t bwpSize = current_BWP->BWPSize; const uint32_t bwpSize = current_BWP->BWPSize;
while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) const uint32_t bwpStart = current_BWP->BWPStart;
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
rbStart++; rbStart++;
sched_pusch->rbStart = rbStart; sched_pusch->rbStart = rbStart;
uint16_t max_rbSize = 1; 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++; max_rbSize++;
if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) { if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) {
...@@ -2055,13 +2060,18 @@ static void pf_ul(module_id_t module_id, ...@@ -2055,13 +2060,18 @@ static void pf_ul(module_id_t module_id,
iterator++; iterator++;
continue; continue;
} else } 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 */ /* Calculate the current scheduling bytes */
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0); const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
/* adjust rbSize and MCS according to PHR and BPRE */ /* adjust rbSize and MCS according to PHR and BPRE */
if(sched_ctrl->pcmax!=0 || if(sched_ctrl->pcmax != 0 || sched_ctrl->ph != 0) // verify if the PHR related parameter have been initialized
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); 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) if (sched_pusch->mcs < sched_ctrl->ul_bler_stats.mcs)
...@@ -2097,23 +2107,28 @@ static void pf_ul(module_id_t module_id, ...@@ -2097,23 +2107,28 @@ static void pf_ul(module_id_t module_id,
sched_pusch->rbSize = rbSize; sched_pusch->rbSize = rbSize;
sched_pusch->tb_size = TBS; 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", sched_pusch->frame = sched_frame;
rbSize, max_rbSize,sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B, sched_pusch->slot = sched_slot;
sched_ctrl->cce_index,sched_pusch->dmrs_info.num_dmrs_symb,sched_pusch->dmrs_info.N_PRB_DMRS); 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 */ /* Mark the corresponding RBs as used */
sched_ctrl->cce_index = CCEIndex; sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nrmac, fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, 0); // TODO use beam index
CC_id,
&sched_ctrl->sched_pdcch,
CCEIndex,
sched_ctrl->aggregation_level,
0); // TODO use beam index);
n_rb_sched -= sched_pusch->rbSize; 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; 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 */ /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
remainUEs--; remainUEs--;
...@@ -2124,92 +2139,25 @@ static void pf_ul(module_id_t module_id, ...@@ -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) 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]; gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
// no UEs
if (nr_mac->UE_info.list[0] == NULL)
return false;
NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; 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; 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; NR_ServingCellConfigCommonSIB_t *scc_sib1 = sib1 ? sib1->servingCellConfigCommon : NULL;
AssertFatal(scc || scc_sib1, "We need one serving cell config common\n"); AssertFatal(scc || scc_sib1, "We need one serving cell config common\n");
const int slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
// no UEs // TODO we assume the same K2 for all UEs
if (nr_mac->UE_info.list[0] == NULL) const int K2 = nr_mac->radio_config.minRXTXTIME + get_NTN_Koffset(scc);
return false; const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % slots_frame;
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));
if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
return false; 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 bw = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
int average_agg_level = 4; // TODO find a better estimation int average_agg_level = 4; // TODO find a better estimation
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); 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_ ...@@ -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); max_sched_ues = min(max_sched_ues, MAX_DCI_CORESET);
/* proportional fair scheduling algorithm */ /* proportional fair scheduling algorithm */
pf_ul(module_id, pf_ul(module_id, frame, slot, sched_frame, sched_slot, nr_mac->UE_info.list, max_sched_ues, bw);
frame,
slot,
nr_mac->UE_info.list,
max_sched_ues,
len,
rballoc_mask);
return true; return true;
} }
......
...@@ -226,8 +226,6 @@ RUs = ( ...@@ -226,8 +226,6 @@ RUs = (
max_pdschReferenceSignalPower = -27; max_pdschReferenceSignalPower = -27;
max_rxgain = 114; max_rxgain = 114;
eNB_instances = [0]; eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
clock_src = "internal"; clock_src = "internal";
} }
); );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment