From 51a72b847947e550adef85514e529247971848eb Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 9 Mar 2022 15:07:23 +0000 Subject: [PATCH] LS channel estimation at UE based on CSI-RS --- openair1/PHY/INIT/nr_init_ue.c | 25 +++++++++++++ openair1/PHY/NR_TRANSPORT/nr_csi_rs.c | 3 +- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 51 ++++++++++++++++++++++++++- openair1/PHY/defs_nr_common.h | 4 +++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 04c4b5a7ca..fd9a021a80 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -364,11 +364,16 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); } } + ue->nr_csi_rs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); ue->nr_csi_rs_info->csi_rs_generated_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) ); ue->nr_csi_rs_info->csi_rs_received_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) ); + ue->nr_csi_rs_info->csi_rs_ls_estimated_channel = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) ); + ue->nr_csi_rs_info->csi_rs_estimated_channel_freq = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) ); for (i=0; inb_antennas_rx; i++) { ue->nr_csi_rs_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); ue->nr_csi_rs_info->csi_rs_received_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); + ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); + ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); } ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); @@ -647,6 +652,26 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->pdcch_vars[th_id][gNB_id]); } + for (int i = 0; i < fp->nb_antennas_rx; i++) { + free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal[i]); + free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal[i]); + free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i]); + free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i]); + } + for (int slot=0; slotslots_per_frame; slot++) { + for (int symb=0; symbsymbols_per_slot; symb++) { + free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]); + } + free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]); + } + free_and_zero(ue->nr_csi_rs_info->noise_power); + free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs); + free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal); + free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal); + free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel); + free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq); + free_and_zero(ue->nr_csi_rs_info); + for (int i = 0; i < fp->nb_antennas_rx; i++) { free_and_zero(ue->nr_srs_info->srs_received_signal[i]); free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]); diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c index 2dc41aa015..85c49b7eb2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c @@ -79,6 +79,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, uint8_t fi = 0; double rho, alpha; uint32_t beta = amp; + nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp); AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n"); @@ -639,7 +640,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; } #ifdef NR_CSIRS_DEBUG - printf("l,k (%d %d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000, + printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000, ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)], ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]); #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index c0006beada..1f34bc75ee 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -63,7 +63,7 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, #ifdef NR_CSIRS_DEBUG int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[ant][symbol_offset+dataF_offset]; - LOG_I(NR_PHY, "l,k (%d %d) \t tx (%d,%d) \t rx (%d,%d)\n", + LOG_I(NR_PHY, "l,k (%2d,%3d) |\ttx (%4d,%4d)\trx (%4d,%4d)\n", symb, nr_csi_rs_info->map_list[symb][k_id], tx_csi_rs_signal[k<<1], @@ -78,6 +78,48 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, return 0; } +int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_csi_rs_info_t *nr_csi_rs_info, + int32_t **csi_rs_generated_signal, + int32_t **csi_rs_received_signal, + int32_t **csi_rs_estimated_channel_freq, + uint32_t *noise_power) { + + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; + int16_t ls_estimated[2]; + + for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) { + + uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; + int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[ant][symbol_offset+dataF_offset]; + int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant][symbol_offset]; + + for(int k_id = 0; k_idk_list_length[symb]; k_id++) { + uint16_t k = nr_csi_rs_info->map_list[symb][k_id]; + ls_estimated[0] = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[k<<1] + (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[(k<<1)+1])>>nr_csi_rs_info->csi_rs_generated_signal_bits); + ls_estimated[1] = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[(k<<1)+1] - (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[k<<1])>>nr_csi_rs_info->csi_rs_generated_signal_bits); + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "l,k (%2d,%3d) |\ttx (%4d,%4d)\trx (%4d,%4d)\tls (%4d,%4d)\n", + symb, + nr_csi_rs_info->map_list[symb][k_id], + tx_csi_rs_signal[k<<1], + tx_csi_rs_signal[(k<<1)+1], + rx_csi_rs_signal[k<<1], + rx_csi_rs_signal[(k<<1)+1], + ls_estimated[0], + ls_estimated[1]); +#endif + } + } + } + + return 0; +} + int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { return 0; } @@ -117,5 +159,12 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t nr_get_csi_rs_signal(ue, proc, ue->nr_csi_rs_info, ue->nr_csi_rs_info->csi_rs_received_signal); + nr_csi_rs_channel_estimation(ue, + proc, + ue->nr_csi_rs_info, + ue->nr_csi_rs_info->csi_rs_generated_signal, + ue->nr_csi_rs_info->csi_rs_received_signal, + ue->nr_csi_rs_info->csi_rs_estimated_channel_freq, + ue->nr_csi_rs_info->noise_power); return 0; } diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 1863aaa33a..de307dac32 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -268,8 +268,12 @@ typedef struct { uint32_t ***nr_gold_csi_rs; uint16_t k_list_length[NR_SYMBOLS_PER_SLOT]; uint16_t map_list[NR_SYMBOLS_PER_SLOT][NR_MAX_CSI_RS_LENGTH]; + uint8_t csi_rs_generated_signal_bits; int32_t **csi_rs_generated_signal; int32_t **csi_rs_received_signal; + int32_t **csi_rs_ls_estimated_channel; + int32_t **csi_rs_estimated_channel_freq; + uint32_t *noise_power; } nr_csi_rs_info_t; typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;