From 64ed4e9262c06e9728838292de3711a758c59e52 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 12 Aug 2024 19:31:42 +0200 Subject: [PATCH] handling beams in PHY TX channels --- common/utils/nr/nr_common.h | 1 + executables/nr-ru.c | 16 +-- openair1/PHY/INIT/nr_init.c | 65 ++++++----- openair1/PHY/INIT/nr_init_ru.c | 11 +- openair1/PHY/INIT/nr_phy_init.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_dci.c | 82 +++++++------- openair1/PHY/NR_TRANSPORT/nr_dci.h | 6 +- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 33 +++--- openair1/PHY/defs_RU.h | 5 +- openair1/PHY/defs_gNB.h | 11 +- openair1/SCHED_NR/nr_ru_procedures.c | 73 ++++++------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 125 ++++++++++++++-------- openair1/SCHED_NR/sched_nr.h | 8 +- openair1/SIMULATION/NR_PHY/dlsim.c | 19 +++- openair1/SIMULATION/NR_PHY/pbchsim.c | 36 +++---- openair1/SIMULATION/NR_PHY/pucchsim.c | 2 +- openair2/GNB_APP/RRC_nr_paramsvalues.h | 1 - openair2/LAYER2/NR_MAC_gNB/config.c | 2 - openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 - 19 files changed, 274 insertions(+), 225 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 9087f335c5..4f05a5b0c1 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -39,6 +39,7 @@ #include "PHY/defs_common.h" #define NR_MAX_PDSCH_TBS 3824 +#define MAX_NUM_BEAM_PERIODS 4 #define MAX_BWP_SIZE 275 #define NR_MAX_NUM_BWP 4 #define NR_MAX_HARQ_PROCESSES 32 diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 8fd1660889..dfb7cabb2f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -538,9 +538,11 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx ); } - if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx); + if (ru->feptx_ofdm) + ru->feptx_ofdm(ru, frame_tx, slot_tx); - if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx); + if (ru->fh_south_out) + ru->fh_south_out(ru, frame_tx, slot_tx, proc->timestamp_tx); } void fh_if5_north_out(RU_t *ru) { @@ -715,7 +717,7 @@ static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot) if (ru->common.beam_id) { int prev_slot = (slot - 1 + fp->slots_per_frame) % fp->slots_per_frame; - const uint8_t *beam_ids = ru->common.beam_id[0]; + const int *beam_ids = ru->common.beam_id[0]; int prev_beam = beam_ids[prev_slot * fp->symbols_per_slot]; int beam = beam_ids[slot * fp->symbols_per_slot]; if (prev_beam != beam) { @@ -1041,7 +1043,7 @@ void ru_tx_func(void *param) int slot_tx = info->slot_tx; int print_frame = 8; char filename[40]; - + int cumul_samples = fp->get_samples_per_slot(0, fp); int i = 1; for (; i < fp->slots_per_subframe / 2; i++) @@ -1052,10 +1054,12 @@ void ru_tx_func(void *param) int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]); // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx); + if (ru->feptx_prec) + ru->feptx_prec(ru,frame_tx,slot_tx); // do OFDM with/without TX front-end processing if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) + ru->feptx_ofdm(ru, frame_tx, slot_tx); if(!emulate_rf) { // do outgoing fronthaul (south) if needed diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 68333c821c..ed3a86295b 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -41,7 +41,6 @@ #include "SCHED_NR/fapi_nr_l1.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" - int l1_north_init_gNB() { if (RC.nb_nr_L1_inst > 0 && RC.gNB != NULL) { @@ -104,7 +103,7 @@ void reset_active_stats(PHY_VARS_gNB *gNB, int frame) // A global var to reduce the changes size ldpc_interface_t ldpc_interface = {0}, ldpc_interface_offload = {0}; -int phy_init_nr_gNB(PHY_VARS_gNB *gNB) +void phy_init_nr_gNB(PHY_VARS_gNB *gNB) { // shortcuts NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms; @@ -112,16 +111,24 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) NR_gNB_COMMON *const common_vars = &gNB->common_vars; NR_gNB_PRACH *const prach_vars = &gNB->prach_vars; - int i; - int Ptx=cfg->carrier_config.num_tx_ant.value; - int Prx=cfg->carrier_config.num_rx_ant.value; + common_vars->analog_bf = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value; + LOG_I(PHY, "L1 configured with%s analog beamforming\n", common_vars->analog_bf ? "" : "out"); + if (common_vars->analog_bf) { + common_vars->num_beams_period = cfg->analog_beamforming_ve.num_beams_period_vendor_ext.value; + LOG_I(PHY, "Max number of concurrent beams: %d\n", common_vars->num_beams_period); + } else + common_vars->num_beams_period = 1; + + int Ptx = cfg->carrier_config.num_tx_ant.value; + int Prx = cfg->carrier_config.num_rx_ant.value; int max_ul_mimo_layers = 4; - AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx); - AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx); - LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__); + AssertFatal(Ptx > 0 && Ptx < 9,"Ptx %d is not supported\n", Ptx); + AssertFatal(Prx > 0 && Prx < 9,"Prx %d is not supported\n", Prx); + LOG_I(PHY, "[gNB %d]About to wait for gNB to be configured\n", gNB->Mod_id); - while(gNB->configured == 0) usleep(10000); + while(gNB->configured == 0) + usleep(10000); load_dftslib(); @@ -172,19 +179,21 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) } } - common_vars->txdataF = (c16_t **)malloc16(Ptx*sizeof(c16_t*)); - common_vars->rxdataF = (c16_t **)malloc16(Prx*sizeof(c16_t*)); - /* Do NOT allocate per-antenna txdataF/rxdataF: the gNB gets a pointer to the + /* Do NOT allocate per-antenna rxdataF: the gNB gets a pointer to the * RU to copy/recover freq-domain memory from there */ - common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*)); + common_vars->rxdataF = (c16_t **)malloc16(Prx * sizeof(c16_t*)); - for (i=0;itxdataF[i] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(c16_t)); // [hna] samples_per_frame without CP - LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", - i,common_vars->txdataF[i], - fp->samples_per_frame_wCP*sizeof(c16_t)); - common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t)); - memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame); + common_vars->num_beams = cfg->dbt_config.num_dig_beams; + if (common_vars->num_beams > 0) { + 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)); + } + common_vars->txdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**)); + for (int i = 0; i < common_vars->num_beams_period; i++) { + common_vars->txdataF[i] = (c16_t**)malloc16_clear(Ptx * sizeof(c16_t*)); + for (int j = 0; j < Ptx; j++) + common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(c16_t)); } common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100); common_vars->debugBuff_sample_offset = 0; @@ -209,14 +218,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) pusch->ul_ch_estimates_time = (int32_t **)malloc16(n_buf * sizeof(int32_t *)); pusch->rxdataF_comp = (int32_t **)malloc16(n_buf * sizeof(int32_t *)); pusch->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers * sizeof(int32_t *)); - for (i = 0; i < n_buf; i++) { + for (int i = 0; i < n_buf; i++) { pusch->ul_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size * fp->symbols_per_slot); pusch->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size); pusch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->symbols_per_slot); // symbols per slot pusch->rxdataF_comp[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot); } - for (i=0; i< max_ul_mimo_layers; i++) { + for (int i = 0; i < max_ul_mimo_layers; i++) { pusch->llr_layers[i] = (int16_t *)malloc16_clear((8 * ((3 * 8 * 6144) + 12)) * sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear } @@ -224,8 +233,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) * sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear pusch->ul_valid_re_per_slot = (int16_t *)malloc16_clear(sizeof(int16_t) * fp->symbols_per_slot); } // ulsch_id - - return (0); } void phy_free_nr_gNB(PHY_VARS_gNB *gNB) @@ -258,9 +265,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) reset_nr_transport(gNB); NR_gNB_COMMON * common_vars = &gNB->common_vars; - for (int i = 0; i < Ptx; i++) { - free_and_zero(common_vars->txdataF[i]); - free_and_zero(common_vars->beam_id[i]); + for (int j = 0; j < common_vars->num_beams_period; j++) { + if (common_vars->beam_id) + free_and_zero(common_vars->beam_id[j]); + for (int i = 0; i < Ptx; i++) { + free_and_zero(common_vars->txdataF[j][i]); + } + free_and_zero(common_vars->txdataF[j]); } /* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 7168e3e70c..93b95b96eb 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -42,17 +42,14 @@ int nr_phy_init_RU(RU_t *ru) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value; } - ru->analog_beamforming = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value; - LOG_I(PHY, "RU configured with%s analog beamforming\n", ru->analog_beamforming ? "" : "out"); - // copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration // (at least the parts that are needed by the RU, numerology and PRACH) 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(ru->nb_log_antennas * sizeof(uint8_t*)); - for(int i = 0; i < ru->nb_tx; ++i) - ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(uint8_t)); + ru->common.beam_id = malloc16_clear(MAX_NUM_BEAM_PERIODS * sizeof(int*)); + for(int i = 0; i < MAX_NUM_BEAM_PERIODS; 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 @@ -178,7 +175,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 < ru->nb_log_antennas; ++i) + for(int i = 0; i < MAX_NUM_BEAM_PERIODS; ++i) free_and_zero(ru->common.beam_id[i]); free_and_zero(ru->common.beam_id); } diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index a6a7852d2c..d2c65e939f 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -38,7 +38,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB); void init_nr_ue_transport(PHY_VARS_NR_UE *ue); void init_N_TA_offset(PHY_VARS_NR_UE *ue); void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); -int phy_init_nr_gNB(PHY_VARS_gNB *gNB); +void phy_init_nr_gNB(PHY_VARS_gNB *gNB); int init_codebook_gNB(PHY_VARS_gNB *gNB); void nr_phy_config_request(NR_PHY_Config_t *gNB); void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index e3b3f3b42e..6cae31d465 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -36,6 +36,7 @@ #include "nr_sch_dmrs.h" #include "PHY/MODULATION/nr_modulation.h" #include "common/utils/nr/nr_common.h" +#include "SCHED_NR/sched_nr.h" //#define DEBUG_PDCCH_DMRS //#define DEBUG_DCI @@ -50,17 +51,12 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3 out[i] = in[i] ^ seq[i]; } -void nr_generate_dci(PHY_VARS_gNB *gNB, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, - int32_t *txdataF, - int16_t amp, - NR_DL_FRAME_PARMS *frame_parms, - int slot) { - - uint16_t cset_start_sc; - uint8_t cset_start_symb, cset_nsymb; - int k,l,k_prime,dci_idx, dmrs_idx; - +static void nr_generate_dci(PHY_VARS_gNB *gNB, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + int txdataF_offset, + NR_DL_FRAME_PARMS *frame_parms, + int slot) +{ // fill reg list per symbol int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE]; nr_fill_reg_list(reg_list, pdcch_pdu_rel15); @@ -68,20 +64,29 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, int rb_offset; int n_rb; get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); - cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; + uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; + int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols; + int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 6 + 15) >> 4) << 4; + int16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16))); - int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(((n_rb+rb_offset+pdcch_pdu_rel15->BWPStart)*6+15)>>4)<<4] __attribute__((aligned(16))); // 3 for the max coreset duration - - for (int d=0;dnumDlDci;d++) { + for (int d = 0; d < pdcch_pdu_rel15->numDlDci; d++) { /*The coreset is initialised * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 * or the rb_offset for other coresets * in time: by its first slot and its first symbol*/ const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d]; - cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; - cset_nsymb = pdcch_pdu_rel15->DurationSymbols; - dci_idx = 0; + uint32_t cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; + uint32_t cset_nsymb = pdcch_pdu_rel15->DurationSymbols; + int dci_idx = 0; + // multi-beam number (for concurrent beams) + int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx, + &gNB->common_vars, + slot, + frame_parms->symbols_per_slot, + cset_start_symb, + pdcch_pdu_rel15->DurationSymbols); + LOG_D(NR_PHY_DCI, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n", rb_offset, n_rb, pdcch_pdu_rel15->BWPStart); LOG_D(NR_PHY_DCI, "pdcch: Coreset starting subcarrier %d on symbol %d (%d symbols)\n", @@ -107,16 +112,18 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset /// DMRS QPSK modulation - for (int symb=cset_start_symb; symbDurationSymbols; symb++) { + for (int symb = cset_start_symb; symb < cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) { const uint32_t *gold = nr_gold_pdcch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, dci_pdu->ScramblingId, slot, symb); - nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER, - mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated + nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_PDCCH_DMRS if(dci_pdu->RNTI!=0xFFFF) { for (int i=0; i>1; i++) - printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i, - &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]); + printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", + symb, + i, + &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], + mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]); } #endif } @@ -163,7 +170,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, #endif /// Resource mapping - + uint16_t amp = gNB->TX_AMP; + int32_t *txdataF = (int32_t *)&gNB->common_vars.txdataF[beam_nb][0][txdataF_offset]; if (cset_start_sc >= frame_parms->ofdm_symbol_size) cset_start_sc -= frame_parms->ofdm_symbol_size; @@ -172,20 +180,21 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) { // allocating rbs per symbol for (int reg_count = 0; reg_count < num_regs; reg_count++) { - k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB; + int k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB; LOG_D(NR_PHY_DCI, "REG %d k %d\n", reg_list[d][reg_count], k); if (k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; - l = cset_start_symb + symbol_idx; + int l = cset_start_symb + symbol_idx; // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 + int dmrs_idx; if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) dmrs_idx = (reg_list[d][reg_count] + pdcch_pdu_rel15->BWPStart) * 3; else dmrs_idx = (reg_list[d][reg_count] + rb_offset) * 3; - k_prime = 0; + int k_prime = 0; for (int m = 0; m < NR_NB_SC_PER_RB; m++) { if (m == (k_prime << 2) + 1) { // DMRS if not already mapped @@ -235,16 +244,13 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, } // for (int d=0;dnumDlDci;d++) } -void nr_generate_dci_top(processingData_L1tx_t *msgTx, - int slot, - int32_t *txdataF, - int16_t amp, - NR_DL_FRAME_PARMS *frame_parms) { - - for (int i=0; inum_ul_pdcch; i++) - nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot); - for (int i=0; inum_dl_pdcch; i++) - nr_generate_dci(msgTx->gNB,&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,txdataF,amp,frame_parms,slot); - +void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset) +{ + PHY_VARS_gNB *gNB = msgTx->gNB; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + for (int i = 0; i < msgTx->num_ul_pdcch; i++) + nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot); + for (int i = 0; i < msgTx->num_dl_pdcch; i++) + nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 3a61d0b4a0..e735069975 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -26,11 +26,7 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" -void nr_generate_dci_top(processingData_L1tx_t *msgTx, - int slot, - int32_t *txdataF, - int16_t amp, - NR_DL_FRAME_PARMS *frame_parms); +void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset); int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 41746a6ba2..a1b9b5b283 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -39,6 +39,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/nr/nr_common.h" #include "executables/softmodem-common.h" +#include "SCHED_NR/sched_nr.h" //#define DEBUG_DLSCH //#define DEBUG_DLSCH_MAPPING @@ -468,7 +469,16 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) // The Precoding matrix: // The Codebook Type I start_meas(&gNB->dlsch_precoding_stats); - c16_t **txdataF = gNB->common_vars.txdataF; + nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; + // beam number in multi-beam scenario (concurrent beams) + int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, + &gNB->common_vars, + slot, + frame_parms->symbols_per_slot, + rel15->StartSymbolIndex, + rel15->NrOfSymbols); + + c16_t **txdataF = gNB->common_vars.txdataF[beam_nb]; for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) { for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) { @@ -477,10 +487,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) int rb = 0; while(rb < rel15->rbSize) { //get pmi info - const int pmi = (rel15->precodingAndBeamforming.prg_size > 0) ? - (rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx) : 0; - const int pmi2 = (rb < (rel15->rbSize - 1) && rel15->precodingAndBeamforming.prg_size > 0) ? - (rel15->precodingAndBeamforming.prgs_list[(int)(rb+1)/rel15->precodingAndBeamforming.prg_size].pm_idx) : -1; + const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0; + const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb+1)/pb->prg_size].pm_idx) : -1; // If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row // if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row @@ -576,21 +584,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) stop_meas(&gNB->dlsch_precoding_stats); - // TODO: handle precoding - // this maps the layers onto antenna ports - - // handle beamforming ID - // each antenna port is assigned a beam_index - // since PHY can only handle BF on slot basis we set the whole slot - - // first check if this slot has not already been allocated to another beam - if (gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot]==255) { - for (int j=0;jsymbols_per_slot;j++) - gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - } - else { - LOG_D(PHY,"beam index for PDSCH allocation already taken\n"); - } }// dlsch loop } diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 41de0193e9..e3e7df19f4 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -130,9 +130,9 @@ typedef struct { /// - third index: frequency [0..] int32_t **tdd_calib_coeffs; /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU) - /// - first index: antenna port + /// - first index: concurrent beam /// - second index: beam_id [0.. symbols_per_frame[ - uint8_t **beam_id; + int **beam_id; } RU_COMMON; @@ -663,7 +663,6 @@ typedef struct RU_t_s { /// structure for analyzing high-level RT measurements rt_ru_profiling_t rt_ru_profiling; void* scopeData; - bool analog_beamforming; } RU_t; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 154f752392..3b847046c0 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -269,14 +269,17 @@ typedef struct { 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: eNB id [0..2] (hard coded) + /// - first index: beam (for concurrent beams) /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. /// - third index: sample [0..samples_per_frame_woCP] - c16_t **txdataF; + c16_t ***txdataF; /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU) - /// - first index: antenna port + /// - first index: beam index (for concurrent beams) /// - second index: beam_id [0.. symbols_per_frame[ - uint8_t **beam_id; + int **beam_id; + int num_beams; + int num_beams_period; + bool analog_bf; int32_t *debugBuff; int32_t debugBuff_sample_offset; } NR_gNB_COMMON; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index a508ae4a9c..984f493e11 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -198,22 +198,23 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int tti_tx) gNB = gNB_list[0]; if (ru->config.dbt_config.num_dig_beams != 0) { - for(int i = 0; i < ru->nb_log_antennas; ++i) { + 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(uint8_t)); + (fp->symbols_per_slot) * sizeof(int)); } } - if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming) { - for (int i = 0; i < ru->nb_log_antennas; ++i) - memcpy(ru->common.txdataF_BF[i], &gNB->common_vars.txdataF[i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t)); + 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) { - memcpy((void*)ru->common.txdataF[i], - (void*)&gNB->common_vars.txdataF[i][txdataF_offset], - fp->samples_per_slot_wCP * sizeof(int32_t)); + // 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++) { @@ -255,17 +256,17 @@ void nr_feptx(void *arg) start_meas(&ru->precoding_stats); if (ru->config.dbt_config.num_dig_beams != 0) { - for(int i = 0; i < ru->nb_log_antennas; ++i) { - memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot], - (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot], - (fp->symbols_per_slot)*sizeof(uint8_t)); + 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 there is no digital beamforming we just need to copy the data to RU - if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming) + 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[aa][txdataF_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 numSamples * sizeof(int32_t)); else { AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n"); @@ -301,28 +302,28 @@ 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); for (int aid = 0; aid < ru->nb_tx; aid++) { - notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx); - feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req); - 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; - pushTpool(ru->threadPool, req); - nbfeptx++; - if (ru->half_slot_parallelization > 0) { - notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx); - feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req); - 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; - pushTpool(ru->threadPool, req); - nbfeptx++; - } + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx); + feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req); + 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; + pushTpool(ru->threadPool, req); + nbfeptx++; + if (ru->half_slot_parallelization > 0) { + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx); + feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req); + 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; + pushTpool(ru->threadPool, req); + nbfeptx++; + } } while (nbfeptx > 0) { notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6e89313762..92e2ab34ad 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -43,12 +43,42 @@ //#define DEBUG_RXDATA //#define SRS_IND_DEBUG -extern uint8_t nfapi_mode; +int beam_index_allocation(int fapi_beam_index, + NR_gNB_COMMON *common_vars, + int slot, + int symbols_per_slot, + int start_symbol, + int nb_symbols) +{ + if (!common_vars->beam_id) + return 0; -void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu) + int idx = -1; + for (int j = 0; j < common_vars->num_beams_period; j++) { + for (int i = start_symbol; i < start_symbol + nb_symbols; i++) { + int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i]; + if (current_beam == -1 || current_beam == fapi_beam_index) + idx = j; + else { + idx = -1; + break; + } + } + if (idx != -1) + break; + } + AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index); + for (int j = start_symbol; j < start_symbol + nb_symbols; j++) + common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index; + LOG_D(PHY, "Allocating beam %d in slot %d\n", idx, slot); + return idx; +} + +void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - uint8_t ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex; + nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &ssb_pdu.ssb_pdu_rel15; + uint8_t ssb_index = pdu->SsbBlockIndex; LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n", frame, slot, ssb_index); int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp, ssb_index); // computing the starting symbol for current ssb @@ -61,10 +91,8 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr // by the higher-layer parameter subCarrierSpacingCommon nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const int scs = cfg->ssb_config.scs_common.value; - const int prb_offset = (fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> scs - : ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> (scs - 2); - const int sc_offset = - (fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset; + const int prb_offset = (fp->freq_range == FR1) ? pdu->ssbOffsetPointA >> scs : pdu->ssbOffsetPointA >> (scs - 2); + const int sc_offset = (fp->freq_range == FR1) ? pdu->SsbSubcarrierOffset >> scs : pdu->SsbSubcarrierOffset; fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); if (fp->print_ue_help_cmdline_log && get_softmodem_params()->sa) { @@ -89,25 +117,34 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr } LOG_D(PHY, "ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n", - ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA, - ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset, + pdu->ssbOffsetPointA, + pdu->SsbSubcarrierOffset, prb_offset, sc_offset, scs, fp->ssb_start_subcarrier); - LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); - c16_t **txdataF = gNB->common_vars.txdataF; + LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); + nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; + c16_t ***txdataF = gNB->common_vars.txdataF; int txdataF_offset = slot * fp->samples_per_slot_wCP; - nr_generate_pss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); - nr_generate_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); + // beam number in a scenario with multiple concurrent beams + int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, + &gNB->common_vars, + slot, + fp->symbols_per_slot, + ssb_start_symbol, + 4); // 4 ssb symbols + + nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); + nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); uint16_t slots_per_hf = (fp->slots_per_frame) >> 1; int n_hf = slot < slots_per_hf ? 0 : 1; int hf = fp->Lmax == 4 ? n_hf : 0; nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7), - &txdataF[0][txdataF_offset], + &txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, @@ -116,23 +153,16 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr #if T_TRACER if (T_ACTIVE(T_GNB_PHY_MIB)) { unsigned char bch[3]; - bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff; - bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff; - bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff; + bch[0] = pdu->bchPayload & 0xff; + bch[1] = (pdu->bchPayload >> 8) & 0xff; + bch[2] = (pdu->bchPayload >> 16) & 0xff; T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3)); } #endif - // Beam_id is currently used only for FR2 - if (fp->freq_range == FR2) { - LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n", slot, ssb_index, cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value); - for (int j = 0; j < fp->symbols_per_slot; j++) - gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value; - } - nr_generate_pbch(gNB, &ssb_pdu, - &txdataF[0][txdataF_offset], + &txdataF[beam_nb][0][txdataF_offset], ssb_start_symbol, n_hf, frame, @@ -159,9 +189,12 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 1); // clear the transmit data array and beam index for the current slot - for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { - memset(&gNB->common_vars.txdataF[aa][txdataF_offset], 0, fp->samples_per_slot_wCP*sizeof(int32_t)); - memset(&gNB->common_vars.beam_id[aa][slot * fp->symbols_per_slot], 255, fp->symbols_per_slot*sizeof(uint8_t)); + 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)); + } } // Check for PRS slot - section 7.4.1.7.4 in 3GPP rel16 38.211 @@ -174,7 +207,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, { slot_prs = (slot - i*prs_config->PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame; LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id); - nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp); + nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, cfg, fp); } } } @@ -186,7 +219,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, msgTx->ssb[i].active = false; } } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0); int num_pdcch_pdus = msgTx->num_ul_pdcch + msgTx->num_dl_pdcch; @@ -197,7 +230,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1); - nr_generate_dci_top(msgTx, slot, (int32_t *)&gNB->common_vars.txdataF[0][txdataF_offset], gNB->TX_AMP, fp); + nr_generate_dci_top(msgTx, slot, txdataF_offset); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0); } @@ -212,10 +245,11 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){ NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i]; if (csirs->active == 1) { + AssertFatal(gNB->common_vars.beam_id == NULL, "Cannot handle CSI in the framework of beamforming yet\n"); LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; nr_generate_csi_rs(&gNB->frame_parms, - (int32_t **)gNB->common_vars.txdataF, + (int32_t **)gNB->common_vars.txdataF[0], gNB->TX_AMP, gNB->nr_csi_info, csi_params, @@ -232,22 +266,21 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, } } -// if ((frame&127) == 0) dump_pdsch_stats(gNB); - //apply the OFDM symbol rotation here if (gNB->phase_comp) { - for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { - apply_nr_rotation_TX(fp, - &gNB->common_vars.txdataF[aa][txdataF_offset], - fp->symbol_rotation[0], - slot, - fp->N_RB_DL, - 0, - fp->Ncp == EXTENDED ? 12 : 14); - - T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0), - T_INT(frame), T_INT(slot), - T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t))); + for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) { + for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { + apply_nr_rotation_TX(fp, + &gNB->common_vars.txdataF[i][aa][txdataF_offset], + fp->symbol_rotation[0], + slot, + fp->N_RB_DL, + 0, + fp->Ncp == EXTENDED ? 12 : 14); + T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0), + T_INT(frame), T_INT(slot), + T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t))); + } } } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index c31d3669a4..8220f2627d 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -39,7 +39,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); - void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx); void nr_fep_tp(RU_t *ru, int slot); @@ -47,5 +46,10 @@ 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); - +int beam_index_allocation(int fapi_beam_index, + NR_gNB_COMMON *common_vars, + int slot, + int symbols_per_slot, + int start_symbol, + int nb_symbols); #endif diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 47957be52e..e4a3a068fd 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1042,24 +1042,33 @@ int main(int argc, char **argv) int txdataF_offset = slot * frame_parms->samples_per_slot_wCP; if (n_trials==1) { - LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + LOG_M("txsigF0.m","txsF0=", + &gNB->common_vars.txdataF[0][0][txdataF_offset +2 * frame_parms->ofdm_symbol_size], + frame_parms->ofdm_symbol_size, + 1, + 1); if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + LOG_M("txsigF1.m","txsF1=", + &gNB->common_vars.txdataF[0][1][txdataF_offset + 2 * frame_parms->ofdm_symbol_size], + frame_parms->ofdm_symbol_size, + 1, + 1); } - if (n_trials == 1) printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset); + if (n_trials == 1) + printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset); //TODO: loop over slots for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { if (cyclic_prefix_type == 1) { - PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[aa][txdataF_offset], + PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][txdataF_offset], (int *)&txdata[aa][slot_offset], frame_parms->ofdm_symbol_size, 12, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); } else { - nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], + nr_normal_prefix_mod(&gNB->common_vars.txdataF[0][aa][txdataF_offset], &txdata[aa][slot_offset], 14, frame_parms, diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index aea092152f..f9b39de894 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -640,49 +640,45 @@ int main(int argc, char **argv) int slot = start_symbol/14; for (aa=0; aaframe_parms.nb_antennas_tx; aa++) - memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t)); + memset(gNB->common_vars.txdataF[0][aa], 0, frame_parms->samples_per_slot_wCP * sizeof(int32_t)); nr_common_signal_procedures (gNB,frame,slot,msgDataTx.ssb[i].ssb_pdu); + int samp = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { if (cyclic_prefix_type == 1) { apply_nr_rotation_TX(frame_parms, - gNB->common_vars.txdataF[aa], + gNB->common_vars.txdataF[0][aa], frame_parms->symbol_rotation[0], slot, frame_parms->N_RB_DL, 0, 12); - PHY_ofdm_mod((int *)gNB->common_vars.txdataF[aa], - (int *)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); + PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], + (int *)&txdata[aa][samp], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); } else { apply_nr_rotation_TX(frame_parms, - gNB->common_vars.txdataF[aa], + gNB->common_vars.txdataF[0][aa], frame_parms->symbol_rotation[0], slot, frame_parms->N_RB_DL, 0, 14); - /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], - 14, - frame_parms);*/ - - PHY_ofdm_mod((int *)gNB->common_vars.txdataF[aa], - (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], + PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], + (int*)&txdata[aa][samp], frame_parms->ofdm_symbol_size, 1, frame_parms->nb_prefix_samples0, CYCLIC_PREFIX); - PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size], - (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], + PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][frame_parms->ofdm_symbol_size], + (int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 13, frame_parms->nb_prefix_samples, @@ -691,9 +687,9 @@ int main(int argc, char **argv) } } } - LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0][0],frame_length_complex_samples_no_prefix, 1, 1); if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[0][1],frame_length_complex_samples_no_prefix, 1, 1); } else { printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 9dd9ef61a9..8faaba90ab 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -544,7 +544,7 @@ int main(int argc, char **argv) ack_nack_errors=0; sr_errors=0; n_errors = 0; - c16_t **txdataF = gNB->common_vars.txdataF; + c16_t **txdataF = gNB->common_vars.txdataF[0]; for (trial=0; trialofdm_symbol_size*sizeof(int)); diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index bfda253fbf..ffdfc0cb18 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -34,7 +34,6 @@ #define __NR_RRC_PARAMSVALUES__H__ #include "common/config/config_paramdesc.h" -#include "NR_ServingCellConfigCommon.h" /* cell configuration section name */ #define GNB_CONFIG_STRING_GNB_LIST "gNBs" diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index f31ac7cb95..39ee7fc238 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -532,8 +532,6 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts = config->pdsch_AntennaPorts; int num_pdsch_antenna_ports = pdsch_AntennaPorts.N1 * pdsch_AntennaPorts.N2 * pdsch_AntennaPorts.XP; cfg->carrier_config.num_tx_ant.value = num_pdsch_antenna_ports; - if(nrmac->beam_info.beam_allocation) // analog beamforming - cfg->carrier_config.num_tx_ant.value *= nrmac->beam_info.beams_per_period; AssertFatal(num_pdsch_antenna_ports > 0 && num_pdsch_antenna_ports < 33, "pdsch_AntennaPorts in 1...32\n"); cfg->carrier_config.num_tx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_TX_ANT_TAG; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 77c676c3a3..dcb82c199e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -100,7 +100,6 @@ #define MAX_NUM_OF_SSB 64 #define MAX_NUM_NR_PRACH_PREAMBLES 64 #define MIN_NUM_PRBS_TO_SCHEDULE 5 -#define MAX_NUM_BEAM_PERIODS 4 extern const uint8_t nr_rv_round_map[4];