making DLSCH preprocessor agnostic to UEs BWP and TDA
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");
|
||||
@@ -390,10 +390,12 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid)
|
||||
UE->mac_stats.dl.errors++;
|
||||
}
|
||||
|
||||
static void get_start_stop_allocation(gNB_MAC_INST *mac,
|
||||
NR_UE_info_t *UE,
|
||||
int *rbStart,
|
||||
int *rbStop)
|
||||
typedef struct {
|
||||
int bwpStart;
|
||||
int bwpSize;
|
||||
} dl_bwp_info_t;
|
||||
|
||||
static dl_bwp_info_t get_bwp_start_size(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
||||
{
|
||||
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
@@ -402,25 +404,28 @@ static void get_start_stop_allocation(gNB_MAC_INST *mac,
|
||||
// in which case the size of CORESET 0 shall be used if CORESET 0 is configured for the cell
|
||||
// and the size of initial DL bandwidth part shall be used if CORESET 0 is not configured for the cell.
|
||||
// TS 38.214 Section 5.1.2.2.2
|
||||
*rbStop = dl_bwp->BWPSize - 1;
|
||||
*rbStart = 0; // start wrt BWPstart
|
||||
dl_bwp_info_t bwp_info;
|
||||
bwp_info.bwpSize = dl_bwp->BWPSize;
|
||||
bwp_info.bwpStart = dl_bwp->BWPStart;
|
||||
if (sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common &&
|
||||
dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) {
|
||||
if (mac->cset0_bwp_size != 0) {
|
||||
*rbStart = mac->cset0_bwp_start;
|
||||
*rbStop = *rbStart + mac->cset0_bwp_size - 1;
|
||||
bwp_info.bwpStart = mac->cset0_bwp_start;
|
||||
bwp_info.bwpSize = mac->cset0_bwp_size;
|
||||
}
|
||||
else {
|
||||
*rbStart = UE->sc_info.initial_dl_BWPStart;
|
||||
*rbStop = *rbStart + UE->sc_info.initial_dl_BWPSize - 1;
|
||||
// TODO this is not entirely correct
|
||||
// start would be the start of CORESET not of the initial BWP
|
||||
bwp_info.bwpStart = UE->sc_info.initial_dl_BWPStart;
|
||||
bwp_info.bwpSize = UE->sc_info.initial_dl_BWPSize;
|
||||
}
|
||||
}
|
||||
return bwp_info;
|
||||
}
|
||||
|
||||
static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
uint16_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
NR_UE_info_t *UE,
|
||||
int current_harq_pid)
|
||||
@@ -442,12 +447,6 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index;
|
||||
|
||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
||||
|
||||
int rbStop = 0;
|
||||
int rbStart = 0;
|
||||
get_start_stop_allocation(nr_mac, UE, &rbStart, &rbStop);
|
||||
|
||||
int rbSize = 0;
|
||||
const int tda = get_dl_tda(nr_mac, scc, slot);
|
||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
@@ -470,6 +469,14 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
reuse_old_tda ? "reuse" : "do not reuse",
|
||||
layers == retInfo->nrOfLayers ? "same" : "different");
|
||||
|
||||
// TODO assuming beam 0 for now
|
||||
uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[0];
|
||||
|
||||
dl_bwp_info_t bwp_info = get_bwp_start_size(nr_mac, UE);
|
||||
int rbStart = bwp_info.bwpStart;
|
||||
int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1;
|
||||
int rbSize = 0;
|
||||
|
||||
if (reuse_old_tda && layers == retInfo->nrOfLayers) {
|
||||
/* Check that there are enough resources for retransmission */
|
||||
while (rbSize < retInfo->rbSize) {
|
||||
@@ -481,23 +488,17 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
rbStart++;
|
||||
|
||||
if (rbStart >= rbStop) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n",
|
||||
UE->rnti,
|
||||
frame,
|
||||
slot);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize)
|
||||
while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize)
|
||||
rbSize++;
|
||||
}
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc,
|
||||
dl_bwp,
|
||||
&temp_tda,
|
||||
layers);
|
||||
NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers);
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols);
|
||||
while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap))
|
||||
@@ -546,7 +547,9 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
|
||||
/* Find a free CCE */
|
||||
int CCEIndex = get_cce_index(nr_mac,
|
||||
CC_id, slot, UE->rnti,
|
||||
CC_id,
|
||||
slot,
|
||||
UE->rnti,
|
||||
&sched_ctrl->aggregation_level,
|
||||
beam,
|
||||
sched_ctrl->search_space,
|
||||
@@ -554,10 +557,7 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
false);
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n",
|
||||
UE->rnti,
|
||||
frame,
|
||||
slot);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -569,30 +569,27 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex);
|
||||
alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, beam, r_pucch, 0);
|
||||
if (alloc < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n",
|
||||
UE->rnti,
|
||||
frame,
|
||||
slot);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
/* CC_id = */ 0,
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level,
|
||||
beam);
|
||||
/* just reuse from previous scheduling opportunity, set new start RB */
|
||||
sched_ctrl->sched_pdsch = *retInfo;
|
||||
sched_ctrl->sched_pdsch.rbStart = rbStart;
|
||||
sched_ctrl->sched_pdsch.rbStart = rbStart - bwp_info.bwpStart;
|
||||
sched_ctrl->sched_pdsch.pucch_allocation = alloc;
|
||||
/* retransmissions: directly allocate */
|
||||
*n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
|
||||
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
|
||||
for (int rb = rbStart; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
|
||||
rballoc_mask[rb] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -612,8 +609,7 @@ static void pf_dl(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
NR_UE_info_t **UE_list,
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint16_t *rballoc_mask)
|
||||
int n_rb_sched)
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
||||
@@ -649,7 +645,7 @@ static void pf_dl(module_id_t module_id,
|
||||
/* retransmission */
|
||||
if (sched_pdsch->dl_harq_pid >= 0) {
|
||||
/* Allocate retransmission */
|
||||
bool r = allocate_dl_retransmission(module_id, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pdsch->dl_harq_pid);
|
||||
bool r = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched, UE, sched_pdsch->dl_harq_pid);
|
||||
|
||||
if (!r) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n",
|
||||
@@ -744,7 +740,9 @@ static void pf_dl(module_id_t module_id,
|
||||
int beam = 0;
|
||||
|
||||
int CCEIndex = get_cce_index(mac,
|
||||
CC_id, slot, iterator->UE->rnti,
|
||||
CC_id,
|
||||
slot,
|
||||
iterator->UE->rnti,
|
||||
&sched_ctrl->aggregation_level,
|
||||
beam,
|
||||
sched_ctrl->search_space,
|
||||
@@ -778,12 +776,7 @@ static void pf_dl(module_id_t module_id,
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(mac,
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level,
|
||||
beam);
|
||||
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam);
|
||||
|
||||
/* MCS has been set above */
|
||||
sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot);
|
||||
@@ -804,22 +797,22 @@ static void pf_dl(module_id_t module_id,
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
|
||||
|
||||
int rbStop = 0;
|
||||
int rbStart = 0;
|
||||
get_start_stop_allocation(mac, iterator->UE, &rbStart, &rbStop);
|
||||
// TODO assuming beam 0 for now
|
||||
uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[0];
|
||||
dl_bwp_info_t bwp_info = get_bwp_start_size(mac, iterator->UE);
|
||||
int rbStart = 0; // WRT BWP start
|
||||
int rbStop = bwp_info.bwpSize - 1;
|
||||
int bwp_start = bwp_info.bwpStart;
|
||||
// Freq-demain allocation
|
||||
while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap))
|
||||
while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap))
|
||||
rbStart++;
|
||||
|
||||
uint16_t max_rbSize = 1;
|
||||
|
||||
while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize] & slbitmap))
|
||||
while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize + bwp_start] & slbitmap))
|
||||
max_rbSize++;
|
||||
|
||||
sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc,
|
||||
dl_bwp,
|
||||
tda_info,
|
||||
sched_pdsch->nrOfLayers);
|
||||
sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, tda_info, sched_pdsch->nrOfLayers);
|
||||
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
|
||||
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
@@ -848,7 +841,7 @@ static void pf_dl(module_id_t module_id,
|
||||
/* transmissions: directly allocate */
|
||||
n_rb_sched -= sched_pdsch->rbSize;
|
||||
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
for (int rb = bwp_start; rb < sched_pdsch->rbSize; rb++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] |= slbitmap;
|
||||
|
||||
remainUEs--;
|
||||
@@ -864,41 +857,11 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
|
||||
return;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
const int CC_id = 0;
|
||||
/* Get bwpSize and TDAfrom the first UE */
|
||||
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
||||
NR_UE_info_t *UE=UE_info->list[0];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP;
|
||||
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
get_dl_tdalist(current_BWP, coresetid, sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_);
|
||||
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
const uint16_t bwpSize = current_BWP->BWPSize;
|
||||
const uint16_t BWPStart = current_BWP->BWPStart;
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
// TODO improve handling of beam in vrb_map (for now just using 0)
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map[0];
|
||||
uint16_t rballoc_mask[bwpSize];
|
||||
int n_rb_sched = 0;
|
||||
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
rballoc_mask[i] = vrb_map[i + BWPStart];
|
||||
// if all the pdsch symbols are free
|
||||
if (!(rballoc_mask[i] & slbitmap))
|
||||
n_rb_sched++;
|
||||
}
|
||||
int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
nr_store_dlsch_buffer(module_id, frame, slot);
|
||||
|
||||
int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
int average_agg_level = 4; // TODO find a better estimation
|
||||
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE);
|
||||
|
||||
@@ -911,8 +874,7 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
|
||||
slot,
|
||||
UE_info->list,
|
||||
max_sched_ues,
|
||||
n_rb_sched,
|
||||
rballoc_mask);
|
||||
bw); // we set the whole BW as max number
|
||||
}
|
||||
|
||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) {
|
||||
@@ -1087,8 +1049,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
const int pduindex = gNB_mac->pdu_index[CC_id]++;
|
||||
pdsch_pdu->pduIndex = pduindex;
|
||||
|
||||
pdsch_pdu->BWPSize = current_BWP->BWPSize;
|
||||
pdsch_pdu->BWPStart = current_BWP->BWPStart;
|
||||
dl_bwp_info_t bwp_info = get_bwp_start_size(gNB_mac, UE);
|
||||
pdsch_pdu->BWPSize = bwp_info.bwpSize;
|
||||
pdsch_pdu->BWPStart = bwp_info.bwpStart;
|
||||
|
||||
pdsch_pdu->SubcarrierSpacing = current_BWP->scs;
|
||||
pdsch_pdu->CyclicPrefix = current_BWP->cyclicprefix ? *current_BWP->cyclicprefix : 0;
|
||||
@@ -1202,17 +1165,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
AssertFatal(pdsch_Config == NULL || pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
|
||||
"Only frequency resource allocation type 1 is currently supported\n");
|
||||
|
||||
|
||||
// For a PDSCH scheduled with a DCI format 1_0 in any type of PDCCH common search space, regardless of which
|
||||
// bandwidth part is the active bandwidth part, RB numbering starts from the lowest RB of the CORESET in which the
|
||||
// DCI was received; otherwise RB numbering starts from the lowest RB in the determined downlink bandwidth part.
|
||||
// TS 38.214 Section 5.1.2.2.2
|
||||
int rbStop = 0;
|
||||
int rbStart = 0;
|
||||
get_start_stop_allocation(gNB_mac, UE, &rbStart, &rbStop);
|
||||
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize,
|
||||
pdsch_pdu->rbStart - rbStart,
|
||||
rbStop - rbStart + 1);
|
||||
pdsch_pdu->rbStart,
|
||||
pdsch_pdu->BWPSize);
|
||||
dci_payload.format_indicator = 1;
|
||||
dci_payload.time_domain_assignment.val = sched_pdsch->time_domain_allocation;
|
||||
dci_payload.mcs = sched_pdsch->mcs;
|
||||
|
||||
Reference in New Issue
Block a user