add option to directly send the beam index to L1 via FAPI without look-up table (for 7.2 split)
This commit is contained in:
@@ -17,11 +17,13 @@ Analog beamforming implementation also allows to enable distributed antenna syst
|
||||
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)
|
||||
|
||||
In the `MACRLC` section of configuration files, there are three new parameters: `set_analog_beamforming`, `beam_duration` and `beams_per_period`. The explanation of these parameters is here provided:
|
||||
- `set_analog_beamforming` can be set to 1 or 0 to activate or desactivate analog beamforming (default value is 0)
|
||||
- `set_analog_beamforming` can be set a value equal to 1 or 2 to activate or 0 to desactivate analog beamforming (default value is 0)
|
||||
- `beam_duration` is the number of slots (currently minimum duration of a beam) the scheduler is tied to a beam (default value is 1)
|
||||
- `beams_per_period` is the number of concurrent beams the RU can handle in the beam duration (default value is 1)
|
||||
- `beam_weights` is a vector field containing the set of beam indices to be provided by the OAI L1 to the RU is also required. In current implementation, the number of beam indices should be equal to the number of SSBs transmitted
|
||||
|
||||
Setting analog beamforming to 1 or 2 changes the way FAPI beam index is treated. By setting 1, we instruct L1 to look up in Hi-PHY preconfigured DBM beam index. By setting 2, we instruct L2 to directly signal to Lo-PHY the beam index (e.g. over 7.2x fronthaul).
|
||||
|
||||
DAS is enabled by setting to 1 the parameter `enable_das` in the L1 section of the configuration file. In case of DAS enabled, the field `beam_weights` in `MACRLC` section can be omitted.
|
||||
|
||||
# Implementation in OAI scheduler
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS_F1U, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{CONFIG_STRING_MACRLC_TRANSPORT_S_SHM_PREFIX, NULL, 0, .strptr=NULL, .defstrval="nvipc", TYPE_STRING, 0}, \
|
||||
{CONFIG_STRING_MACRLC_TRANSPORT_S_POLL_CORE, NULL, 0, .i8ptr=NULL, .defintval=-1, TYPE_INT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ANALOG_BEAMFORMING, HLP_MACRLC_AB, PARAMFLAG_BOOL, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ANALOG_BEAMFORMING, HLP_MACRLC_AB, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_BEAM_DURATION, HLP_MACRLC_BEAM_DURATION, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_BEAMS_PERIOD, HLP_MACRLC_BEAMS_PERIOD, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY,0}, \
|
||||
|
||||
@@ -1787,8 +1787,8 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
LOG_I(NR_PHY, "Copying %d blacklisted PRB to L1 context\n", num_ulprbbl);
|
||||
memcpy(RC.nrmac[j]->ulprbbl, prbbl, MAX_BWP_SIZE * sizeof(prbbl[0]));
|
||||
}
|
||||
bool ab = *MacRLC_ParamList.paramarray[j][MACRLC_ANALOG_BEAMFORMING_IDX].u8ptr;
|
||||
if (ab) {
|
||||
int ab = *MacRLC_ParamList.paramarray[j][MACRLC_ANALOG_BEAMFORMING_IDX].u8ptr;
|
||||
if (ab > 0) {
|
||||
AssertFatal(NFAPI_MODE == NFAPI_MONOLITHIC, "Analog beamforming only supported for monolithic scenario\n");
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[j]->beam_info;
|
||||
int beams_per_period = *MacRLC_ParamList.paramarray[j][MACRLC_ANALOG_BEAMS_PERIOD_IDX].u8ptr;
|
||||
@@ -1796,6 +1796,9 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
beam_info->beam_duration = *MacRLC_ParamList.paramarray[j][MACRLC_ANALOG_BEAM_DURATION_IDX].u8ptr;
|
||||
beam_info->beams_per_period = beams_per_period;
|
||||
beam_info->beam_allocation_size = -1; // to be initialized once we have information on frame configuration
|
||||
beam_info->beam_mode = ab == 1 ? PRECONFIGURED_BEAM_IDX : LOPHY_BEAM_IDX;
|
||||
} else {
|
||||
RC.nrmac[j]->beam_info.beam_mode = NO_BEAM_MODE;
|
||||
}
|
||||
// TODO config_isparamset doesn't seem to work for array types, checking numelt instead
|
||||
int n = MacRLC_ParamList.paramarray[j][MACRLC_BEAMWEIGHTS_IDX].numelt;
|
||||
|
||||
@@ -393,9 +393,7 @@ int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed)
|
||||
return ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_period;
|
||||
}
|
||||
|
||||
static void config_common(gNB_MAC_INST *nrmac,
|
||||
const nr_mac_config_t *config,
|
||||
NR_ServingCellConfigCommon_t *scc)
|
||||
static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR_ServingCellConfigCommon_t *scc)
|
||||
{
|
||||
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
|
||||
nrmac->common_channels[0].ServingCellConfigCommon = scc;
|
||||
@@ -713,7 +711,7 @@ static void config_common(gNB_MAC_INST *nrmac,
|
||||
cfg->pmi_list = init_DL_MIMO_codebook(nrmac, pdsch_AntennaPorts);
|
||||
|
||||
int nb_beams = config->nb_bfw[1]; // number of beams
|
||||
if (nrmac->beam_info.beam_allocation) {
|
||||
if (nrmac->beam_info.beam_mode == PRECONFIGURED_BEAM_IDX) {
|
||||
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;
|
||||
@@ -740,7 +738,7 @@ static void config_common(gNB_MAC_INST *nrmac,
|
||||
|
||||
static void initialize_beam_information(NR_beam_info_t *beam_info, int mu, int slots_per_frame)
|
||||
{
|
||||
if (!beam_info->beam_allocation)
|
||||
if (beam_info->beam_mode == NO_BEAM_MODE)
|
||||
return;
|
||||
|
||||
int size = mu == 0 ? slots_per_frame << 1 : slots_per_frame;
|
||||
@@ -817,7 +815,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
||||
nrmac->vrb_map_UL_size = size;
|
||||
|
||||
int num_beams = 1;
|
||||
if(nrmac->beam_info.beam_allocation)
|
||||
if(nrmac->beam_info.beam_mode != NO_BEAM_MODE)
|
||||
num_beams = nrmac->beam_info.beams_per_period;
|
||||
for (int i = 0; i < num_beams; i++) {
|
||||
nrmac->common_channels[0].vrb_map_UL[i] = calloc(size * MAX_BWP_SIZE, sizeof(uint16_t));
|
||||
@@ -834,7 +832,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
||||
LOG_D(NR_MAC, "Configuring common parameters from NR ServingCellConfig\n");
|
||||
|
||||
config_common(nrmac, config, scc);
|
||||
fapi_beam_index_allocation(scc, nrmac);
|
||||
fapi_beam_index_allocation(scc, config, nrmac);
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
|
||||
// nothing to be sent in the other cases
|
||||
|
||||
@@ -108,7 +108,7 @@ static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slo
|
||||
{
|
||||
// for now we use the same logic of UL_tti_req_ahead
|
||||
// reset after 1 frame with the exception of 15kHz
|
||||
if(!beam_info->beam_allocation)
|
||||
if (beam_info->beam_mode == NO_BEAM_MODE)
|
||||
return;
|
||||
// initialization done only once
|
||||
AssertFatal(beam_info->beam_allocation_size >= 0, "Beam information not initialized\n");
|
||||
@@ -179,7 +179,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo
|
||||
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
int num_beams = 1;
|
||||
if(gNB->beam_info.beam_allocation)
|
||||
if(gNB->beam_info.beam_mode != NO_BEAM_MODE)
|
||||
num_beams = gNB->beam_info.beams_per_period;
|
||||
// clear vrb_maps
|
||||
for (int i = 0; i < num_beams; i++)
|
||||
|
||||
@@ -3346,8 +3346,10 @@ int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx)
|
||||
|
||||
// TODO this is a placeholder for a possibly more complex function
|
||||
// for now the fapi beam index is the number of SSBs transmitted before ssb_index i
|
||||
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST *mac)
|
||||
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac)
|
||||
{
|
||||
if (mac->beam_info.beam_mode == NO_BEAM_MODE)
|
||||
return;
|
||||
int len = 0;
|
||||
uint8_t* buf = NULL;
|
||||
switch (scc->ssb_PositionsInBurst->present) {
|
||||
@@ -3366,11 +3368,13 @@ void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST
|
||||
default :
|
||||
AssertFatal(false, "Invalid configuration\n");
|
||||
}
|
||||
int fapi_index = 0;
|
||||
int index = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if ((buf[i / 8] >> (7 - i % 8)) & 0x1)
|
||||
mac->fapi_beam_index[i] = fapi_index++;
|
||||
else
|
||||
if ((buf[i / 8] >> (7 - i % 8)) & 0x1) {
|
||||
int fapi_index = mac->beam_info.beam_mode == LOPHY_BEAM_IDX ? config->bw_list[index] : index;
|
||||
mac->fapi_beam_index[i] = fapi_index;
|
||||
index++;
|
||||
} else
|
||||
mac->fapi_beam_index[i] = -1;
|
||||
}
|
||||
}
|
||||
@@ -3383,7 +3387,7 @@ static inline int get_beam_index(const NR_beam_info_t *beam_info, int frame, int
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame)
|
||||
{
|
||||
// if no beam allocation for analog beamforming we always return beam index 0 (no multiple beams)
|
||||
if (!beam_info->beam_allocation)
|
||||
if (beam_info->beam_mode == NO_BEAM_MODE)
|
||||
return (NR_beam_alloc_t) {.new_beam = false, .idx = 0};
|
||||
|
||||
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
|
||||
@@ -3417,7 +3421,7 @@ void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int beam_
|
||||
void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
||||
{
|
||||
// do not perform beam procedures if there is no beam information
|
||||
if (!mac->beam_info.beam_allocation)
|
||||
if (mac->beam_info.beam_mode == NO_BEAM_MODE)
|
||||
return;
|
||||
RSRP_report_t *rsrp_report = &UE->UE_sched_ctrl.CSI_report.ssb_rsrp_report;
|
||||
// simple beam switching algorithm -> we select beam with highest RSRP from CSI report
|
||||
|
||||
@@ -451,7 +451,7 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options,
|
||||
|
||||
int ul_buffer_index(int frame, int slot, int slots_per_frame, int size);
|
||||
void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
|
||||
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST *mac);
|
||||
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac);
|
||||
int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx);
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame);
|
||||
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame, bool new_beam);
|
||||
|
||||
@@ -787,12 +787,19 @@ typedef struct {
|
||||
uid_allocator_t uid_allocator;
|
||||
} NR_UEs_t;
|
||||
|
||||
typedef enum {
|
||||
NO_BEAM_MODE,
|
||||
PRECONFIGURED_BEAM_IDX,
|
||||
LOPHY_BEAM_IDX,
|
||||
} nr_beam_mode_t;
|
||||
|
||||
typedef struct {
|
||||
/// list of allocated beams per period
|
||||
int **beam_allocation;
|
||||
int beam_duration; // in slots
|
||||
int beams_per_period;
|
||||
int beam_allocation_size;
|
||||
nr_beam_mode_t beam_mode;
|
||||
} NR_beam_info_t;
|
||||
|
||||
#define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++)))
|
||||
|
||||
Reference in New Issue
Block a user