From 3a983dbf9c7eecbb8924783d321ddb9d1c85e944 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 30 Nov 2021 18:24:51 +0000 Subject: [PATCH] LS channel estimation based on SRS at gNB --- openair1/PHY/INIT/nr_init.c | 5 ++ openair1/PHY/INIT/nr_init_ue.c | 5 ++ .../NR_ESTIMATION/nr_ul_channel_estimation.c | 60 +++++++++++++++++++ openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 10 ++++ .../PHY/NR_UE_TRANSPORT/srs_modulation_nr.c | 1 + openair1/PHY/defs_nr_common.h | 4 ++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 8 +++ 7 files changed, 93 insertions(+) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 929e1c050f..322f656c2b 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -198,9 +198,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, for (int id=0; idnr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); gNB->nr_srs_info[id]->srs_generated_signal = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); + gNB->nr_srs_info[id]->noise_power = (double*)malloc16_clear(sizeof(double)); 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 = (int32_t **)malloc16(Prx*sizeof(int32_t*)); for (i=0;inr_srs_info[id]->srs_received_signal[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_ls_estimated_channel[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_estimated_channel[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); } } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 3c9f90d121..56547e7617 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -325,9 +325,14 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, srs_vars[gNB_id]->active = false; ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); ue->nr_srs_info->srs_generated_signal = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); + ue->nr_srs_info->noise_power = (double*)malloc16_clear(sizeof(double)); 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 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); for (i=0; inb_antennas_rx; i++) { ue->nr_srs_info->srs_received_signal[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); + ue->nr_srs_info->srs_ls_estimated_channel[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); + ue->nr_srs_info->srs_estimated_channel[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); } if (abstraction_flag == 0) { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 1f164748bf..349bb52e3c 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -36,6 +36,7 @@ //#define DEBUG_CH //#define DEBUG_PUSCH +//#define SRS_DEBUG #define NO_INTERP 1 #define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y))) @@ -1091,3 +1092,62 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, }// last symbol check }//Antenna loop } + +int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_srs_pdu_t *srs_pdu, + nr_srs_info_t *nr_srs_info, + int32_t *srs_generated_signal, + int32_t **srs_received_signal, + int32_t **srs_estimated_channel, + double *noise_power) { + + if(nr_srs_info->n_symbs==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; + uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; + + for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + + memset(srs_ls_estimated_channel[ant], 0, frame_parms->samples_per_frame*sizeof(int32_t)); + memset(srs_estimated_channel[ant], 0, frame_parms->samples_per_frame*sizeof(int32_t)); + + for(int sc_idx = 0; sc_idx < nr_srs_info->n_symbs; sc_idx++) { + + int16_t generated_real = srs_generated_signal[nr_srs_info->subcarrier_idx[sc_idx] + subcarrier_offset]&0xFFFF; + int16_t generated_imag = (srs_generated_signal[nr_srs_info->subcarrier_idx[sc_idx] + subcarrier_offset]>>16)&0xFFFF; + + int16_t received_real = srs_received_signal[ant][nr_srs_info->subcarrier_idx[sc_idx] + subcarrier_offset]&0xFFFF; + int16_t received_imag = (srs_received_signal[ant][nr_srs_info->subcarrier_idx[sc_idx] + subcarrier_offset]>>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. + int16_t ls_estimated_real = (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits); + int16_t ls_estimated_imag = (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->subcarrier_idx[sc_idx] + subcarrier_offset] = ls_estimated_real + (((int32_t)ls_estimated_imag<<16)&0xFFFF0000); + +#ifdef SRS_DEBUG + if(sc_idx == 0) { + LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant); + } + if(nr_srs_info->subcarrier_idx[sc_idx]%12 == 0) { + LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", nr_srs_info->subcarrier_idx[sc_idx]/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", + nr_srs_info->subcarrier_idx[sc_idx], + generated_real, generated_imag, + received_real, received_imag, + ls_estimated_real, ls_estimated_imag); +#endif + } + } + + return 0; +} \ No newline at end of file diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index fd3403236e..cafb181d73 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -62,4 +62,14 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, uint8_t nr_tti_rx, unsigned char symbol, uint32_t nb_re_pusch); + +int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_srs_pdu_t *srs_pdu, + nr_srs_info_t *nr_srs_info, + int32_t *srs_generated_signal, + int32_t **srs_received_signal, + int32_t **srs_estimated_channel, + double *noise_power); #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 32a09549c8..d1521943fd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -120,6 +120,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, if(nr_srs_info) { nr_srs_info->n_symbs = 0; + nr_srs_info->srs_generated_signal_bits = log2_approx(amp); } #ifdef SRS_DEBUG diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 2eb05a145e..ca8c95bc40 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -243,8 +243,12 @@ typedef struct { typedef struct { uint16_t n_symbs; uint16_t subcarrier_idx[6*NR_MAX_NB_RB]; + 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; + double *noise_power; } 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 d56318ef16..1f01bc4a46 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -804,6 +804,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } nr_get_srs_signal(gNB,frame_rx,slot_rx,srs_pdu, gNB->nr_srs_info[i], gNB->nr_srs_info[i]->srs_received_signal); + + nr_srs_channel_estimation(gNB,frame_rx,slot_rx,srs_pdu, + gNB->nr_srs_info[i], + gNB->nr_srs_info[i]->srs_generated_signal, + gNB->nr_srs_info[i]->srs_received_signal, + gNB->nr_srs_info[i]->srs_estimated_channel, + gNB->nr_srs_info[i]->noise_power); + srs->active = 0; } }