From 598fbb5a241eeda6b94b24e11e46023486c52af8 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 18 Apr 2025 11:08:54 +0200 Subject: [PATCH 1/2] Consider PDSCH EPRE to DMRS EPRE in NR UE --- common/utils/nr/nr_common.c | 4 ++-- common/utils/nr/nr_common.h | 10 +++++----- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 3 +-- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 4 +++- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 3 ++- .../PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 6 +++++- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 1 + openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 1 + 9 files changed, 21 insertions(+), 13 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 7954db7d54..265b680500 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -1465,13 +1465,13 @@ frequency_range_t get_freq_range_from_band(uint16_t band) return band <= 256 ? FR1 : FR2; } -float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type) +float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2) { float beta_dmrs_pusch = 1.0; if (num_cdm_groups_no_data == 2) { beta_dmrs_pusch = powf(10.0, 3.0 / 20.0); } else if (num_cdm_groups_no_data == 3) { - if (dmrs_type == pusch_dmrs_type2) + if (is_type2) beta_dmrs_pusch = powf(10.0, 4.77 / 20.0); } return beta_dmrs_pusch; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 752d500c1b..6ab3f58dab 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -320,15 +320,15 @@ frequency_range_t get_freq_range_from_arfcn(uint32_t arfcn); frequency_range_t get_freq_range_from_band(uint16_t band); /** - * @brief Calculates the scaling factor for the ratio of PUSCH EPRE to DMRS EPRE. + * @brief Calculates the scaling factor for the ratio of PUSCH/PDSCH EPRE to DMRS EPRE. * * @param num_cdm_groups_no_data The number of CDM groups without data. - * @param dmrs_type The DMRS type. - * @return The calculated beta scaling factor for the ratio of PUSCH EPRE to DMRS EPRE. + * @param is_type2 true if calculating for DMRS configuration type 2 + * @return The calculated beta scaling factor for the ratio of PUSCH/PDSCH EPRE to DMRS EPRE. * - * @note The values are derived from TS 38.214 Table 6.2.2-1. + * @note The values are the same for PUSCH and PDSCH and are derived from TS 38.214 Table 6.2.2-1./4.1-1 */ -float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type); +float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2); #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 383140ba88..3b644ba4d3 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -499,8 +499,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, pusch_pdu->scid, Ns, symbol); - pusch_dmrs_type_t dmrs_type = pusch_pdu->dmrs_config_type == NFAPI_NR_DMRS_TYPE1 ? pusch_dmrs_type1 : pusch_dmrs_type2; - float beta_dmrs_pusch = get_beta_dmrs_pusch(pusch_pdu->num_dmrs_cdm_grps_no_data, dmrs_type); + float beta_dmrs_pusch = get_beta_dmrs(pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type == pusch_dmrs_type2); int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14); nr_pusch_dmrs_rx(gNB, Ns, diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index e929fc5f3e..7fd703ea30 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -117,7 +117,8 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short p, unsigned char lp, unsigned short nb_pdsch_rb, - uint8_t config_type) + uint8_t config_type, + int16_t dmrs_scaling) { typedef int array_of_w[2]; const array_of_w *wf = (config_type == NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2; @@ -131,6 +132,7 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) { int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); output[i] = get_modulated(nr_gold_pdsch, i, w == 1); + output[i] = c16mulRealShift(output[i], dmrs_scaling, 14); #ifdef DEBUG_PDSCH printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb); diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 7df105d05c..1d2d4b87ae 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -49,7 +49,8 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short p, unsigned char lp, unsigned short nb_pdsch_rb, - uint8_t config_type); + uint8_t config_type, + int16_t dmrs_scaling); void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling); void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); 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 0e186a3bc3..a291eb9bd1 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "nr_common.h" #include #include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" @@ -1258,6 +1259,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short scrambling_id, unsigned short BWPStart, uint8_t config_type, + int n_dmrs_cdm_groups, uint16_t rb_offset, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch, @@ -1291,8 +1293,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pilot[3280] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + float beta_dmrs_pdsch = get_beta_dmrs(n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2); + int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14)); const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol); - nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type); + nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); delay_t delay = {0}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index da6fd31eb5..0d35fe6ada 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -87,6 +87,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short scrambling_id, unsigned short BWPStart, uint8_t config_type, + int n_dmrs_cdm_groups, uint16_t rb_offset, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index ebfd6f6352..0eabc873e4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -396,7 +396,7 @@ static void dmrs_amp_mult(const uint32_t dmrs_port, const pusch_dmrs_type_t dmrs_type, const unsigned int num_cdm_groups_no_data) { - float beta_dmrs_pusch = get_beta_dmrs_pusch(num_cdm_groups_no_data, dmrs_type); + float beta_dmrs_pusch = get_beta_dmrs(num_cdm_groups_no_data, dmrs_type == pusch_dmrs_type2); /* short array that hold amplitude for k_prime = 0 and k_prime = 1 */ int32_t alpha_dmrs[2] __attribute((aligned(16))); for (int_fast8_t i = 0; i < sizeofArray(alpha_dmrs); i++) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index b95c7b8f79..bd0e110565 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -553,6 +553,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, dlschCfg->dlDmrsScramblingId, dlschCfg->BWPStart, dlschCfg->dmrsConfigType, + dlschCfg->n_dmrs_cdm_groups, dlschCfg->rb_offset, ue->frame_parms.first_carrier_offset + (dlschCfg->BWPStart + dlschCfg->start_rb) * 12, dlschCfg->number_rbs, From e5b68fb6ee3ac188b4adc982f13f2e53f66fe555 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 25 Aug 2025 09:27:31 +0200 Subject: [PATCH 2/2] NR UE: modify shift value in nr_dlsch_mmse() for improved performance --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 1da2ef8d45..e281e1851d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -80,7 +80,7 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{ /* compute the MMSE up to 4x4 matrices */ static void nr_dlsch_mmse(uint32_t rx_size_symbol, unsigned char n_rx, - unsigned char n_tx, // number of layer + unsigned char nl, // number of layer int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], c16_t dl_ch_mag[][n_rx][rx_size_symbol], c16_t dl_ch_magb[][n_rx][rx_size_symbol], @@ -203,7 +203,7 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol, uint32_t len, unsigned short nb_rb); static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, - short n_tx, + short nl, short n_rx, int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], int ***rho, @@ -1456,7 +1456,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, int length, uint32_t noise_var) { - uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0); + uint32_t nb_rb_0 = (length + 11) / 12; c16_t determ_fin[12 * nb_rb_0] __attribute__((aligned(32))); ///Allocate H^*H matrix elements and sub elements @@ -1513,7 +1513,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, determ_fin, // determin nb_rb_0, fp_flag, // fixed point flag - shift - (fp_flag == 1 ? 2 : 0)); // the out put is Q15 + shift - (fp_flag == 1 ? 1 : 0)); // the out put is Q15 // multiply Matrix inversion pf H_h_H by the rx signal vector c16_t outtemp[12 * nb_rb_0] __attribute__((aligned(32))); @@ -1531,7 +1531,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, (c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol), outtemp, sizeofArray(outtemp), - shift - (fp_flag == 1 ? 2 : 0)); + shift - (fp_flag == 1 ? 1 : 0)); nr_a_sum_b(rxdataF_zforcing[rtx], outtemp, nb_rb_0); // a = a + b } #ifdef DEBUG_DLSCH_DEMOD @@ -1582,13 +1582,9 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, dl_ch_mag128b_0[0] = mmtmpD2; dl_ch_mag128r_0[0] = mmtmpD2; - dl_ch_mag128_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128); - dl_ch_mag128_0[0] = simde_mm_slli_epi16(dl_ch_mag128_0[0],1); - - dl_ch_mag128b_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b); - dl_ch_mag128b_0[0] = simde_mm_slli_epi16(dl_ch_mag128b_0[0],1); - dl_ch_mag128r_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r); - dl_ch_mag128r_0[0] = simde_mm_slli_epi16(dl_ch_mag128r_0[0],1); + dl_ch_mag128_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128_0[0], QAM_amp128); + dl_ch_mag128b_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128b_0[0],QAM_amp128b); + dl_ch_mag128r_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128r_0[0],QAM_amp128r); determ_fin_128 += 1; dl_ch_mag128_0 += 1;