From 86874047ac6e43960e477f234c1d89e241b22044 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 17 May 2022 17:42:48 +0100 Subject: [PATCH] Channel estimation, channel interpolation and SNR per RB computation based on SRS up to 4 antenna ports --- openair1/PHY/INIT/nr_init.c | 22 +- openair1/PHY/INIT/nr_init_ue.c | 12 - .../NR_ESTIMATION/nr_ul_channel_estimation.c | 359 ++++++++++-------- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 8 +- .../PHY/NR_UE_TRANSPORT/srs_modulation_nr.c | 2 +- openair1/PHY/defs_nr_common.h | 8 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 8 +- 7 files changed, 234 insertions(+), 185 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 198e46c166..6ce196c49d 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -625,18 +625,24 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->nr_srs_info[id]->snr_per_rb = (int8_t*)malloc16_clear(fp->N_RB_UL*sizeof(int8_t)); gNB->nr_srs_info[id]->snr = (int8_t*)malloc16_clear(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*)); - gNB->nr_srs_info[id]->srs_estimated_channel_time = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted = (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**)); + gNB->nr_srs_info[id]->srs_estimated_channel_time = (int32_t ***)malloc16(Prx*sizeof(int32_t**)); + gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted = (int32_t ***)malloc16(Prx*sizeof(int32_t**)); for (i=0;inr_srs_info[id]->k_0_p[i] = (uint8_t*)malloc16_clear(MAX_NUM_NR_SRS_SYMBOLS*sizeof(uint8_t)); gNB->nr_srs_info[id]->srs_generated_signal[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); gNB->nr_srs_info[id]->srs_received_signal[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_ls_estimated_channel[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_freq[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_time[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_ls_estimated_channel[i] = (int32_t**)malloc16_clear(Prx*sizeof(int32_t*)); + gNB->nr_srs_info[id]->srs_estimated_channel_freq[i] = (int32_t**)malloc16_clear(Prx*sizeof(int32_t*)); + gNB->nr_srs_info[id]->srs_estimated_channel_time[i] = (int32_t**)malloc16_clear(Prx*sizeof(int32_t*)); + gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i] = (int32_t**)malloc16_clear(Prx*sizeof(int32_t*)); + for (int j = 0; j < Prx; j++) { + gNB->nr_srs_info[id]->srs_ls_estimated_channel[i][j] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_estimated_channel_freq[i][j] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_estimated_channel_time[i][j] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i][j] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + } } } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 709e43af85..2aa6400bfb 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -345,22 +345,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); ue->nr_srs_info->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); ue->nr_srs_info->k_0_p = (uint8_t**)malloc16_clear(fp->nb_antennas_rx*sizeof(uint8_t*)); - ue->nr_srs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - ue->nr_srs_info->srs_received_signal = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_ls_estimated_channel = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_freq = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_time_shifted = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); for (i=0; inb_antennas_rx; i++) { ue->nr_srs_info->k_0_p[i] = (uint8_t*)malloc16_clear(MAX_NUM_NR_SRS_SYMBOLS*sizeof(uint8_t)); - ue->nr_srs_info->srs_received_signal[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_ls_estimated_channel[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_freq[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_time[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); } - // RACH prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index b91f603f3c..91295d0015 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -28,6 +28,7 @@ #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" @@ -951,139 +952,228 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, int slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, - int32_t *srs_generated_signal, + int32_t **srs_generated_signal, int32_t **srs_received_signal, - int32_t **srs_estimated_channel_freq, - int32_t **srs_estimated_channel_time, - int32_t **srs_estimated_channel_time_shifted, + 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, int8_t *snr) { +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); +#endif + if(nr_srs_info->sc_list_length == 0) { LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); return -1; } NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - int32_t **srs_ls_estimated_channel = nr_srs_info->srs_ls_estimated_channel; + int32_t ***srs_ls_estimated_channel = nr_srs_info->srs_ls_estimated_channel; - 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]; + uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; + + uint8_t N_ap = 1<num_ant_ports; + uint8_t K_TC = 2<comb_size; + uint16_t m_SRS_b = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; + uint8_t fd_cdm = N_ap; + if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) { + fd_cdm = 2; + } + + int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + int16_t noise_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t ls_estimated[2]; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - memset(srs_ls_estimated_channel[ant], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); - memset(srs_estimated_channel_freq[ant], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); + for (int p_index = 0; p_index < N_ap; p_index++) { - int16_t *srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][nr_srs_info->sc_list[0]]; + memset(srs_ls_estimated_channel[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); + memset(srs_estimated_channel_freq[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant); +#endif - int16_t generated_real = srs_generated_signal[nr_srs_info->sc_list[sc_idx]] & 0xFFFF; - int16_t generated_imag = (srs_generated_signal[nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF; + uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } - int16_t received_real = srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] & 0xFFFF; - int16_t received_imag = (srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF; + int16_t *srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][p_index][subcarrier]; - // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. - // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. - ls_estimated[0] = (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits); - ls_estimated[1] = (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits); - srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000); + for (int k = 0; k < M_sc_b_SRS; k++) { - // Channel interpolation - if(srs_pdu->comb_size == 0) { - if(sc_idx == 0) { // First subcarrier case - // filt8_start is {12288,8192,4096,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8); - } else if(nr_srs_info->sc_list[sc_idx] < nr_srs_info->sc_list[sc_idx - 1]) { // Start of OFDM symbol case - // filt8_start is {12288,8192,4096,0,0,0,0,0} - srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx + 2]] - sizeof(uint64_t); - multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8); - } else if((sc_idx < (nr_srs_info->sc_list_length - 1) && nr_srs_info->sc_list[sc_idx + 1] < nr_srs_info->sc_list[sc_idx]) - || (sc_idx == (nr_srs_info->sc_list_length - 1))) { // End of OFDM symbol or last subcarrier cases - // filt8_end is {4096,8192,12288,16384,0,0,0,0} - multadd_real_vector_complex_scalar(filt8_end, ls_estimated, srs_estimated_channel16, 8); - } else if(sc_idx%2 == 1) { // 1st middle case - // filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0} - multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8); - } else if(sc_idx%2 == 0) { // 2nd middle case - // filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0} - multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8); - srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]; + if (k%fd_cdm==0) { + + ls_estimated[0] = 0; + ls_estimated[1] = 0; + uint16_t subcarrier_cdm = subcarrier; + + for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) { + + int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm] & 0xFFFF; + int16_t generated_imag = (srs_generated_signal[p_index][subcarrier_cdm] >> 16) & 0xFFFF; + + int16_t received_real = srs_received_signal[ant][subcarrier_cdm] & 0xFFFF; + int16_t received_imag = (srs_received_signal[ant][subcarrier_cdm] >> 16) & 0xFFFF; + + // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. + // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. + ls_estimated[0] += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits); + ls_estimated[1] += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits); + + // Subcarrier increment + subcarrier_cdm += K_TC; + if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) { + subcarrier_cdm=subcarrier_cdm-frame_parms->ofdm_symbol_size; + } + } } - } else { - if(sc_idx == 0) { // First subcarrier case - // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); - } else if(nr_srs_info->sc_list[sc_idx] < nr_srs_info->sc_list[sc_idx - 1]) { // Start of OFDM symbol case - srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx + 1]] - sizeof(uint64_t); - // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); - } else if((sc_idx < (nr_srs_info->sc_list_length - 1) && nr_srs_info->sc_list[sc_idx + 1] < nr_srs_info->sc_list[sc_idx]) - || (sc_idx == (nr_srs_info->sc_list_length - 1))) { // End of OFDM symbol or last subcarrier cases - // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16); - } else { // Middle case - // filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0} - multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16); - srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]; + + srs_ls_estimated_channel[ant][p_index][subcarrier] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000); + +#ifdef SRS_DEBUG + int subcarrier_log = subcarrier-subcarrier_offset; + if(subcarrier_log < 0) { + subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + } + if(subcarrier_log%12 == 0) { + LOG_I(NR_PHY,"------------------------------------ %d ------------------------------------\n", subcarrier_log/12); + LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); + } + LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + subcarrier_log, + (int16_t)(srs_generated_signal[p_index][subcarrier] & 0xFFFF), (int16_t)((srs_generated_signal[p_index][subcarrier] >> 16) & 0xFFFF), + (int16_t)(srs_received_signal[ant][subcarrier] & 0xFFFF), (int16_t)((srs_received_signal[ant][subcarrier] >> 16) & 0xFFFF), + ls_estimated[0], ls_estimated[1]); +#endif + + // Channel interpolation + if(srs_pdu->comb_size == 0) { + if(k == 0) { // First subcarrier case + // filt8_start is {12288,8192,4096,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8); + } else if(subcarrier < K_TC) { // Start of OFDM symbol case + // filt8_start is {12288,8192,4096,0,0,0,0,0} + srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][p_index][subcarrier + (K_TC<<1)] - sizeof(uint64_t); + multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8); + } else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases + // filt8_end is {4096,8192,12288,16384,0,0,0,0} + multadd_real_vector_complex_scalar(filt8_end, ls_estimated, srs_estimated_channel16, 8); + } else if(k%2 == 1) { // 1st middle case + // filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0} + multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8); + } else if(k%2 == 0) { // 2nd middle case + // filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0} + multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8); + srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][p_index][subcarrier]; + } + } else { + if(k == 0) { // First subcarrier case + // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); + } else if(subcarrier < K_TC) { // Start of OFDM symbol case + srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][p_index][subcarrier + K_TC] - sizeof(uint64_t); + // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16); + } else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases + // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16); + } else { // Middle case + // filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0} + multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16); + srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][p_index][subcarrier]; + } + } + + // Subcarrier increment + subcarrier += K_TC; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } + + } // for (int k = 0; k < M_sc_b_SRS; k++) + + // Compute noise + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } + uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS; + for (int k = 0; k < M_sc_b_SRS; k++) { + ch_real[base_idx+k] = (int16_t)(srs_estimated_channel_freq[ant][p_index][subcarrier] & 0xFFFF); + ch_imag[base_idx+k] = (int16_t)((srs_estimated_channel_freq[ant][p_index][subcarrier] >> 16) & 0xFFFF); + noise_real[base_idx+k] = abs((int16_t)(srs_ls_estimated_channel[ant][p_index][subcarrier] & 0xFFFF) - ch_real[base_idx+k]); + noise_imag[base_idx+k] = abs((int16_t)((srs_ls_estimated_channel[ant][p_index][subcarrier] >> 16) & 0xFFFF) - ch_imag[base_idx+k]); + subcarrier += K_TC; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; } } #ifdef SRS_DEBUG - uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; - int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; } - if(sc_idx == 0) { - LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant); + + for (int k = 0; k < K_TC*M_sc_b_SRS; k++) { + + int subcarrier_log = subcarrier-subcarrier_offset; + if(subcarrier_log < 0) { + subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; + } + + if(subcarrier_log%12 == 0) { + LOG_I(NR_PHY,"------------------------------------- %d -------------------------------------\n", subcarrier_log/12); + LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n"); + } + + LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + subcarrier_log, + (int16_t)(srs_ls_estimated_channel[ant][p_index][subcarrier]&0xFFFF), + (int16_t)((srs_ls_estimated_channel[ant][p_index][subcarrier]>>16)&0xFFFF), + (int16_t)(srs_estimated_channel_freq[ant][p_index][subcarrier]&0xFFFF), + (int16_t)((srs_estimated_channel_freq[ant][p_index][subcarrier]>>16)&0xFFFF), + noise_real[base_idx+(k/K_TC)], noise_imag[base_idx+(k/K_TC)]); + + // Subcarrier increment + subcarrier++; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", subcarrier_log/12); - LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); - } - LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", - subcarrier_log, - generated_real, generated_imag, - received_real, received_imag, - ls_estimated[0], ls_estimated[1]); #endif - } - // Compute noise - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - 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 + freq2time(gNB->frame_parms.ofdm_symbol_size, + (int16_t*) srs_estimated_channel_freq[ant][p_index], + (int16_t*) srs_estimated_channel_time[ant][p_index]); - // Convert to time domain - freq2time(gNB->frame_parms.ofdm_symbol_size, - (int16_t*) srs_estimated_channel_freq[ant], - (int16_t*) srs_estimated_channel_time[ant]); + memcpy(&srs_estimated_channel_time_shifted[ant][p_index][0], + &srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1], + (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - memcpy(&srs_estimated_channel_time_shifted[ant][0], - &srs_estimated_channel_time[ant][gNB->frame_parms.ofdm_symbol_size>>1], - (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); + memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1], + &srs_estimated_channel_time[ant][p_index][0], + (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - memcpy(&srs_estimated_channel_time_shifted[ant][gNB->frame_parms.ofdm_symbol_size>>1], - &srs_estimated_channel_time[ant][0], - (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); - } + } // for (int p_index = 0; p_index < N_ap; p_index++) + } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) // 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); + *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) + + calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); #ifdef SRS_DEBUG LOG_I(NR_PHY,"signal_power = %u\n", *signal_power); @@ -1095,83 +1185,48 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, 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<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; - uint8_t count_estimates = 0; + uint8_t n_noise_estimates = frame_parms->nb_antennas_rx*N_ap*srs_symbols_per_rb; uint64_t sum_re = 0; uint64_t sum_re2 = 0; uint64_t sum_im = 0; uint64_t sum_im2 = 0; - for (int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { + for (int rb = 0; rb < m_SRS_b; rb++) { - int subcarrier0 = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier0 < 0) { - subcarrier0 = subcarrier0 + frame_parms->ofdm_symbol_size; - } - int rb = subcarrier0/NR_NB_SC_PER_RB; + sum_re = 0; + sum_re2 = 0; + sum_im = 0; + sum_im2 = 0; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + for (int p_index = 0; p_index < N_ap; p_index++) { + uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS + rb*srs_symbols_per_rb; + for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) { + sum_re = sum_re + noise_real[base_idx+srs_symb]; + sum_re2 = sum_re2 + noise_real[base_idx+srs_symb]*noise_real[base_idx+srs_symb]; + sum_im = sum_im + noise_imag[base_idx+srs_symb]; + sum_im2 = sum_im2 + noise_imag[base_idx+srs_symb]*noise_imag[base_idx+srs_symb]; + } // for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) + } // for (int p_index = 0; p_index < N_ap; p_index++) + } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) - sum_re = sum_re + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; - sum_re2 = sum_re2 + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]*noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; - sum_im = sum_im + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; - sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; - - count_estimates++; - 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<nb_antennas_rx*nr_srs_info->sc_list_length) - + calc_power(noise_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + *noise_power = calc_power(noise_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) + + calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); *snr = dB_fixed((int32_t)((*signal_power<first_carrier_offset + srs_pdu->bwp_start*12; - uint8_t R = srs_pdu->comb_size == 0 ? 2 : 4; - for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; - if(subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; - } - if(sc_idx == 0) { - LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant); - } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", subcarrier_log/12); - LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm_\n"); - } - for(int r = 0; rsc_list[sc_idx]+r]&0xFFFF), - (int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]+r]>>16)&0xFFFF), - (int16_t)(srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]+r]&0xFFFF), - (int16_t)((srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]+r]>>16)&0xFFFF), - noise_real[ant*nr_srs_info->sc_list_length+sc_idx], - noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]); - } - - } - } LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", *noise_power, *snr); #endif diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 914b0d7385..c940853a8d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -71,11 +71,11 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, int slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, - int32_t *srs_generated_signal, + int32_t **srs_generated_signal, int32_t **srs_received_signal, - int32_t **srs_estimated_channel_freq, - int32_t **srs_estimated_channel_time, - int32_t **srs_estimated_channel_time_shifted, + 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, diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 6ed9277ce3..242ce102fb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -216,7 +216,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // Starting symbol position in the time domain uint8_t n_SRS_cs_max = srs_max_number_cs[srs_config_pdu->comb_size]; uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; // Number of resource blocks - uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; // Length of the SRS sequence + uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; // Length of the SRS sequence #ifdef SRS_DEBUG LOG_I(NR_PHY,"Frame = %i, slot = %i\n", frame_number, slot_number); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 0286b91d0f..6dc889bc83 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -246,10 +246,10 @@ typedef struct { uint8_t srs_generated_signal_bits; int32_t **srs_generated_signal; int32_t **srs_received_signal; - int32_t **srs_ls_estimated_channel; - int32_t **srs_estimated_channel_freq; - int32_t **srs_estimated_channel_time; - int32_t **srs_estimated_channel_time_shifted; + int32_t ***srs_ls_estimated_channel; + 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; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 5b3c4ac26d..297693c31d 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -862,7 +862,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { nr_srs_channel_estimation(gNB,frame_rx,slot_rx,srs_pdu, gNB->nr_srs_info[i], - gNB->nr_srs_info[i]->srs_generated_signal[0], + gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i]->srs_received_signal, gNB->nr_srs_info[i]->srs_estimated_channel_freq, gNB->nr_srs_info[i]->srs_estimated_channel_time, @@ -874,10 +874,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->nr_srs_info[i]->snr); 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))); + T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_freq[0][0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); T(T_GNB_PHY_UL_TIME_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_time_shifted[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted[0][0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); uint16_t num_srs = gNB->UL_INFO.srs_ind.number_of_pdus; gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0]; @@ -885,7 +885,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->UL_INFO.srs_ind.slot = slot_rx; gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle; gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; - gNB->srs_pdu_list[num_srs].timing_advance = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time); + gNB->srs_pdu_list[num_srs].timing_advance = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time[0]); gNB->srs_pdu_list[num_srs].num_symbols = 1<num_symbols; gNB->srs_pdu_list[num_srs].wide_band_snr = (*gNB->nr_srs_info[i]->snr + 64)<<1; gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<num_symbols;