From ab6d7afd09b02963ba345c983acef44acfdf8322 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta <rmagueta@allbesmart.pt> Date: Mon, 9 May 2022 15:54:20 +0100 Subject: [PATCH] Compute the SNR per RB using the SRS --- openair1/PHY/INIT/nr_init.c | 2 + .../NR_ESTIMATION/nr_ul_channel_estimation.c | 37 ++++++++++++++----- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 4 +- openair1/PHY/defs_nr_common.h | 2 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 64bbdfa4878..21ebcc14059 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -618,8 +618,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); gNB->nr_srs_info[id]->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); gNB->nr_srs_info[id]->srs_generated_signal = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->signal_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); gNB->nr_srs_info[id]->noise_power_per_rb = (uint32_t*)malloc16_clear(fp->N_RB_UL*sizeof(uint32_t)); gNB->nr_srs_info[id]->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); + gNB->nr_srs_info[id]->snr_per_rb = (int8_t*)malloc16_clear(fp->N_RB_UL*sizeof(int8_t)); gNB->nr_srs_info[id]->srs_received_signal = (int32_t **)malloc16(Prx*sizeof(int32_t*)); gNB->nr_srs_info[id]->srs_ls_estimated_channel = (int32_t **)malloc16(Prx*sizeof(int32_t*)); gNB->nr_srs_info[id]->srs_estimated_channel_freq = (int32_t **)malloc16(Prx*sizeof(int32_t*)); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index ffdf07860dd..8db33e3e185 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -1079,9 +1079,9 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, }//Antenna loop } -uint32_t calc_power(uint16_t *x, uint32_t size) { - uint64_t sum_x = 0; - uint64_t sum_x2 = 0; +uint32_t calc_power(const int16_t *x, uint32_t size) { + int64_t sum_x = 0; + int64_t sum_x2 = 0; for(int k = 0; k<size; k++) { sum_x = sum_x + x[k]; sum_x2 = sum_x2 + x[k]*x[k]; @@ -1099,8 +1099,10 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, int32_t **srs_estimated_channel_freq, int32_t **srs_estimated_channel_time, int32_t **srs_estimated_channel_time_shifted, + uint32_t *signal_power, uint32_t *noise_power_per_rb, - uint32_t *noise_power) { + uint32_t *noise_power, + int8_t *snr_per_rb) { if(nr_srs_info->sc_list_length == 0) { LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); @@ -1110,8 +1112,10 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; int32_t **srs_ls_estimated_channel = nr_srs_info->srs_ls_estimated_channel; - uint16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; - uint16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t ch_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t ch_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; int16_t ls_estimated[2]; @@ -1199,8 +1203,10 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, // Compute noise for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]]-srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]) & 0xFFFF)); - noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)(((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]]-srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]) >> 16) & 0xFFFF)); + ch_real[ant*nr_srs_info->sc_list_length + sc_idx] = (int16_t)(srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]] & 0xFFFF); + ch_imag[ant*nr_srs_info->sc_list_length + sc_idx] = (int16_t)((srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF); + noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)(srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]] & 0xFFFF) - ch_real[ant*nr_srs_info->sc_list_length + sc_idx]); + noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF) - ch_imag[ant*nr_srs_info->sc_list_length + sc_idx]); } // Convert to time domain @@ -1217,8 +1223,20 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); } + // Compute signal power + *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length) + + calc_power(ch_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"signal_power = %u\n", *signal_power); +#endif + // Compute noise power + uint8_t signal_power_bits = log2_approx(*signal_power); + uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x) + int32_t factor_dB = dB_fixed(1<<factor_bits); + uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3; uint8_t n_noise_estimates = frame_parms->nb_antennas_rx*srs_symbols_per_rb; @@ -1247,6 +1265,7 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, if (count_estimates == n_noise_estimates) { noise_power_per_rb[rb] = sum_re2/n_noise_estimates - (sum_re/n_noise_estimates)*(sum_re/n_noise_estimates) + sum_im2/n_noise_estimates - (sum_im/n_noise_estimates)*(sum_im/n_noise_estimates); + snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB; count_estimates = 0; sum_re = 0; sum_re2 = 0; @@ -1254,7 +1273,7 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, sum_im2 = 0; #ifdef SRS_DEBUG - LOG_I(NR_PHY,"noise_power_per_rb[%i] = %i\n", rb, noise_power_per_rb[rb]); + LOG_I(NR_PHY,"noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]); #endif } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 9c7d67b25d6..f7ac055dcc0 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -73,6 +73,8 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, int32_t **srs_estimated_channel_freq, int32_t **srs_estimated_channel_time, int32_t **srs_estimated_channel_time_shifted, + uint32_t *signal_power, uint32_t *noise_power_per_rb, - uint32_t *noise_power); + uint32_t *noise_power, + int8_t *snr_per_rb); #endif diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 80842eef386..4109b138317 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -244,8 +244,10 @@ typedef struct { int32_t **srs_estimated_channel_freq; int32_t **srs_estimated_channel_time; int32_t **srs_estimated_channel_time_shifted; + uint32_t *signal_power; uint32_t *noise_power_per_rb; uint32_t *noise_power; + int8_t *snr_per_rb; } nr_srs_info_t; typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index aa75cc64ef3..b342b87fa80 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -834,8 +834,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->nr_srs_info[i]->srs_estimated_channel_freq, gNB->nr_srs_info[i]->srs_estimated_channel_time, gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted, + gNB->nr_srs_info[i]->signal_power, gNB->nr_srs_info[i]->noise_power_per_rb, - gNB->nr_srs_info[i]->noise_power); + gNB->nr_srs_info[i]->noise_power, + gNB->nr_srs_info[i]->snr_per_rb); T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_freq[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); -- GitLab