diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 69e095878f..30e8e6c32e 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -36,6 +36,7 @@ #include "common/utils/LOG/log.h" #include "nr_common.h" #include +#include #define C_SRS_NUMBER (64) #define B_SRS_NUMBER (4) @@ -1427,3 +1428,15 @@ 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 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) + 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 ef04daaad1..f98ce510a2 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -130,6 +130,11 @@ typedef enum frequency_range_e { FR2 } frequency_range_t; +typedef enum { + pusch_dmrs_type1 = 0, + pusch_dmrs_type2 = 1 +} pusch_dmrs_type_t; + #define MAX_NUM_SLOTS_ALLOWED 80 // up to numerology 3 (120 KHz SCS) is supported enum slot_type { TDD_NR_DOWNLINK_SLOT, TDD_NR_UPLINK_SLOT, TDD_NR_MIXED_SLOT }; @@ -302,6 +307,17 @@ frequency_range_t get_freq_range_from_freq(uint64_t freq); 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. + * + * @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. + * + * @note The values are derived from TS 38.214 Table 6.2.2-1. + */ +float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type); + #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 5d318d6fd8..1f1e36ddef 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "nr_common.h" #include #include "nr_ul_estimation.h" @@ -480,6 +481,9 @@ 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); + int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14); nr_pusch_dmrs_rx(gNB, Ns, gold, @@ -488,7 +492,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, 0, nb_rb_pusch, (pusch_pdu->bwp_start + pusch_pdu->rb_start) * NR_NB_SC_PER_RB, - pusch_pdu->dmrs_config_type); + pusch_pdu->dmrs_config_type, + dmrs_scaling); } else { // if transform precoding or SC-FDMA is enabled in Uplink // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible const int index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB / 2)); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 01b05071a2..e929fc5f3e 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -34,6 +34,7 @@ //#define NR_PBCH_DMRS_LENGTH 144 //#define DEBUG_PUSCH +#include "PHY/TOOLS/tools_defs.h" #include "refsig_defs_ue.h" #include "PHY/defs_nr_UE.h" #include "nr_refsig.h" @@ -73,7 +74,8 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned char lp, unsigned short nb_pusch_rb, uint32_t re_offset, - uint8_t dmrs_type) + uint8_t dmrs_type, + int16_t dmrs_scaling) { typedef int array_of_w[2]; const array_of_w *wf = (dmrs_type == pusch_dmrs_type1) ? wf1 : wf2; @@ -91,6 +93,7 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, int i = k + dmrs_offset; int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); output[k] = get_modulated(nr_gold_pusch, i, w == 1); + output[k] = c16mulRealShift(output[k], dmrs_scaling, 14); #ifdef DEBUG_PUSCH printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index b0cd9449f0..ceb9048d7f 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -36,7 +36,8 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned char lp, unsigned short nb_pusch_rb, uint32_t re_offset, - uint8_t dmrs_type); + uint8_t dmrs_type, + int16_t dmrs_scaling); void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, int32_t **dataF, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index be7a8101db..299eeb6c64 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -392,13 +392,15 @@ static void dmrs_amp_mult(const uint32_t dmrs_port, const c16_t *mod_dmrs, c16_t *mod_dmrs_out, const uint32_t n_dmrs, - const pusch_dmrs_type_t dmrs_type) + 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); /* 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++) { const int32_t a = Wf[i] * Wt * AMP; - alpha_dmrs[i] = a; + alpha_dmrs[i] = a * beta_dmrs_pusch; } /* multiply amplitude with complex DMRS vector */ @@ -440,9 +442,9 @@ static void map_symbols(const nr_phy_pxsch_params_t p, c16_t mod_dmrs[ALNARS_16_4(n_dmrs)] __attribute((aligned(16))); if (p.transform_precoding == transformPrecoder_disabled) { nr_modulation(gold, n_dmrs * 2, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); - dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, mod_dmrs, mod_dmrs_amp, n_dmrs, p.dmrs_type); + dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, mod_dmrs, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); } else { - dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, dmrs_seq, mod_dmrs_amp, n_dmrs, p.dmrs_type); + dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, dmrs_seq, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); } } else if ((p.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && ptrs_symbol) { AssertFatal(p.transform_precoding == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 123dbe162a..9db686d664 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -344,12 +344,6 @@ typedef enum { * DESCRIPTION : configuration for PUSCH * ************************************************************************/ - -typedef enum { - pusch_dmrs_type1 = 0, - pusch_dmrs_type2 = 1 -} pusch_dmrs_type_t; - typedef enum { txConfig_codebook = 1, txConfig_nonCodebook = 2