From 032fc5e9c24f97726e078e7a752f0099d3a1a990 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 31 Oct 2025 12:25:54 +0100 Subject: [PATCH] fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding by not processing useless samples in one symbol --- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 17 ++------ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 5 +-- .../nr_dl_channel_estimation.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 39 +++++++++---------- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 5 files changed, 25 insertions(+), 40 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index e25d9700da..62dc85e90c 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -150,22 +150,11 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, return(0); } -int nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch, - c16_t *output, - unsigned short p, - unsigned short nb_rb_coreset) +void nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_coreset) { - if (p==2000) { - for (int i=0; i<((nb_rb_coreset*6)>>1); i++) { - output[i] = get_modulated(nr_gold_pdcch, i, true); -#ifdef DEBUG_PDCCH - if (i<8) - printf("i %d idx %d pdcch mod_dmrs %d %d\n", i, idx, output[i].r, output[i].i); -#endif - } + for (int i = 0; i < ((nb_rb_coreset * 6) >> 1); i++) { + output[i] = get_modulated(nr_gold_pdcch, i, true); } - - return(0); } void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink) diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 414dae9976..d9d1ef4534 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -35,10 +35,7 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables */ -int nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch, - c16_t *output, - unsigned short p, - unsigned short nb_rb_corset); +void nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_corset); int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned int Ns, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 6a49a17608..f310c0236b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -846,7 +846,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS const uint32_t *gold = nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol); - nr_pdcch_dmrs_rx(gold, pilot, 2000, (nb_rb_coreset + dmrs_ref)); + nr_pdcch_dmrs_rx(gold, pilot, nb_rb_coreset + dmrs_ref); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 9e48f52a03..d956ca7cc3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -294,8 +294,9 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, } static void nr_pdcch_channel_compensation(int arraySz, - c16_t rxdataF_ext[][arraySz], - c16_t dl_ch_estimates_ext[][arraySz], + int sz2, + c16_t rxdataF_ext[][sz2], + c16_t dl_ch_estimates_ext[][sz2], c16_t rxdataF_comp[][arraySz], int antRx, uint8_t output_shift) @@ -306,17 +307,17 @@ static void nr_pdcch_channel_compensation(int arraySz, } } -static void nr_pdcch_detection_mrc(int sz, c16_t rxdataF_comp[][sz]) +static void nr_pdcch_detection_mrc(int nb_ant, int sz, c16_t rxdataF_comp[][sz]) { - LOG_D(NR_PHY_DCI, "we enter nr_pdcch_detection_mrc (hard coded 2 antennas)\n"); c16_t *rx0 = rxdataF_comp[0]; - c16_t *rx1 = rxdataF_comp[1]; - // MRC on each re of rb // input always aligned and accepting tail padding to process all actual samples - for (int i = 0; i < sz; i += 4) { - *(simde__m128i *)(rx0 + i) = - simde_mm_adds_epi16(simde_mm_srai_epi16(*(simde__m128i *)(rx0 + i), 1), simde_mm_srai_epi16(*(simde__m128i *)(rx1 + i), 1)); + for (int a = 1; a < nb_ant; a++) { + c16_t *rx = rxdataF_comp[a]; + for (int i = 0; i < sz; i += 4) { + *(simde__m128i *)(rx0 + i) = simde_mm_adds_epi16(simde_mm_srai_epi16(*(simde__m128i *)(rx0 + i), 1), + simde_mm_srai_epi16(*(simde__m128i *)(rx + i), 1)); + } } } @@ -334,7 +335,7 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *fp = &ue->frame_parms; NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; fapi_nr_coreset_t *coreset = &phy_pdcch_config->pdcch_config[ss_idx].coreset; - int32_t pdcch_est_size = ((((fp->ofdm_symbol_size + LTE_CE_FILTER_LENGTH) + 15) / 16) * 16); + int32_t pdcch_est_size = ceil_mod(fp->ofdm_symbol_size + LTE_CE_FILTER_LENGTH, 16); __attribute__((aligned(16))) c16_t pdcch_dl_ch_estimates[fp->nb_antennas_rx][pdcch_est_size]; nr_pdcch_channel_estimation(ue, @@ -347,12 +348,9 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, pdcch_dl_ch_estimates, rxdataF); - const int32_t rx_size = ((4 * fp->N_RB_DL * 12 + 31) >> 5) << 5; + const int32_t rx_size = ceil_mod(fp->N_RB_DL * 12, 32); __attribute__((aligned(32))) c16_t rxdataF_ext[fp->nb_antennas_rx][rx_size]; - __attribute__((aligned(32))) c16_t rxdataF_comp[fp->nb_antennas_rx][rx_size]; __attribute__((aligned(32))) c16_t pdcch_dl_ch_estimates_ext[fp->nb_antennas_rx][rx_size]; - memset(rxdataF_comp, 0, sizeof(rxdataF_comp)); - int n_rb; int rb_offset; get_coreset_rballoc(coreset->frequency_domain_resource, &n_rb, &rb_offset); @@ -376,20 +374,21 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, for (int i = 1; i < fp->nb_antennas_rx; i++) avgs = cmax(avgs, avg[i]); const int log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx; - - nr_pdcch_channel_compensation(rx_size, + int rx_comp_sz = ceil_mod(llr_size_symbol, 4); + __attribute__((aligned(32))) c16_t rxdataF_comp[fp->nb_antennas_rx][rx_comp_sz]; + memset(rxdataF_comp, 0, sizeof(rxdataF_comp)); + nr_pdcch_channel_compensation(rx_comp_sz, + rx_size, rxdataF_ext, pdcch_dl_ch_estimates_ext, rxdataF_comp, fp->nb_antennas_rx, log2_maxh); // log2_maxh+I0_shift - UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), fp->nb_antennas_rx, rx_size, 0); - if (fp->nb_antennas_rx > 1) { - nr_pdcch_detection_mrc(rx_size, rxdataF_comp); + nr_pdcch_detection_mrc(fp->nb_antennas_rx, rx_comp_sz, rxdataF_comp); } - + UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), 1, llr_size_symbol, 0); nr_pdcch_llr(llr_size_symbol, rxdataF_comp[0], llr); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index cbef1dc62a..51c7bf2c55 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1041,7 +1041,7 @@ void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ nr_pdcch_generate_llr(ue, proc, symbol, phy_data, llr_size_symbol, num_monitoring_occ, max_nb_symb_pdcch, rxdataF_symb, pdcch_llr); if (symbol == last_symb_pdcch) { nr_pdcch_dci_indication(proc, llr_size_symbol * max_nb_symb_pdcch, num_monitoring_occ, ue, phy_data, pdcch_llr); - UEscopeCopy(ue, pdcchLlr, pdcch_llr, sizeof(c16_t), 1, sizeof(pdcch_llr), 0); + UEscopeCopy(ue, pdcchLlr, pdcch_llr, sizeof(c16_t), 1, sizeof(pdcch_llr) / sizeof(c16_t), 0); } } stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);