From 6c590b900a7763a3cc4c58164eaf95ecf64a661c Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 22 Feb 2023 19:32:53 +0000 Subject: [PATCH] Compute noise variance to be used in MMSE --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 18 ++++++++++++++++-- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 3 ++- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 14 +++++++++----- openair1/PHY/TOOLS/tools_defs.h | 11 +++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index e953d8a4a0..ad7b364119 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -120,7 +120,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int ul_id, unsigned short bwp_start_subcarrier, nfapi_nr_pusch_pdu_t *pusch_pdu, - int *max_ch) { + int *max_ch, + uint32_t *nvar) { c16_t pilot[3280] __attribute__((aligned(32))); const int chest_freq = gNB->chest_freq; @@ -186,6 +187,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif + int nest_count = 0; + uint64_t noise_amp2 = 0; c16_t ul_ls_est[symbolSize] __attribute__((aligned(32))); memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize); NR_ULSCH_delay_t *delay = &gNB->ulsch[ul_id].delay; @@ -284,12 +287,16 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int k = pilot_cnt << 1; ul_ch[k] = c16mulShift(ul_ch[k], ul_inv_delay_table[k], 8); ul_ch[k + 1] = c16mulShift(ul_ch[k + 1], ul_inv_delay_table[k + 1], 8); + noise_amp2 += c16amp2(c16sub(ul_ls_est[k], ul_ch[k])); + noise_amp2 += c16amp2(c16sub(ul_ls_est[k + 1], ul_ch[k + 1])); + #ifdef DEBUG_PUSCH re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize; c16_t *rxF = &rxdataF[soffset + re_offset]; printf("ch -> (%4d,%4d), ch_inter -> (%4d,%4d)\n", ul_ls_est[k].r, ul_ls_est[k].i, ul_ch[k].r, ul_ch[k].i); #endif pilot_cnt++; + nest_count += 2; } } @@ -307,6 +314,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, multadd_real_four_symbols_vector_complex_scalar(filt8_rep4, &ch, &ul_ls_est[n]); ul_ls_est[n + 4] = ch; ul_ls_est[n + 5] = ch; + noise_amp2 += c16amp2(c16sub(ch0, ch)); + nest_count++; } // Delay compensation @@ -501,7 +510,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #ifdef DEBUG_CH fclose(debug_ch_est); #endif - return(0); + + if (nvar && nest_count > 0) { + *nvar = (uint32_t)(noise_amp2 / nest_count); + } + + return 0; } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 41f841a975..9dc6edf8d2 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -47,7 +47,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int ul_id, unsigned short bwp_start_subcarrier, nfapi_nr_pusch_pdu_t *pusch_pdu, - int *max_ch); + int *max_ch, + uint32_t *nvar); void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index e85ddd682e..bb213c595b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1482,7 +1482,7 @@ uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms, int shift, unsigned char symbol, int length, - int noise_var) + uint32_t noise_var) { int *ch00, *ch01, *ch10, *ch11; int *ch20, *ch30, *ch21, *ch31; @@ -1881,6 +1881,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //---------------------------------------------------------- start_meas(&gNB->ulsch_channel_estimation_stats); int max_ch = 0; + uint32_t nvar = 0; for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); @@ -1890,7 +1891,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, pusch_vars->dmrs_symbol = symbol; for (int nl=0; nlnrOfLayers; nl++) { - + uint32_t nvar_tmp = 0; nr_pusch_channel_estimation(gNB, slot, get_dmrs_port(nl,rel15_ul->dmrs_ports), @@ -1898,7 +1899,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ulsch_id, bwp_start_subcarrier, rel15_ul, - &max_ch); + &max_ch, + &nvar_tmp); + nvar += nvar_tmp; } nr_gnb_measurements(gNB, ulsch, pusch_vars, symbol, rel15_ul->nrOfLayers); @@ -1929,6 +1932,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, } } + nvar /= (rel15_ul->nr_of_symbols * rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx); + if (gNB->chest_time == 1) { // averaging time domain channel estimates nr_chest_time_domain_avg(frame_parms, pusch_vars->ul_ch_estimates, @@ -2055,7 +2060,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, // Apply MMSE for 2 Tx layers if (rel15_ul->nrOfLayers == 2) { - int noise_var = 100; // TODO: Get noise variance nr_ulsch_mmse_2layers(frame_parms, pusch_vars->rxdataF_comp, pusch_vars->ul_ch_mag0, @@ -2067,7 +2071,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, pusch_vars->log2_maxh, symbol, nb_re_pusch, - noise_var); + nvar); } stop_meas(&gNB->ulsch_mrc_stats); diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index aa3ea6fc41..3079e5029c 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -97,6 +97,17 @@ extern "C" { #define squaredMod(a) ((a).r*(a).r + (a).i*(a).i) #define csum(res, i1, i2) (res).r = (i1).r + (i2).r ; (res).i = (i1).i + (i2).i + __attribute__((always_inline)) inline uint32_t c16amp2(const c16_t a) { + return a.r * a.r + a.i * a.i; + } + + __attribute__((always_inline)) inline c16_t c16sub(const c16_t a, const c16_t b) { + return (c16_t) { + .r = (int16_t) (a.r - b.r), + .i = (int16_t) (a.i - b.i) + }; + } + __attribute__((always_inline)) inline c16_t c16Shift(const c16_t a, const int Shift) { return (c16_t) { .r = (int16_t)(a.r >> Shift),