using the analog beamforming oai extension fapi fields instead of digital beamforming structure for analog beamforming

This commit is contained in:
francescomani
2025-06-10 12:10:55 +02:00
parent 8a544b9fbb
commit 675e1129b4
14 changed files with 31 additions and 35 deletions
+2
View File
@@ -10,6 +10,8 @@ There are three main beamforming techinques: analog, digital and hybrid. The nam
The presence of a limited number of predefined beams at RU poses constraints to the scheduler at gNB. As a matter of fact, the scheduler can serve only a limited number of beams, depending on the RU characteristics (possibly only 1), in a given time scale, that also depends on the RU characteristics (e.g. 1 slot or 1 symbol). This limitation doesn't exist for digital beamforming.
To be noted that in our implementation analog beamforming is only supported in non-split/monolithic mode because we don't support yet SCF P19 interface that would be needed to manage these procedure in a split scenario with SCF FAPI.
# Configuration file fields for analog beamforming
A set of parameters in configuration files controls the implementation of analog beamforming and instructs the scheduler on how to behave in such scenarios. Since most notably this technique in 5G is employed in FR2, the configuration file example currently available is a RFsim one for band 261. [Config file example](../ci-scripts/conf_files/gnb.sa.band261.u3.32prb.rfsim.conf)
@@ -496,6 +496,8 @@ typedef struct {
typedef struct {
nfapi_uint8_tlv_t num_beams_period_vendor_ext;
nfapi_uint8_tlv_t analog_bf_vendor_ext;
nfapi_uint8_tlv_t total_num_beams_vendor_ext;
nfapi_uint8_tlv_t *analog_beam_list;
} nfapi_nr_analog_beamforming_ve_t;
// ERROR enums
+1 -2
View File
@@ -172,8 +172,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
for (int i = 0; i < common_vars->num_beams_period; i++)
common_vars->rxdataF[i] = (c16_t **)malloc16(Prx * sizeof(c16_t*));
common_vars->num_beams = cfg->dbt_config.num_dig_beams;
if (common_vars->num_beams > 0) {
if (cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) {
common_vars->beam_id = (int **)malloc16(common_vars->num_beams_period * sizeof(int*));
for (int i = 0; i < common_vars->num_beams_period; i++)
common_vars->beam_id[i] = (int*)malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
+1 -1
View File
@@ -82,7 +82,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
// multi-beam number (for concurrent beams)
int bitmap = SL_to_bitmap(cset_start_symb, pdcch_pdu_rel15->DurationSymbols);
int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->gNB_config.dbt_config,
&gNB->gNB_config.analog_beamforming_ve,
&gNB->common_vars,
slot,
frame_parms->symbols_per_slot,
+1 -1
View File
@@ -681,7 +681,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
// beam number in multi-beam scenario (concurrent beams)
int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols);
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->gNB_config.dbt_config,
&gNB->gNB_config.analog_beamforming_ve,
&gNB->common_vars,
slot,
frame_parms->symbols_per_slot,
+1 -1
View File
@@ -86,7 +86,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p
int temp_nb_symbols = NR_NUMBER_OF_SYMBOLS_PER_SLOT - prach_pdu->prach_start_symbol;
int bitmap = SL_to_bitmap(prach_pdu->prach_start_symbol, temp_nb_symbols);
prach->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->gNB_config.dbt_config,
&gNB->gNB_config.analog_beamforming_ve,
&gNB->common_vars,
Slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
+1 -1
View File
@@ -77,7 +77,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
int bitmap = SL_to_bitmap(ulsch_pdu->start_symbol_index, ulsch_pdu->nr_of_symbols);
ulsch->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->gNB_config.dbt_config,
&gNB->gNB_config.analog_beamforming_ve,
&gNB->common_vars,
slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
+1 -1
View File
@@ -74,7 +74,7 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB,
int fapi_beam_idx = pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
int bitmap = SL_to_bitmap(pucch_pdu->start_symbol_index, pucch_pdu->nr_of_symbols);
pucch->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->gNB_config.dbt_config,
&gNB->gNB_config.analog_beamforming_ve,
&gNB->common_vars,
slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
+1 -1
View File
@@ -60,7 +60,7 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
int bitmap = SL_to_bitmap(srs_pdu->time_start_position, 1 << srs_pdu->num_symbols);
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
srs->beam_nb = beam_index_allocation(fapi_beam_idx,
&gNB->gNB_config.dbt_config,
&gNB->gNB_config.analog_beamforming_ve,
&gNB->common_vars,
slot,
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
-1
View File
@@ -287,7 +287,6 @@ typedef struct {
/// - first index: beam index (for concurrent beams)
/// - second index: beam_id [0.. symbols_per_frame[
int **beam_id;
int num_beams;
int num_beams_period;
bool analog_bf;
int32_t *debugBuff;
+4 -4
View File
@@ -46,7 +46,7 @@
//#define SRS_IND_DEBUG
int beam_index_allocation(int fapi_beam_index,
nfapi_nr_dbt_pdu_t *dbt_config,
nfapi_nr_analog_beamforming_ve_t *analog_bf,
NR_gNB_COMMON *common_vars,
int slot,
int symbols_per_slot,
@@ -56,7 +56,7 @@ int beam_index_allocation(int fapi_beam_index,
return 0;
int idx = -1;
int ru_beam_idx = dbt_config->dig_beam_list[fapi_beam_index].txru_list[0].dig_beam_weight_Re;
int ru_beam_idx = analog_bf->analog_beam_list[fapi_beam_index].value;
for (int j = 0; j < common_vars->num_beams_period; j++) {
for (int i = 0; i < symbols_per_slot; i++) {
if (((bitmap_symbols >> i) & 0x01) == 0)
@@ -138,7 +138,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n
// beam number in a scenario with multiple concurrent beams
int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&cfg->dbt_config,
&cfg->analog_beamforming_ve,
&gNB->common_vars,
slot,
fp->symbols_per_slot,
@@ -280,7 +280,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
for (int j = 0; j < mapping_parms.size; j++)
csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j];
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&cfg->dbt_config,
&cfg->analog_beamforming_ve,
&gNB->common_vars,
slot,
fp->symbols_per_slot,
+1 -1
View File
@@ -48,7 +48,7 @@ void nr_phy_init_RU(RU_t *ru);
void nr_phy_free_RU(RU_t *ru);
void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot);
int beam_index_allocation(int fapi_beam_index,
nfapi_nr_dbt_pdu_t *dbt_config,
nfapi_nr_analog_beamforming_ve_t *analog_bf,
NR_gNB_COMMON *common_vars,
int slot,
int symbols_per_slot,
+1 -1
View File
@@ -1572,7 +1572,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
// each beam is described by a set of weights (one for each antenna)
// on the other hand in case of analog beamforming an index to the RU beam identifier is provided
config.nb_bfw[0] = num_tx; // number of tx antennas
config.nb_bfw[1] = n / num_tx; // number of beams
config.nb_bfw[1] = n; // number of beams weights/indices
config.bw_list = malloc16_clear(n * sizeof(*config.bw_list));
for (int b = 0; b < n; b++) {
config.bw_list[b] = GNBParamList.paramarray[0][GNB_BEAMWEIGHTS_IDX].iptr[b];
+14 -20
View File
@@ -715,36 +715,30 @@ 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.analog_bf_vendor_ext.tl.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].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++;
}
}
}