reworking prach scheduler to use new rach occasion information

This commit is contained in:
francescomani
2025-03-12 10:15:49 +01:00
parent 8f1661c66c
commit 24fed617b5
4 changed files with 46 additions and 141 deletions
+1 -3
View File
@@ -320,7 +320,7 @@ typedef struct {
int Pc_max;
} NR_PRACH_RESOURCES_t;
typedef struct{
typedef struct {
float ssb_per_ro;
int preambles_per_ssb;
} ssb_ro_preambles_t;
@@ -362,8 +362,6 @@ typedef struct {
bool RA_active;
/// Random-access preamble index
int ra_PreambleIndex;
// When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble
uint8_t ssb_nb_in_ro;
int zeroCorrelationZoneConfig;
int restricted_set_config;
// selected SSB for RACH (not the SSB-Index but the cumulative index, excluding not trasmitted SSBs)
-1
View File
@@ -302,4 +302,3 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca
for (int i = mac->TAG_list.count; i > 0 ; i--)
asn_sequence_del(&mac->TAG_list, i - 1, 1);
}
+11 -11
View File
@@ -403,7 +403,7 @@ static void ra_resource_selection(NR_UE_MAC_INST_t *mac)
ssb = mac->mib_ssb;
// set the PREAMBLE_INDEX to a ra-PreambleIndex corresponding to the selected SSB
ra->ra_PreambleIndex = res->ra_PreambleIndex;
ra->ro_mask_index = cfra->resourcesTwoStep_r16.ra_ssb_OccasionMaskIndex;
ra->ro_mask_index = cfra->resourcesTwoStep_r16.ra_ssb_OccasionMaskIndex;
break;
}
}
@@ -454,7 +454,7 @@ static void select_prach_occasion(RA_config_t *ra,
int idx_ssb = 0;
int temp_idx = 0;
if (ra->ssb_ro_config.ssb_per_ro < 1) {
num_ros_per_ssb = (int) (1 / ra->ssb_ro_config.ssb_per_ro);
num_ros_per_ssb = (int)(1 / ra->ssb_ro_config.ssb_per_ro);
idx_ssb = (rand_r(&seed) % num_ros_per_ssb);
temp_idx = ra->ra_ssb * num_ros_per_ssb + idx_ssb;
} else {
@@ -508,13 +508,13 @@ static void configure_prach_occasions(NR_UE_MAC_INST_t *mac, int prach_config_in
if (fs->frame_type == TDD && !check_mixed_slot_prach(fs, slot, start_symbol, end_symbol))
continue;
for (int f = 0; f < num_fd_occasions; f++) { // fd occasions
ra_occasions_period[num_ra_occasions_period] = (prach_occasion_info_t) {
.slot = slot,
.frame_info[0] = prach_info.x,
.frame_info[1] = n == 0 ? prach_info.y : prach_info.y2,
.start_symbol = start_symbol,
.fdm = f,
.format = prach_info.format};
ra_occasions_period[num_ra_occasions_period] =
(prach_occasion_info_t){.slot = slot,
.frame_info[0] = prach_info.x,
.frame_info[1] = n == 0 ? prach_info.y : prach_info.y2,
.start_symbol = start_symbol,
.fdm = f,
.format = prach_info.format};
LOG_D(NR_MAC,
"RA occasion %d: slot %d start symbol %d fd occasion %d\n",
num_ra_occasions_period,
@@ -533,10 +533,10 @@ static void configure_prach_occasions(NR_UE_MAC_INST_t *mac, int prach_config_in
ra->association_periods = 1;
int nb_eq_ssb = mac->ssb_list.nb_tx_ssb;
if (ra->ssb_ro_config.ssb_per_ro < 1)
nb_eq_ssb *= (int) (1 / ra->ssb_ro_config.ssb_per_ro);
nb_eq_ssb *= (int)(1 / ra->ssb_ro_config.ssb_per_ro);
int nb_eq_ro = num_ra_occasions_period;
if (ra->ssb_ro_config.ssb_per_ro > 1)
nb_eq_ro *= (int) ra->ssb_ro_config.ssb_per_ro;
nb_eq_ro *= (int)ra->ssb_ro_config.ssb_per_ro;
while (nb_eq_ssb > nb_eq_ro) {
// not enough PRACH occasions -> need to increase association period
ra->association_periods <<= 1;
+34 -126
View File
@@ -1939,91 +1939,6 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
}
}
// Returns a RACH occasion if any matches the SSB idx, the frame and the slot
static int get_nr_prach_info_from_ssb_index(prach_association_pattern_t *prach_assoc_pattern,
int ssb_idx,
int frame,
int slot,
ssb_list_info_t *ssb_list,
prach_occasion_info_t **prach_occasion_info_pp)
{
prach_occasion_slot_t *prach_occasion_slot_p = NULL;
*prach_occasion_info_pp = NULL;
// Search for a matching RO slot in the SSB_to_RO map
// A valid RO slot will match:
// - ssb_idx mapped to one of the ROs in that RO slot
// - exact slot number
// - frame offset
int idx_list = ssb_list->nb_ssb_per_index[ssb_idx];
ssb_info_t *ssb_info_p = &ssb_list->tx_ssb[idx_list];
LOG_D(NR_MAC, "checking for prach : ssb_info_p->nb_mapped_ro %d\n", ssb_info_p->nb_mapped_ro);
for (int n_mapped_ro = 0; n_mapped_ro < ssb_info_p->nb_mapped_ro; n_mapped_ro++) {
LOG_D(NR_MAC,
"%d.%d: mapped_ro[%d]->frame.slot %d.%d, prach_assoc_pattern->nb_of_frame %d\n",
frame,
slot,
n_mapped_ro,
ssb_info_p->mapped_ro[n_mapped_ro]->frame,
ssb_info_p->mapped_ro[n_mapped_ro]->slot,
prach_assoc_pattern->nb_of_frame);
if ((slot == ssb_info_p->mapped_ro[n_mapped_ro]->slot) && prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame != 0 &&
(ssb_info_p->mapped_ro[n_mapped_ro]->frame == (frame % prach_assoc_pattern->nb_of_frame))) {
uint8_t prach_config_period_nb = ssb_info_p->mapped_ro[n_mapped_ro]->frame / prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame;
uint8_t frame_nb_in_prach_config_period = ssb_info_p->mapped_ro[n_mapped_ro]->frame % prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame;
prach_occasion_slot_p = &prach_assoc_pattern->prach_conf_period_list[prach_config_period_nb].prach_occasion_slot_map[frame_nb_in_prach_config_period][slot];
}
}
// If there is a matching RO slot in the SSB_to_RO map
if (NULL != prach_occasion_slot_p) {
// A random RO mapped to the SSB index should be selected in the slot
// First count the number of times the SSB index is found in that RO
uint8_t nb_mapped_ssb = 0;
for (int ro_in_time = 0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) {
for (int ro_in_freq = 0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) {
prach_occasion_info_t *ro_p =
prach_occasion_slot_p->prach_occasion + ro_in_time * prach_occasion_slot_p->nb_of_prach_occasion_in_freq + ro_in_freq;
for (uint8_t ssb_nb = 0; ssb_nb < ro_p->nb_mapped_ssb; ssb_nb++) {
if (ro_p->mapped_ssb_idx[ssb_nb] == ssb_idx) {
nb_mapped_ssb++;
}
}
}
}
// Choose a random SSB nb
uint8_t random_ssb_nb = 0;
random_ssb_nb = ((taus()) % nb_mapped_ssb);
// Select the RO according to the chosen random SSB nb
nb_mapped_ssb=0;
for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) {
for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) {
prach_occasion_info_t *ro_p =
prach_occasion_slot_p->prach_occasion + ro_in_time * prach_occasion_slot_p->nb_of_prach_occasion_in_freq + ro_in_freq;
for (uint8_t ssb_nb = 0; ssb_nb < ro_p->nb_mapped_ssb; ssb_nb++) {
if (ro_p->mapped_ssb_idx[ssb_nb] == ssb_idx) {
if (nb_mapped_ssb == random_ssb_nb) {
*prach_occasion_info_pp = ro_p;
return 1;
}
else {
nb_mapped_ssb++;
}
}
}
}
}
}
return 0;
}
// Build the SSB to RO mapping upon RRC configuration update
void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac)
{
@@ -2522,6 +2437,23 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot)
}
}
static bool is_prach_frame(frame_t frame, prach_occasion_info_t *prach_occasion_info, int association_periods)
{
int config_period = prach_occasion_info->frame_info[0];
int frame_period = config_period * association_periods;
int frame_in_period = frame % frame_period;
if (association_periods > 1) {
int current_assoc_period = frame_in_period / config_period;
if (current_assoc_period != prach_occasion_info->association_period_idx)
return false;
frame_in_period %= config_period;
}
if (frame_in_period == prach_occasion_info->frame_info[1]) // SFN % x == y (see Tables in Table 6.3.3.2 of 38.211)
return true;
else
return false;
}
// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
// - todo:
@@ -2533,49 +2465,36 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
if (ra->ra_state != nrRA_GENERATE_PREAMBLE)
return;
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
// Get any valid PRACH occasion in the current slot for the selected SSB index
prach_occasion_info_t *prach_occasion_info = &ra->sched_ro_info;
const int bwp_id = mac->current_UL_BWP->bwp_id;
if (!is_prach_frame(frameP, prach_occasion_info, ra->association_periods))
return;
if (is_ul_slot(slotP, &mac->frame_structure)) {
// WIP Need to get the proper selected ssb_idx
// Initial beam selection functionality is not available yet
uint8_t selected_gnb_ssb_idx = mac->mib_ssb;
// Get any valid PRACH occasion in the current slot for the selected SSB index
prach_occasion_info_t *prach_occasion_info_p;
int is_nr_prach_slot = get_nr_prach_info_from_ssb_index(&mac->prach_assoc_pattern[bwp_id],
selected_gnb_ssb_idx,
(int)frameP,
(int)slotP,
&mac->ssb_list,
&prach_occasion_info_p);
if (is_nr_prach_slot) {
AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n");
if (slotP == prach_occasion_info->slot) {
nr_get_RA_window(mac);
uint16_t format = prach_occasion_info_p->format;
uint16_t format0 = format & 0xff; // single PRACH format
uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
if (!pdu) {
LOG_E(NR_MAC, "Error in PRACH allocation\n");
return;
}
uint16_t format = prach_occasion_info->format;
uint16_t format0 = format & 0xff; // single PRACH format
uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format
fapi_nr_prach_config_t *prach_config = &mac->phy_config.config_req.prach_config;
pdu->prach_config_pdu = (fapi_nr_ul_config_prach_pdu){
.phys_cell_id = mac->physCellId,
.num_prach_ocas = 1,
.prach_slot = prach_occasion_info_p->slot,
.prach_start_symbol = prach_occasion_info_p->start_symbol,
.num_ra = prach_occasion_info_p->fdm,
.prach_slot = prach_occasion_info->slot,
.prach_start_symbol = prach_occasion_info->start_symbol,
.num_ra = prach_occasion_info->fdm,
.num_cs = get_NCS(ra->zeroCorrelationZoneConfig, format0, ra->restricted_set_config),
.root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index,
.root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].prach_root_sequence_index,
.restricted_set = prach_config->restricted_set_config,
.freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1};
.freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].k1};
LOG_I(NR_MAC,
"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n",
@@ -2584,15 +2503,6 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
pdu->prach_config_pdu.prach_start_symbol,
pdu->prach_config_pdu.num_ra);
// Search which SSB is mapped in the RO (among all the SSBs mapped to this RO)
for (int ssb_nb_in_ro=0; ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; ssb_nb_in_ro++) {
if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb_in_ro] == selected_gnb_ssb_idx) {
ra->ssb_nb_in_ro = ssb_nb_in_ro;
break;
}
}
AssertFatal(ra->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx);
if (format1 != 0xff) {
switch (format0) { // dual PRACH format
case 0xa1:
@@ -2706,7 +2616,7 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
// Compute MsgB RNTI
ra->MsgB_rnti =
nr_get_MsgB_rnti(prach_occasion_info_p->start_symbol, slot_RA, prach_occasion_info_p->fdm, 0);
nr_get_MsgB_rnti(prach_occasion_info->start_symbol, slot_RA, prach_occasion_info->fdm, 0);
LOG_D(NR_MAC, "ra->ra_state %s\n", nrra_ue_text[ra->ra_state]);
ra->ra_state = nrRA_WAIT_MSGB;
ra->t_crnti = 0;
@@ -2715,8 +2625,6 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
} else {
AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type);
}
// rnti = ra->t_crnti;
} // is_nr_prach_slot
} // if is_nr_UL_slot
}