From 675e1129b42dd863503a8e25656b5411ac5e45c4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 9 Dec 2024 10:25:07 +0100 Subject: [PATCH] using the analog beamforming oai extension fapi fields instead of digital beamforming structure for analog beamforming --- doc/analog_beamforming.md | 2 ++ .../nfapi/public_inc/nfapi_nr_interface_scf.h | 2 ++ openair1/PHY/INIT/nr_init.c | 3 +- openair1/PHY/NR_TRANSPORT/nr_dci.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 2 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 2 +- openair1/PHY/NR_TRANSPORT/srs_rx.c | 2 +- openair1/PHY/defs_gNB.h | 1 - openair1/SCHED_NR/phy_procedures_nr_gNB.c | 8 ++--- openair1/SCHED_NR/sched_nr.h | 2 +- openair2/GNB_APP/gnb_config.c | 2 +- openair2/LAYER2/NR_MAC_gNB/config.c | 34 ++++++++----------- 14 files changed, 31 insertions(+), 35 deletions(-) diff --git a/doc/analog_beamforming.md b/doc/analog_beamforming.md index 6d9e5bf71c..7943111f72 100644 --- a/doc/analog_beamforming.md +++ b/doc/analog_beamforming.md @@ -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) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index a34796eeb3..6ddb376bd3 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -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 diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d94d2ba493..ca453b6e65 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -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)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 899432c37a..38a671d50c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -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, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index ee93f78e45..7e3d68f282 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -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, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index a5e6c86e86..b01b35f502 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -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, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 84656ba1d0..f63bec4d5b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -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, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index c7dacd7104..a16b68f708 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -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, diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 642095345d..16b92be946 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -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, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 59d92444d5..d305197554 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -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; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 19fdd4dca8..ca90965ebc 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -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, diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 72d2d96b4c..7450518f19 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -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, diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 70e6c026ca..4b34c3858d 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -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]; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 43d48eeeeb..59262c50d9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -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++; + } } }