From 25fdc1d23d4c246324ccb665799de1a1029f276e Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 26 Jul 2023 17:40:20 +0200 Subject: [PATCH] beam association for prach --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 54 ++++++------ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 88 +++++++++++-------- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 86cc68e327..3f0db0e4da 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1800,20 +1800,20 @@ int get_nr_prach_info_from_index(uint8_t index, y = table_6_3_3_2_4_prachConfig_Index[index][3]; y2 = table_6_3_3_2_4_prachConfig_Index[index][4]; // checking n_sfn mod x = y - if ( (frame%x)==y || (frame%x)==y2 ) { - slot_60khz = slot >> (mu-2); // in table slots are numbered wrt 60kHz + if ((frame % x) == y || (frame % x) == y2) { + slot_60khz = slot >> (mu - 2); // in table slots are numbered wrt 60kHz s_map = table_6_3_3_2_4_prachConfig_Index[index][5]; - if ((s_map >> slot_60khz) & 0x01 ) { + if ((s_map >> slot_60khz) & 0x01) { for(int i = 0; i <= slot_60khz ;i++) { - if ( (s_map >> i) & 0x01) { + if ((s_map >> i) & 0x01) { (*RA_sfn_index)++; } } } - if ( ((s_map>>slot_60khz)&0x01) ) { + if (((s_map >> slot_60khz) & 0x01)) { *N_RA_slot = table_6_3_3_2_4_prachConfig_Index[index][7]; // Number of RACH slots within a subframe if (mu == 3) { - if ( (*N_RA_slot == 1) && (slot%2 == 0) ) + if ((*N_RA_slot == 1) && (slot % 2 == 0) ) return 0; // no prach in even slots @ 120kHz for 1 prach per 60khz slot } if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ @@ -1850,23 +1850,23 @@ int get_nr_prach_info_from_index(uint8_t index, if (unpaired) { x = table_6_3_3_2_3_prachConfig_Index[index][2]; y = table_6_3_3_2_3_prachConfig_Index[index][3]; - if ( (frame%x)==y ) { + if ((frame % x) == y) { subframe = slot >> mu; s_map = table_6_3_3_2_3_prachConfig_Index[index][4]; - if ((s_map >> subframe) & 0x01 ) { + if ((s_map >> subframe) & 0x01) { for(int i = 0; i <= subframe ;i++) { - if ( (s_map >> i) & 0x01) { + if ((s_map >> i) & 0x01) { (*RA_sfn_index)++; } } } - if ( (s_map>>subframe)&0x01 ) { + if ((s_map >> subframe) & 0x01 ) { *N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe if (mu == 1 && index >= 67) { - if ( (*N_RA_slot <= 1) && (slot%2 == 0) ) + if ((*N_RA_slot <= 1) && (slot % 2 == 0)) return 0; // no prach in even slots @ 30kHz for 1 prach per subframe } - if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL) { *config_period = x; *start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5]; *N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7]; @@ -1874,17 +1874,19 @@ int get_nr_prach_info_from_index(uint8_t index, if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1) format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1]; *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8); - LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %lu) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u \n", frame, - slot, - index, table_6_3_3_2_3_prachConfig_Index[index][6], - pointa, - mu, - unpaired, - *start_symbol, - *N_t_slot, - *N_dur, - *N_RA_slot, - *RA_sfn_index); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %lu) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u \n", + frame, + slot, + index, + table_6_3_3_2_3_prachConfig_Index[index][6], + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur, + *N_RA_slot, + *RA_sfn_index); } return 1; } @@ -1897,10 +1899,10 @@ int get_nr_prach_info_from_index(uint8_t index, else { // FDD x = table_6_3_3_2_2_prachConfig_Index[index][2]; y = table_6_3_3_2_2_prachConfig_Index[index][3]; - if ( (frame%x)==y ) { + if ((frame % x) == y) { subframe = slot >> mu; s_map = table_6_3_3_2_2_prachConfig_Index[index][4]; - if ( (s_map>>subframe)&0x01 ) { + if ((s_map>>subframe) & 0x01) { *N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6]; // Number of RACH slots within a subframe if (mu == 1) { if ((*N_RA_slot <= 1) && (slot % 2 == 0)){ @@ -1908,7 +1910,7 @@ int get_nr_prach_info_from_index(uint8_t index, } } for(int i = 0; i <= subframe ; i++) { - if ( (s_map >> i) & 0x01) { + if ((s_map >> i) & 0x01) { (*RA_sfn_index)++; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e55be8974e..d8f6690818 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -81,13 +81,13 @@ static int16_t ssb_index_from_prach(module_id_t module_idP, NR_COMMON_channels_t *cc = &gNB->common_channels[0]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; - - uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + uint8_t config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES; - if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) - total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + if (rach_ConfigCommon->totalNumberOfRA_Preambles != NULL) + total_RApreambles = *rach_ConfigCommon->totalNumberOfRA_Preambles; float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; uint16_t start_symbol_index = 0; @@ -97,8 +97,8 @@ static int16_t ssb_index_from_prach(module_id_t module_idP, uint16_t prach_occasion_id = -1; uint8_t num_active_ssb = cc->num_active_ssb; - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) - mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + if (rach_ConfigCommon->msg1_SubcarrierSpacing) + mu = *rach_ConfigCommon->msg1_SubcarrierSpacing; else mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; @@ -115,13 +115,13 @@ static int16_t ssb_index_from_prach(module_id_t module_idP, &RA_sfn_index, &N_RA_slot, &config_period); - uint8_t index = 0,slot_index = 0; - for (slot_index = 0;slot_index < N_RA_slot; slot_index++) { + uint8_t index = 0, slot_index = 0; + for (slot_index = 0; slot_index < N_RA_slot; slot_index++) { if (N_RA_slot <= 1) { //1 PRACH slot in a subframe if((mu == 1) || (mu == 3)) slot_index = 1; //For scs = 30khz and 120khz } - for (int i=0; i< N_t_slot; i++) { + for (int i = 0; i < N_t_slot; i++) { temp_start_symbol = (start_symbol + i * N_dur + 14 * slot_index) % 14; if(symbol == temp_start_symbol) { start_symbol_index = i; @@ -134,18 +134,18 @@ static int16_t ssb_index_from_prach(module_id_t module_idP, slot_index = 0; //For scs = 30khz and 120khz } - // prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index; + // prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index; prach_occasion_id = (((frameP % (cc->max_association_period * config_period)) / config_period) * cc->total_prach_occasions_per_config_period) + - (RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index; + (RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index; - //one RO is shared by one or more SSB - if(num_ssb_per_RO <= 1 ) - index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb; //one SSB have more than one continuous RO - else if ( num_ssb_per_RO > 1) { - index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ; - for(int j = 0;j < num_ssb_per_RO;j++) { - if(preamble_index < (((j + 1) * total_RApreambles) / num_ssb_per_RO)) + if(num_ssb_per_RO <= 1) + index = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % num_active_ssb; + //one RO is shared by one or more SSB + else if (num_ssb_per_RO > 1) { + index = (prach_occasion_id * (int)num_ssb_per_RO) % num_active_ssb; + for(int j = 0; j < num_ssb_per_RO; j++) { + if(preamble_index < ((j + 1) * cc->cb_preambles_per_ssb)) index = index + j; } } @@ -165,14 +165,14 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0]; - - uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + uint8_t config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; uint8_t mu,N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0; uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0; uint8_t num_active_ssb = 0; uint8_t max_association_period = 1; - struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB; + struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB; switch (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present){ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: @@ -204,8 +204,8 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) break; } - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) - mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + if (rach_ConfigCommon->msg1_SubcarrierSpacing) + mu = *rach_ConfigCommon->msg1_SubcarrierSpacing; else mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; @@ -227,24 +227,24 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm; - for(int i = 0;i < 64;i++) { - if ((L_ssb >> (63-i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1 - cc->ssb_index[num_active_ssb] = i; + for(int i = 0; i < 64; i++) { + if ((L_ssb >> (63 - i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1 + cc->ssb_index[num_active_ssb] = i; num_active_ssb++; } } cc->total_prach_occasions_per_config_period = total_RA_occasions; - for(int i=1; (1 << (i-1)) <= max_association_period; i++) { - cc->max_association_period = (1 <<(i-1)); + for(int i = 1; (1 << (i-1)) <= max_association_period; i++) { + cc->max_association_period = (1 << (i - 1)); total_RA_occasions = total_RA_occasions * cc->max_association_period; - if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) { - repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb); + if(total_RA_occasions >= (int) (num_active_ssb / num_ssb_per_RO)) { + repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO) / num_active_ssb); break; } } - unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO); + unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition) / num_ssb_per_RO); cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion; cc->num_active_ssb = num_active_ssb; @@ -319,13 +319,30 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP UL_tti_req->SFN = frameP; UL_tti_req->Slot = slotP; UL_tti_req->rach_present = 1; + NR_beam_alloc_t beam = {0}; for (int fdm_index = 0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion for (int td_index = 0; td_index < N_t_slot; td_index++) { prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index; - if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)) { + if (prach_occasion_id >= cc->total_prach_occasions) // to be confirmed: unused occasion? + continue; + + float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; + if(num_ssb_per_RO <= 1) { + int ssb_index = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % cc->num_active_ssb; + beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, ssb_index, nr_slots_per_frame[mu]); + AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", ssb_index); + } + 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++) { + beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, j, nr_slots_per_frame[mu]); + AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j); + } + } + if(td_index == 0) { AssertFatal(UL_tti_req->n_pdus < sizeof(UL_tti_req->pdus_list) / sizeof(UL_tti_req->pdus_list[0]), "Invalid UL_tti_req->n_pdus %d\n", UL_tti_req->n_pdus); @@ -414,13 +431,10 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP } // block resources in vrb_map_UL - // TODO properly allocate beam index for PRACH - int beam_idx = 0; - const uint8_t mu_pusch = - scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + const int mu_pusch = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; const int16_t n_ra_rb = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch); index = ul_buffer_index(frameP, slotP, mu, gNB->vrb_map_UL_size); - uint16_t *vrb_map_UL = &cc->vrb_map_UL[beam_idx][index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &cc->vrb_map_UL[beam.idx][index * MAX_BWP_SIZE]; for (int i = 0; i < n_ra_rb * fdm; ++i) vrb_map_UL[bwp_start + rach_ConfigGeneric->msg1_FrequencyStart + i] |= SL_to_bitmap(start_symbol, N_t_slot * N_dur); }