From abc5069a5530274e1eae85fa05f1927dfe2884d0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 23 Aug 2024 16:10:52 +0200 Subject: [PATCH] handling beams in PHY RX channels --- executables/nr-gnb.c | 35 ++-- executables/nr-ru.c | 12 +- openair1/PHY/INIT/nr_init.c | 6 +- .../PHY/NR_ESTIMATION/nr_measurements_gNB.c | 16 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 3 +- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 1 + openair1/PHY/NR_TRANSPORT/nr_prach.c | 180 ++++++++++-------- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 6 +- openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 11 ++ .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 14 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 24 ++- openair1/PHY/NR_TRANSPORT/srs_rx.c | 18 +- openair1/PHY/defs_gNB.h | 14 +- openair1/SCHED_NR/fapi_nr_l1.c | 8 +- openair1/SCHED_NR/nr_ru_procedures.c | 3 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 62 +++--- openair1/SCHED_NR/sched_nr.h | 1 + openair1/SIMULATION/NR_PHY/pucchsim.c | 18 +- openair1/SIMULATION/NR_PHY/ulsim.c | 14 +- 19 files changed, 256 insertions(+), 190 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 0e9b85eed9..c1229a07e3 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -128,7 +128,7 @@ static void tx_func(processingData_L1tx_t *info) // At this point, MAC scheduler just ran, including scheduling // PRACH/PUCCH/PUSCH, so trigger RX chain processing - LOG_D(NR_PHY, "%s() trigger RX for %d.%d\n", __func__, frame_rx, slot_rx); + LOG_D(NR_PHY, "Trigger RX for %d.%d\n", frame_rx, slot_rx); notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, NULL); processingData_L1_t *syncMsg = NotifiedFifoData(res); syncMsg->gNB = gNB; @@ -229,15 +229,17 @@ static void rx_func(processingData_L1_t *info) if (gNB->phase_comp) { //apply the rx signal rotation here int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; - for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { - apply_nr_rotation_RX(&gNB->frame_parms, - gNB->common_vars.rxdataF[aa], - gNB->frame_parms.symbol_rotation[1], - slot_rx, - gNB->frame_parms.N_RB_UL, - soffset, - 0, - gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); + for (int bb = 0; bb < gNB->common_vars.num_beams_period; bb++) { + for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { + apply_nr_rotation_RX(&gNB->frame_parms, + gNB->common_vars.rxdataF[bb][aa], + gNB->frame_parms.symbol_rotation[1], + slot_rx, + gNB->frame_parms.N_RB_UL, + soffset, + 0, + gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); + } } } phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); @@ -417,17 +419,14 @@ void init_eNB_afterRU(void) { LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU); for (ru_id=0,aa=0; ru_idnum_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); + 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 (i=0; iRU_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]; - gNB->common_vars.rxdataF[aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[i]; + 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]; } } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index de2b14be80..0a7e28431f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1106,7 +1106,8 @@ void ru_tx_func(void *param) LOG_D(PHY,"rt_prof_idx %d : RU_TX time %d\n",rt_prof_idx,(int)(1e9 * (t1->tv_sec - t0->tv_sec) + (t1->tv_nsec-t0->tv_nsec))); } -void *ru_thread( void *param ) { +void *ru_thread(void *param) +{ static int ru_thread_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; @@ -1339,11 +1340,11 @@ void *ru_thread( void *param ) { // Do PRACH RU processing int prach_id = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); - if (prach_id>=0) { + if (prach_id >= 0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0), - T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2)); + T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2)); int N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt); for (int prach_oc = 0; prach_ocprach_list[prach_id].num_prach_ocas; prach_oc++) { @@ -1354,11 +1355,12 @@ void *ru_thread( void *param ) { ru->prach_list[prach_id].numRA, prachStartSymbol, prach_oc, - proc->frame_rx,proc->tti_rx); + proc->frame_rx, + proc->tti_rx); } clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx]); free_nr_ru_prach_entry(ru,prach_id); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0); } // end if (prach_id > 0) } // end if (ru->feprx) else { diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index ed3a86295b..309f444f82 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -181,7 +181,9 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) /* Do NOT allocate per-antenna rxdataF: the gNB gets a pointer to the * RU to copy/recover freq-domain memory from there */ - common_vars->rxdataF = (c16_t **)malloc16(Prx * sizeof(c16_t*)); + common_vars->rxdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**)); + 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) { @@ -276,6 +278,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) /* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the * RU's txdataF/rxdataF, and the RU will free that */ + for (int j = 0; j < common_vars->num_beams_period; j++) + free_and_zero(common_vars->rxdataF[j]); free_and_zero(common_vars->txdataF); free_and_zero(common_vars->rxdataF); free_and_zero(common_vars->beam_id); diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index e36471c25d..c55be480d7 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -119,7 +119,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_COMMON *common_vars = &gNB->common_vars; PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements; - int rb, nb_symb[275]={0}; + int nb_symb[275]={0}; allocCast2D(n0_subband_power, unsigned int, @@ -135,20 +135,20 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy frame_parms->N_RB_UL, false); - for (int s=first_symb;s<(first_symb+num_symb);s++) { + // TODO modify the measurements to take into account concurrent beams + for (int s = first_symb; s < first_symb + num_symb; s++) { int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; - for (rb=0; rbN_RB_UL; rb++) { + for (int rb = 0; rb < frame_parms->N_RB_UL; rb++) { if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe !(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT int offset = offset0 + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; nb_symb[rb]++; - for (int aarx=0; aarxnb_antennas_rx; aarx++) { - c16_t *ul_ch = &common_vars->rxdataF[aarx][offset]; + for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + c16_t *ul_ch = &common_vars->rxdataF[0][aarx][offset]; int32_t signal_energy; - if (((frame_parms->N_RB_UL&1) == 1) && - (rb==(frame_parms->N_RB_UL>>1))) { + if (((frame_parms->N_RB_UL & 1) == 1) && (rb == (frame_parms->N_RB_UL >> 1))) { signal_energy = signal_energy_nodc(ul_ch, 6); - ul_ch = &common_vars->rxdataF[aarx][offset0]; + ul_ch = &common_vars->rxdataF[0][aarx][offset0]; signal_energy += signal_energy_nodc(ul_ch, 6); } else { signal_energy = signal_energy_nodc(ul_ch, 12); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 7a46cd1b20..0226cadf84 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -71,6 +71,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned short p, unsigned char symbol, int ul_id, + int beam_nb, unsigned short bwp_start_subcarrier, nfapi_nr_pusch_pdu_t *pusch_pdu, int *max_ch, @@ -153,7 +154,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, memset(delay, 0, sizeof(*delay)); for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[aarx][symbol_offset + slot_offset]; + c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[beam_nb][aarx][symbol_offset + slot_offset]; c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][symbol_offset]; memset(ul_ch, 0, sizeof(*ul_ch) * symbolSize); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index e1e905c3fa..9f340d84d6 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -47,6 +47,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned short p, unsigned char symbol, int ul_id, + int beam_nb, unsigned short bwp_start_subcarrier, nfapi_nr_pusch_pdu_t *pusch_pdu, int *max_ch, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 40c358477f..a043d93500 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -31,23 +31,26 @@ */ #include "PHY/defs_gNB.h" +#include "SCHED_NR/sched_nr.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "openair1/PHY/NR_TRANSPORT/nr_prach.h" void init_prach_list(PHY_VARS_gNB *gNB) { - AssertFatal(gNB!=NULL,"gNB is null\n"); - for (int i=0; iprach_vars.list[i].frame = -1; - gNB->prach_vars.list[i].slot = -1; + gNB->prach_vars.list[i].slot = -1; + gNB->prach_vars.list[i].beam_nb = -1; } } 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].slot = -1; + gNB->prach_vars.list[prach_id].beam_nb = -1; } int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) { @@ -70,47 +73,54 @@ 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) +void 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); + 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); - - gNB->prach_vars.list[prach_id].frame=SFN; - gNB->prach_vars.list[prach_id].slot=Slot; - LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n",(int)sizeof(*prach_pdu),prach_id); - memcpy((void*)&gNB->prach_vars.list[prach_id].pdu,(void*)prach_pdu,sizeof(*prach_pdu)); - + gNB_PRACH_list_t *prach = &gNB->prach_vars.list[prach_id]; + prach->frame = SFN; + prach->slot = Slot; + 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; + prach->beam_nb = beam_index_allocation(fapi_beam_idx, + &gNB->common_vars, + Slot, + NR_NUMBER_OF_SYMBOLS_PER_SLOT, + prach_pdu->prach_start_symbol, + temp_nb_symbols); + } + 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)); } -void init_prach_ru_list(RU_t *ru) { - - AssertFatal(ru!=NULL,"ruis null\n"); - for (int i=0; iprach_list[i].frame = -1; - ru->prach_list[i].slot = -1; - } - pthread_mutex_init(&ru->prach_list_mutex,NULL); +void init_prach_ru_list(RU_t *ru) +{ + AssertFatal(ru != NULL, "ru is null\n"); + for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) { + ru->prach_list[i].frame = -1; + ru->prach_list[i].slot = -1; + } + pthread_mutex_init(&ru->prach_list_mutex, NULL); } -int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) { - - AssertFatal(ru!=NULL,"ru is null\n"); +int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) +{ + AssertFatal(ru != NULL, "ru is null\n"); pthread_mutex_lock(&ru->prach_list_mutex); - for (uint16_t i=0; i %d.%d\n", frame,slot,i, + for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) { + LOG_D(PHY,"searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", + frame, + slot, + i, ru->prach_list[i].frame,ru->prach_list[i].slot); - if((type == SEARCH_EXIST_OR_FREE) && - (ru->prach_list[i].frame == -1) && - (ru->prach_list[i].slot == -1)) { - pthread_mutex_unlock(&ru->prach_list_mutex); - return i; + if((type == SEARCH_EXIST_OR_FREE) && (ru->prach_list[i].frame == -1) && (ru->prach_list[i].slot == -1)) { + pthread_mutex_unlock(&ru->prach_list_mutex); + return i; } - else if ((type == SEARCH_EXIST) && - (ru->prach_list[i].frame == frame) && - (ru->prach_list[i].slot == slot)) { + else if ((type == SEARCH_EXIST) && (ru->prach_list[i].frame == frame) && (ru->prach_list[i].slot == slot)) { pthread_mutex_unlock(&ru->prach_list_mutex); return i; } @@ -119,55 +129,42 @@ 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) { - - int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE); - AssertFatal( ((prach_id>=0) && (prach_id= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0), + "illegal or no prach_id found!!! prach_id %d\n", + prach_id); pthread_mutex_lock(&ru->prach_list_mutex); - ru->prach_list[prach_id].frame = SFN; - ru->prach_list[prach_id].slot = Slot; - ru->prach_list[prach_id].fmt = prach_pdu->prach_format; - ru->prach_list[prach_id].numRA = prach_pdu->num_ra; - 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); - + ru->prach_list[prach_id].frame = SFN; + ru->prach_list[prach_id].slot = Slot; + ru->prach_list[prach_id].fmt = prach_pdu->prach_format; + ru->prach_list[prach_id].numRA = prach_pdu->num_ra; + 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); } -void free_nr_ru_prach_entry(RU_t *ru, - int prach_id) { - +void free_nr_ru_prach_entry(RU_t *ru, int prach_id) +{ pthread_mutex_lock(&ru->prach_list_mutex); ru->prach_list[prach_id].frame = -1; - ru->prach_list[prach_id].slot = -1; + ru->prach_list[prach_id].slot = -1; pthread_mutex_unlock(&ru->prach_list_mutex); - } -void rx_nr_prach_ru(RU_t *ru, - int prachFormat, - int numRA, - int prachStartSymbol, - int prachOccasion, - int frame, - int slot) { - - AssertFatal(ru!=NULL,"ru is null\n"); - - int16_t **rxsigF=NULL; - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - int slot2=slot; +void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol, int prachOccasion, int frame, int slot) +{ + 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]; int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value; - - int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; + int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; int sample_offset_slot; if (prachStartSymbol == 0) { @@ -184,16 +181,24 @@ void rx_nr_prach_ru(RU_t *ru, sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; } - LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion); + LOG_D(PHY, + "frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n", + frame, + slot, + prachFormat, + numRA, + prachStartSymbol, + prachOccasion); - rxsigF = ru->prach_rxsigF[prachOccasion]; + 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; aanb_rx; aa++){ - if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe; - prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2,fp,0)+sample_offset_slot-ru->N_TA_offset]; + if (prach_sequence_length == 0) + slot2 = (slot / fp->slots_per_subframe) * fp->slots_per_subframe; + prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset]; } int reps; @@ -202,8 +207,13 @@ void rx_nr_prach_ru(RU_t *ru, int mu = fp->numerology_index; if (prach_sequence_length == 0) { - LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n", - ru->idx,frame,slot2,prachFormat,msg1_frequencystart); + LOG_D(PHY, + "PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n", + ru->idx, + frame, + slot2, + prachFormat, + msg1_frequencystart); switch (prachFormat) { case 0: reps = 1; @@ -235,8 +245,14 @@ void rx_nr_prach_ru(RU_t *ru, } } else { - LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n", - ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol); + LOG_D(PHY, + "PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n", + ru->idx, + frame, + slot, + prachfmt[prachFormat], + msg1_frequencystart, + prachStartSymbol); switch (prachFormat) { case 4: //A1 reps = 2; @@ -293,7 +309,9 @@ void rx_nr_prach_ru(RU_t *ru, dftlen = 2048 >> mu; } - //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary + //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. + //I am not quite sure for which paramter set this would be the case, + //so I will ignore it for now and just check if the prach starts on a 0.5ms boundary if(fp->numerology_index == 0) { if (prachStartSymbol == 0 || prachStartSymbol == 7) Ncp += 16; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index a086c347ef..397c0adf98 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -127,7 +127,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, uint8_t ulsch_id, uint32_t frame, uint8_t slot, - unsigned char harq_pid); + unsigned char harq_pid, + int beam_nb); /*! \brief This function implements the idft transform precoding in PUSCH @@ -297,6 +298,7 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, nfapi_nr_srs_pdu_t *srs_pdu); int nr_get_srs_signal(PHY_VARS_gNB *gNB, + c16_t **rxdataF, frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, @@ -326,12 +328,14 @@ void nr_decode_pucch1(c16_t **rxdataF, uint8_t nr_bit); void nr_decode_pucch2(PHY_VARS_gNB *gNB, + c16_t **rxdataF, int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); void nr_decode_pucch0(PHY_VARS_gNB *gNB, + c16_t **rxdataF, int frame, int slot, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 2d98662813..47a0afc625 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -33,6 +33,7 @@ #include #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" +#include "SCHED_NR/sched_nr.h" static NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid) { @@ -71,6 +72,16 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t ulsch->harq_pid = harq_pid; ulsch->handled = 0; ulsch->active = true; + ulsch->beam_nb = 0; + if (gNB->common_vars.beam_id) { + int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; + ulsch->beam_nb = beam_index_allocation(fapi_beam_idx, + &gNB->common_vars, + slot, + NR_NUMBER_OF_SYMBOLS_PER_SLOT, + ulsch_pdu->start_symbol_index, + ulsch_pdu->nr_of_symbols); + } ulsch->frame = frame; ulsch->slot = slot; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index af675e5d49..e29e3e7b51 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1394,6 +1394,7 @@ typedef struct puschSymbolProc_s { int16_t **llr_layers; int16_t *scramblingSequence; uint32_t nvar; + int beam_nb; } puschSymbolProc_t; static void nr_pusch_symbol_processing(void *arg) @@ -1416,7 +1417,7 @@ static void nr_pusch_symbol_processing(void *arg) frame_parms, pusch_vars, rel15_ul, - gNB->common_vars.rxdataF, + gNB->common_vars.rxdataF[rdata->beam_nb], (c16_t**)gNB->pusch_vars[ulsch_id].ul_ch_estimates, rdata->llr_layers, soffset, @@ -1471,7 +1472,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, uint8_t ulsch_id, uint32_t frame, uint8_t slot, - unsigned char harq_pid) + unsigned char harq_pid, + int beam_nb) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id].harq_process->ulsch_pdu; @@ -1503,6 +1505,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, get_dmrs_port(nl, rel15_ul->dmrs_ports), symbol, ulsch_id, + beam_nb, bwp_start_subcarrier, rel15_ul, &max_ch, @@ -1535,10 +1538,10 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, for (int s = rel15_ul->start_symbol_index; s < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); s++) { int offset0 = ((slot & 3) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size; - c16_t *ul_ch = &gNB->common_vars.rxdataF[aarx][offset]; + c16_t *ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset]; if (end_sc < start_sc) { int64_t symb_energy_aux = signal_energy_nodc(ul_ch, middle_sc - start_sc) * (middle_sc - start_sc); - ul_ch = &gNB->common_vars.rxdataF[aarx][offset0]; + ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset0]; symb_energy_aux += (signal_energy_nodc(ul_ch, end_sc + 1) * (end_sc + 1)); symb_energy += symb_energy_aux / (rel15_ul->rb_size * NR_NB_SC_PER_RB); } else { @@ -1644,7 +1647,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, c16_t temp_rxFext[frame_parms->nb_antennas_rx][buffer_length] __attribute__((aligned(32))); for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++) - nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[aarx], + nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[beam_nb][aarx], (c16_t *)pusch_vars->ul_ch_estimates[nl * frame_parms->nb_antennas_rx + aarx], temp_rxFext[aarx], (c16_t*)&ul_ch_estimates_ext[nl * frame_parms->nb_antennas_rx + aarx][meas_symbol * nb_re_pusch], @@ -1723,6 +1726,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, rdata->llr_layers = pusch_vars->llr_layers; rdata->scramblingSequence = scramblingSequence; rdata->nvar = nvar; + rdata->beam_nb = beam_nb; if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { nr_pusch_symbol_processing(rdata); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index d4cf436c76..cda49b83d8 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -42,7 +42,7 @@ #include "PHY/defs_gNB.h" #include "PHY/sse_intrin.h" #include "PHY/NR_UE_TRANSPORT/pucch_nr.h" -#include +#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" @@ -50,6 +50,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "SCHED_NR/sched_nr.h" #include "T.h" @@ -62,15 +63,25 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, { if (NFAPI_MODE == NFAPI_MODE_PNF) - gNB->pucch[0].active = 0; // check if ture in monolithic mode + gNB->pucch[0].active = false; // check if true in monolithic mode bool found = false; for (int i = 0; i < gNB->max_nb_pucch; i++) { NR_gNB_PUCCH_t *pucch = &gNB->pucch[i]; - if (pucch->active == 0) { + if (pucch->active == false) { pucch->frame = frame; pucch->slot = slot; - pucch->active = 1; + pucch->active = true; + pucch->beam_nb = 0; + if (gNB->common_vars.beam_id) { + int fapi_beam_idx = pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; + pucch->beam_nb = beam_index_allocation(fapi_beam_idx, + &gNB->common_vars, + slot, + NR_NUMBER_OF_SYMBOLS_PER_SLOT, + pucch_pdu->start_symbol_index, + pucch_pdu->nr_of_symbols); + } memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t)); LOG_D(PHY, "Programming PUCCH[%d] for %d.%d, format %d, nb_harq %d, nb_sr %d, nb_csi %d\n", @@ -148,12 +159,12 @@ static const int16_t idft12_im[12][12] = { }; //************************************************************************// void nr_decode_pucch0(PHY_VARS_gNB *gNB, + c16_t **rxdataF, int frame, int slot, nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu, nfapi_nr_pucch_pdu_t *pucch_pdu) { - c16_t **rxdataF = gNB->common_vars.rxdataF; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; @@ -1012,13 +1023,12 @@ void init_pucch2_luts() { void nr_decode_pucch2(PHY_VARS_gNB *gNB, + c16_t **rxdataF, int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu) { - - c16_t **rxdataF = gNB->common_vars.rxdataF; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; //pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 037528b407..931bfe21e7 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -38,7 +38,7 @@ #include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" #include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h" #include "common/utils/LOG/log.h" - +#include "SCHED_NR/sched_nr.h" #include "nfapi/oai_integration/vendor_ext.h" #include "T.h" @@ -50,11 +50,21 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu bool found = false; for (int i = 0; i < gNB->max_nb_srs; i++) { NR_gNB_SRS_t *srs = &gNB->srs[i]; - if (srs->active == 0) { + if (srs->active == false) { found = true; srs->frame = frame; srs->slot = slot; - srs->active = 1; + srs->active = true; + srs->beam_nb = 0; + if (gNB->common_vars.beam_id) { + 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, + srs_pdu->time_start_position, + 1 << srs_pdu->num_symbols); + } memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t)); break; } @@ -63,13 +73,13 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu } int nr_get_srs_signal(PHY_VARS_gNB *gNB, + c16_t **rxdataF, frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]) { - c16_t **rxdataF = gNB->common_vars.rxdataF; const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 6540177c63..4e059373f9 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -137,6 +137,8 @@ typedef struct { typedef struct { int frame; int slot; + // identifier for concurrent beams + int beam_nb; nfapi_nr_prach_pdu_t pdu; } gNB_PRACH_list_t; @@ -221,6 +223,8 @@ typedef struct { typedef struct { uint32_t frame; uint32_t slot; + // identifier for concurrent beams + int beam_nb; uint32_t unav_res; /// Pointers to 16 HARQ processes for the ULSCH NR_UL_gNB_HARQ_t *harq_process; @@ -241,7 +245,9 @@ typedef struct { } NR_gNB_ULSCH_t; typedef struct { - uint8_t active; + bool active; + // identifier for concurrent beams + int beam_nb; /// Frame where current PUCCH pdu was sent uint32_t frame; /// Slot where current PUCCH pdu was sent @@ -251,7 +257,9 @@ typedef struct { } NR_gNB_PUCCH_t; typedef struct { - uint8_t active; + bool active; + // identifier for concurrent beams + int beam_nb; /// Frame where current SRS pdu was received uint32_t frame; /// Slot where current SRS pdu was received @@ -264,7 +272,7 @@ typedef struct { /// \brief Pointers (dynamic) to the received data in the frequency domain. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ - c16_t **rxdataF; + c16_t ***rxdataF; /// \brief holds the transmit data in the frequency domain. /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? /// - first index: beam (for concurrent beams) diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index f990d6c157..06747c9a2e 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -157,7 +157,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus; uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs; - if (NFAPI_MODE == NFAPI_MONOLITHIC){ + clear_slot_beamid(gNB, slot); // reset beam_id information for the slot to be processed + + if (NFAPI_MODE == NFAPI_MONOLITHIC) { if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) { processingData_L1tx_t *msgTx = gNB->msgDataTx; msgTx->num_pdsch_slot = 0; @@ -227,8 +229,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, 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); - 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); + 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); break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 984f493e11..475bbed493 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -339,7 +339,6 @@ 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; @@ -347,7 +346,7 @@ void nr_fep(void* arg) int endSymbol = feprx_cmd->endSymbol; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - LOG_D(PHY,"In nr_fep for aid %d, slot = %d, startSymbol %d, endSymbol %d\n", aid, tti_rx,startSymbol,endSymbol); + LOG_D(PHY,"aid %d, frame %d slot %d, startSymbol %d, endSymbol %d\n", aid, ru->proc.frame_rx, tti_rx, startSymbol, endSymbol); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 92e2ab34ad..9dd8c43fc2 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -170,6 +170,16 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n fp); } +// clearing beam information to be provided to RU for all slots (DL and UL) +void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot) +{ + LOG_D(PHY, "Clearing beam_id structure for slot %d\n", slot); + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + for (int i = 0; i < gNB->common_vars.num_beams_period; i++) { + if (gNB->common_vars.beam_id) + memset(&gNB->common_vars.beam_id[i][slot * fp->symbols_per_slot], -1, fp->symbols_per_slot * sizeof(int)); + } +} void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame, @@ -190,8 +200,6 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, // clear the transmit data array and beam index for the current slot for (int i = 0; i < gNB->common_vars.num_beams_period; i++) { - if (gNB->common_vars.beam_id) - memset(&gNB->common_vars.beam_id[i][slot * fp->symbols_per_slot], -1, fp->symbols_per_slot * sizeof(int)); for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { memset(&gNB->common_vars.txdataF[i][aa][txdataF_offset], 0, fp->samples_per_slot_wCP * sizeof(int32_t)); } @@ -366,7 +374,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) { int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0; - LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot%RU_RX_SLOT_DEPTH)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1); + LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][0][(ulsch_harq->slot%RU_RX_SLOT_DEPTH)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1); LOG_M("rxsigF0_ext.m","rxsF0_ext", &gNB->pusch_vars[0].rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB * @@ -755,13 +763,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB_I0_measurements(gNB, slot_rx, first_symb, num_symb, rb_mask_ul); const int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; - int offset = 10 * gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; - LOG_D(PHY, - "frame %d, slot %d: UL signal energy %d\n", - frame_rx, - slot_rx, - signal_energy_nodc(&gNB->common_vars.rxdataF[0][soffset + offset + (47 * 12)], 12 * 18)); - start_meas(&gNB->phy_proc_rx); for (int i = 0; i < gNB->max_nb_pucch; i++) { @@ -769,13 +770,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) if (pucch) { if (NFAPI_MODE == NFAPI_MODE_PNF) pucch->frame = frame_rx; - if ((pucch->active == 1) && - (pucch->frame == frame_rx) && - (pucch->slot == slot_rx) ) { - + if (pucch->active && (pucch->frame == frame_rx) && (pucch->slot == slot_rx)) { + c16_t **rxdataF = gNB->common_vars.rxdataF[pucch->beam_nb]; pucch_decode_done = 1; - - nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; + nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; uint16_t num_ucis; switch (pucch_pdu->format_type) { case 0: @@ -787,21 +785,17 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1; - offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12); + int offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12); LOG_D(PHY, "frame %d, slot %d: PUCCH signal energy %d\n", frame_rx, slot_rx, - signal_energy_nodc(&gNB->common_vars.rxdataF[0][soffset + offset], 12)); + signal_energy_nodc(&rxdataF[0][soffset + offset], 12)); - nr_decode_pucch0(gNB, - frame_rx, - slot_rx, - uci_pdu_format0, - pucch_pdu); + nr_decode_pucch0(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format0, pucch_pdu); gNB->UL_INFO.uci_ind.num_ucis += 1; - pucch->active = 0; + pucch->active = false; break; case 2: num_ucis = gNB->UL_INFO.uci_ind.num_ucis; @@ -813,14 +807,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_2_3_4; LOG_D(PHY, "%d.%d Calling nr_decode_pucch2\n", frame_rx, slot_rx); - nr_decode_pucch2(gNB, - frame_rx, - slot_rx, - uci_pdu_format2, - pucch_pdu); + nr_decode_pucch2(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format2, pucch_pdu); gNB->UL_INFO.uci_ind.num_ucis += 1; - pucch->active = 0; + pucch->active = false; break; default: AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n"); @@ -879,7 +869,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH, 1); start_meas(&gNB->rx_pusch_stats); - nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid); + nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid, ulsch->beam_nb); NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id]; pusch_vars->ulsch_power_tot = 0; pusch_vars->ulsch_noise_power_tot = 0; @@ -950,7 +940,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) for (int i = 0; i < gNB->max_nb_srs; i++) { NR_gNB_SRS_t *srs = &gNB->srs[i]; if (srs) { - if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) { + if ((srs->active == true) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) { LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i); start_meas(&gNB->rx_srs_stats); @@ -970,9 +960,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); } stop_meas(&gNB->generate_srs_stats); - + c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb]; start_meas(&gNB->get_srs_signal_stats); - int srs_est = nr_get_srs_signal(gNB, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); + int srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); stop_meas(&gNB->get_srs_signal_stats); if (srs_est >= 0) { @@ -1158,7 +1148,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) #endif gNB->UL_INFO.srs_ind.number_of_pdus += 1; - srs->active = 0; + srs->active = false; stop_meas(&gNB->rx_srs_stats); } @@ -1168,7 +1158,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) stop_meas(&gNB->phy_proc_rx); if (pucch_decode_done || pusch_decode_done) { - T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4)); + T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 8220f2627d..6cde0e8614 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -46,6 +46,7 @@ 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_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, diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 8faaba90ab..7d1ded5d2e 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -436,7 +436,7 @@ int main(int argc, char **argv) /* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU, * so we need to allocate that memory as well. */ for (i = 0; i < n_rx; i++) - gNB->common_vars.rxdataF[i] = malloc16_clear(gNB->frame_parms.samples_per_frame_wCP*sizeof(c16_t)); + gNB->common_vars.rxdataF[0][i] = malloc16_clear(gNB->frame_parms.samples_per_frame_wCP * sizeof(c16_t)); double fs,txbw,rxbw; uint32_t samples; @@ -540,9 +540,10 @@ int main(int argc, char **argv) pucch_GroupHopping_t PUCCH_GroupHopping = pucch_tx_pdu.group_hop_flag + (pucch_tx_pdu.sequence_hop_flag<<1); double tx_level_fp = 100.0; - for(SNR=snr0;SNR<=snr1;SNR+=1){ + c16_t **rxdataF = gNB->common_vars.rxdataF[0]; + for(SNR = snr0; SNR <= snr1; SNR += 1) { ack_nack_errors=0; - sr_errors=0; + sr_errors = 0; n_errors = 0; c16_t **txdataF = gNB->common_vars.txdataF[0]; for (trial=0; trialofdm_symbol_size,sigma2,sigma2_dB); - c16_t **rxdataF = gNB->common_vars.rxdataF; for (int symb=0; symbframe_parms.symbols_per_slot;symb++) { if (symb= startingSymbolIndex+nrofSymbols) { int i0 = symb*gNB->frame_parms.ofdm_symbol_size; @@ -668,7 +668,7 @@ int main(int argc, char **argv) } else pucch_pdu.freq_hop_flag = 0; - nr_decode_pucch0(gNB, nr_frame_tx, nr_slot_tx,&uci_pdu,&pucch_pdu); + nr_decode_pucch0(gNB, rxdataF, nr_frame_tx, nr_slot_tx,&uci_pdu,&pucch_pdu); if(sr_flag==1){ if (uci_pdu.sr.sr_indication == 0 || uci_pdu.sr.sr_confidence_level == 1) sr_errors+=1; @@ -721,7 +721,7 @@ int main(int argc, char **argv) pucch_pdu.second_hop_prb = N_RB_DL-1; } else pucch_pdu.freq_hop_flag = 0; - nr_decode_pucch2(gNB,nr_frame_tx,nr_slot_tx,&uci_pdu,&pucch_pdu); + nr_decode_pucch2(gNB, rxdataF, nr_frame_tx, nr_slot_tx, &uci_pdu, &pucch_pdu); int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; for (int i=0;igNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); - for (i = 0; i < n_rx; i++) - free(gNB->common_vars.rxdataF[i]); + for (int j = 0; j < gNB->common_vars.num_beams_period; j++) { + for (i = 0; i < n_rx; i++) + free(gNB->common_vars.rxdataF[j][i]); + } phy_free_nr_gNB(gNB); free(RC.gNB[0]); free(RC.gNB); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b4a44f4130..f861c4831b 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -656,7 +656,7 @@ int main(int argc, char *argv[]) /* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU, * so we need to allocate that memory as well. */ for (i = 0; i < n_rx; i++) - gNB->common_vars.rxdataF[i] = malloc16_clear(gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t)); + gNB->common_vars.rxdataF[0][i] = malloc16_clear(gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t)); N_RB_DL = gNB->frame_parms.N_RB_DL; /* no RU: need to have rxdata */ @@ -1228,7 +1228,7 @@ int main(int argc, char *argv[]) for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) nr_slot_fep_ul(&gNB->frame_parms, (int32_t *)rxdata[aa], - (int32_t *)gNB->common_vars.rxdataF[aa], + (int32_t *)gNB->common_vars.rxdataF[0][aa], symbol, slot, 0); @@ -1236,7 +1236,7 @@ int main(int argc, char *argv[]) int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { apply_nr_rotation_RX(&gNB->frame_parms, - gNB->common_vars.rxdataF[aa], + gNB->common_vars.rxdataF[0][aa], gNB->frame_parms.symbol_rotation[1], slot, gNB->frame_parms.N_RB_UL, @@ -1249,15 +1249,15 @@ int main(int argc, char *argv[]) if (n_trials == 1 && round == 0) { LOG_M("rxsig0.m", "rx0", &rxdata[0][slot_offset], slot_length, 1, 1); - LOG_M("rxsigF0.m", "rxsF0", gNB->common_vars.rxdataF[0], 14 * frame_parms->ofdm_symbol_size, 1, 1); + LOG_M("rxsigF0.m", "rxsF0", gNB->common_vars.rxdataF[0][0], 14 * frame_parms->ofdm_symbol_size, 1, 1); if (precod_nbr_layers > 1) { LOG_M("rxsig1.m", "rx1", &rxdata[1][slot_offset], slot_length, 1, 1); - LOG_M("rxsigF1.m", "rxsF1", gNB->common_vars.rxdataF[1], 14 * frame_parms->ofdm_symbol_size, 1, 1); + LOG_M("rxsigF1.m", "rxsF1", gNB->common_vars.rxdataF[0][1], 14 * frame_parms->ofdm_symbol_size, 1, 1); if (precod_nbr_layers == 4) { LOG_M("rxsig2.m", "rx2", &rxdata[2][slot_offset], slot_length, 1, 1); LOG_M("rxsig3.m", "rx3", &rxdata[3][slot_offset], slot_length, 1, 1); - LOG_M("rxsigF2.m", "rxsF2", gNB->common_vars.rxdataF[2], 14 * frame_parms->ofdm_symbol_size, 1, 1); - LOG_M("rxsigF3.m", "rxsF3", gNB->common_vars.rxdataF[3], 14 * frame_parms->ofdm_symbol_size, 1, 1); + LOG_M("rxsigF2.m", "rxsF2", gNB->common_vars.rxdataF[0][2], 14 * frame_parms->ofdm_symbol_size, 1, 1); + LOG_M("rxsigF3.m", "rxsF3", gNB->common_vars.rxdataF[0][3], 14 * frame_parms->ofdm_symbol_size, 1, 1); } } }