Merge remote-tracking branch 'origin/RU_beam_management' into integration_2025_w24 (!3169)
NR RU improvements for analog beamforming
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
|
||||
int nr_phy_init_RU(RU_t *ru)
|
||||
void nr_phy_init_RU(RU_t *ru)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
@@ -47,36 +47,40 @@ int nr_phy_init_RU(RU_t *ru)
|
||||
|
||||
AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
|
||||
|
||||
ru->common.beam_id = malloc16_clear(MAX_NUM_BEAM_PERIODS * sizeof(int*));
|
||||
for(int i = 0; i < MAX_NUM_BEAM_PERIODS; i++)
|
||||
nfapi_nr_analog_beamforming_ve_t *analog_config = &cfg->analog_beamforming_ve;
|
||||
ru->num_beams_period = analog_config->analog_bf_vendor_ext.value ? analog_config->num_beams_period_vendor_ext.value : 1;
|
||||
int nb_tx_streams = ru->nb_tx * ru->num_beams_period;
|
||||
int nb_rx_streams = ru->nb_rx * ru->num_beams_period;
|
||||
LOG_I(NR_PHY, "nb_tx_streams %d, nb_rx_streams %d, num_Beams_period %d\n", nb_tx_streams, nb_rx_streams, ru->num_beams_period);
|
||||
ru->common.beam_id = malloc16_clear(ru->num_beams_period * sizeof(int*));
|
||||
for(int i = 0; i < ru->num_beams_period; i++)
|
||||
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
|
||||
|
||||
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
|
||||
// Time-domain signals
|
||||
ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
ru->common.rxdata = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
ru->common.txdata = (int32_t**)malloc16(nb_tx_streams * sizeof(int32_t*));
|
||||
ru->common.rxdata = (int32_t**)malloc16(nb_rx_streams * sizeof(int32_t*));
|
||||
|
||||
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
for (int i = 0; i < nb_tx_streams; i++) {
|
||||
// Allocate 10 subframes of I/Q TX signal data (time) if not
|
||||
ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t));
|
||||
ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame) * sizeof(int32_t));
|
||||
LOG_D(PHY,
|
||||
"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",
|
||||
i,
|
||||
ru->common.txdata[i],
|
||||
(ru->sf_extension + fp->samples_per_frame) * sizeof(int32_t),
|
||||
ru->sf_extension);
|
||||
ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension];
|
||||
ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension];
|
||||
|
||||
LOG_D(PHY, "[INIT] common.txdata[%d] = %p \n", i, ru->common.txdata[i]);
|
||||
}
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_frame*sizeof(int32_t) );
|
||||
for (int i = 0; i < nb_rx_streams; i++) {
|
||||
ru->common.rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame * sizeof(int32_t));
|
||||
}
|
||||
} // IF5 or local RF
|
||||
else {
|
||||
ru->common.txdata = (int32_t**)NULL;
|
||||
ru->common.rxdata = (int32_t**)NULL;
|
||||
ru->common.txdata = (int32_t**)NULL;
|
||||
ru->common.rxdata = (int32_t**)NULL;
|
||||
}
|
||||
if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
|
||||
LOG_D(PHY, "nb_tx %d\n", ru->nb_tx);
|
||||
@@ -85,7 +89,6 @@ int nr_phy_init_RU(RU_t *ru)
|
||||
ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_subframe*2*sizeof(int32_t) );
|
||||
LOG_D(PHY, "rxdata_7_5kHz[%d] %p for RU %d\n", i, ru->common.rxdata_7_5kHz[i], ru->idx);
|
||||
}
|
||||
|
||||
|
||||
// allocate precoding input buffers (TX)
|
||||
ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
@@ -94,15 +97,15 @@ int nr_phy_init_RU(RU_t *ru)
|
||||
ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
|
||||
// allocate IFFT input buffers (TX)
|
||||
ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
LOG_D(PHY, "[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, ru->nb_tx * sizeof(int32_t *));
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP*sizeof(int32_t) );
|
||||
ru->common.txdataF_BF = (int32_t **)malloc16(nb_tx_streams * sizeof(int32_t*));
|
||||
LOG_D(PHY, "[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, nb_tx_streams * sizeof(int32_t *));
|
||||
for (int i = 0; i < nb_tx_streams; i++) {
|
||||
ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP * sizeof(int32_t));
|
||||
LOG_D(PHY, "txdataF_BF[%d] %p for RU %d\n", i, ru->common.txdataF_BF[i], ru->idx);
|
||||
}
|
||||
// allocate FFT output buffers (RX)
|
||||
ru->common.rxdataF = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
ru->common.rxdataF = (int32_t**)malloc16(nb_rx_streams * sizeof(int32_t*));
|
||||
for (int i = 0; i < nb_rx_streams; i++) {
|
||||
// allocate 4 slots of I/Q signal data (frequency)
|
||||
int size = RU_RX_SLOT_DEPTH * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF) * size);
|
||||
@@ -113,40 +116,38 @@ int nr_phy_init_RU(RU_t *ru)
|
||||
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
|
||||
// "nb_antennas_rx too large");
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
|
||||
ru->prach_rxsigF[j] = (int16_t**)malloc(nb_rx_streams * sizeof(int16_t*));
|
||||
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
for (int i = 0; i < nb_rx_streams; i++) {
|
||||
// largest size for PRACH FFT is 4x98304 (16*24576)
|
||||
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
|
||||
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear(4 * 98304 * 2 * sizeof(int16_t));
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n", i, ru->prach_rxsigF[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(ru->num_gNB <= NUMBER_OF_gNB_MAX,"gNB instances %d > %d\n",
|
||||
ru->num_gNB,NUMBER_OF_gNB_MAX);
|
||||
|
||||
AssertFatal(ru->num_gNB <= NUMBER_OF_gNB_MAX, "gNB instances %d > %d\n", ru->num_gNB,NUMBER_OF_gNB_MAX);
|
||||
|
||||
LOG_D(PHY, "[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
|
||||
|
||||
} // !=IF5
|
||||
|
||||
init_prach_ru_list(ru);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void nr_phy_free_RU(RU_t *ru)
|
||||
{
|
||||
LOG_D(PHY, "Freeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);
|
||||
int nb_tx_streams = ru->nb_tx * ru->num_beams_period;
|
||||
int nb_rx_streams = ru->nb_rx * ru->num_beams_period;
|
||||
|
||||
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
|
||||
// Hack: undo what is done at allocation
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
for (int i = 0; i < nb_tx_streams; i++) {
|
||||
int32_t *p = &ru->common.txdata[i][-ru->sf_extension];
|
||||
free_and_zero(p);
|
||||
}
|
||||
free_and_zero(ru->common.txdata);
|
||||
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
for (int i = 0; i < nb_rx_streams; i++)
|
||||
free_and_zero(ru->common.rxdata[i]);
|
||||
free_and_zero(ru->common.rxdata);
|
||||
} // else: IF5 or local RF -> nothing to free()
|
||||
@@ -162,21 +163,21 @@ void nr_phy_free_RU(RU_t *ru)
|
||||
free_and_zero(ru->common.txdataF);
|
||||
|
||||
// free IFFT input buffers (TX)
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
for (int i = 0; i < nb_tx_streams; i++)
|
||||
free_and_zero(ru->common.txdataF_BF[i]);
|
||||
free_and_zero(ru->common.txdataF_BF);
|
||||
|
||||
// free FFT output buffers (RX)
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
for (int i = 0; i < nb_rx_streams; i++)
|
||||
free_and_zero(ru->common.rxdataF[i]);
|
||||
free_and_zero(ru->common.rxdataF);
|
||||
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
for (int i = 0; i < nb_rx_streams; i++)
|
||||
free_and_zero(ru->prach_rxsigF[j][i]);
|
||||
free_and_zero(ru->prach_rxsigF[j]);
|
||||
}
|
||||
for(int i = 0; i < MAX_NUM_BEAM_PERIODS; ++i)
|
||||
for(int i = 0; i < ru->num_beams_period; ++i)
|
||||
free_and_zero(ru->common.beam_id[i]);
|
||||
free_and_zero(ru->common.beam_id);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,9 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
int dci_idx = 0;
|
||||
// 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,
|
||||
int beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->gNB_config.analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
|
||||
@@ -680,7 +680,9 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
// 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,
|
||||
int beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->gNB_config.analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
|
||||
@@ -42,7 +42,6 @@ void init_prach_list(PHY_VARS_gNB *gNB)
|
||||
for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++){
|
||||
gNB->prach_vars.list[i].frame = -1;
|
||||
gNB->prach_vars.list[i].slot = -1;
|
||||
gNB->prach_vars.list[i].beam_nb = -1;
|
||||
gNB->prach_vars.list[i].num_slots = -1;
|
||||
}
|
||||
}
|
||||
@@ -51,8 +50,8 @@ void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id)
|
||||
{
|
||||
gNB->prach_vars.list[prach_id].frame = -1;
|
||||
gNB->prach_vars.list[prach_id].slot = -1;
|
||||
gNB->prach_vars.list[prach_id].beam_nb = -1;
|
||||
gNB->prach_vars.list[prach_id].num_slots = -1;
|
||||
free_and_zero(gNB->prach_vars.list[prach_id].beam_nb);
|
||||
}
|
||||
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
|
||||
@@ -70,7 +69,7 @@ int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
{
|
||||
int prach_id = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
|
||||
@@ -79,16 +78,25 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p
|
||||
prach->slot = Slot;
|
||||
const int format = prach_pdu->prach_format;
|
||||
prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1;
|
||||
prach->beam_nb = 0;
|
||||
if (gNB->common_vars.beam_id) {
|
||||
int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
// TODO no idea how to compute final prach symbol here so for now we go til the end of the slot
|
||||
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->common_vars, Slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
|
||||
int n_symb = get_nr_prach_duration(prach_pdu->prach_format);
|
||||
prach->beam_nb = calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach->beam_nb));
|
||||
for (int i = 0; i < prach_pdu->beamforming.dig_bf_interface; i++) {
|
||||
int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[i].beam_idx;
|
||||
int start_symb = prach_pdu->prach_start_symbol + i * n_symb;
|
||||
int bitmap = SL_to_bitmap(start_symb, n_symb);
|
||||
prach->beam_nb[i] = beam_index_allocation(gNB->enable_analog_das,
|
||||
fapi_beam_idx,
|
||||
&gNB->gNB_config.analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
Slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
bitmap);
|
||||
}
|
||||
}
|
||||
LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id);
|
||||
memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu));
|
||||
return prach_id;
|
||||
}
|
||||
|
||||
void init_prach_ru_list(RU_t *ru)
|
||||
@@ -121,10 +129,10 @@ int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id)
|
||||
{
|
||||
int prach_id = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
|
||||
AssertFatal((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX),
|
||||
"illegal or no prach_id found!!! prach_id %d\n",
|
||||
prach_id);
|
||||
|
||||
@@ -135,6 +143,7 @@ void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_p
|
||||
ru->prach_list[prach_id].num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1;
|
||||
ru->prach_list[prach_id].fmt = fmt;
|
||||
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
|
||||
ru->prach_list[prach_id].beam = beam_id;
|
||||
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
|
||||
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
@@ -151,6 +160,7 @@ void free_nr_ru_prach_entry(RU_t *ru, int prach_id)
|
||||
void rx_nr_prach_ru(RU_t *ru,
|
||||
int prachFormat,
|
||||
int numRA,
|
||||
int beam,
|
||||
int prachStartSymbol,
|
||||
int prachStartSlot,
|
||||
int prachOccasion,
|
||||
@@ -159,7 +169,6 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
{
|
||||
AssertFatal(ru != NULL,"ru is null\n");
|
||||
|
||||
int16_t **rxsigF = NULL;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int slot2 = slot;
|
||||
int16_t *prach[ru->nb_rx];
|
||||
@@ -191,15 +200,16 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
prachStartSymbol,
|
||||
prachOccasion);
|
||||
|
||||
rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
int16_t **rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
|
||||
AssertFatal(ru->if_south == LOCAL_RF || ru->if_south == REMOTE_IF5,
|
||||
"we shouldn't call this if if_south != LOCAL_RF or REMOTE_IF5\n");
|
||||
|
||||
for (int aa=0; aa<ru->nb_rx; aa++){
|
||||
for (int aa = 0; aa < ru->nb_rx; aa++) {
|
||||
if (prach_sequence_length == 0)
|
||||
slot2 = prachStartSlot;
|
||||
prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset];
|
||||
int idx = aa + beam * ru->nb_rx;
|
||||
prach[aa] = (int16_t*)&ru->common.rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset];
|
||||
}
|
||||
|
||||
int reps;
|
||||
|
||||
@@ -257,14 +257,11 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
|
||||
int slot,
|
||||
nfapi_nr_pusch_pdu_t *ulsch_pdu);
|
||||
|
||||
void nr_fill_prach(PHY_VARS_gNB *gNB,
|
||||
int SFN,
|
||||
int Slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu);
|
||||
int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu);
|
||||
|
||||
void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu,
|
||||
int prachOccasion,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int subframe,
|
||||
uint16_t *max_preamble,
|
||||
@@ -274,16 +271,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
void rx_nr_prach_ru(RU_t *ru,
|
||||
int prach_fmt,
|
||||
int numRA,
|
||||
int beam,
|
||||
int prachStartSymbol,
|
||||
int prachStartSlot,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int subframe);
|
||||
|
||||
void nr_fill_prach_ru(RU_t *ru,
|
||||
int SFN,
|
||||
int Slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu);
|
||||
void nr_fill_prach_ru(RU_t *ru,int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_nb);
|
||||
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type);
|
||||
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type);
|
||||
@@ -309,7 +304,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
void init_prach_list(PHY_VARS_gNB *gNB);
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
|
||||
uint8_t get_nr_prach_duration(uint8_t prach_format);
|
||||
int get_nr_prach_duration(uint8_t prach_format);
|
||||
|
||||
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
|
||||
|
||||
|
||||
@@ -76,7 +76,13 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
|
||||
if (gNB->common_vars.beam_id) {
|
||||
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->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
|
||||
ulsch->beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
fapi_beam_idx,
|
||||
&gNB->gNB_config.analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
bitmap);
|
||||
}
|
||||
ulsch->frame = frame;
|
||||
ulsch->slot = slot;
|
||||
|
||||
@@ -57,10 +57,7 @@
|
||||
|
||||
//#define DEBUG_NR_PUCCH_RX 1
|
||||
|
||||
void nr_fill_pucch(PHY_VARS_gNB *gNB,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu)
|
||||
void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu)
|
||||
{
|
||||
bool found = false;
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
@@ -73,7 +70,13 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB,
|
||||
if (gNB->common_vars.beam_id) {
|
||||
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->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
|
||||
pucch->beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
fapi_beam_idx,
|
||||
&gNB->gNB_config.analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
bitmap);
|
||||
}
|
||||
memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t));
|
||||
LOG_D(PHY,
|
||||
|
||||
@@ -59,7 +59,13 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
|
||||
if (gNB->common_vars.beam_id) {
|
||||
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->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap);
|
||||
srs->beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
fapi_beam_idx,
|
||||
&gNB->gNB_config.analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
bitmap);
|
||||
}
|
||||
memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
|
||||
break;
|
||||
|
||||
@@ -172,6 +172,7 @@ typedef struct RU_prec_t_s{
|
||||
|
||||
typedef struct {
|
||||
int aid;
|
||||
int beam;
|
||||
struct RU_t_s *ru;
|
||||
int startSymbol;
|
||||
int endSymbol;
|
||||
@@ -181,6 +182,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int aid;
|
||||
int beam;
|
||||
struct RU_t_s *ru;
|
||||
int slot;
|
||||
int startSymbol;
|
||||
@@ -196,6 +198,7 @@ typedef struct {
|
||||
int prachStartSymbol;
|
||||
int num_prach_ocas;
|
||||
int num_slots;
|
||||
int *beam;
|
||||
} RU_PRACH_list_t;
|
||||
|
||||
#define NUMBER_OF_NR_RU_PRACH_MAX 8
|
||||
@@ -488,6 +491,8 @@ typedef struct RU_t_s {
|
||||
int nb_rx;
|
||||
/// number of TX paths on device
|
||||
int nb_tx;
|
||||
/// number of concurrent analog beams in period
|
||||
int num_beams_period;
|
||||
/// number of logical antennas at TX beamformer input
|
||||
int nb_log_antennas;
|
||||
/// maximum PDSCH RS EPRE
|
||||
|
||||
@@ -138,9 +138,9 @@ typedef struct {
|
||||
int frame;
|
||||
int slot;
|
||||
// identifier for concurrent beams
|
||||
int beam_nb;
|
||||
// prach duration in slots
|
||||
int num_slots;
|
||||
int *beam_nb;
|
||||
nfapi_nr_prach_pdu_t pdu;
|
||||
} gNB_PRACH_list_t;
|
||||
|
||||
@@ -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;
|
||||
@@ -493,6 +492,8 @@ typedef struct PHY_VARS_gNB_s {
|
||||
int num_ulprbbl;
|
||||
uint16_t ulprbbl [MAX_BWP_SIZE];
|
||||
|
||||
bool enable_analog_das;
|
||||
|
||||
time_stats_t phy_proc_tx;
|
||||
time_stats_t phy_proc_rx;
|
||||
time_stats_t rx_prach;
|
||||
|
||||
@@ -157,9 +157,9 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti
|
||||
UL_tti_req->SFN,
|
||||
UL_tti_req->Slot);
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
|
||||
nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
|
||||
int id = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
|
||||
if (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)
|
||||
nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
|
||||
nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, gNB->prach_vars.list[id].beam_nb);
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
|
||||
LOG_D(NR_PHY,
|
||||
|
||||
@@ -37,62 +37,14 @@
|
||||
#include "nfapi_pnf.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include <time.h>
|
||||
uint8_t get_nr_prach_duration(uint8_t prach_format){
|
||||
|
||||
switch(prach_format){
|
||||
|
||||
case 0: // format 0
|
||||
return 0;
|
||||
|
||||
case 1: // format 1
|
||||
return 0;
|
||||
|
||||
case 2: // format 2
|
||||
return 0;
|
||||
|
||||
case 3: // format 3
|
||||
return 0;
|
||||
|
||||
case 4: // format A1
|
||||
return 2;
|
||||
|
||||
case 5: // format A2
|
||||
return 4;
|
||||
|
||||
case 6: // format A3
|
||||
return 6;
|
||||
|
||||
case 7: // format B1
|
||||
return 2;
|
||||
|
||||
case 8: // format B4
|
||||
return 12;
|
||||
|
||||
case 9: // format C0
|
||||
return 2;
|
||||
|
||||
case 10: // format C2
|
||||
return 6;
|
||||
|
||||
case 11: // format A1/B1
|
||||
return 2;
|
||||
|
||||
case 12: // format A2/B2
|
||||
return 4;
|
||||
|
||||
case 13: // format A3/B3
|
||||
return 6;
|
||||
|
||||
default :
|
||||
AssertFatal(1==0,"Invalid Prach format\n");
|
||||
break;
|
||||
|
||||
}
|
||||
int get_nr_prach_duration(uint8_t prach_format)
|
||||
{
|
||||
const int val[14] = {0, 0, 0, 0, 2, 4, 6, 2, 12, 2, 6, 2, 4, 6};
|
||||
AssertFatal(prach_format < sizeofArray(val), "Invalid Prach format %d\n", prach_format);
|
||||
return val[prach_format];
|
||||
}
|
||||
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rach_indication_t *rach_ind)
|
||||
@@ -117,14 +69,14 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
|
||||
const int prach_start_slot = gNB->prach_vars.list[prach_id].slot;
|
||||
uint8_t prachStartSymbol;
|
||||
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
|
||||
int N_dur = get_nr_prach_duration(prach_pdu->prach_format);
|
||||
|
||||
for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) {
|
||||
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
|
||||
gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa];
|
||||
}
|
||||
|
||||
prachStartSymbol = prach_pdu->prach_start_symbol+prach_oc*N_dur;
|
||||
prachStartSymbol = prach_pdu->prach_start_symbol + prach_oc * N_dur;
|
||||
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
|
||||
|
||||
rx_nr_prach(gNB,
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
// RU OFDM Modulator gNodeB
|
||||
// OFDM modulation core routine, generates a first_symbol to first_symbol+num_symbols on a particular slot and TX antenna port
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa)
|
||||
void nr_feptx0(RU_t *ru, int tti_tx, int first_symbol, int num_symbols, int aa)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
@@ -175,57 +175,39 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
}
|
||||
|
||||
void nr_feptx_prec(RU_t *ru, int frame_tx, int tti_tx)
|
||||
void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
|
||||
{
|
||||
PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
PHY_VARS_gNB **gNB_list = ru->gNB_list;
|
||||
AssertFatal(ru->num_gNB == 1, "Cannot handle more than 1 gNB\n");
|
||||
PHY_VARS_gNB *gNB = gNB_list[0];
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
int slot_tx = tti_tx;
|
||||
int txdataF_offset = (tti_tx*fp->samples_per_slot_wCP);
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int txdataF_offset = slot_tx * fp->samples_per_slot_wCP;
|
||||
start_meas(&ru->precoding_stats);
|
||||
AssertFatal(ru->nb_log_antennas > 0, "ru->nb_log_antennas is 0!\n");
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
|
||||
if (ru->num_gNB == 1) {
|
||||
gNB = gNB_list[0];
|
||||
if (gNB->common_vars.analog_bf) {
|
||||
for (int i = 0; i < ru->num_beams_period; i++) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(void*) &gNB->common_vars.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
if (ru->config.dbt_config.num_dig_beams != 0) {
|
||||
for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(void*) &gNB->common_vars.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || gNB->common_vars.analog_bf) {
|
||||
for (int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
// TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
memcpy(ru->common.txdataF_BF[i], &gNB->common_vars.txdataF[0][i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
// TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
memcpy(ru->common.txdataF[i], &gNB->common_vars.txdataF[0][i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
for (int l = 0; l < fp->symbols_per_slot; l++) {
|
||||
for (int aa = 0; aa < ru->nb_tx; aa++) {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
nr_beam_precoding((c16_t **)ru->common.txdataF,
|
||||
(c16_t **)ru->common.txdataF_BF,
|
||||
fp,
|
||||
ru->beam_weights[0],
|
||||
tti_tx,
|
||||
l,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
0);
|
||||
}
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
for (int b = 0; b < ru->num_beams_period; b++) {
|
||||
for (int i = 0; i < ru->nb_tx; ++i) {
|
||||
int tx_idx = i + b * ru->nb_tx;
|
||||
memcpy((void*)ru->common.txdataF_BF[tx_idx],
|
||||
(void*)&gNB->common_vars.txdataF[b][i][txdataF_offset],
|
||||
fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
}
|
||||
stop_meas(&ru->precoding_stats);
|
||||
}
|
||||
@@ -238,6 +220,7 @@ void nr_feptx(void *arg)
|
||||
RU_t *ru = feptx->ru;
|
||||
int slot = feptx->slot;
|
||||
int aa = feptx->aid;
|
||||
int bb = feptx->beam;
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
@@ -246,44 +229,32 @@ void nr_feptx(void *arg)
|
||||
int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 1);
|
||||
int tx_idx = aa + bb * ru->nb_tx;
|
||||
|
||||
if (aa == 0)
|
||||
if (tx_idx == 0)
|
||||
start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->config.dbt_config.num_dig_beams != 0) {
|
||||
for(int i = 0; i < ru->gNB_list[0]->common_vars.num_beams_period; i++) {
|
||||
memcpy(&ru->common.beam_id[i][slot * fp->symbols_per_slot],
|
||||
&ru->gNB_list[0]->common_vars.beam_id[i][slot * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
if (ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
memcpy(&ru->common.beam_id[bb][slot * fp->symbols_per_slot],
|
||||
&ru->gNB_list[0]->common_vars.beam_id[bb][slot * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf)
|
||||
memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][aa][txdataF_offset], // TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset],
|
||||
numSamples * sizeof(int32_t));
|
||||
else {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
for(int i = 0; i < fp->symbols_per_slot; ++i) {
|
||||
nr_beam_precoding((c16_t **)ru->gNB_list[0]->common_vars.txdataF,
|
||||
(c16_t **)ru->common.txdataF_BF,
|
||||
fp,
|
||||
ru->beam_weights[0],
|
||||
slot,
|
||||
i,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
txdataF_offset);
|
||||
}
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
}
|
||||
|
||||
if (aa==0)
|
||||
if (tx_idx == 0)
|
||||
stop_meas(&ru->precoding_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 0);
|
||||
|
||||
////////////FEPTX////////////
|
||||
nr_feptx0(ru, slot, startSymbol, numSymbols, aa);
|
||||
nr_feptx0(ru, slot, startSymbol, numSymbols, tx_idx);
|
||||
|
||||
// Task completed in //
|
||||
completed_task_ans(feptx->ans);
|
||||
@@ -299,39 +270,42 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1);
|
||||
start_meas(&ru->ofdm_total_stats);
|
||||
|
||||
size_t const sz = ru->nb_tx + (ru->half_slot_parallelization > 0) * ru->nb_tx;
|
||||
int nt = ru->nb_tx * ru->num_beams_period;
|
||||
size_t const sz = nt + (ru->half_slot_parallelization > 0) * nt;
|
||||
feptx_cmd_t arr[sz];
|
||||
task_ans_t ans;
|
||||
init_task_ans(&ans, sz);
|
||||
|
||||
int nbfeptx = 0;
|
||||
for (int aid = 0; aid < ru->nb_tx; aid++) {
|
||||
feptx_cmd_t *feptx_cmd = &arr[nbfeptx];
|
||||
feptx_cmd->ans = &ans;
|
||||
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols =
|
||||
(ru->half_slot_parallelization > 0) ? ru->nr_frame_parms->symbols_per_slot >> 1 : ru->nr_frame_parms->symbols_per_slot;
|
||||
|
||||
task_t t = {.func = nr_feptx, .args = feptx_cmd};
|
||||
pushTpool(ru->threadPool, t);
|
||||
nbfeptx++;
|
||||
if (ru->half_slot_parallelization > 0) {
|
||||
for (int beam = 0; beam < ru->num_beams_period; beam++) {
|
||||
for (int aid = 0; aid < ru->nb_tx; aid++) {
|
||||
feptx_cmd_t *feptx_cmd = &arr[nbfeptx];
|
||||
feptx_cmd->ans = &ans;
|
||||
|
||||
feptx_cmd->beam = beam;
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols =
|
||||
(ru->half_slot_parallelization > 0) ? ru->nr_frame_parms->symbols_per_slot >> 1 : ru->nr_frame_parms->symbols_per_slot;
|
||||
|
||||
task_t t = {.func = nr_feptx, .args = feptx_cmd};
|
||||
pushTpool(ru->threadPool, t);
|
||||
nbfeptx++;
|
||||
if (ru->half_slot_parallelization > 0) {
|
||||
feptx_cmd_t *feptx_cmd = &arr[nbfeptx];
|
||||
feptx_cmd->ans = &ans;
|
||||
feptx_cmd->beam = beam;
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
|
||||
task_t t = {.func = nr_feptx, .args = feptx_cmd};
|
||||
pushTpool(ru->threadPool, t);
|
||||
nbfeptx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
join_task_ans(&ans);
|
||||
@@ -345,24 +319,26 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
|
||||
void nr_fep(void* arg)
|
||||
{
|
||||
feprx_cmd_t *feprx_cmd = (feprx_cmd_t *)arg;
|
||||
RU_t *ru = feprx_cmd->ru;
|
||||
int aid = feprx_cmd->aid;
|
||||
int tti_rx = feprx_cmd->slot;
|
||||
int startSymbol = feprx_cmd->startSymbol;
|
||||
int endSymbol = feprx_cmd->endSymbol;
|
||||
RU_t *ru = feprx_cmd->ru;
|
||||
int aid = feprx_cmd->aid;
|
||||
int beam = feprx_cmd->beam;
|
||||
int slot = feprx_cmd->slot;
|
||||
int startSymbol = feprx_cmd->startSymbol;
|
||||
int endSymbol = feprx_cmd->endSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
LOG_D(PHY,"aid %d, frame %d slot %d, startSymbol %d, endSymbol %d\n", aid, ru->proc.frame_rx, tti_rx, startSymbol, endSymbol);
|
||||
LOG_D(PHY,"aid %d, frame %d slot %d, startSymbol %d, endSymbol %d\n", aid, ru->proc.frame_rx, slot, startSymbol, endSymbol);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1);
|
||||
|
||||
int offset = (tti_rx % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
int idx = aid + beam * ru->nb_rx;
|
||||
int offset = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
for (int l = startSymbol; l <= endSymbol; l++)
|
||||
nr_slot_fep_ul(fp,
|
||||
ru->common.rxdata[aid],
|
||||
&ru->common.rxdataF[aid][offset],
|
||||
ru->common.rxdata[idx],
|
||||
&ru->common.rxdataF[idx][offset],
|
||||
l,
|
||||
tti_rx,
|
||||
slot,
|
||||
ru->N_TA_offset);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 0);
|
||||
|
||||
@@ -377,39 +353,42 @@ void nr_fep_tp(RU_t *ru, int slot) {
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
|
||||
start_meas(&ru->ofdm_demod_stats);
|
||||
|
||||
size_t const sz = ru->nb_rx + (ru->half_slot_parallelization > 0) * ru->nb_rx;
|
||||
int nt = ru->nb_rx * ru->num_beams_period;
|
||||
size_t const sz = nt + (ru->half_slot_parallelization > 0) * nt;
|
||||
feprx_cmd_t arr[sz];
|
||||
task_ans_t ans;
|
||||
init_task_ans(&ans, sz);
|
||||
|
||||
for (int aid=0;aid<ru->nb_rx;aid++) {
|
||||
feprx_cmd_t *feprx_cmd = &arr[nbfeprx];
|
||||
feprx_cmd->ans = &ans;
|
||||
|
||||
feprx_cmd->aid = aid;
|
||||
feprx_cmd->ru = ru;
|
||||
feprx_cmd->slot = ru->proc.tti_rx;
|
||||
feprx_cmd->startSymbol = 0;
|
||||
feprx_cmd->endSymbol = (ru->half_slot_parallelization > 0) ? (ru->nr_frame_parms->symbols_per_slot >> 1) - 1
|
||||
: (ru->nr_frame_parms->symbols_per_slot - 1);
|
||||
|
||||
task_t t = {.func = nr_fep, .args = feprx_cmd};
|
||||
pushTpool(ru->threadPool, t);
|
||||
nbfeprx++;
|
||||
if (ru->half_slot_parallelization > 0) {
|
||||
for (int beam = 0; beam < ru->num_beams_period; beam++) {
|
||||
for (int aid = 0; aid < ru->nb_rx; aid++) {
|
||||
feprx_cmd_t *feprx_cmd = &arr[nbfeprx];
|
||||
feprx_cmd->ans = &ans;
|
||||
|
||||
feprx_cmd->beam = beam;
|
||||
feprx_cmd->aid = aid;
|
||||
feprx_cmd->ru = ru;
|
||||
feprx_cmd->slot = ru->proc.tti_rx;
|
||||
feprx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feprx_cmd->endSymbol = ru->nr_frame_parms->symbols_per_slot - 1;
|
||||
feprx_cmd->startSymbol = 0;
|
||||
feprx_cmd->endSymbol = (ru->half_slot_parallelization > 0) ? (ru->nr_frame_parms->symbols_per_slot >> 1) - 1
|
||||
: (ru->nr_frame_parms->symbols_per_slot - 1);
|
||||
|
||||
task_t t = {.func = nr_fep, .args = feprx_cmd};
|
||||
pushTpool(ru->threadPool, t);
|
||||
|
||||
nbfeprx++;
|
||||
if (ru->half_slot_parallelization > 0) {
|
||||
feprx_cmd_t *feprx_cmd = &arr[nbfeprx];
|
||||
feprx_cmd->ans = &ans;
|
||||
feprx_cmd->beam = beam;
|
||||
feprx_cmd->aid = aid;
|
||||
feprx_cmd->ru = ru;
|
||||
feprx_cmd->slot = ru->proc.tti_rx;
|
||||
feprx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feprx_cmd->endSymbol = ru->nr_frame_parms->symbols_per_slot - 1;
|
||||
|
||||
task_t t = {.func = nr_fep, .args = feprx_cmd};
|
||||
pushTpool(ru->threadPool, t);
|
||||
|
||||
nbfeprx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
join_task_ans(&ans);
|
||||
|
||||
@@ -45,18 +45,26 @@
|
||||
//#define DEBUG_RXDATA
|
||||
//#define SRS_IND_DEBUG
|
||||
|
||||
int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols)
|
||||
int beam_index_allocation(bool das,
|
||||
int fapi_beam_index,
|
||||
nfapi_nr_analog_beamforming_ve_t *analog_bf,
|
||||
NR_gNB_COMMON *common_vars,
|
||||
int slot,
|
||||
int symbols_per_slot,
|
||||
int bitmap_symbols)
|
||||
{
|
||||
if (!common_vars->beam_id)
|
||||
return 0;
|
||||
if (das)
|
||||
return fapi_beam_index;
|
||||
|
||||
int ru_beam_idx = analog_bf->analog_beam_list[fapi_beam_index].value;
|
||||
int idx = -1;
|
||||
for (int j = 0; j < common_vars->num_beams_period; j++) {
|
||||
// L2 analog beam implementation is slot based, so we need to verify occupancy for the whole slot
|
||||
for (int i = 0; i < symbols_per_slot; i++) {
|
||||
if (((bitmap_symbols >> i) & 0x01) == 0)
|
||||
continue;
|
||||
int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i];
|
||||
if (current_beam == -1 || current_beam == fapi_beam_index)
|
||||
if (current_beam == -1 || current_beam == ru_beam_idx)
|
||||
idx = j;
|
||||
else {
|
||||
idx = -1;
|
||||
@@ -66,12 +74,12 @@ int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int s
|
||||
if (idx != -1)
|
||||
break;
|
||||
}
|
||||
AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index);
|
||||
AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", ru_beam_idx);
|
||||
for (int j = 0; j < symbols_per_slot; j++) {
|
||||
if (((bitmap_symbols >> j) & 0x01))
|
||||
common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index;
|
||||
common_vars->beam_id[idx][slot * symbols_per_slot + j] = ru_beam_idx;
|
||||
}
|
||||
LOG_D(PHY, "Allocating beam %d in slot %d\n", idx, slot);
|
||||
LOG_D(PHY, "Allocating beam_id[%d] %d in slot %d\n", idx, ru_beam_idx, slot);
|
||||
return idx;
|
||||
}
|
||||
|
||||
@@ -131,7 +139,9 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n
|
||||
int txdataF_offset = slot * fp->samples_per_slot_wCP;
|
||||
// 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,
|
||||
int beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&cfg->analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
fp->symbols_per_slot,
|
||||
@@ -272,7 +282,9 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
int lprime_num = mapping_parms.lprime + 1;
|
||||
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,
|
||||
int beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&cfg->analog_beamforming_ve,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
fp->symbols_per_slot,
|
||||
|
||||
@@ -44,8 +44,14 @@ void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx);
|
||||
void nr_fep_tp(RU_t *ru, int slot);
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot);
|
||||
void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
|
||||
int nr_phy_init_RU(RU_t *ru);
|
||||
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, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols);
|
||||
int beam_index_allocation(bool das,
|
||||
int fapi_beam_index,
|
||||
nfapi_nr_analog_beamforming_ve_t *analog_bf,
|
||||
NR_gNB_COMMON *common_vars,
|
||||
int slot,
|
||||
int symbols_per_slot,
|
||||
int bitmap_symbols);
|
||||
#endif
|
||||
|
||||
@@ -773,7 +773,7 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, slot, prachOccasion, frame, slot);
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, 0, prachStartSymbol, slot, prachOccasion, frame, slot);
|
||||
|
||||
for (int i = 0; i < ru->nb_rx; ++i)
|
||||
gNB->prach_vars.rxsigF[i] = ru->prach_rxsigF[prachOccasion][i];
|
||||
|
||||
Reference in New Issue
Block a user