From 038247f0743e2a5b86e963470a6fdbc73b09907f Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 11 Dec 2024 16:13:21 +0100 Subject: [PATCH] RU analog beam management (not for 7.2) --- executables/nr-gnb.c | 9 +- executables/nr-ru.c | 17 ++- openair1/PHY/INIT/nr_init_ru.c | 40 +++--- openair1/PHY/NR_TRANSPORT/nr_prach.c | 10 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 8 +- openair1/PHY/defs_RU.h | 5 + openair1/SCHED_NR/fapi_nr_l1.c | 4 +- openair1/SCHED_NR/nr_ru_procedures.c | 123 +++++++++--------- openair1/SIMULATION/NR_PHY/prachsim.c | 2 +- 9 files changed, 115 insertions(+), 103 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 24b835d419..acab30751b 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -360,7 +360,6 @@ void term_gNB_Tpool(int inst) { } /// eNB kept in function name for nffapi calls, TO FIX - void init_eNB_afterRU(void) { for (int inst = 0; inst < RC.nb_nr_L1_inst; inst++) { @@ -371,17 +370,17 @@ void init_eNB_afterRU(void) if (0) AssertFatal(gNB->num_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id); LOG_D(NR_PHY, "Mapping RX ports from %d RUs to gNB %d\n", gNB->num_RU, gNB->Mod_id); - int aa = 0; for (int ru_id = 0; ru_id < gNB->num_RU; ru_id++) { AssertFatal(gNB->RU_list[ru_id]->common.rxdataF != NULL, "RU %d : common.rxdataF is NULL\n", gNB->RU_list[ru_id]->idx); AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF != NULL, "RU %d : prach_rxsigF is NULL\n", gNB->RU_list[ru_id]->idx); - for (int i = 0; i < gNB->RU_list[ru_id]->nb_rx; aa++, i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n", gNB->RU_list[ru_id]->idx, i, aa); gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i]; - // TODO hardcoded beam to 0, still need to understand how to handle this properly - gNB->common_vars.rxdataF[0][aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[i]; + for (int b = 0; b < gNB->RU_list[ru_id]->num_beams_period; b++) { + int idx = i + b * gNB->RU_list[ru_id]->nb_rx; + gNB->common_vars.rxdataF[b][aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[idx]; + } } } /* TODO: review this code, there is something wrong. diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 0ae303b4e8..a8ef32485f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -591,12 +591,13 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; openair0_config_t *cfg = &ru->openair0_cfg; - uint32_t samples_per_slot = fp->get_samples_per_slot(*slot,fp); + uint32_t samples_per_slot = fp->get_samples_per_slot(*slot, fp); AssertFatal(*slot < fp->slots_per_frame && *slot >= 0, "slot %d is illegal (%d)\n", *slot, fp->slots_per_frame); start_meas(&ru->rx_fhaul); - void *rxp[ru->nb_rx]; - for (int i = 0; i < ru->nb_rx; i++) + int nb = ru->nb_rx * ru->num_beams_period; + void *rxp[nb]; + for (int i = 0; i < nb; i++) rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot, fp, 0)]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1); @@ -611,7 +612,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) rxs = samples_per_slot; ts = old_ts + rxs; } else { - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, samples_per_slot, ru->nb_rx); + rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, samples_per_slot, nb); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); @@ -812,8 +813,9 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot); - void *txp[ru->nb_tx]; - for (int i = 0; i < ru->nb_tx; i++) + int nt = ru->nb_tx * ru->num_beams_period; + void *txp[nt]; + for (int i = 0; i < nt; i++) txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot, fp, 0)] - sf_extension * sizeof(int32_t); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp + ru->ts_offset) & 0xffffffff); @@ -823,7 +825,7 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) timestamp + ru->ts_offset - sf_extension, txp, siglen + sf_extension, - ru->nb_tx, + nt, flags); LOG_D(PHY, "[TXPATH] RU %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, " @@ -1321,6 +1323,7 @@ void *ru_thread(void *param) rx_nr_prach_ru(ru, p->fmt, // could also use format p->numRA, + p->beam, prachStartSymbol, p->slot, prach_oc, diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 93964f3ee9..49d3890a0b 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -47,17 +47,21 @@ void 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; + + 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)); LOG_D(PHY, @@ -70,7 +74,7 @@ void nr_phy_init_RU(RU_t *ru) LOG_D(PHY, "[INIT] common.txdata[%d] = %p \n", i, ru->common.txdata[i]); } - for (int i = 0; i < ru->nb_rx; i++) { + 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 @@ -93,15 +97,15 @@ void 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 = (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); @@ -132,16 +136,18 @@ void nr_phy_init_RU(RU_t *ru) 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() @@ -157,12 +163,12 @@ 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); @@ -171,7 +177,7 @@ void nr_phy_free_RU(RU_t *ru) 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); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index b01b35f502..ed90a3e318 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -70,7 +70,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); @@ -94,6 +94,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p } 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) @@ -126,7 +127,7 @@ 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), @@ -140,6 +141,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); @@ -156,6 +158,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, @@ -203,7 +206,8 @@ void rx_nr_prach_ru(RU_t *ru, 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; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index c6d0ed1ef3..ab1c9c2990 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -257,10 +257,7 @@ 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, @@ -274,13 +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_pdum, int beam_id); 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); diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 1417180cb3..95667943a2 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -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 diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 5570b329fd..6b671abcfe 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -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, diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 0dc8c360b0..cf0a1c6ee1 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -238,6 +238,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 +247,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); - } } - 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 +288,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); @@ -347,6 +339,7 @@ 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 beam = feprx_cmd->beam; int slot = feprx_cmd->slot; int startSymbol = feprx_cmd->startSymbol; int endSymbol = feprx_cmd->endSymbol; @@ -356,11 +349,12 @@ void nr_fep(void* arg) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1); + 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, slot, ru->N_TA_offset); @@ -377,39 +371,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;aidnb_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); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index aebfe4997f..a13918a606 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -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];