Merge remote-tracking branch 'origin/RU_beam_management' into integration_2025_w24 (!3169)

NR RU improvements for analog beamforming
This commit is contained in:
Robert Schmidt
2025-06-11 18:37:15 +02:00
35 changed files with 534 additions and 411 deletions
+16 -20
View File
@@ -715,36 +715,32 @@ static void config_common(gNB_MAC_INST *nrmac,
if (cfg->cell_config.frame_duplex_type.value == TDD)
set_tdd_config_nr(cfg, fs);
int nb_tx = config->nb_bfw[0]; // number of tx antennas
int nb_beams = config->nb_bfw[1]; // number of beams
// precoding matrix configuration (to be improved)
cfg->pmi_list = init_DL_MIMO_codebook(nrmac, pdsch_AntennaPorts);
// beamforming matrix configuration
cfg->dbt_config.num_dig_beams = nb_beams;
if (nb_beams > 0) {
cfg->dbt_config.num_txrus = nb_tx;
cfg->dbt_config.dig_beam_list = malloc16(nb_beams * sizeof(*cfg->dbt_config.dig_beam_list));
AssertFatal(cfg->dbt_config.dig_beam_list, "out of memory\n");
for (int i = 0; i < nb_beams; i++) {
nfapi_nr_dig_beam_t *beam = &cfg->dbt_config.dig_beam_list[i];
beam->beam_idx = i;
beam->txru_list = malloc16(nb_tx * sizeof(*beam->txru_list));
for (int j = 0; j < nb_tx; j++) {
nfapi_nr_txru_t *txru = &beam->txru_list[j];
txru->dig_beam_weight_Re = config->bw_list[j + i * nb_tx] & 0xffff;
txru->dig_beam_weight_Im = (config->bw_list[j + i * nb_tx] >> 16) & 0xffff;
LOG_D(NR_MAC, "Beam %d Tx %d Weight (%d, %d)\n", i, j, txru->dig_beam_weight_Re, txru->dig_beam_weight_Im);
}
}
}
int nb_beams = config->nb_bfw[1]; // number of beams
if (nrmac->beam_info.beam_allocation) {
LOG_I(NR_MAC, "Configuring analog beamforming in config_request message\n");
cfg->analog_beamforming_ve.num_beams_period_vendor_ext.tl.tag = NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG;
cfg->analog_beamforming_ve.num_beams_period_vendor_ext.value = nrmac->beam_info.beams_per_period;
cfg->num_tlv++;
cfg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag = NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG;
cfg->analog_beamforming_ve.analog_bf_vendor_ext.value = 1; // analog BF enabled
cfg->num_tlv++;
cfg->analog_beamforming_ve.total_num_beams_vendor_ext.tl.tag = NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG;
cfg->analog_beamforming_ve.total_num_beams_vendor_ext.value = nb_beams;
cfg->num_tlv++;
cfg->analog_beamforming_ve.analog_beam_list = malloc16(nb_beams * sizeof(*cfg->analog_beamforming_ve.analog_beam_list));
for (int i = 0; i < nb_beams; i++) {
cfg->analog_beamforming_ve.analog_beam_list[i].tl.tag = NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG;
cfg->analog_beamforming_ve.analog_beam_list[i].value = config->bw_list[i];
}
} else {
cfg->analog_beamforming_ve.analog_bf_vendor_ext.value = 0; // analog BF disabled
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
cfg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag = NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG;
cfg->num_tlv++;
}
}
}
+38 -34
View File
@@ -356,10 +356,11 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_BWP_UplinkCommon_t *initialUplinkBWP = scc->uplinkConfigCommon->initialUplinkBWP;
NR_RACH_ConfigCommon_t *rach_ConfigCommon = initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_MsgA_ConfigCommon_r16_t *msgacc = NULL;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
if (initialUplinkBWP->ext1 && initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
msgacc = initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
int slots_frame = gNB->frame_structure.numb_slots_frame;
int index = ul_buffer_index(frameP, slotP, slots_frame, gNB->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index];
@@ -371,7 +372,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
int slot_index = 0;
uint16_t prach_occasion_id = -1;
int bwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int bwp_start = NRRIV2PRBOFFSET(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
const int ul_mu = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
@@ -399,6 +400,16 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
uint32_t N_t_slot = cc->prach_info.N_t_slot;
uint32_t start_symb = cc->prach_info.start_symbol;
for (int fdm_index = 0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
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);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu, 0, sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus += 1;
int num_td_occ = 0;
for (int td_index = 0; td_index < N_t_slot; td_index++) {
uint32_t config_period = cc->prach_info.x;
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) +
@@ -407,6 +418,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
if (prach_occasion_id >= cc->total_prach_occasions) // to be confirmed: unused occasion?
continue;
num_td_occ++;
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
int beam_index = 0;
if(num_ssb_per_RO <= 1) {
@@ -417,8 +429,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
// 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);
}
else {
} 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
@@ -428,40 +439,15 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
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);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
if(num_td_occ == 1) {
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
gNB->num_scheduled_prach_rx += N_t_slot;
prach_pdu->prach_start_symbol = start_symb;
prach_pdu->num_ra = fdm_index;
prach_pdu->num_cs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig,
format0,
rach_ConfigCommon->restrictedSetConfig);
prach_pdu->beamforming.num_prgs = 0;
prach_pdu->beamforming.prg_size = 0;
prach_pdu->beamforming.dig_bf_interface = 1;
prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
LOG_D(NR_MAC,
"Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
frameP,
slotP,
prach_occasion_id,
prach_pdu->num_ra,
start_symb,
slot_index,
RA_sfn_index);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
@@ -518,8 +504,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
AssertFatal(1==0,"Invalid PRACH format");
}
}
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1
&& scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
if (initialUplinkBWP->ext1 && initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
if (gNB->UE_info.connected_ue_list[0] == NULL)
schedule_nr_MsgA_pusch(scc->uplinkConfigCommon,
gNB,
@@ -531,7 +516,26 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
*scc->physCellId);
}
}
prach_pdu->num_prach_ocas = num_td_occ;
prach_pdu->beamforming.num_prgs = 0;
prach_pdu->beamforming.prg_size = 0;
prach_pdu->beamforming.dig_bf_interface = num_td_occ;
prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[num_td_occ - 1].beam_idx = beam_index;
LOG_D(NR_MAC,
"Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
frameP,
slotP,
prach_occasion_id,
prach_pdu->num_ra,
prach_pdu->prach_start_symbol,
slot_index,
RA_sfn_index);
}
if (num_td_occ == 0) // no TD PRACH occasion -> no PRACH PDU
UL_tti_req->n_pdus -= 1;
else
gNB->num_scheduled_prach_rx += num_td_occ;
}
// block resources in vrb_map_UL