From 8aac96062a6896f73687596acfdd931a0fae958c Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 15 Dec 2021 17:02:57 +0000 Subject: [PATCH] Add UL time channel estimation based on SRS --- common/utils/T/T_messages.txt | 8 +- common/utils/T/tracer/gnb.c | 27 ++++- openair1/PHY/INIT/nr_init.c | 2 + openair1/PHY/INIT/nr_init_ue.c | 2 + .../NR_ESTIMATION/nr_ul_channel_estimation.c | 102 ++++++++---------- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 1 + openair1/PHY/defs_nr_common.h | 1 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 6 +- 8 files changed, 84 insertions(+), 65 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 81ad3acc27..6b8d5777ab 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -93,8 +93,12 @@ ID = GNB_PHY_PUCCH_PUSCH_IQ DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB FORMAT = int,frame : int,slot : buffer,rxdataF -ID = GNB_PHY_UL_CHANNEL_ESTIMATE - DESC = gNodeB channel estimation in the time/frequency domain +ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE + DESC = gNodeB channel estimation in the frequency domain + GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB + FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t +ID = GNB_PHY_UL_TIME_CHANNEL_ESTIMATE + DESC = gNodeB channel estimation in the time domain GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t ID = GNB_PHY_PRACH_INPUT_SIGNAL diff --git a/common/utils/T/tracer/gnb.c b/common/utils/T/tracer/gnb.c index 43d3368c42..342c2e8cb2 100644 --- a/common/utils/T/tracer/gnb.c +++ b/common/utils/T/tracer/gnb.c @@ -18,12 +18,14 @@ int next_ue_id; typedef struct { widget *pucch_pusch_iq_plot; widget *ul_freq_estimate_ue_xy_plot; + widget *ul_time_estimate_ue_xy_plot; widget *current_ue_label; widget *current_ue_button; widget *prev_ue_button; widget *next_ue_button; logger *pucch_pusch_iq_logger; logger *ul_freq_estimate_ue_logger; + logger *ul_time_estimate_ue_logger; } gnb_gui; typedef struct { @@ -93,6 +95,9 @@ static void set_current_ue(gui *g, gnb_data *e, int ue) sprintf(s, "UL channel estimation in frequency domain [UE %d]", ue); xy_plot_set_title(g, e->e->ul_freq_estimate_ue_xy_plot, s); + + sprintf(s, "UL channel estimation in time domain [UE %d]", ue); + xy_plot_set_title(g, e->e->ul_time_estimate_ue_xy_plot, s); } void reset_ue_ids(void) @@ -141,7 +146,7 @@ static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, g logger *l; view *v; - main_window = new_toplevel_window(g, 1050, 230, "gNB tracer"); + main_window = new_toplevel_window(g, 1500, 230, "gNB tracer"); top_container = new_container(g, VERTICAL); widget_add_child(g, main_window, top_container, -1); @@ -179,17 +184,28 @@ static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, g logger_add_view(l, v); e->pucch_pusch_iq_logger = l; - /* UL estimated channel */ - w = new_xy_plot(g, 600, 200, "", 50); + /* UL channel estimation in frequency domain */ + w = new_xy_plot(g, 490, 200, "", 50); e->ul_freq_estimate_ue_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 100*10, -10, 80); - l = new_framelog(h, database, "GNB_PHY_UL_CHANNEL_ESTIMATE", "subframe", "chest_t"); + l = new_framelog(h, database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", "subframe", "chest_t"); framelog_set_update_only_at_sf9(l, 0); v = new_view_xy(100*10, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE); logger_add_view(l, v); e->ul_freq_estimate_ue_logger = l; + /* UL channel estimation in time domain */ + w = new_xy_plot(g, 490, 200, "", 50); + e->ul_time_estimate_ue_xy_plot = w; + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, 0, 100*10, -10, 80); + l = new_framelog(h, database, "GNB_PHY_UL_TIME_CHANNEL_ESTIMATE", "subframe", "chest_t"); + framelog_set_update_only_at_sf9(l, 0); + v = new_view_xy(100*10, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE); + logger_add_view(l, v); + e->ul_time_estimate_ue_logger = l; + set_current_ue(g, ed, ed->ue); register_notifier(g, "click", e->current_ue_button, click, ed); register_notifier(g, "click", e->prev_ue_button, click, ed); @@ -233,7 +249,8 @@ int main(int n, char **v) h = new_handler(database); on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1); - on_off(database, "GNB_PHY_UL_CHANNEL_ESTIMATE", is_on, 1); + on_off(database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", is_on, 1); + on_off(database, "GNB_PHY_UL_TIME_CHANNEL_ESTIMATE", is_on, 1); gnb_data.ue = 0; gnb_data.e = ⪚ diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 22149349ab..89b76f9131 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -202,10 +202,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, 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*)); 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_freq[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_estimated_channel_time[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 888e05dea2..2bd6922302 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -329,10 +329,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, 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 *) ); 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_freq[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); + ue->nr_srs_info->srs_estimated_channel_time[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 eb6973d7ee..90d385f50b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -41,6 +41,41 @@ #define NO_INTERP 1 #define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y))) +void freq2time(uint16_t ofdm_symbol_size, + int16_t *freq_signal, + int16_t *time_signal) { + + switch (ofdm_symbol_size) { + case 128: + idft(IDFT_128, freq_signal, time_signal, 1); + break; + case 256: + idft(IDFT_256, freq_signal, time_signal, 1); + break; + case 512: + idft(IDFT_512, freq_signal, time_signal, 1); + break; + case 1024: + idft(IDFT_1024, freq_signal, time_signal, 1); + break; + case 1536: + idft(IDFT_1536, freq_signal, time_signal, 1); + break; + case 2048: + idft(IDFT_2048, freq_signal, time_signal, 1); + break; + case 4096: + idft(IDFT_4096, freq_signal, time_signal, 1); + break; + case 8192: + idft(IDFT_8192, freq_signal, time_signal, 1); + break; + default: + idft(IDFT_512, freq_signal, time_signal, 1); + break; + } +} + int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned char Ns, unsigned short p, @@ -899,63 +934,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif // Convert to time domain - - switch (gNB->frame_parms.ofdm_symbol_size) { - case 128: - idft(IDFT_128,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 256: - idft(IDFT_256,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 512: - idft(IDFT_512,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 1024: - idft(IDFT_1024,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 1536: - idft(IDFT_1536,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 2048: - idft(IDFT_2048,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 4096: - idft(IDFT_4096,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - case 8192: - idft(IDFT_8192,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - - default: - idft(IDFT_512,(int16_t*) &ul_ch_estimates[aarx][symbol_offset], - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - } - + freq2time(gNB->frame_parms.ofdm_symbol_size, + (int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx]); } #ifdef DEBUG_CH @@ -1111,6 +1092,7 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, int32_t *srs_generated_signal, int32_t **srs_received_signal, int32_t **srs_estimated_channel_freq, + int32_t **srs_estimated_channel_time, uint32_t *noise_power) { if(nr_srs_info->n_symbs==0) { @@ -1131,6 +1113,7 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, memset(srs_ls_estimated_channel[ant], 0, frame_parms->samples_per_frame*sizeof(int32_t)); memset(srs_estimated_channel_freq[ant], 0, frame_parms->samples_per_frame*sizeof(int32_t)); + memset(srs_estimated_channel_time[ant], 0, frame_parms->samples_per_frame*sizeof(int32_t)); int16_t *srs_estimated_channel16 = (int16_t *)&srs_estimated_channel_freq[ant][nr_srs_info->subcarrier_idx[0]]; @@ -1213,6 +1196,11 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, prev_ls_estimated[0], prev_ls_estimated[1]); #endif } + + // 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]); } *noise_power = calc_power(noise_real,frame_parms->nb_antennas_rx*nr_srs_info->n_symbs) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index e361684f5d..bfb1627c0d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -71,5 +71,6 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, int32_t *srs_generated_signal, int32_t **srs_received_signal, int32_t **srs_estimated_channel_freq, + int32_t **srs_estimated_channel_time, uint32_t *noise_power); #endif diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index e5be7f820b..1fe442b7f5 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -248,6 +248,7 @@ typedef struct { int32_t **srs_received_signal; int32_t **srs_ls_estimated_channel; int32_t **srs_estimated_channel_freq; + int32_t **srs_estimated_channel_time; uint32_t *noise_power; } nr_srs_info_t; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index ef0a7b1dc5..ad998ac505 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -810,11 +810,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { 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, gNB->nr_srs_info[i]->noise_power); - T(T_GNB_PHY_UL_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(slot_rx%10), T_INT(0), + T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(slot_rx%10), T_INT(0), T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_freq[0], 100 * 4)); + T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(slot_rx%10), T_INT(0), + T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_time[0], 100 * 4)); + srs->active = 0; } }