From c84c858c56b4eeb25e46e179b3791fd23c75a48f Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 22 Sep 2025 20:57:07 +0000 Subject: [PATCH 1/3] phy: use smaller buffer for txdataF It is enough to allocate txdataF for one slot. --- openair1/PHY/INIT/nr_init.c | 2 +- openair1/PHY/INIT/nr_init_ru.c | 2 +- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_dci.c | 3 +-- openair1/PHY/NR_TRANSPORT/nr_dci.h | 1 - openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 3 +-- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 3 +-- .../nr_phy_common/src/nr_phy_common_csirs.c | 6 +---- openair1/SCHED_NR/nr_ru_procedures.c | 14 +++++------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 22 +++++++++---------- openair1/SIMULATION/NR_PHY/dlsim.c | 12 +++++----- openair1/SIMULATION/NR_PHY/pbchsim.c | 6 ++--- 12 files changed, 31 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d8b34b2598..bb7e4c3f0c 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -185,7 +185,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) 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->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_slot_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; diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 48621afee4..21b564d3c2 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -97,7 +97,7 @@ void nr_phy_init_RU(RU_t *ru) ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); // [hna] samples_per_frame without CP for(int i = 0; i < ru->nb_tx; ++i) - ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); + ru->common.txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_slot_wCP * sizeof(int32_t)); // allocate IFFT input buffers (TX) ru->common.txdataF_BF = (int32_t **)malloc16(nb_tx_streams * sizeof(int32_t*)); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 19977b01e3..68066f8a86 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -265,7 +265,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_CSI_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal)); for (int i = 0; i < NR_MAX_CSI_PORTS; i++) { ue->nr_csi_info->csi_rs_generated_signal[i] = - malloc16_clear(fp->samples_per_frame_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal)); + malloc16_clear(fp->samples_per_slot_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal)); } ue->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 12bff45dee..edb296e8a4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -53,7 +53,6 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3 void nr_generate_dci(PHY_VARS_gNB *gNB, const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, - int txdataF_offset, NR_DL_FRAME_PARMS *frame_parms, int slot) { @@ -179,7 +178,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, /// Resource mapping uint16_t amp = gNB->TX_AMP; - c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0] + txdataF_offset; + c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0]; if (cset_start_sc >= frame_parms->ofdm_symbol_size) cset_start_sc -= frame_parms->ofdm_symbol_size; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 57651f03a2..5a237ba80d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -28,7 +28,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, - int txdataF_offset, NR_DL_FRAME_PARMS *frame_parms, int slot); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 24cf6b72b6..b09f816c7d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -645,7 +645,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC if (start_sc >= symbol_sz) start_sc -= symbol_sz; - const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP; #ifdef DEBUG_DLSCH_MAPPING printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", start_sc, @@ -756,7 +755,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC start_meas(&gNB->dlsch_precoding_stats); for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) { - const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset; + const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz; do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol); } stop_meas(&gNB->dlsch_precoding_stats); diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 3004728091..566a382bfa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -281,7 +281,6 @@ static int nr_csi_rs_channel_estimation( int16_t *log2_maxh, uint32_t *noise_power) { - const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP; *noise_power = 0; int maxh = 0; int count = 0; @@ -316,7 +315,7 @@ static int nr_csi_rs_channel_estimation( for (int lp = 0; lp <= csi_mapping->lprime; lp++) { uint16_t symb = lp + csi_mapping->loverline[cdm_id]; uint64_t symbol_offset = symb * fp->ofdm_symbol_size; - const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset]; const c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset]; c16_t tmp = c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits); // This is not just the LS estimation for each (k,l), but also the sum of the different contributions diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c b/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c index 557214c63f..7cc14b385f 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c @@ -25,7 +25,6 @@ static void csi_rs_resource_mapping(c16_t **dataF, int csi_rs_length, int16_t mod_csi[][csi_rs_length >> 1], int ofdm_symbol_size, - int dataF_offset, int start_sc, const csi_mapping_parms_t *mapping_parms, int start_rb, @@ -66,7 +65,7 @@ static void csi_rs_resource_mapping(c16_t **dataF, else wt = -1; } - int index = (l * ofdm_symbol_size + k) + dataF_offset; + int index = (l * ofdm_symbol_size + k); dataF[p][index].r = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15; dataF[p][index].i = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15; LOG_D(PHY, @@ -622,13 +621,10 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, // CDM group size from CDM type index const int gs = get_cdm_group_size(cdm_type); - const int dataF_offset = slot * frame_parms->samples_per_slot_wCP; - csi_rs_resource_mapping(dataF, frame_parms->N_RB_DL << 4, mod_csi, frame_parms->ofdm_symbol_size, - dataF_offset, frame_parms->first_carrier_offset, phy_csi_parms, start_rb, diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index ca712bbaf9..01b6fe7389 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -175,7 +175,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx) PHY_VARS_gNB *gNB = gNB_list[0]; nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - int txdataF_offset = slot_tx * fp->samples_per_slot_wCP; start_meas(&ru->precoding_stats); if (gNB->common_vars.analog_bf) { @@ -195,8 +194,8 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx) for (int b = 0; b < ru->num_beams_period; b++) { for (int i = 0; i < Ptx; ++i) { int tx_idx = i + b * ru->nb_tx; - memcpy((void*)ru->common.txdataF_BF[tx_idx], - (void*)&gNB->common_vars.txdataF[b][i][txdataF_offset], + memcpy((void *)ru->common.txdataF_BF[tx_idx], + (void *)gNB->common_vars.txdataF[b][i], fp->samples_per_slot_wCP * sizeof(int32_t)); } } @@ -219,8 +218,7 @@ void nr_feptx(void *arg) NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; int numSymbols = feptx->numSymbols; int numSamples = feptx->numSymbols * fp->ofdm_symbol_size; - int txdataF_offset = (slot * fp->samples_per_slot_wCP) + startSymbol * fp->ofdm_symbol_size; - int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size; + int txdataF_offset = startSymbol * fp->ofdm_symbol_size; int tx_idx = aa + bb * ru->nb_tx; @@ -235,9 +233,9 @@ void nr_feptx(void *arg) // If there is no digital beamforming we just need to copy the data to RU if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) - memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset], - (void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset], - numSamples * sizeof(int32_t)); + memcpy((void *)&ru->common.txdataF_BF[tx_idx][txdataF_offset], + (void *)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset], + numSamples * sizeof(int32_t)); else { AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n"); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 4e69f8fa69..80f96e1f43 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -146,7 +146,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); const 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; // beam number in a scenario with multiple concurrent beams int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols int beam_nb = beam_index_allocation(gNB->enable_analog_das, @@ -156,15 +155,15 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n fp->symbols_per_slot, bitmap); - 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); + nr_generate_pss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp); + nr_generate_sss(txdataF[beam_nb][0], 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[beam_nb][0][txdataF_offset], + txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, @@ -182,7 +181,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n nr_generate_pbch(gNB, ssb_pdu, - &txdataF[beam_nb][0][txdataF_offset], + txdataF[beam_nb][0], ssb_start_symbol, n_hf, frame, @@ -246,7 +245,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, { const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - const int txdataF_offset = slot * fp->samples_per_slot_wCP; if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return; @@ -254,7 +252,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, // clear the transmit data array and beam index for the current slot 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++) { - memset(&gNB->common_vars.txdataF[i][aa][txdataF_offset], 0, fp->samples_per_slot_wCP * sizeof(***gNB->common_vars.txdataF)); + memset(gNB->common_vars.txdataF[i][aa], 0, fp->samples_per_slot_wCP * sizeof(***gNB->common_vars.txdataF)); } } @@ -268,13 +266,13 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, { int 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][0][txdataF_offset], AMP, prs_config, fp); + nr_generate_prs(slot_prs, gNB->common_vars.txdataF[0][0], AMP, prs_config, fp); } } } for (int i = 0; i < UL_dci_req->numPdus; ++i) - nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); + nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, &gNB->frame_parms, slot); int num_pdsch = 0; for (int i = 0; i < DL_req->dl_tti_request_body.nPDUs; ++i) { @@ -284,7 +282,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, nr_common_signal_procedures(gNB, frame, slot, &dl_tti_pdu->ssb_pdu); break; case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: - nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); + nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, &gNB->frame_parms, slot); break; case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: nr_generate_csi_rs_gNB(gNB, slot, &dl_tti_pdu->csi_rs_pdu); @@ -321,7 +319,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { if (gNB->phase_comp) { apply_nr_rotation_TX(fp, - &gNB->common_vars.txdataF[i][aa][txdataF_offset], + gNB->common_vars.txdataF[i][aa], fp->symbol_rotation[0], slot, fp->N_RB_DL, @@ -333,7 +331,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, T_INT(frame), T_INT(slot), T_INT(aa), - T_BUFFER(&gNB->common_vars.txdataF[i][aa][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t))); + T_BUFFER(gNB->common_vars.txdataF[i][aa], fp->samples_per_slot_wCP * sizeof(int32_t))); } } stop_meas(&gNB->phase_comp_stats); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index b068936739..aa9ebccde8 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1123,29 +1123,27 @@ int main(int argc, char **argv) phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot); stop_meas(&gNB->phy_proc_tx); - int txdataF_offset = slot * frame_parms->samples_per_slot_wCP; - if (n_trials==1) { LOG_M("txsigF0.m","txsF0=", - &gNB->common_vars.txdataF[0][0][txdataF_offset +2 * frame_parms->ofdm_symbol_size], + &gNB->common_vars.txdataF[0][0][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[0][1][txdataF_offset + 2 * frame_parms->ofdm_symbol_size], + &gNB->common_vars.txdataF[0][1][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); + printf("slot_offset %d\n", slot_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[0][aa][txdataF_offset], + PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], (int *)&txdata[aa][slot_offset], frame_parms->ofdm_symbol_size, 12, @@ -1156,7 +1154,7 @@ int main(int argc, char **argv) for (int i = 0; i < 14; i++) { was_symbol_used[i] = true; } - nr_normal_prefix_mod(&gNB->common_vars.txdataF[0][aa][txdataF_offset], + nr_normal_prefix_mod(gNB->common_vars.txdataF[0][aa], &txdata[aa][slot_offset], 14, frame_parms, diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 5702be2cf9..cad3012400 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -567,9 +567,9 @@ int main(int argc, char **argv) } } } - 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[0][1],frame_length_complex_samples_no_prefix, 1, 1); + LOG_M("txsigF0.m", "txsF0", gNB->common_vars.txdataF[0][0], frame_parms->samples_per_slot_wCP, 1, 1); + if (gNB->frame_parms.nb_antennas_tx > 1) + LOG_M("txsigF1.m", "txsF1", gNB->common_vars.txdataF[0][1], frame_parms->samples_per_slot_wCP, 1, 1); } else { printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); From d7512bdc8b62c033b9ef8ebeb46772a64b50dfd1 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 27 Feb 2026 18:01:25 +0000 Subject: [PATCH 2/3] oaioran: fix compression for arm read data from start PRB of each section. --- radio/fhi_72/oaioran.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 047c216898..7f858219ac 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -693,7 +693,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp); #elif defined(__arm__) || defined(__aarch64__) - armral_bfp_compression(p_prbMapElm->iqWidth, numRB, (int16_t *)local_src, (int8_t *)dst); + armral_bfp_compression(p_prbMapElm->iqWidth, numRB, (int16_t *)(local_src + startRB * N_SC_PER_PRB), (int8_t *)dst); #else AssertFatal(1 == 0, "BFP compression not supported on this architecture"); #endif From 044ca835d621ae24c1bef084629bc1af440bcd03 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 23 Sep 2025 04:21:38 +0000 Subject: [PATCH 3/3] phy: use fftshift'ed buffer for txdataF So far txdataF buffer has DC RE as the first element. This was prefered most likely to avoid memcpy before iFFT but comes with a small complexity in RE mapping functions. Instead, we use a flat buffer that holds freq domain data starting from first negative SC. After resource mapping is done on all channels, each OFDM symbol is shifted before iFFT so that the buffer start with DC RE. This reduces complexity in mapping functions and later on when passing beam IDs to 7.2 split RU especially when a beam is associated to interleaved RB and/or REs. There is already a memcpy in place to copy txdataF from gNB stuct to RU struct. So this change does not introduce new memcpy. --- openair1/PHY/INIT/nr_init_ru.c | 3 +- openair1/PHY/MODULATION/nr_modulation.h | 9 ++ openair1/PHY/MODULATION/ofdm_mod.c | 48 +++++--- openair1/PHY/NR_TRANSPORT/nr_dci.c | 9 +- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 108 +++++------------- openair1/PHY/NR_TRANSPORT/nr_pbch.c | 37 +----- openair1/PHY/NR_TRANSPORT/nr_prs.c | 11 +- openair1/PHY/NR_TRANSPORT/nr_pss.c | 6 +- openair1/PHY/NR_TRANSPORT/nr_sss.c | 5 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 9 +- .../nr_phy_common/src/nr_phy_common_csirs.c | 4 +- openair1/SCHED_NR/nr_ru_procedures.c | 18 +-- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 1 + openair1/SIMULATION/NR_PHY/dlsim.c | 21 +++- openair1/SIMULATION/NR_PHY/pbchsim.c | 32 +++++- radio/fhi_72/oaioran.c | 81 ++++++------- 16 files changed, 185 insertions(+), 217 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 21b564d3c2..1092545705 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -103,7 +103,8 @@ void nr_phy_init_RU(RU_t *ru) ru->common.txdataF_BF = (int32_t **)malloc16(nb_tx_streams * sizeof(int32_t*)); LOG_D(PHY, "[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, nb_tx_streams * sizeof(int32_t *)); for (int i = 0; i < nb_tx_streams; i++) { - ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP * sizeof(int32_t)); + ru->common.txdataF_BF[i] = + (int32_t *)malloc16_clear(fp->samples_per_slot_wCP * sizeof(int32_t)); LOG_D(PHY, "txdataF_BF[%d] %p for RU %d\n", i, ru->common.txdataF_BF[i], ru->idx); } // allocate FFT output buffers (RX) diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 9e8ac3ba3c..fda32fa86f 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -105,6 +105,7 @@ void nr_beam_precoding(c16_t **txdataF, void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, c16_t *txdataF, + bool is_flat_buff, const c16_t *symbol_rotation, int slot, int nb_rb, @@ -161,4 +162,12 @@ void nr_layer_precoder_simd(const int n_layers, const int sc_offset, const int re_cnt, c16_t *txdataF_precoded); + +void fft_shift(const c16_t *in, + uint32_t in_symb_sz, + uint16_t num_prb, + c16_t *out, + uint16_t fft_size_out, + uint16_t start_symb, + uint16_t num_symb); #endif diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index c3311fb78a..8a31648605 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -288,6 +288,7 @@ void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_s void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, c16_t *txdataF, + bool is_flat_buff, const c16_t *symbol_rotation, int slot, int nb_rb, @@ -309,20 +310,39 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, this_rotation->r, this_rotation->i); - if (nb_rb & 1) { - rotate_cpx_vector(this_symbol, this_rotation, this_symbol, - (nb_rb + 1) * 6, 15); - rotate_cpx_vector(this_symbol + fp->first_carrier_offset - 6, - this_rotation, - this_symbol + fp->first_carrier_offset - 6, - (nb_rb + 1) * 6, 15); - } else { - rotate_cpx_vector(this_symbol, this_rotation, this_symbol, - nb_rb * 6, 15); - rotate_cpx_vector(this_symbol + fp->first_carrier_offset, - this_rotation, - this_symbol + fp->first_carrier_offset, - nb_rb * 6, 15); + if (is_flat_buff) + rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * NR_NB_SC_PER_RB, 15); + else { + c16_t *this_symbol_neg = this_symbol + fp->first_carrier_offset; + if (nb_rb & 1) { + this_symbol_neg -= 6; + nb_rb += 1; + } + rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * 6, 15); + rotate_cpx_vector(this_symbol_neg, this_rotation, this_symbol_neg, nb_rb * 6, 15); } } } + +/* Do FFT-shift for symbols in the provided in buffer and writes to out buffer. */ +void fft_shift(const c16_t *in, + uint32_t in_symb_sz, + uint16_t num_prb, + c16_t *out, + uint16_t fft_size_out, + uint16_t start_symb, + uint16_t num_symb) +{ + const int num_samp_half = num_prb * NR_NB_SC_PER_RB / 2; + const int first_carrier_offset = fft_size_out - num_samp_half; + for (int s = start_symb; s < start_symb + num_symb; s++) { + // Copy negative freq component + uint16_t out_offset = s * fft_size_out + first_carrier_offset; + uint16_t in_offset = s * in_symb_sz; + memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t)); + // Copy positive freq component + out_offset = s * fft_size_out; + in_offset = s * in_symb_sz + num_samp_half; + memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t)); + } +} diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index edb296e8a4..a4f5c80989 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -67,7 +67,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, if (pdcch_pdu_rel15->CoreSetType == 1) additional_offset = (pdcch_pdu_rel15->BWPStart + 5) / 6 * 6 - pdcch_pdu_rel15->BWPStart; int rb_offset = cset_start + additional_offset; - uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; + uint16_t cset_start_sc = (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) * 3) + 15) & ~15; c16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16))); @@ -179,8 +179,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, /// Resource mapping uint16_t amp = gNB->TX_AMP; c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0]; - if (cset_start_sc >= frame_parms->ofdm_symbol_size) - cset_start_sc -= frame_parms->ofdm_symbol_size; int num_regs = dci_pdu->AggregationLevel * NR_NB_REG_PER_CCE / pdcch_pdu_rel15->DurationSymbols; /*Mapping the encoded DCI along with the DMRS */ @@ -189,8 +187,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, for (int reg_count = 0; reg_count < num_regs; reg_count++) { 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; int l = cset_start_symb + symbol_idx; @@ -226,9 +222,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, } k++; - - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; } // m } // reg_count } // symbol_idx diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index b09f816c7d..1edb590a58 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -86,8 +86,7 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, printf("k %d \t txdataF: %d %d\n", k, txF[k].r, txF[k].i); #endif } - if (++k >= symbol_sz) - k -= symbol_sz; + k++; } return in - tx_layer; } @@ -294,7 +293,7 @@ static inline int dmrs_case00(c16_t *output, else { output[k] = (c16_t){0}; } - k = (k + 1) % symbol_sz; + k++; } // RE loop return in - txl; } @@ -355,12 +354,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, { c16_t *txl = txl_start; const uint sz = rel15->rbSize * NR_NB_SC_PER_RB; - int upper_limit = sz; - int remaining_re = 0; - if (start_sc + upper_limit > symbol_sz) { - upper_limit = symbol_sz - start_sc; - remaining_re = sz - upper_limit; - } /* calculate if current symbol is PTRS symbols */ int ptrs_symbol = 0; @@ -385,47 +378,39 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, if (rel15->numDmrsCdmGrpsNoData == 2) { switch (dmrs_port & 3) { case 0: - txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, upper_limit); - txl += interleave_with_0_signal_first(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re); + txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, sz); break; case 1: { c16_t dmrs[sz / 2]; neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, upper_limit); - txl += interleave_with_0_signal_first(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re); + txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, sz); } break; case 2: - txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, upper_limit); - txl += interleave_with_0_start_with_0(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re); + txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, sz); break; case 3: { c16_t dmrs[sz / 2]; neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, upper_limit); - txl += interleave_with_0_start_with_0(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re); + txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, sz); } break; } } else if (rel15->numDmrsCdmGrpsNoData == 1) { switch (dmrs_port & 3) { case 0: - txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, upper_limit); - txl += interleave_signals(output, txl, amp, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re); + txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, sz); break; case 1: { c16_t dmrs[sz / 2]; neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, upper_limit); - txl += interleave_signals(output, txl, amp, dmrs + upper_limit / 2, amp_dmrs, remaining_re); + txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, sz); } break; case 2: - txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, upper_limit); - txl += interleave_signals(output, dmrs_start + upper_limit / 2, amp_dmrs, txl, amp, remaining_re); + txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, sz); break; case 3: { c16_t dmrs[sz / 2]; neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, upper_limit); - txl += interleave_signals(output, dmrs + upper_limit / 2, amp_dmrs, txl, amp, remaining_re); + txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, sz); } break; } } else @@ -445,8 +430,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, rel15->numDmrsCdmGrpsNoData); } // generic DMRS case } else { // no PTRS or DMRS in this symbol - txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, upper_limit); - txl += no_ptrs_dmrs_case(output, txl, amp, remaining_re); + txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz); } // no DMRS/PTRS in symbol return txl - txl_start; } @@ -477,30 +461,13 @@ static inline void do_txdataF(c16_t **txdataF, const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0; const int re_cnt = NR_NB_SC_PER_RB * rb_step; if (pmi == 0) { // unitary Precoding - if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC - if (ant < rel15->nrOfLayers) - memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], - &txdataF_precoding[ant][subCarrier], - re_cnt * sizeof(**txdataF)); - else - memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF)); - } else { // RB does cross DC - const int neg_length = symbol_sz - subCarrier; - const int pos_length = re_cnt - neg_length; - if (ant < rel15->nrOfLayers) { - memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], - &txdataF_precoding[ant][subCarrier], - neg_length * sizeof(**txdataF)); - memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant], pos_length * sizeof(**txdataF)); - } else { - memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, neg_length * sizeof(**txdataF)); - memset(&txdataF[ant][txdataF_offset_per_symbol], 0, pos_length * sizeof(**txdataF)); - } - } + if (ant < rel15->nrOfLayers) + memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], + &txdataF_precoding[ant][subCarrier], + re_cnt * sizeof(**txdataF)); + else + memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF)); subCarrier += re_cnt; - if (subCarrier >= symbol_sz) { - subCarrier -= symbol_sz; - } } else { // non-unitary Precoding AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n"); // get the precoding matrix weights: @@ -514,38 +481,21 @@ static inline void do_txdataF(c16_t **txdataF, "Number of layers %d doesn't match to the one in precoding matrix %d\n", rel15->nrOfLayers, pmi_pdu->numLayers); - if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe - nr_layer_precoder_simd(rel15->nrOfLayers, - symbol_sz, - txdataF_precoding, - ant, - pmi_pdu, - subCarrier, - re_cnt, - &txdataF[ant][txdataF_offset_per_symbol]); - subCarrier += re_cnt; - } else { // crossing ofdm_symbol_size, use simple arithmetic operations - for (int i = 0; i < re_cnt; i++) { - txdataF[ant][txdataF_offset_per_symbol + subCarrier] = - nr_layer_precoder_cm(rel15->nrOfLayers, symbol_sz, txdataF_precoding, ant, pmi_pdu, subCarrier); -#ifdef DEBUG_DLSCH_MAPPING - printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n", - ant, - l_symbol, - subCarrier, - txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].r, - txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i); -#endif - if (++subCarrier >= symbol_sz) { - subCarrier -= symbol_sz; - } - } - } // else{ // crossing ofdm_symbol_size, use simple arithmetic operations + nr_layer_precoder_simd(rel15->nrOfLayers, + symbol_sz, + txdataF_precoding, + ant, + pmi_pdu, + subCarrier, + re_cnt, + &txdataF[ant][txdataF_offset_per_symbol]); + subCarrier += re_cnt; } // else { // non-unitary Precoding rb += rb_step; } // RB loop: while(rb < rel15->rbSize) } + static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot) { const int16_t amp = gNB->TX_AMP; @@ -641,9 +591,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC start_meas(&gNB->dlsch_pdsch_generation_stats); /// Resource mapping // Non interleaved VRB to PRB mapping - uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB; - if (start_sc >= symbol_sz) - start_sc -= symbol_sz; + uint16_t start_sc = (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB; #ifdef DEBUG_DLSCH_MAPPING printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 159e040d11..4acda03b91 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -71,7 +71,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, /// Resource mapping // PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3 ///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; + k = frame_parms->ssb_start_subcarrier + nushift; l = ssb_start_symbol + 1; for (int m = 0; m < 60; m++) { @@ -80,13 +80,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, #endif txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15); k+=4; - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } ///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; + k = frame_parms->ssb_start_subcarrier + nushift; l++; for (int m = 60; m < 84; m++) { @@ -100,13 +97,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); #endif k+=(m==71)?148:4; // Jump from 44+nu to 192+nu - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } ///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; + k = frame_parms->ssb_start_subcarrier + nushift; l++; for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) { @@ -115,9 +109,6 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, #endif txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15); k+=4; - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } #ifdef DEBUG_PBCH_DMRS @@ -334,7 +325,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, nushift = config->cell_config.phy_cell_id.value &3; // PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS ///symbol 1 [0:239] -- 180 mod symbols - int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; + int k = frame_parms->ssb_start_subcarrier; int l = ssb_start_symbol + 1; int m = 0; int16_t amp = gNB->TX_AMP; @@ -351,13 +342,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, k++; m++; } - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } ///symbol 2 [0:47 ; 192:239] -- 72 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; + k = frame_parms->ssb_start_subcarrier; l++; m=180; @@ -373,16 +361,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, k++; m++; } - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } k += 144; - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; - m=216; for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) { @@ -397,13 +379,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, k++; m++; } - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } ///symbol 3 [0:239] -- 180 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; + k = frame_parms->ssb_start_subcarrier; l++; m=252; @@ -419,9 +398,5 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, k++; m++; } - - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index 207a94447d..87edffdc7d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -51,9 +51,9 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg else if (prs_cfg->CombSize == 12){ k_prime = k_prime_table[3][symInd]; } - - k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_parms->first_carrier_offset; - + + k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12; + // QPSK modulation uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l); for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) { @@ -66,10 +66,7 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_prs[m], amp, 15); k = k + prs_cfg->CombSize; - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; - } + } } #ifdef DEBUG_PRS_MAP LOG_M("nr_prs.m", "prs",(int16_t *)&txdataF[prs_cfg->SymbolStart*frame_parms->ofdm_symbol_size],prs_cfg->NumPRSSymbols*frame_parms->ofdm_symbol_size, 1, 1); diff --git a/openair1/PHY/NR_TRANSPORT/nr_pss.c b/openair1/PHY/NR_TRANSPORT/nr_pss.c index 965ac51c21..6b219dba90 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pss.c @@ -49,8 +49,7 @@ int nr_generate_pss( c16_t *txdataF, /// Resource mapping // PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from - int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and - if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size; + int k = frame_parms->ssb_start_subcarrier + 56; int l = ssb_start_symbol; @@ -61,9 +60,6 @@ int nr_generate_pss( c16_t *txdataF, // printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size); ((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_pss) >> 15; k++; - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } #ifdef NR_PSS_DEBUG diff --git a/openair1/PHY/NR_TRANSPORT/nr_sss.c b/openair1/PHY/NR_TRANSPORT/nr_sss.c index 45835f8206..71bae9a065 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sss.c @@ -59,16 +59,13 @@ int nr_generate_sss( c16_t *txdataF, /// Resource mapping // SSS occupies a predefined position (subcarriers 56-182, symbol 2) within the SSB block starting from - int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and + int k = frame_parms->ssb_start_subcarrier + 56; int l = ssb_start_symbol + 2; for (int i = 0; i < NR_SSS_LENGTH; i++) { int16_t d_sss = (1 - 2*x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2*x1[(i + m1) % NR_SSS_LENGTH] ) * 23170; ((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15; k++; - - if (k >= frame_parms->ofdm_symbol_size) - k-=frame_parms->ofdm_symbol_size; } #ifdef NR_SSS_DEBUG // write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 881ce016bc..e24166a5b6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -1619,7 +1619,14 @@ uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot, if (was_symbol_used[i] == false) continue; for (int ap = 0; ap < n_antenna_ports; ap++) { - apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1); + apply_nr_rotation_TX(frame_parms, + txdataF[ap], + false, + frame_parms->symbol_rotation[linktype], + slot, + N_RB, + i, + 1); } } } diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c b/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c index 7cc14b385f..a0db67e50d 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common_csirs.c @@ -25,7 +25,6 @@ static void csi_rs_resource_mapping(c16_t **dataF, int csi_rs_length, int16_t mod_csi[][csi_rs_length >> 1], int ofdm_symbol_size, - int start_sc, const csi_mapping_parms_t *mapping_parms, int start_rb, int nb_rbs, @@ -43,7 +42,7 @@ static void csi_rs_resource_mapping(c16_t **dataF, int p = s + mapping_parms->j[ji] * gs; // port index for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group // frequency index of current resource element - int k = (start_sc + (n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp) % (ofdm_symbol_size); + int k = ((n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp); // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1); int na = n * alpha; @@ -625,7 +624,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, frame_parms->N_RB_DL << 4, mod_csi, frame_parms->ofdm_symbol_size, - frame_parms->first_carrier_offset, phy_csi_parms, start_rb, nr_of_rbs, diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 01b6fe7389..20ca99f0c4 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -217,8 +217,6 @@ void nr_feptx(void *arg) int startSymbol = feptx->startSymbol; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; int numSymbols = feptx->numSymbols; - int numSamples = feptx->numSymbols * fp->ofdm_symbol_size; - int txdataF_offset = startSymbol * fp->ofdm_symbol_size; int tx_idx = aa + bb * ru->nb_tx; @@ -232,11 +230,17 @@ void nr_feptx(void *arg) } // If there is no digital beamforming we just need to copy the data to RU - if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) - memcpy((void *)&ru->common.txdataF_BF[tx_idx][txdataF_offset], - (void *)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset], - numSamples * sizeof(int32_t)); - else { + if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) { + // FFT shift + const NR_DL_FRAME_PARMS *fp = &ru->gNB_list[0]->frame_parms; + fft_shift(ru->gNB_list[0]->common_vars.txdataF[bb][aa], + fp->ofdm_symbol_size, + fp->N_RB_DL, + (c16_t *)ru->common.txdataF_BF[tx_idx], + fp->ofdm_symbol_size, + startSymbol, + numSymbols); + } else { AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n"); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 80f96e1f43..629d9cc406 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -320,6 +320,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, if (gNB->phase_comp) { apply_nr_rotation_TX(fp, gNB->common_vars.txdataF[i][aa], + true, fp->symbol_rotation[0], slot, fp->N_RB_DL, diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index aa9ebccde8..2cdaa4143e 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1141,9 +1141,17 @@ int main(int argc, char **argv) //TODO: loop over slots for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - + c16_t fft_in_buff[frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot] __attribute__((aligned(64))); + memset(fft_in_buff, 0, sizeof(fft_in_buff)); if (cyclic_prefix_type == 1) { - PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], + fft_shift(gNB->common_vars.txdataF[0][aa], + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + fft_in_buff, + frame_parms->ofdm_symbol_size, + 0, + 12); + PHY_ofdm_mod((int *)fft_in_buff, (int *)&txdata[aa][slot_offset], frame_parms->ofdm_symbol_size, 12, @@ -1154,7 +1162,14 @@ int main(int argc, char **argv) for (int i = 0; i < 14; i++) { was_symbol_used[i] = true; } - nr_normal_prefix_mod(gNB->common_vars.txdataF[0][aa], + fft_shift(gNB->common_vars.txdataF[0][aa], + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + fft_in_buff, + frame_parms->ofdm_symbol_size, + 0, + 14); + nr_normal_prefix_mod(fft_in_buff, &txdata[aa][slot_offset], 14, frame_parms, diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index cad3012400..a828db184d 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -525,17 +525,28 @@ int main(int argc, char **argv) nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]); int samp = get_samples_slot_timestamp(frame_parms, slot); - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + for (aa = 0; aa < gNB->frame_parms.nb_antennas_tx; aa++) { + c16_t fft_in_buff[frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot] __attribute__((aligned(64))); + memset(fft_in_buff, 0, sizeof(fft_in_buff)); if (cyclic_prefix_type == 1) { apply_nr_rotation_TX(frame_parms, gNB->common_vars.txdataF[0][aa], + true, frame_parms->symbol_rotation[0], slot, frame_parms->N_RB_DL, 0, 12); - PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], + fft_shift(gNB->common_vars.txdataF[0][aa], + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + fft_in_buff, + frame_parms->ofdm_symbol_size, + 0, + 12); + + PHY_ofdm_mod((int *)fft_in_buff, (int *)&txdata[aa][samp], frame_parms->ofdm_symbol_size, 12, @@ -544,21 +555,30 @@ int main(int argc, char **argv) } else { apply_nr_rotation_TX(frame_parms, gNB->common_vars.txdataF[0][aa], + true, frame_parms->symbol_rotation[0], slot, frame_parms->N_RB_DL, 0, 14); - PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], - (int*)&txdata[aa][samp], + fft_shift(gNB->common_vars.txdataF[0][aa], + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + fft_in_buff, + frame_parms->ofdm_symbol_size, + 0, + 14); + + PHY_ofdm_mod((int *)fft_in_buff, + (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[0][aa][frame_parms->ofdm_symbol_size], - (int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size], + PHY_ofdm_mod((int *)fft_in_buff + 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, diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 7f858219ac..d7b39b307b 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -612,21 +612,6 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) int num_totalRB = p_prbMapElm->nRBSize; int start_totalRB = p_prbMapElm->nRBStart; - int pos_len = 0; - int neg_len = 0; - - if (start_totalRB < (num_totalRB >> 1)) // there are PRBs left of DC - neg_len = min((num_totalRB * 6) - (start_totalRB * 12), num_totalRB * N_SC_PER_PRB); - pos_len = (num_totalRB * N_SC_PER_PRB) - neg_len; - // Calculation of the pointer for the section in the buffer. - // start of positive frequency component - uint16_t *src1 = (uint16_t *)&pos[(neg_len == 0) ? ((start_totalRB * N_SC_PER_PRB) - (num_totalRB * 6)) : 0]; - // start of negative frequency component - uint16_t *src2 = (uint16_t *)&pos[(start_totalRB * N_SC_PER_PRB) + fftsize - (num_totalRB * 6)]; - - uint32_t local_src[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64))); - memcpy((void *)local_src, (void *)src2, neg_len * 4); - memcpy((void *)&local_src[neg_len], (void *)src1, pos_len * 4); if (ptr && pos) { u8dptr = (uint8_t *)ptr; int16_t payload_len = 0; @@ -662,26 +647,33 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) } uint16_t *dst16 = (uint16_t *)dst; + // Start of this section + int32_t *pos_start = pos + (start_totalRB + startRB) * N_SC_PER_PRB; + if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) { payload_len = numRB * N_SC_PER_PRB * 4L; /* convert to Network order */ // NOTE: ggc 11 knows how to generate AVX2 for this! for (idx = 0; idx < (numRB * N_SC_PER_PRB) * 2; idx++) - ((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx + startRB * N_SC_PER_PRB * 2]); + ((uint16_t *)dst16)[idx] = htons(((uint16_t *)pos_start)[idx]); } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { payload_len = (3 * p_prbMapElm->iqWidth + 1) * numRB; + /* Although arm intrinsics natively handle unaligned memory + access, we use a 64 byte aligned input here for maximum + performance. So the src_compr buffer is used for both x86 and arm. + */ + uint32_t src_compr[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64))); + + /* Copy from txdataF with current symbol's PRB start (nRBStart) + + current section's PRB start (UP_nPRBStart) */ + memcpy(src_compr, pos_start, (numRB * N_SC_PER_PRB) * sizeof(*pos_start)); + #if defined(__i386__) || defined(__x86_64__) struct xranlib_compress_request bfp_com_req = {}; struct xranlib_compress_response bfp_com_rsp = {}; - uint32_t src_compr[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64))); - if (numRB == num_totalRB) { - bfp_com_req.data_in = (int16_t *)local_src; - } else { - memcpy(src_compr, local_src + (startRB * N_SC_PER_PRB), (numRB * N_SC_PER_PRB) * sizeof(*local_src)); - bfp_com_req.data_in = (int16_t *)src_compr; - } + bfp_com_req.data_in = (int16_t *)src_compr; bfp_com_req.numRBs = numRB; bfp_com_req.len = payload_len; @@ -693,7 +685,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp); #elif defined(__arm__) || defined(__aarch64__) - armral_bfp_compression(p_prbMapElm->iqWidth, numRB, (int16_t *)(local_src + startRB * N_SC_PER_PRB), (int8_t *)dst); + armral_bfp_compression(p_prbMapElm->iqWidth, numRB, (int16_t *)src_compr, (int8_t *)dst); #else AssertFatal(1 == 0, "BFP compression not supported on this architecture"); #endif @@ -950,7 +942,6 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t const struct xran_fh_init *fh_init = get_xran_fh_init(); const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); - int nPRBs = fh_cfg->nDLRBs; int fftsize = 1 << fh_cfg->nDLFftSize; int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; @@ -1105,36 +1096,32 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t } uint16_t *dst16 = (uint16_t *)dst; - int pos_len = 0; - int neg_len = 0; - - if (p_prbMapElm->UP_nRBStart < (nPRBs >> 1)) // there are PRBs left of DC - neg_len = min((nPRBs * 6) - (p_prbMapElm->UP_nRBStart * 12), p_prbMapElm->UP_nRBSize * N_SC_PER_PRB); - pos_len = (p_prbMapElm->UP_nRBSize * N_SC_PER_PRB) - neg_len; - // Calculation of the pointer for the section in the buffer. - // start of positive frequency component - uint16_t *src1 = (uint16_t *)&pos[(neg_len == 0) ? ((p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) - (nPRBs * 6)) : 0]; - // start of negative frequency component - uint16_t *src2 = (uint16_t *)&pos[(p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) + fftsize - (nPRBs * 6)]; - - uint32_t local_src[p_prbMapElm->UP_nRBSize * N_SC_PER_PRB] __attribute__((aligned(64))); - memcpy((void *)local_src, (void *)src2, neg_len * 4); - memcpy((void *)&local_src[neg_len], (void *)src1, pos_len * 4); + int32_t *pos_start = pos + p_prbMapElm->UP_nRBStart * N_SC_PER_PRB; + uint32_t numPrb = p_prbMapElm->UP_nRBSize; if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) { - payload_len = p_prbMapElm->UP_nRBSize * N_SC_PER_PRB * 4L; + payload_len = numPrb * N_SC_PER_PRB * 4L; /* convert to Network order */ // NOTE: ggc 11 knows how to generate AVX2 for this! - for (idx = 0; idx < (pos_len + neg_len) * 2; idx++) - ((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]); + for (idx = 0; idx < numPrb * N_SC_PER_PRB * 2; idx++) + ((uint16_t *)dst16)[idx] = htons(((uint16_t *)pos_start)[idx]); } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { - payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->UP_nRBSize; + payload_len = (3 * p_prbMapElm->iqWidth + 1) * numPrb; + /* Although arm intrinsics natively handle unaligned memory + access, we use a 64 byte aligned input here for maximum + performance. So the src_compr buffer is used for both x86 and arm. + */ + uint32_t src_compr[numPrb * N_SC_PER_PRB] __attribute__((aligned(64))); + + /* Copy from txdataF with current symbol's PRB start (nRBStart) + + current section's PRB start (UP_nPRBStart) */ + memcpy(src_compr, pos_start, (numPrb * N_SC_PER_PRB) * sizeof(*pos_start)); #if defined(__i386__) || defined(__x86_64__) struct xranlib_compress_request bfp_com_req = {}; struct xranlib_compress_response bfp_com_rsp = {}; - bfp_com_req.data_in = (int16_t *)local_src; - bfp_com_req.numRBs = p_prbMapElm->UP_nRBSize; + bfp_com_req.data_in = (int16_t *)src_compr; + bfp_com_req.numRBs = numPrb; bfp_com_req.len = payload_len; bfp_com_req.compMethod = p_prbMapElm->compMethod; bfp_com_req.iqWidth = p_prbMapElm->iqWidth; @@ -1144,7 +1131,7 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp); #elif defined(__arm__) || defined(__aarch64__) - armral_bfp_compression(p_prbMapElm->iqWidth, p_prbMapElm->UP_nRBSize, (int16_t *)local_src, (int8_t *)dst); + armral_bfp_compression(p_prbMapElm->iqWidth, numPrb, (int16_t *)src_compr, (int8_t *)dst); #else AssertFatal(1 == 0, "BFP compression not supported on this architecture"); #endif