Merge remote-tracking branch 'origin/Fix_xlsch_bwp_start_size' into integration_2025_w20 (!3423)

Fix PDSCH and PUSCH BWP Start and Size when PXSCH is scheduled with a DCI format x_0 in any type of PDCCH common search space

- Fix PDSCH and PUSCH BWP Start and Size when PDSCH/PUSCH is scheduled
  with a DCI format x_0 in any type of PDCCH common search space
- Fix resource block assignment information (RIV field) for DCI format
  x_0 when scheduling in any type of PDCCH common search space
This commit is contained in:
Robert Schmidt
2025-05-19 12:19:10 +02:00
7 changed files with 111 additions and 47 deletions
@@ -66,6 +66,11 @@ typedef struct {
uint64_t s_map; uint64_t s_map;
} nr_prach_info_t; } nr_prach_info_t;
typedef struct {
uint16_t bwpStart;
uint16_t bwpSize;
} bwp_info_t;
uint32_t get_Y(const NR_SearchSpace_t *ss, int slot, rnti_t rnti); uint32_t get_Y(const NR_SearchSpace_t *ss, int slot, rnti_t rnti);
uint8_t get_BG(uint32_t A, uint16_t R); uint8_t get_BG(uint32_t A, uint16_t R);
@@ -935,7 +935,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
ra->Msg3_tda_id, ra->Msg3_tda_id,
ra->msg3_TPC, ra->msg3_TPC,
1, // Not toggling NDI in msg3 retransmissions 1, // Not toggling NDI in msg3 retransmissions
ul_bwp); ul_bwp,
ss->searchSpaceType->present);
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR // Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
ra->msg3_TPC = 1; ra->msg3_TPC = 1;
@@ -381,35 +381,39 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid)
UE->mac_stats.dl.errors++; UE->mac_stats.dl.errors++;
} }
typedef struct { static bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
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_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;
// UE is scheduled in a set of contiguously allocated resource blocks within the active bandwidth part of size N_BWP PRBs bwp_info_t bwp_info;
// except for the case when DCI format 1_0 is decoded in any common search space
// in which case the size of CORESET 0 shall be used if CORESET 0 is configured for the cell // 3GPP TS 38.214 Section 5.1.2.2 Resource allocation in frequency domain
// and the size of initial DL bandwidth part shall be used if CORESET 0 is not configured for the cell. // 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
// TS 38.214 Section 5.1.2.2.2 // active bandwidth part, RB numbering starts from the lowest RB of the CORESET in which the DCI was received; otherwise RB
dl_bwp_info_t bwp_info; // numbering starts from the lowest RB in the determined downlink bandwidth part.
bwp_info.bwpSize = dl_bwp->BWPSize; //
bwp_info.bwpStart = dl_bwp->BWPStart; // 3GPP TS 38.214 Section 5.1.2.2.2 Downlink resource allocation type 1
if (sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common && // In downlink resource allocation of type 1, the resource block assignment information indicates to a scheduled UE a set of
dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) { // contiguously allocated non-interleaved or interleaved virtual resource blocks within the active bandwidth part of size PRBs
if (mac->cset0_bwp_size != 0) { // except for the case when DCI format 1_0 is decoded in any common search space in which case the size of CORESET 0 shall be
bwp_info.bwpStart = mac->cset0_bwp_start; // 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
bwp_info.bwpSize = mac->cset0_bwp_size; // configured for the cell.
if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 && sched_ctrl->search_space->searchSpaceType
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common
&& dl_bwp->pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) {
if (sched_ctrl->coreset->controlResourceSetId == 0) {
bwp_info.bwpStart = nr_mac->cset0_bwp_start;
} else {
bwp_info.bwpStart = dl_bwp->BWPStart + sched_ctrl->sched_pdcch.rb_start;
} }
else { if (nr_mac->cset0_bwp_size > 0) {
// TODO this is not entirely correct bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, nr_mac->cset0_bwp_size);
// start would be the start of CORESET not of the initial BWP } else {
bwp_info.bwpStart = UE->sc_info.initial_dl_BWPStart; bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, UE->sc_info.initial_dl_BWPSize);
bwp_info.bwpSize = UE->sc_info.initial_dl_BWPSize;
} }
} else {
bwp_info.bwpSize = dl_bwp->BWPSize;
bwp_info.bwpStart = dl_bwp->BWPStart;
} }
return bwp_info; return bwp_info;
} }
@@ -463,7 +467,7 @@ static bool allocate_dl_retransmission(module_id_t module_id,
uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam_idx]; uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam_idx];
dl_bwp_info_t bwp_info = get_bwp_start_size(nr_mac, UE); bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
int rbStart = bwp_info.bwpStart; int rbStart = bwp_info.bwpStart;
int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1; int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1;
int rbSize = 0; int rbSize = 0;
@@ -758,7 +762,7 @@ static void pf_dl(module_id_t module_id,
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);
uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[beam.idx]; uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[beam.idx];
dl_bwp_info_t bwp_info = get_bwp_start_size(mac, iterator->UE); bwp_info_t bwp_info = get_pdsch_bwp_start_size(mac, iterator->UE);
int rbStart = 0; // WRT BWP start int rbStart = 0; // WRT BWP start
int rbStop = bwp_info.bwpSize - 1; int rbStop = bwp_info.bwpSize - 1;
int bwp_start = bwp_info.bwpStart; int bwp_start = bwp_info.bwpStart;
@@ -1060,7 +1064,7 @@ 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;
dl_bwp_info_t bwp_info = get_bwp_start_size(gNB_mac, UE); bwp_info_t bwp_info = get_pdsch_bwp_start_size(gNB_mac, UE);
pdsch_pdu->BWPSize = bwp_info.bwpSize; pdsch_pdu->BWPSize = bwp_info.bwpSize;
pdsch_pdu->BWPStart = bwp_info.bwpStart; pdsch_pdu->BWPStart = bwp_info.bwpStart;
@@ -1176,9 +1180,20 @@ 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");
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize, // 3GPP TS 38.214 Section 5.1.2.2.2 Downlink resource allocation type 1
pdsch_pdu->rbStart, uint16_t riv_bwp_size = pdsch_pdu->BWPSize;
pdsch_pdu->BWPSize); if (current_BWP->dci_format == NR_DL_DCI_FORMAT_1_0
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common
&& pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) {
if (gNB_mac->cset0_bwp_size > 0) {
riv_bwp_size = gNB_mac->cset0_bwp_size;
} else {
riv_bwp_size = UE->sc_info.initial_dl_BWPSize;
}
}
dci_payload.frequency_domain_assignment.val =
PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize, pdsch_pdu->rbStart, riv_bwp_size);
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;
@@ -497,13 +497,21 @@ NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac,
pdcch.ShiftIndex = 0; pdcch.ShiftIndex = 0;
} }
int N_rb = 0; // nb of rbs of coreset per symbol uint16_t N_rb = 0; // nb of rbs of coreset per symbol
for (int i=0;i<6;i++) { uint16_t rb_start = 0;
for (int t=0;t<8;t++) { for (int i = 0; i < 6; i++) {
N_rb+=((coreset->frequencyDomainResources.buf[i]>>t)&1); for (int t = 0; t < 8; t++) {
if (coreset->frequencyDomainResources.buf[i] >> (7 - t) & 1) {
if (N_rb == 0) {
rb_start = 48 * i + t * 6;
}
N_rb++;
}
} }
} }
pdcch.n_rb = N_rb*=6; // each bit of frequencyDomainResources represents 6 PRBs
pdcch.rb_start = rb_start;
pdcch.n_rb = N_rb *= 6; // each bit of frequencyDomainResources represents 6 PRBs
return pdcch; return pdcch;
} }
@@ -782,13 +790,20 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info,
int time_domain_assignment, int time_domain_assignment,
uint8_t tpc, uint8_t tpc,
uint8_t ndi, uint8_t ndi,
NR_UE_UL_BWP_t *ul_bwp) NR_UE_UL_BWP_t *ul_bwp,
NR_SearchSpace__searchSpaceType_PR ss_type)
{ {
int bwp_id = ul_bwp->bwp_id; int bwp_id = ul_bwp->bwp_id;
nr_dci_format_t dci_format = ul_bwp->dci_format; nr_dci_format_t dci_format = ul_bwp->dci_format;
// 3GPP TS 38.214 Section 6.1.2.2.2 Uplink resource allocation type 1
uint16_t riv_bwp_size = ul_bwp->BWPSize;
if (dci_format == NR_UL_DCI_FORMAT_0_0 && ss_type == NR_SearchSpace__searchSpaceType_PR_common && ul_bwp->pusch_Config
&& ul_bwp->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
riv_bwp_size = sc_info->initial_ul_BWPSize;
}
dci_pdu_rel15->frequency_domain_assignment.val = dci_pdu_rel15->frequency_domain_assignment.val =
PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, ul_bwp->BWPSize); PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, riv_bwp_size);
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
dci_pdu_rel15->mcs = pusch_pdu->mcs_index; dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
@@ -65,6 +65,28 @@ int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot)
return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots) return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots)
} }
static bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE)
{
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
bwp_info_t bwp_info;
bwp_info.bwpStart = ul_bwp->BWPStart;
// 3GPP TS 38.214 Section 6.1.2.2.2 Uplink resource allocation type 1
// In uplink resource allocation of type 1, the resource block assignment information indicates to a scheduled UE a set of
// contiguously allocated non-interleaved virtual resource blocks within the active bandwidth part of size PRBs except for the
// case when DCI format 0_0 is decoded in any common search space in which case the size of the initial UL bandwidth part shall
// be used.
if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 && sched_ctrl->search_space->searchSpaceType
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common
&& ul_bwp->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
bwp_info.bwpSize = min(ul_bwp->BWPSize, UE->sc_info.initial_ul_BWPSize);
} else {
bwp_info.bwpSize = ul_bwp->BWPSize;
}
return bwp_info;
}
static int compute_ph_factor(int mu, int tbs_bits, int rb, int n_layers, int n_symbols, int n_dmrs, long *deltaMCS, bool include_bw) static int compute_ph_factor(int mu, int tbs_bits, int rb, int n_layers, int n_symbols, int n_dmrs, long *deltaMCS, bool include_bw)
{ {
// 38.213 7.1.1 // 38.213 7.1.1
@@ -1673,8 +1695,9 @@ 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 uint32_t bwpSize = ul_bwp->BWPSize; bwp_info_t bwp_info = get_pusch_bwp_start_size(UE);
const uint32_t bwpStart = ul_bwp->BWPStart; const uint32_t bwpSize = bwp_info.bwpSize;
const uint32_t bwpStart = bwp_info.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);
@@ -1963,8 +1986,9 @@ static void pf_ul(module_id_t module_id,
min_rb, min_rb,
rbStart, rbStart,
sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data); sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data);
const uint32_t bwpSize = current_BWP->BWPSize; bwp_info_t bwp_info = get_pusch_bwp_start_size(UE);
const uint32_t bwpStart = current_BWP->BWPStart; const uint32_t bwpStart = bwp_info.bwpStart;
const uint32_t bwpSize = bwp_info.bwpSize;
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 + bwpStart] & slbitmap)) while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
rbStart++; rbStart++;
@@ -2112,8 +2136,9 @@ static void pf_ul(module_id_t module_id,
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 uint32_t bwpSize = current_BWP->BWPSize; bwp_info_t bwp_info = get_pusch_bwp_start_size(iterator->UE);
const uint32_t bwpStart = current_BWP->BWPStart; const uint32_t bwpStart = bwp_info.bwpStart;
const uint32_t bwpSize = bwp_info.bwpSize;
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
rbStart++; rbStart++;
sched_pusch->rbStart = rbStart; sched_pusch->rbStart = rbStart;
@@ -2662,7 +2687,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, slot_t slot, nfapi_
sched_pusch->time_domain_allocation, sched_pusch->time_domain_allocation,
UE->UE_sched_ctrl.tpc0, UE->UE_sched_ctrl.tpc0,
cur_harq->ndi, cur_harq->ndi,
current_BWP); current_BWP,
ss->searchSpaceType->present);
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR // Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
UE->UE_sched_ctrl.tpc0 = 1; UE->UE_sched_ctrl.tpc0 = 1;
+2 -1
View File
@@ -166,7 +166,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info,
int time_domain_assignment, int time_domain_assignment,
uint8_t tpc, uint8_t tpc,
uint8_t ndi, uint8_t ndi,
NR_UE_UL_BWP_t *ul_bwp); NR_UE_UL_BWP_t *ul_bwp,
NR_SearchSpace__searchSpaceType_PR ss_type);
void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP); void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP);
+2 -1
View File
@@ -198,7 +198,8 @@ typedef struct NR_sched_pdcch {
uint8_t InterleaverSize; uint8_t InterleaverSize;
uint16_t ShiftIndex; uint16_t ShiftIndex;
uint8_t DurationSymbols; uint8_t DurationSymbols;
int n_rb; uint16_t n_rb;
uint16_t rb_start;
} NR_sched_pdcch_t; } NR_sched_pdcch_t;
/*! \brief gNB template for the Random access information */ /*! \brief gNB template for the Random access information */