Compare commits

...

3 Commits

Author SHA1 Message Date
francescomani
26fe404fde implementation of symbol level beam handling at L2 2026-04-10 19:00:19 +02:00
francescomani
2fb03fd59a remove unnecessary get_allocated_beam function 2026-04-10 18:38:35 +02:00
francescomani
f1180d09d4 remove slot level limitation when checking beam occupation at L1 2026-04-10 18:38:35 +02:00
15 changed files with 589 additions and 345 deletions

View File

@@ -63,8 +63,9 @@ int beam_index_allocation(bool das,
int idx = -1;
for (int j = 0; j < common_vars->num_beams_period; j++) {
// L2 analog beam implementation is slot based, so we need to verify occupancy for the whole slot
for (int i = 0; i < symbols_per_slot; i++) {
if (!((bitmap_symbols >> i) & 0x01))
continue;
int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i];
if (current_beam == -1 || current_beam == ru_beam_idx)
idx = j;

View File

@@ -114,14 +114,12 @@
{MACRLC_TRANSPORT_S_SHM_PREFIX, NULL, 0, .strptr=NULL, .defstrval="nvipc", TYPE_STRING, 0}, \
{MACRLC_TRANSPORT_S_POLL_CORE, NULL, 0, .i8ptr=NULL, .defintval=-1, TYPE_INT8, 0}, \
{MACRLC_ANALOG_BEAMFORMING, HLP_MACRLC_AB, 0, .strptr=NULL, .defstrval="none", TYPE_STRING, 0}, \
{MACRLC_BEAM_DURATION, HLP_MACRLC_BEAM_DURATION, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
{MACRLC_BEAM_DURATION, HLP_MACRLC_BEAM_DURATION, 0, .i8ptr=NULL, .defintval=1, TYPE_INT8, 0}, \
{MACRLC_BEAMS_PERIOD, HLP_MACRLC_BEAMS_PERIOD, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
{MACRLC_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY,0}, \
{MACRLC_DBT_FILE, HLP_MACRLC_DBT_FILE, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
{MACRLC_PUSCH_RSSI_THRESHOLD, HLP_MACRLC_PUSCH_RSSI_THRESHOLD, \
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, \
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{MACRLC_PUSCH_RSSI_THRESHOLD, HLP_MACRLC_PUSCH_RSSI_THRESHOLD, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{MACRLC_STATS_MAX_UE, HLP_MACRLC_STATS_MAX_UE, 0, .iptr=NULL, .defintval=8, TYPE_INT, 0}, \
}
// clang-format off

View File

@@ -1748,9 +1748,13 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
NR_beam_info_t *beam_info = &RC.nrmac[j]->beam_info;
int beams_per_period = *gpd(params, np, MACRLC_BEAMS_PERIOD)->u8ptr;
beam_info->beam_allocation = malloc16(beams_per_period * sizeof(beam_info->beam_allocation));
beam_info->beam_duration = *gpd(params, np, MACRLC_BEAM_DURATION)->u8ptr;
int duration = *gpd(params, np, MACRLC_BEAM_DURATION)->i8ptr;
AssertFatal(duration > -15 && duration != 0, "Invalid beam duration %d\n", duration);
beam_info->beam_slot_duration = duration > 0 ? duration : 1;
beam_info->beam_symbol_duration = duration < 0 ? -duration : 0;
beam_info->beams_per_period = beams_per_period;
beam_info->beam_allocation_size = -1; // to be initialized once we have information on frame configuration
beam_info->beam_allocation_size[0] = -1; // to be initialized once we have information on frame configuration
beam_info->beam_allocation_size[1] = -1;
}
bool das_enabled = false;
if (NFAPI_MODE == NFAPI_MONOLITHIC) {

View File

@@ -832,15 +832,24 @@ static void initialize_beam_information(NR_beam_info_t *beam_info, int mu, int s
int size = mu == 0 ? slots_per_frame << 1 : slots_per_frame;
// slots in beam duration gives the number of consecutive slots tied the the same beam
AssertFatal(size % beam_info->beam_duration == 0,
AssertFatal(size % beam_info->beam_slot_duration == 0,
"Beam duration %d should be divider of number of slots per frame %d\n",
beam_info->beam_duration,
beam_info->beam_slot_duration,
slots_per_frame);
beam_info->beam_allocation_size = size / beam_info->beam_duration;
beam_info->beam_allocation_size[0] = size / beam_info->beam_slot_duration;
int symb_dur = beam_info->beam_symbol_duration ? beam_info->beam_symbol_duration : NR_SYMBOLS_PER_SLOT;
AssertFatal(NR_SYMBOLS_PER_SLOT % symb_dur == 0,
"Beam duration in symbols %d should be a divider of number of symbols per slot %d\n",
symb_dur,
NR_SYMBOLS_PER_SLOT);
beam_info->beam_allocation_size[1] = NR_SYMBOLS_PER_SLOT / symb_dur;
for (int i = 0; i < beam_info->beams_per_period; i++) {
beam_info->beam_allocation[i] = malloc16(beam_info->beam_allocation_size * sizeof(*beam_info->beam_allocation));
for (int j = 0; j < beam_info->beam_allocation_size; j++)
beam_info->beam_allocation[i][j] = -1;
beam_info->beam_allocation[i] = malloc16(beam_info->beam_allocation_size[0] * sizeof(**beam_info->beam_allocation));
for (int j = 0; j < beam_info->beam_allocation_size[0]; j++) {
beam_info->beam_allocation[i][j] = malloc16(beam_info->beam_allocation_size[1] * sizeof(*beam_info->beam_allocation));
for (int k = 0; k < beam_info->beam_allocation_size[1]; k++)
beam_info->beam_allocation[i][j][k] = -1;
}
}
}

View File

@@ -66,14 +66,17 @@ static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slo
if (beam_info->beam_mode == NO_BEAM_MODE)
return;
// initialization done only once
AssertFatal(beam_info->beam_allocation_size >= 0, "Beam information not initialized\n");
int idx_to_clear = (frame * slots_per_frame + slot) / beam_info->beam_duration;
idx_to_clear = (idx_to_clear + beam_info->beam_allocation_size - 1) % beam_info->beam_allocation_size;
if (slot % beam_info->beam_duration == 0) {
AssertFatal(beam_info->beam_allocation_size[0] >= 0
&& beam_info->beam_allocation_size[1] >= 0,
"Beam information not initialized\n");
int idx_to_clear = (frame * slots_per_frame + slot) / beam_info->beam_slot_duration;
idx_to_clear = (idx_to_clear + beam_info->beam_allocation_size[0] - 1) % beam_info->beam_allocation_size[0];
if (slot % beam_info->beam_slot_duration == 0) {
// resetting previous period allocation
LOG_D(NR_MAC, "%d.%d Clear beam information for index %d\n", frame, slot, idx_to_clear);
for (int i = 0; i < beam_info->beams_per_period; i++)
beam_info->beam_allocation[i][idx_to_clear] = -1;
for (int k = 0; k < beam_info->beam_allocation_size[1]; k++)
beam_info->beam_allocation[i][idx_to_clear][k] = -1;
}
}

View File

@@ -371,9 +371,16 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
UL_tti_req->rach_present = 1;
NR_beam_alloc_t beam = {0};
uint32_t N_t_slot = cc->prach_info.N_t_slot;
uint32_t start_symb = cc->prach_info.start_symbol;
int total_prach_slots = 1;
uint32_t N_dur = cc->prach_info.N_dur;
if (format0 < 4) {
N_dur = 14; // number of PRACH symbols in PRACH slot
total_prach_slots = get_long_prach_dur(format0, mu_pusch);
AssertFatal(slotP + total_prach_slots - 1 < slots_frame, "PRACH cannot extend across frames\n");
}
NR_beam_alloc_t beam[total_prach_slots];
for (int fdm_index = 0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
AssertFatal(UL_tti_req->n_pdus < sizeofArray(UL_tti_req->pdus_list), "Invalid UL_tti_req->n_pdus %d\n", UL_tti_req->n_pdus);
nfapi_nr_ul_tti_request_number_of_pdus_t *newpdu = UL_tti_req->pdus_list + UL_tti_req->n_pdus;
@@ -395,22 +402,29 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
num_td_occ++;
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
int beam_index = 0;
int td_start = td_index * N_dur + start_symb;
if(num_ssb_per_RO <= 1) {
// ordered ssb number
int n_ssb = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % cc->num_active_ssb;
// fapi beam index
beam_index = get_beam_from_ssbidx(gNB, cc->ssb_index[n_ssb]);
// multi-beam allocation structure
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1);
// mark beam as occupied for current and future slots if prach extends beyond current slot
for (int i = 0; i < total_prach_slots; i++) {
beam[i] = beam_allocation_procedure(&gNB->beam_info, frameP, slotP + i, td_start, N_dur, beam_index, slots_frame);
AssertFatal(beam[i].idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1);
}
} else {
int first_ssb_index = (prach_occasion_id * (int)num_ssb_per_RO) % cc->num_active_ssb;
for(int j = first_ssb_index; j < first_ssb_index + num_ssb_per_RO; j++) {
// fapi beam index
beam_index = get_beam_from_ssbidx(gNB, cc->ssb_index[j]);
// multi-beam allocation structure
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j);
// mark beam as occupied for current and future slots if prach extends beyond current slot
for (int i = 0; i < total_prach_slots; i++) {
beam[i] = beam_allocation_procedure(&gNB->beam_info, frameP, slotP + i, td_start, N_dur, beam_index, slots_frame);
AssertFatal(beam[i].idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j);
}
}
}
if(num_td_occ == 1) {
@@ -515,21 +529,12 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
// block resources in vrb_map_UL
// mark PRBs as occupied for current and future slots if prach extends beyond current slot
int total_prach_slots;
uint32_t N_dur = cc->prach_info.N_dur;
if (format0 < 4) {
N_dur = 14; // number of PRACH symbols in PRACH slot
total_prach_slots = get_long_prach_dur(format0, mu_pusch);
AssertFatal(slotP + total_prach_slots - 1 < slots_frame, "PRACH cannot extend across frames\n");
} else {
total_prach_slots = 1;
}
// reserve PRBs occupied by PRACH in all PRACH slot.
for (int i = 0; i < total_prach_slots; i++) {
fill_vrb(frameP,
slotP + i,
n_ra_rb * fdm,
beam.idx,
beam[i].idx,
gNB->vrb_map_UL_size,
slots_frame,
bwp_start + rach_ConfigGeneric->msg1_FrequencyStart,
@@ -792,16 +797,29 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
const int sched_slot = (slot + K2) % slots_frame;
uint16_t slot_bitmap = get_ul_bitmap(&nr_mac->frame_structure, sched_slot);
uint16_t msg3_mask = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
NR_sched_pdcch_t *pdcch = &UE->UE_sched_ctrl.sched_pdcch;
if (!is_dl_slot(slot, &nr_mac->frame_structure)
|| !is_ul_slot(sched_slot, &nr_mac->frame_structure)
|| !((msg3_mask & slot_bitmap) == msg3_mask))
return;
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame);
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info,
sched_frame,
sched_slot,
tda_info.startSymbolIndex,
tda_info.nrOfSymbols,
UE->UE_beam_index,
slots_frame);
if (beam_ul.idx < 0)
return;
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame);
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info,
frame,
slot,
pdcch->StartSymbolIndex,
pdcch->DurationSymbols,
UE->UE_beam_index,
slots_frame);
if (beam_dci.idx < 0) {
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
return;
@@ -895,19 +913,12 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu_rel15, coreset, &UE->UE_sched_ctrl.sched_pdcch);
nr_configure_pdcch(pdcch_pdu_rel15, coreset, pdcch);
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
}
int aggregation_level;
int CCEIndex = get_cce_index(nr_mac,
CC_id, slot, 0,
&aggregation_level,
beam_dci.idx,
ss,
coreset,
&UE->UE_sched_ctrl.sched_pdcch,
0);
int CCEIndex = get_cce_index(nr_mac, CC_id, slot, 0, &aggregation_level, beam_dci.idx, ss, coreset, pdcch, 0);
if (CCEIndex < 0) {
LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", UE->rnti);
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
@@ -949,12 +960,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
nr_mac->cset0_bwp_size);
// Mark the corresponding RBs as used
fill_pdcch_vrb_map(nr_mac,
CC_id,
&UE->UE_sched_ctrl.sched_pdcch,
CCEIndex,
aggregation_level,
beam_dci.idx);
fill_pdcch_vrb_map(nr_mac, CC_id, pdcch, CCEIndex, aggregation_level, beam_dci.idx);
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= msg3_mask;
@@ -1012,7 +1018,7 @@ static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
continue;
// check if it is possible to allocate MSG3 in a beam in this slot
NR_beam_alloc_t beam = beam_allocation_procedure(beam_info, temp_frame, temp_slot, ue_beam_idx, slots_per_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(beam_info, temp_frame, temp_slot, start, nr, ue_beam_idx, slots_per_frame);
if (beam.idx < 0)
continue;
@@ -1415,37 +1421,15 @@ static void nr_generate_Msg2(module_id_t module_idP,
return;
}
// Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_W(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
return;
}
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_SearchSpace_t *ss = sched_ctrl->search_space;
if (!check_msg2_monitoring(ss, n_slots_frame, frameP, slotP)) {
LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: Msg2 not monitored by UE\n", ra->RA_rnti, UE->rnti);
return;
}
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame);
if (beam.idx < 0)
return;
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
// check the feasibility of Msg3, the actual Msg3 allocation
// is further below. In the case of CFRA, we don't need Msg3, but 38.321
// §5.1.4 does not clearly exclude Msg3, and UL TA might still be useful.
// Before the change in this commit, we used CFRA but required Msg3, which
// COTS UE would often (but not always) send.
bool ret = get_feasible_msg3_tda(scc,
get_delta_for_k2(ul_bwp->scs),
ul_bwp->tdaList_Common,
frameP,
slotP,
ra,
&nr_mac->beam_info,
UE->UE_beam_index,
&nr_mac->frame_structure);
if (!ret || ra->Msg3_tda_id > 15) {
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", UE->rnti, frameP, slotP);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
return;
}
NR_ControlResourceSet_t *coreset = sched_ctrl->coreset;
AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n");
const int coresetid = coreset->controlResourceSetId;
@@ -1465,6 +1449,55 @@ static void nr_generate_Msg2(module_id_t module_idP,
if (!tda_info.valid_tda)
return;
if (!check_msg2_monitoring(ss, n_slots_frame, frameP, slotP)) {
LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: Msg2 not monitored by UE\n", ra->RA_rnti, UE->rnti);
return;
}
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info,
frameP,
slotP,
tda_info.startSymbolIndex,
tda_info.nrOfSymbols,
UE->UE_beam_index,
n_slots_frame);
if (beam.idx < 0)
return;
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nr_mac->beam_info,
frameP,
slotP,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
UE->UE_beam_index,
n_slots_frame);
if (dci_beam.idx < 0) {
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
return;
}
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
// check the feasibility of Msg3, the actual Msg3 allocation
// is further below. In the case of CFRA, we don't need Msg3, but 38.321
// §5.1.4 does not clearly exclude Msg3, and UL TA might still be useful.
// Before the change in this commit, we used CFRA but required Msg3, which
// COTS UE would often (but not always) send.
bool ret = get_feasible_msg3_tda(scc,
get_delta_for_k2(ul_bwp->scs),
ul_bwp->tdaList_Common,
frameP,
slotP,
ra,
&nr_mac->beam_info,
UE->UE_beam_index,
&nr_mac->frame_structure);
if (!ret || ra->Msg3_tda_id > 15) {
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", UE->rnti, frameP, slotP);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
int rbStart = 0;
int rbSize = 0;
uint16_t msg2_nb_rb = max(8, nr_mac->min_grant_prb); // RAR TBS is 9 bytes
@@ -1475,15 +1508,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
LOG_W(NR_MAC, "Cannot find free vrb_map for RA RNTI %04x!\n", ra->RA_rnti);
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
return;
}
// Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_W(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
@@ -1494,6 +1519,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", UE->rnti, frameP, slotP);
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
@@ -1502,6 +1528,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
if (!msg3_ret) {
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
@@ -1627,7 +1654,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
// Mark the corresponding symbols RBs as used
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, aggregation_level, beam.idx);
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, aggregation_level, dci_beam.idx);
for (int rb = 0; rb < rbSize; rb++) {
vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg2_mask;
}
@@ -1682,11 +1709,51 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
}
}
// Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
return;
}
uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP);
int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index);
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index];
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
ss->searchSpaceType->present,
time_domain_assignment,
scc->dmrs_TypeA_Position,
mux_pattern,
TYPE_TC_RNTI_,
coreset->controlResourceSetId,
false);
if (!msg4_tda.valid_tda)
return;
const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame;
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info,
frameP,
slotP,
msg4_tda.startSymbolIndex,
msg4_tda.nrOfSymbols,
UE->UE_beam_index,
n_slots_frame);
if (beam.idx < 0)
return;
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nr_mac->beam_info,
frameP,
slotP,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
UE->UE_beam_index,
n_slots_frame);
if (dci_beam.idx < 0) {
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
return;
}
// get CCEindex, needed also for PUCCH and then later for PDCCH
int aggregation_level;
int CCEIndex = get_cce_index(nr_mac,
@@ -1701,30 +1768,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
if (CCEIndex < 0) {
LOG_E(NR_MAC, "Cannot find free CCE for RA RNTI 0x%04x!\n", UE->rnti);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
return;
}
// Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
return;
}
int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index);
uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP);
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index];
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
ss->searchSpaceType->present,
time_domain_assignment,
scc->dmrs_TypeA_Position,
mux_pattern,
TYPE_TC_RNTI_,
coreset->controlResourceSetId,
false);
if (!msg4_tda.valid_tda) {
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
@@ -1771,6 +1815,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
if (!get_rb_alloc(msg4_nr_rb, msg4_nr_rb, bwp_info.bwpStart, bwp_info.bwpSize, vrb_map, msg4_mask, &rbStart, &rbSize)) {
LOG_E(NR_MAC, "Cannot find free vrb_map for RNTI %04x!\n", UE->rnti);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
@@ -1780,6 +1825,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
if (alloc < 0) {
LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n", frameP, slotP);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
return;
}
@@ -1903,7 +1949,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
&sched_ctrl->sched_pdcch,
CCEIndex,
aggregation_level,
beam.idx);
dci_beam.idx);
for (int rb = 0; rb < rbSize; rb++) {
vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg4_mask;
}

View File

@@ -188,14 +188,16 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi
if (is_ssb_configured(scc, i_ssb)) {
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol / 14) == rel_slot) {
if ((ssb_start_symbol / NR_SYMBOLS_PER_SLOT) == rel_slot) {
const uint16_t alloc_beam_idx = get_beam_from_ssbidx(gNB, i_ssb);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info,
frameP,
slotP,
get_beam_from_ssbidx(gNB, i_ssb),
ssb_start_symbol % NR_SYMBOLS_PER_SLOT,
4,
alloc_beam_idx,
slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
const uint16_t alloc_beam_idx = get_allocated_beam(&gNB->beam_info, frameP, slotP, slots_per_frame, beam.idx);
const uint16_t fapi_beam = convert_to_fapi_beam(alloc_beam_idx, gNB->beam_info.beam_mode);
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, fapi_beam, ssbSubcarrierOffset, offset_pointa, mib_pdu);
fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx);
@@ -510,17 +512,24 @@ void schedule_nr_sib1(module_id_t module_idP,
"Trying to schedule SIB1 for SSB %d in slot %d which is not DL. Check searchSpaceZero configuration.\n",
type0_PDCCH_CSS_config->ssb_index,
slotP);
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
int beam_index = get_beam_from_ssbidx(gNB_mac, i);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i);
LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
NR_sched_pdcch_t sched_pdcch = set_pdcch_structure(NULL,
&gNB_mac->sched_ctrlSIB1->search_space[i],
&gNB_mac->sched_ctrlSIB1->coreset,
scc,
NULL,
type0_PDCCH_CSS_config);
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
int beam_index = get_beam_from_ssbidx(gNB_mac, i);
// DCI BEAM
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info,
frameP,
slotP,
sched_pdcch.StartSymbolIndex,
sched_pdcch.DurationSymbols,
beam_index,
n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate DCI for SIB1 corresponding to SSB %d in any available beam\n", i);
LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
int nr_of_candidates, aggregation_level;
for (int c = 0; c < 3; c++) {
@@ -560,6 +569,16 @@ void schedule_nr_sib1(module_id_t module_idP,
gNB_mac->sib1_pdsch[i].time_domain_allocation,
i,
CC_id);
// PDSCH BEAM
NR_beam_alloc_t beam_sib = beam_allocation_procedure(&gNB_mac->beam_info,
frameP,
slotP,
gNB_mac->sib1_pdsch[i].tda_info.startSymbolIndex,
gNB_mac->sib1_pdsch[i].tda_info.nrOfSymbols,
beam_index,
n_slots_frame);
AssertFatal(beam_sib.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i);
int tb_size = gNB_mac->sib1_pdsch[i].tb_size;
AssertFatal(res && tb_size > 0, "Couldn't allocate TB for SIB1 for an already allocated TDA\n");
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
@@ -635,8 +654,6 @@ static void other_sib_sched_control(module_id_t module_idP,
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[0].ServingCellConfigCommon;
int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
beam_index = get_beam_from_ssbidx(gNB_mac, beam_index);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index);
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
@@ -664,6 +681,16 @@ static void other_sib_sched_control(module_id_t module_idP,
gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI));
*gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config);
}
// DCI BEAM
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info,
frame,
slot,
gNB_mac->sched_pdcch_otherSI->StartSymbolIndex,
gNB_mac->sched_pdcch_otherSI->DurationSymbols,
beam_index,
n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
int cce_index = find_pdcch_candidate(gNB_mac,
0,
aggregation_level,
@@ -687,7 +714,17 @@ static void other_sib_sched_control(module_id_t module_idP,
sched_pdsch_otherSI.pm_index = 0;
sched_pdsch_otherSI.mcs = 0; // starting from mcs 0
uint16_t *vrb_map = cc->vrb_map[beam.idx];
// PDSCH BEAM
NR_beam_alloc_t si_beam = beam_allocation_procedure(&gNB_mac->beam_info,
frame,
slot,
tda_info.startSymbolIndex,
tda_info.nrOfSymbols,
beam_index,
n_slots_frame);
AssertFatal(si_beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
uint16_t *vrb_map = cc->vrb_map[si_beam.idx];
uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx];
int num_total_bytes = cc->other_sib_bcch_length[payload_idx];
bool success = update_rb_mcs_tbs(&sched_pdsch_otherSI, num_total_bytes, vrb_map);

View File

@@ -404,12 +404,12 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
return bwp_info;
}
static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
post_process_pdsch_t *pp_pdsch,
int *n_rb_sched,
NR_UE_info_t *UE,
int beam_idx,
int current_harq_pid)
static NR_rtx_ret_t allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
post_process_pdsch_t *pp_pdsch,
NR_UE_info_t *UE,
int dci_beam_idx,
int current_harq_pid,
int slots_per_frame)
{
frame_t frame = pp_pdsch->frame;
slot_t slot = pp_pdsch->slot;
@@ -443,8 +443,10 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
TYPE_C_RNTI_,
coresetid,
false);
NR_rtx_ret_t ret = {0};
if (!temp_tda.valid_tda)
return false;
return ret;
bool reuse_old_tda = (new_sched.tda_info.startSymbolIndex == temp_tda.startSymbolIndex) && (new_sched.tda_info.nrOfSymbols <= temp_tda.nrOfSymbols);
LOG_D(NR_MAC, "[UE %x] %s old TDA, %s number of layers\n",
@@ -452,27 +454,48 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
reuse_old_tda ? "reuse" : "do not reuse",
layers == new_sched.nrOfLayers ? "same" : "different");
uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam_idx];
bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
const int bwp_start = bwp_info.bwpStart;
const int bwp_size = bwp_info.bwpSize;
// WRT the BWP start, the RBs are indexed from 0 to bwpSize-1
int rbStart = 0;
int rbSize = 0;
uint16_t *rballoc_mask;
NR_beam_alloc_t beam;
if (reuse_old_tda && layers == new_sched.nrOfLayers) {
beam = beam_allocation_procedure(&nr_mac->beam_info,
frame,
slot,
new_sched.tda_info.startSymbolIndex,
new_sched.tda_info.nrOfSymbols,
UE->UE_beam_index,
slots_per_frame);
if (beam.idx < 0)
return ret; // no rtx, couldn't allocate beam
/* Check that there are enough resources for retransmission */
rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam.idx];
const uint16_t slbitmap = SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
if (!get_rb_alloc(new_sched.rbSize, new_sched.rbSize, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
return false;
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret;
}
} 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);
beam = beam_allocation_procedure(&nr_mac->beam_info,
frame,
slot,
temp_tda.startSymbolIndex,
temp_tda.nrOfSymbols,
UE->UE_beam_index,
slots_per_frame);
if (beam.idx < 0)
return ret; // no rtx, couldn't allocate beam
/* Check that there are enough resources for retransmission */
rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam.idx];
NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers);
uint32_t new_tbs;
uint16_t new_rbSize;
bool success = nr_find_nb_rb(new_sched.Qm,
@@ -494,13 +517,15 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
slot,
new_tbs,
new_sched.tb_size);
return false; /* the maximum TBsize we might have is smaller than what we need */
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret; /* the maximum TBsize we might have is smaller than what we need */
}
const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols);
if (!get_rb_alloc(new_rbSize, new_rbSize, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
return false;
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret;
}
/* we can allocate it. Overwrite the time_domain_allocation, the number
@@ -520,15 +545,16 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
slot,
UE->rnti,
&sched_ctrl->aggregation_level,
beam_idx,
dci_beam_idx,
sched_ctrl->search_space,
sched_ctrl->coreset,
&sched_ctrl->sched_pdcch,
sched_ctrl->pdcch_cl_adjust);
if (CCEIndex<0) {
sched_ctrl->dl_cce_fail++;
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot);
return false;
return ret;
}
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
@@ -539,13 +565,14 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex);
alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, UE->UE_beam_index, r_pucch, 0);
if (alloc < 0) {
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", UE->rnti, frame, slot);
return false;
return ret;
}
}
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam_idx);
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam_idx);
new_sched.rbStart = rbStart;
new_sched.pucch_allocation = alloc;
@@ -554,12 +581,14 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
post_process_dlsch(nr_mac, pp_pdsch, UE, &new_sched);
/* retransmissions: directly allocate */
*n_rb_sched -= new_sched.rbSize;
ret.rbsize = new_sched.rbSize;
ret.valid = true;
ret.beam_idx = beam.idx;
for (int rb = new_sched.bwp_info.bwpStart + new_sched.rbStart; rb < new_sched.bwp_info.bwpStart + new_sched.rbStart + new_sched.rbSize; rb++)
rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
return true;
return ret;
}
static void ack_reconfig(gNB_MAC_INST *mac, NR_UE_info_t *UE)
@@ -659,19 +688,26 @@ static void pf_dl(gNB_MAC_INST *mac,
/* retransmission */
if (harq_pid >= 0) {
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame);
bool sch_ret = beam.idx >= 0;
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
UE->UE_beam_index,
slots_per_frame);
if (dci_beam.idx < 0)
continue; // Couldn't allocate beam for DCI
/* Allocate retransmission */
if (sch_ret)
sch_ret = allocate_dl_retransmission(mac, pp_pdsch, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid);
if (!sch_ret) {
NR_rtx_ret_t ret = allocate_dl_retransmission(mac, pp_pdsch, UE, dci_beam.idx, harq_pid, slots_per_frame);
if (!ret.valid) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
remainUEs[beam.idx]--;
remainUEs[ret.beam_idx]--;
n_rb_sched[ret.beam_idx] -= ret.rbsize;
} else {
/* skip this UE if there are no free HARQ processes. This can happen e.g.
* if the UE disconnected in L2sim, in which case the gNB is not notified
@@ -684,7 +720,7 @@ static void pf_dl(gNB_MAC_INST *mac,
continue;
}
update_dlsch_buffer(pp_pdsch->frame, pp_pdsch->slot, UE);
update_dlsch_buffer(frame, slot, UE);
if (!dlsch_to_schedule(sched_ctrl))
continue;
@@ -751,15 +787,15 @@ static void pf_dl(gNB_MAC_INST *mac,
continue;
}
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame);
if (beam.idx < 0) {
// no available beam
iterator++;
continue;
}
if (remainUEs[beam.idx] == 0 || n_rb_sched[beam.idx] < min_rbSize) {
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
iterator->UE->UE_beam_index,
slots_per_frame);
if (dci_beam.idx < 0) {
// no available beam for PDSCH
iterator++;
continue;
}
@@ -779,6 +815,26 @@ static void pf_dl(gNB_MAC_INST *mac,
false);
AssertFatal(tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n");
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
tda_info.startSymbolIndex,
tda_info.nrOfSymbols,
iterator->UE->UE_beam_index,
slots_per_frame);
if (beam.idx < 0) {
// no available beam for PDSCH
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
iterator++;
continue;
}
if (remainUEs[beam.idx] == 0 || n_rb_sched[beam.idx] < min_rbSize) {
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
}
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];
@@ -797,6 +853,7 @@ static void pf_dl(gNB_MAC_INST *mac,
rbStart,
max_rbSize);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
iterator++;
continue;
}
@@ -806,7 +863,7 @@ static void pf_dl(gNB_MAC_INST *mac,
slot,
iterator->UE->rnti,
&sched_ctrl->aggregation_level,
beam.idx,
dci_beam.idx,
sched_ctrl->search_space,
sched_ctrl->coreset,
&sched_ctrl->sched_pdcch,
@@ -815,6 +872,7 @@ static void pf_dl(gNB_MAC_INST *mac,
sched_ctrl->dl_cce_fail++;
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI\n", rnti, frame, slot);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
iterator++;
continue;
}
@@ -829,13 +887,14 @@ static void pf_dl(gNB_MAC_INST *mac,
if (alloc < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", rnti, frame, slot);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
iterator++;
continue;
}
}
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx);
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam.idx);
int l = get_dl_nrOfLayers(sched_ctrl, dl_bwp->dci_format);
NR_sched_pdsch_t sched_pdsch = {

View File

@@ -95,10 +95,23 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
}
}
}
int beam_idx = get_beam_from_ssbidx(mac, ssb_idx_beam);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, beam_idx, mac->frame_structure.numb_slots_frame);
AssertFatal(beam.idx > -1, "Can't allocate beam %d in phytest scheduler\n", beam_idx);
UE->UE_beam_index = get_allocated_beam(&mac->beam_info, frame, slot, mac->frame_structure.numb_slots_frame, beam.idx);
UE->UE_beam_index = get_beam_from_ssbidx(mac, ssb_idx_beam);
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
UE->UE_beam_index,
mac->frame_structure.numb_slots_frame);
AssertFatal(dci_beam.idx > -1, "Can't allocate DCI beam %d in phytest scheduler\n", UE->UE_beam_index);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
tda_info.startSymbolIndex,
tda_info.nrOfSymbols,
UE->UE_beam_index,
mac->frame_structure.numb_slots_frame);
AssertFatal(beam.idx > -1, "Can't allocate beam %d in phytest scheduler\n", UE->UE_beam_index);
int rbStart = 0;
int rbSize = 0;
@@ -125,7 +138,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
slot,
UE->rnti,
&sched_ctrl->aggregation_level,
beam.idx,
dci_beam.idx,
sched_ctrl->search_space,
sched_ctrl->coreset,
&sched_ctrl->sched_pdcch,
@@ -147,7 +160,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx);
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam.idx);
NR_sched_pdsch_t sched_pdsch = {
.rbSize = rbSize,

View File

@@ -3264,9 +3264,6 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
if((frame * n_slots_frame + slot - offset) % period == 0) {
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", frame, slot, nzpcsi->nzp_CSI_RS_ResourceId);
NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n");
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx];
UE_info->sched_csirs |= (1 << dl_bwp->bwp_id);
nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -3313,79 +3310,68 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
csirs_pdu_rel15->freq_density--;
csirs_pdu_rel15->scramb_id = nzpcsi->scramblingID;
csirs_pdu_rel15->power_control_offset = nzpcsi->powerControlOffset + 8;
int n_symb_l0 = 0;
int n_symb_l1 = 0;
if (nzpcsi->powerControlOffsetSS)
csirs_pdu_rel15->power_control_offset_ss = *nzpcsi->powerControlOffsetSS;
else
csirs_pdu_rel15->power_control_offset_ss = 1; // 0 dB
switch(resourceMapping.frequencyDomainAllocation.present){
switch(resourceMapping.frequencyDomainAllocation.present) {
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1:
csirs_pdu_rel15->row = 1;
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
n_symb_l0 = 1;
break;
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
csirs_pdu_rel15->row = 2;
csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<4)&0xff0));
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
n_symb_l0 = 1;
break;
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
csirs_pdu_rel15->row = 4;
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
n_symb_l0 = 1;
break;
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
// determining the row of table 7.4.1.5.3-1 in 38.211
switch(resourceMapping.nrofPorts){
switch(resourceMapping.nrofPorts) {
case NR_CSI_RS_ResourceMapping__nrofPorts_p1:
AssertFatal(1==0,"Resource with 1 CSI port shouldn't be within other rows\n");
AssertFatal(false, "Resource with 1 CSI port shouldn't be within other rows\n");
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
csirs_pdu_rel15->row = 3;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
n_symb_l0 = 1;
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
csirs_pdu_rel15->row = 5;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
n_symb_l0 = 2;
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
csirs_pdu_rel15->row = 8;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
}
else{
n_symb_l0 = 2;
} else {
int num_k = 0;
for (int k=0; k<6; k++)
num_k+=(((csirs_pdu_rel15->freq_domain)>>k)&0x01);
if(num_k==4) {
csirs_pdu_rel15->row = 6;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
}
else {
n_symb_l0 = 1;
} else {
csirs_pdu_rel15->row = 7;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
n_symb_l0 = 2;
}
}
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p12:
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
csirs_pdu_rel15->row = 10;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
}
else {
n_symb_l0 = 2;
} else {
csirs_pdu_rel15->row = 9;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
n_symb_l0 = 2;
}
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
@@ -3393,53 +3379,69 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
csirs_pdu_rel15->row = 12;
else
csirs_pdu_rel15->row = 11;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
n_symb_l0 = 2;
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
csirs_pdu_rel15->row = 14;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
}
else{
n_symb_l0 = 2;
n_symb_l1 = 2;
} else {
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
csirs_pdu_rel15->row = 15;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
}
else {
n_symb_l0 = 4;
} else {
csirs_pdu_rel15->row = 13;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
n_symb_l0 = 2;
n_symb_l1 = 2;
}
}
break;
case NR_CSI_RS_ResourceMapping__nrofPorts_p32:
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
csirs_pdu_rel15->row = 17;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
}
else{
n_symb_l0 = 2;
n_symb_l1 = 2;
} else {
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
csirs_pdu_rel15->row = 18;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
}
else {
n_symb_l0 = 4;
} else {
csirs_pdu_rel15->row = 16;
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
n_symb_l0 = 2;
n_symb_l1 = 2;
}
}
break;
default:
AssertFatal(1==0,"Invalid number of ports in CSI-RS resource\n");
AssertFatal(false, "Invalid number of ports in CSI-RS resource\n");
}
break;
default:
AssertFatal(1==0,"Invalid freqency domain allocation in CSI-RS resource\n");
AssertFatal(false, "Invalid freqency domain allocation in CSI-RS resource\n");
}
NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info,
frame,
slot,
csirs_pdu_rel15->symb_l0,
n_symb_l0,
UE->UE_beam_index,
n_slots_frame);
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n");
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx];
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, n_symb_l0);
if (n_symb_l1) {
NR_beam_alloc_t beam_csi1 = beam_allocation_procedure(&gNB_mac->beam_info,
frame,
slot,
csirs_pdu_rel15->symb_l1,
n_symb_l1,
UE->UE_beam_index,
n_slots_frame);
AssertFatal(beam_csi1.idx >= 0 && beam_csi1.idx == beam_csi.idx, "Cannot allocate CSI-RS in any available beam\n");
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l1, n_symb_l1);
}
dl_req->nPDUs++;
}
@@ -3709,32 +3711,57 @@ void fill_beam_index_list(NR_ServingCellConfigCommon_t *scc, const nr_mac_config
}
}
static inline int get_beam_index(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
static inline int get_beam_allocation_slot_index(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
{
return ((frame * slots_per_frame + slot) / beam_info->beam_duration) % beam_info->beam_allocation_size;
return ((frame * slots_per_frame + slot) / beam_info->beam_slot_duration) % beam_info->beam_allocation_size[0];
}
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame)
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info,
int frame,
int slot,
int start_symbol,
int nb_symbols,
int16_t beam_index,
int slots_per_frame)
{
// if no beam allocation for analog beamforming we always return beam index 0 (no multiple beams)
if (beam_info->beam_mode == NO_BEAM_MODE)
return (NR_beam_alloc_t) {.new_beam = false, .idx = 0};
return (NR_beam_alloc_t) {.new_beam = 0, .idx = 0};
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
const int index = get_beam_allocation_slot_index(beam_info, frame, slot, slots_per_frame);
int alloc_start = 0;
int alloc_end = 0;
if (beam_info->beam_allocation_size[1] > 1) {
int step_size = NR_SYMBOLS_PER_SLOT / beam_info->beam_allocation_size[1];
alloc_start = start_symbol / step_size;
alloc_end = (start_symbol + nb_symbols - 1) / step_size;
}
for (int i = 0; i < beam_info->beams_per_period; i++) {
NR_beam_alloc_t beam_struct = {.new_beam = false, .idx = i};
int16_t *beam = &beam_info->beam_allocation[i][index];
if (*beam == -1) {
beam_struct.new_beam = true;
*beam = beam_index;
bool beam_found = true;
uint16_t new_beam = 0;
for (int j = alloc_start; j <= alloc_end; j++) {
int16_t beam = beam_info->beam_allocation[i][index][j];
if (beam != -1 && beam != beam_index) {
beam_found = false;
break;
} else if (beam == -1)
new_beam |= (1 << j);
}
if (*beam == beam_index) {
LOG_D(NR_MAC, "%d.%d Using beam structure with index %d for beam %d (%s)\n", frame, slot, beam_struct.idx, beam_index, beam_struct.new_beam ? "new beam" : "old beam");
if (beam_found) {
NR_beam_alloc_t beam_struct = {.new_beam = new_beam, .idx = i};
for (int j = alloc_start; j <= alloc_end; j++)
beam_info->beam_allocation[i][index][j] = beam_index;
LOG_D(NR_MAC,
"%d.%d Using beam structure with index %d for beam %d (%s)\n",
frame,
slot,
beam_struct.idx,
beam_index,
beam_struct.new_beam ? "new beam" : "old beam");
return beam_struct;
}
}
return (NR_beam_alloc_t) {.new_beam = false, .idx = -1};
return (NR_beam_alloc_t) {.new_beam = 0, .idx = -1};
}
uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode)
@@ -3743,24 +3770,17 @@ uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode
return (mode == LOPHY_BEAM_IDX) ? SET_BIT(beam_idx, 15) : beam_idx;
}
int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period)
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, uint16_t beam_alloc)
{
int16_t beam_idx = 0;
if (beam_info->beam_mode != NO_BEAM_MODE) {
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
beam_idx = beam_info->beam_allocation[beam_number_in_period][index];
}
return beam_idx;
}
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam)
{
if(!new_beam) // need to reset only if the beam was allocated specifically for this instance
if(beam_alloc == 0) // need to reset only if the beam was allocated specifically for this instance
return;
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
const int index = get_beam_allocation_slot_index(beam_info, frame, slot, slots_per_frame);
for (int i = 0; i < beam_info->beams_per_period; i++) {
if (beam_info->beam_allocation[i][index] == beam_index)
beam_info->beam_allocation[i][index] = -1;
for (int j = 0; j < NR_SYMBOLS_PER_SLOT; j++) {
if (IS_BIT_SET(beam_alloc, j))
if (beam_info->beam_allocation[i][index][j] == beam_index)
beam_info->beam_allocation[i][index][j] = -1;
}
}
}

View File

@@ -458,11 +458,11 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac,
}
const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nrmac->beam_info.beam_mode);
srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = fapi_beam;
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
uint16_t num = 1 << srs_pdu->num_symbols; // 0,1,2 means 1,2,4 symbols, see 222.10.04 table 3-105
const uint8_t l0 = NR_SYMBOLS_PER_SLOT - 1 - srs_pdu->time_start_position;
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, l0, num, UE->UE_beam_index, slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
uint16_t mask = SL_to_bitmap(l0, num);
DevAssert(mask != 0);
for (int i = 0; i < srs_pdu->bwp_size; ++i) {

View File

@@ -254,12 +254,6 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
curr_pucch->active = true;
int bwp_start = ul_bwp->BWPStart;
// going through the list of PUCCH resources to find the one indexed by resource_id
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate CSI measurements on PUCCH in any available beam\n");
const int index = ul_buffer_index(sched_frame, sched_slot, n_slots_frame, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[0].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
const int m = pucch_Config->resourceToAddModList->list.count;
for (int j = 0; j < m; j++) {
NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[j];
@@ -267,11 +261,13 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
continue;
int start = pucchres->startingPRB;
int len = 1;
uint64_t mask = 0;
int startingSymbolIndex = 0;
int nrofSymbols = 0;
switch(pucchres->format.present){
case NR_PUCCH_Resource__format_PR_format2:
len = pucchres->format.choice.format2->nrofPRBs;
mask = SL_to_bitmap(pucchres->format.choice.format2->startingSymbolIndex, pucchres->format.choice.format2->nrofSymbols);
nrofSymbols = pucchres->format.choice.format2->nrofSymbols;
startingSymbolIndex = pucchres->format.choice.format2->startingSymbolIndex;
curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI;
LOG_D(NR_MAC,
"%d.%d Allocating PUCCH format 2, startPRB %d, nPRB %d, simulHARQ %d, num_bits %d\n",
@@ -284,17 +280,30 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
break;
case NR_PUCCH_Resource__format_PR_format3:
len = pucchres->format.choice.format3->nrofPRBs;
mask = SL_to_bitmap(pucchres->format.choice.format3->startingSymbolIndex, pucchres->format.choice.format3->nrofSymbols);
nrofSymbols = pucchres->format.choice.format3->nrofSymbols;
startingSymbolIndex = pucchres->format.choice.format3->startingSymbolIndex;
curr_pucch->simultaneous_harqcsi = pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI;
break;
case NR_PUCCH_Resource__format_PR_format4:
mask = SL_to_bitmap(pucchres->format.choice.format4->startingSymbolIndex, pucchres->format.choice.format4->nrofSymbols);
nrofSymbols = pucchres->format.choice.format4->nrofSymbols;
startingSymbolIndex = pucchres->format.choice.format4->startingSymbolIndex;
curr_pucch->simultaneous_harqcsi = pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI;
break;
default:
AssertFatal(0, "Invalid PUCCH format type\n");
}
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
sched_frame,
sched_slot,
startingSymbolIndex,
nrofSymbols,
UE->UE_beam_index,
n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate CSI measurements on PUCCH in any available beam\n");
const int index = ul_buffer_index(sched_frame, sched_slot, n_slots_frame, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[0].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
// verify resources are free
uint64_t mask = SL_to_bitmap(startingSymbolIndex, nrofSymbols);
for (int i = start; i < start + len; ++i) {
if((vrb_map_UL[i+bwp_start] & mask) != 0) {
LOG_E(NR_MAC,
@@ -1221,7 +1230,13 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
else { // unoccupied occasion
// checking if in ul_slot the resources potentially to be assigned to this PUCCH are available
set_pucch_allocation(ul_bwp, r_pucch, bwp_size, curr_pucch);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, pucch_frame, pucch_slot, ue_beam, n_slots_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
pucch_frame,
pucch_slot,
curr_pucch->start_symb,
curr_pucch->nr_of_symb,
ue_beam,
n_slots_frame);
if (beam.idx < 0) {
LOG_D(NR_MAC,
"DL %4d.%2d, UL_ACK %4d.%2d beam resources for this occasion are already occupied, move to the following occasion\n",
@@ -1325,18 +1340,24 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, slot_t slot)
slot);
memset(curr_pucch, 0, sizeof(*curr_pucch));
continue;
}
else {
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, SFN, slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SR in any available beam\n");
const int index = ul_buffer_index(SFN, slot, n_slots_frame, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
} else {
const int bwp_start = ul_bwp->BWPStart;
const int bwp_size = ul_bwp->BWPSize;
set_pucch_allocation(ul_bwp, -1, bwp_size, curr_pucch);
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
SFN,
slot,
curr_pucch->start_symb,
curr_pucch->nr_of_symb,
UE->UE_beam_index,
n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SR in any available beam\n");
const int index = ul_buffer_index(SFN, slot, n_slots_frame, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
bool ret = test_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, bwp_start);
if (!ret) {
LOG_E(NR_MAC,"Cannot schedule SR. PRBs not available\n");
reset_beam_status(&nrmac->beam_info, SFN, slot, UE->UE_beam_index, n_slots_frame, beam.new_beam);
continue;
}
curr_pucch->frame = SFN;

View File

@@ -1709,16 +1709,15 @@ static void nr_ue_max_mcs_min_rb(int mu,
*mcs = pot.mcs;
}
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
post_process_pusch_t *pp_pusch,
uint16_t *rballoc_mask,
int *n_rb_sched,
int dci_beam_idx,
NR_UE_info_t *UE,
int harq_pid,
const NR_ServingCellConfigCommon_t *scc,
const int tda,
const NR_tda_info_t *tda_info)
static NR_rtx_ret_t allocate_ul_retransmission(gNB_MAC_INST *nrmac,
post_process_pusch_t *pp_pusch,
int dci_beam_idx,
int buf_idx,
NR_UE_info_t *UE,
int harq_pid,
const NR_ServingCellConfigCommon_t *scc,
const int tda,
const NR_tda_info_t *tda_info)
{
const int CC_id = 0;
int frame = pp_pusch->frame;
@@ -1744,10 +1743,24 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
new_sched.bwp_info = bwp_info;
DevAssert(new_sched.ul_harq_pid == harq_pid);
NR_rtx_ret_t ret = {0};
uint16_t *rballoc_mask;
NR_beam_alloc_t beam;
int slots_per_frame = nrmac->frame_structure.numb_slots_frame;
bool reuse_old_tda = retInfo->time_domain_allocation == tda;
if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) {
/* Check the resource is enough for retransmission */
beam = beam_allocation_procedure(&nrmac->beam_info,
new_sched.frame,
new_sched.slot,
retInfo->tda_info.startSymbolIndex,
retInfo->tda_info.nrOfSymbols,
UE->UE_beam_index,
slots_per_frame);
if (beam.idx < 0)
return ret;
const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
rballoc_mask = &nrmac->common_channels[0].vrb_map_UL[beam.idx][buf_idx * MAX_BWP_SIZE];
if (!get_rb_alloc(retInfo->rbSize, retInfo->rbSize, bwpStart, bwpSize, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
LOG_D(NR_MAC,
"[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n",
@@ -1757,12 +1770,22 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
rbStart,
retInfo->rbSize,
bwpSize);
return false;
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret;
}
new_sched.rbStart = rbStart;
LOG_D(NR_MAC, "Retransmission keeping TDA %d and TBS %d\n", tda, retInfo->tb_size);
} else {
NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, tda_info, nrOfLayers);
beam = beam_allocation_procedure(&nrmac->beam_info,
new_sched.frame,
new_sched.slot,
tda_info->startSymbolIndex,
tda_info->nrOfSymbols,
UE->UE_beam_index,
slots_per_frame);
if (beam.idx < 0)
return ret;
/* the retransmission will use a different time domain allocation, check
* that we have enough resources */
uint32_t new_tbs;
@@ -1786,13 +1809,16 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
slot,
new_tbs,
retInfo->tb_size);
return false; /* the maximum TBsize we might have is smaller than what we need */
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret; /* the maximum TBsize we might have is smaller than what we need */
}
rballoc_mask = &nrmac->common_channels[0].vrb_map_UL[beam.idx][buf_idx * MAX_BWP_SIZE];
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
if (!get_rb_alloc(new_rbSize, new_rbSize, bwpStart, bwpSize, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot);
return false;
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret;
}
LOG_D(NR_MAC,
@@ -1825,7 +1851,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
if (CCEIndex<0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot);
sched_ctrl->ul_cce_fail++;
return false;
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
return ret;
}
sched_ctrl->cce_index = CCEIndex;
@@ -1844,10 +1871,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
new_sched.rbSize);
/* Mark the corresponding RBs as used */
n_rb_sched -= new_sched.rbSize;
ret.rbsize = new_sched.rbSize;
ret.valid = true;
ret.beam_idx = beam.idx;
for (int rb = bwpStart + new_sched.rbStart; rb < bwpStart + new_sched.rbStart + new_sched.rbSize; rb++)
rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
return true;
return ret;
}
typedef struct UEsched_s {
@@ -1906,14 +1935,12 @@ static int pf_ul(gNB_MAC_INST *nrmac,
/* Loop UE_list to calculate throughput and coeff */
UE_iterator(UE_list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (!nr_mac_ue_is_active(UE))
continue;
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_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
/* Calculate throughput */
@@ -1930,47 +1957,34 @@ static int pf_ul(gNB_MAC_INST *nrmac,
if (total_rem_ues == 0)
continue;
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI Beam could not be allocated\n", UE->rnti, frame, slot);
continue;
}
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame);
if (beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
const int index = ul_buffer_index(sched_frame, sched_slot, slots_per_frame, nrmac->vrb_map_UL_size);
uint16_t *rballoc_mask = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
/* Check if retransmission is necessary */
int ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n", UE->rnti, ul_harq_pid);
if (ul_harq_pid >= 0) {
/* Allocate retransmission*/
bool r = allocate_ul_retransmission(nrmac,
pp_pusch,
rballoc_mask,
&n_rb_sched[beam.idx],
dci_beam.idx,
UE,
ul_harq_pid,
scc,
tda,
tda_info);
if (!r) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UL retransmission could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info,
frame,
slot,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
UE->UE_beam_index,
slots_per_frame);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DCI for ULSCH beam could not be allocated\n", UE->rnti, frame, slot);
continue;
}
else
/* Allocate retransmission*/
const int index = ul_buffer_index(sched_frame, sched_slot, slots_per_frame, nrmac->vrb_map_UL_size);
NR_rtx_ret_t ret = allocate_ul_retransmission(nrmac, pp_pusch, dci_beam.idx, index, UE, ul_harq_pid, scc, tda, tda_info);
if (!ret.valid) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UL retransmission could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
} else
LOG_D(NR_MAC,"%4d.%2d UL Retransmission UE RNTI %04x to be allocated, max_num_ue %d\n", frame, slot, UE->rnti,max_num_ue);
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
remainUEs[beam.idx]--;
remainUEs[ret.beam_idx]--;
n_rb_sched[ret.beam_idx] -= ret.rbsize;
scheduled_something = true;
continue;
}
@@ -1980,8 +1994,6 @@ static int pf_ul(gNB_MAC_INST *nrmac,
* if the UE disconnected in L2sim, in which case the gNB is not notified
* (this can be considered a design flaw) */
if (sched_ctrl->available_ul_harq.head < 0) {
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] has no free UL HARQ process, skipping\n", UE->rnti, frame, slot);
continue;
}
@@ -1995,11 +2007,8 @@ static int pf_ul(gNB_MAC_INST *nrmac,
nrmac->ulsch_max_frame_inactivity);
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n", UE->rnti, do_sched ? "yes" : "no");
if ((B == 0 && !do_sched) || nr_timer_is_active(&sched_ctrl->transm_interrupt)) {
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
if ((B == 0 && !do_sched) || nr_timer_is_active(&sched_ctrl->transm_interrupt))
continue;
}
const NR_bler_options_t *bo = &nrmac->ul_bler;
const int max_mcs_table = (current_BWP->mcs_table == 0 || current_BWP->mcs_table == 2) ? 28 : 27;
@@ -2055,7 +2064,13 @@ static int pf_ul(gNB_MAC_INST *nrmac,
NR_UE_UL_BWP_t *current_BWP = &iterator->UE->current_UL_BWP;
NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
sched_frame,
sched_slot,
tda_info->startSymbolIndex,
tda_info->nrOfSymbols,
iterator->UE->UE_beam_index,
slots_per_frame);
if (beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", iterator->UE->rnti, sched_frame, sched_slot);
iterator++;
@@ -2068,7 +2083,13 @@ static int pf_ul(gNB_MAC_INST *nrmac,
continue;
}
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame);
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info,
frame,
slot,
sched_ctrl->sched_pdcch.StartSymbolIndex,
sched_ctrl->sched_pdcch.DurationSymbols,
iterator->UE->UE_beam_index,
slots_per_frame);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);

View File

@@ -446,10 +446,15 @@ uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc);
uint64_t get_ssb_bitmap_and_len(const NR_ServingCellConfigCommon_t *scc, uint8_t *len);
void fill_beam_index_list(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac);
int get_beam_from_ssbidx(gNB_MAC_INST *mac, int ssb_idx);
int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period);
uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode);
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame);
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam);
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info,
int frame,
int slot,
int start_symbol,
int nb_symbols,
int16_t beam_index,
int slots_per_frame);
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_alloc, int slots_per_frame, uint16_t new_beam);
int beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE);
void beam_switching_procedure(gNB_MAC_INST *mac, NR_UE_info_t *UE, int new_beam_index);
void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP);

View File

@@ -98,9 +98,15 @@ typedef enum {
static const char *const nrra_text[] =
{"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg4", "MsgB", "WAIT_Msg4_MsgB_ACK"};
typedef struct {
bool valid;
int beam_idx;
int rbsize;
} NR_rtx_ret_t;
typedef struct {
int idx;
bool new_beam;
uint16_t new_beam; // each bit a group of symbols
} NR_beam_alloc_t;
typedef struct nr_pdsch_AntennaPorts_t {
@@ -814,10 +820,11 @@ typedef enum {
typedef struct {
/// list of allocated beams per period
int16_t **beam_allocation;
int beam_duration; // in slots
int16_t ***beam_allocation;
int beam_slot_duration;
int beam_symbol_duration;
int beams_per_period;
int beam_allocation_size;
int beam_allocation_size[2];
nr_beam_mode_t beam_mode;
} NR_beam_info_t;