making DLSCH preprocessor agnostic to UEs BWP and TDA

This commit is contained in:
francescomani
2024-10-24 15:04:27 +02:00
parent 3add576195
commit 38a05d8aad
2 changed files with 63 additions and 108 deletions
+2 -2
View File
@@ -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);
+61 -106
View File
@@ -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;