From 3986d5764d2932dc13da73f1b29354933248b2ef Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 12 Nov 2020 10:05:31 +0100 Subject: [PATCH] Implemented CQI measurement at NR UE - fixes for nr_ue_measurement function - Introduced nr_rrc_measurement function - removed unused params - replaced hardcoded params - code cleanup temp --- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 6 +- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 187 +++++++++++------- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 51 ++--- 3 files changed, 140 insertions(+), 104 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 419f84d418..31f3968326 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -86,11 +86,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, void nr_ue_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - unsigned int subframe_offset, - unsigned char N0_symbol, - unsigned char abstraction_flag, - unsigned char rank_adaptation, - uint8_t subframe); + uint8_t slot); void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index ee67a08472..9e13efa249 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -19,6 +19,18 @@ * contact@openairinterface.org */ +/*! \file nr_ue_measurements.c + * \brief UE measurements routines + * \author R. Knopp, G. Casati + * \date 2020 + * \version 0.1 + * \company Eurecom, Fraunhofer IIS + * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de + * \note + * \warning + */ + +#include "nr-softmodem-common.h" #include "PHY/defs_nr_UE.h" #include "PHY/phy_extern_nr_ue.h" #include "common/utils/LOG/log.h" @@ -82,98 +94,84 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index) return -140.0; } - void nr_ue_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - unsigned int subframe_offset, - unsigned char N0_symbol, - unsigned char abstraction_flag, - unsigned char rank_adaptation, - uint8_t subframe) + uint8_t slot) { - int aarx, aatx, eNB_id = 0; - + int aarx, aatx, gNB_id = 0; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - - int ch_offset, rank_tm3_tm4 = 0; + int ch_offset = frame_parms->ofdm_symbol_size*2; + NR_UE_DLSCH_t *dlsch = ue->dlsch[proc->thread_id][gNB_id][0]; + uint8_t harq_pid = dlsch->current_harq_pid; + int N_RB_DL = dlsch->harq_processes[harq_pid]->nb_rb; ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; - - /*int16_t *dl_ch; - dl_ch = (int16_t *)&ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates[eNB_id][ch_offset];*/ - - ch_offset = ue->frame_parms.ofdm_symbol_size*2; // signal measurements - for (eNB_id=0; eNB_idn_connected_eNB; eNB_id++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { - for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { - ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = - (signal_energy_nodc(&ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates[eNB_id][ch_offset], - (50*12))); + for (gNB_id = 0; gNB_id < ue->n_connected_eNB; gNB_id++){ - if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0) - ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; + ue->measurements.rx_power_tot[gNB_id] = 0; - ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++){ - if (aatx==0) - ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; - else - ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; - } //aatx + ue->measurements.rx_power[gNB_id][aarx] = 0; - ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); + for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){ - if (aarx==0) - ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx]; - else - ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx]; - } //aarx + ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = (signal_energy_nodc(&ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates[gNB_id][ch_offset], N_RB_DL*NR_NB_SC_PER_RB)); - ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]); + if (ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]<0) + ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = 0; - } //eNB_id - - eNB_id=0; + ue->measurements.rx_spatial_power_dB[gNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]); + ue->measurements.rx_power[gNB_id][aarx] += ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]; - if (ue->transmission_mode[eNB_id]!=4 && ue->transmission_mode[eNB_id]!=3) - ue->measurements.rank[eNB_id] = 0; - else - ue->measurements.rank[eNB_id] = rank_tm3_tm4; + } + + ue->measurements.rx_power_dB[gNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[gNB_id][aarx]); + ue->measurements.rx_power_tot[gNB_id] += ue->measurements.rx_power[gNB_id][aarx]; + + } + + ue->measurements.rx_power_tot_dB[gNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[gNB_id]); + + } // filter to remove jitter if (ue->init_averaging == 0) { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) - ue->measurements.rx_power_avg[eNB_id] = (int) - (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) + - (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10); - //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, - ue->measurements.n0_power_avg = (int) - (((k1*((long long int) (ue->measurements.n0_power_avg))) + - (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); + for (gNB_id = 0; gNB_id < ue->n_connected_eNB; gNB_id++) + ue->measurements.rx_power_avg[gNB_id] = (int)(((k1*((long long int)(ue->measurements.rx_power_avg[gNB_id]))) + (k2*((long long int)(ue->measurements.rx_power_tot[gNB_id])))) >> 10); + + ue->measurements.n0_power_avg = (int)(((k1*((long long int) (ue->measurements.n0_power_avg))) + (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); + + LOG_D(PHY, "Noise Power Computation: k1 %d k2 %d n0 avg %lu n0 tot %lu\n", k1, k2, ue->measurements.n0_power_avg, ue->measurements.n0_power_tot); + } else { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) - ue->measurements.rx_power_avg[eNB_id] = ue->measurements.rx_power_tot[eNB_id]; + + for (gNB_id = 0; gNB_id < ue->n_connected_eNB; gNB_id++) + ue->measurements.rx_power_avg[gNB_id] = ue->measurements.rx_power_tot[gNB_id]; ue->measurements.n0_power_avg = ue->measurements.n0_power_tot; ue->init_averaging = 0; + } - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - ue->measurements.rx_power_avg_dB[eNB_id] = dB_fixed( ue->measurements.rx_power_avg[eNB_id]); - ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot); - ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg); - ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB; - LOG_D(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", - eNB_id, - subframe, - ue->measurements.rx_rssi_dBm[eNB_id], - ue->measurements.rx_power_avg_dB[eNB_id], - ue->measurements.wideband_cqi_avg[eNB_id], - ue->measurements.rx_power_avg[eNB_id], - ue->measurements.n0_power_tot); + for (gNB_id = 0; gNB_id < ue->n_connected_eNB; gNB_id++) { + + ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]); + ue->measurements.wideband_cqi_tot[gNB_id] = dB_fixed2(ue->measurements.rx_power_tot[gNB_id], ue->measurements.n0_power_tot); + ue->measurements.wideband_cqi_avg[gNB_id] = dB_fixed2(ue->measurements.rx_power_avg[gNB_id], ue->measurements.n0_power_avg); + ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->rx_total_gain_dB; + + LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", + gNB_id, + slot, + ue->measurements.rx_rssi_dBm[gNB_id], + ue->measurements.rx_power_avg_dB[gNB_id], + ue->measurements.wideband_cqi_avg[gNB_id], + ue->measurements.rx_power_avg[gNB_id], + ue->measurements.n0_power_tot); } #if defined(__x86_64__) || defined(__i386__) @@ -252,3 +250,60 @@ void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue, ue->measurements.rsrp[eNB_offset]); } + +void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t slot){ + + uint8_t k; + int aarx, nb_nulls; + int16_t *rxF_sss; + uint8_t k_left = 48; + uint8_t k_right = 183; + uint8_t k_length = 8; + uint8_t l_sss = ue->symbol_offset + 2; + unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; + ue->measurements.n0_power_tot = 0; + + LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss); + + for (aarx = 0; aarxframe_parms.nb_antennas_rx; aarx++) { + + nb_nulls = 0; + ue->measurements.n0_power[aarx] = 0; + rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; + + //-ve spectrum from SSS + for(k = k_left; k < k_left + k_length; k++){ + + #ifdef DEBUG_MEAS_RRC + LOG_I(PHY, "In %s -rxF_sss %d %d\n", __FUNCTION__, rxF_sss[k*2], rxF_sss[k*2 + 1]); + #endif + + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[k*2]*rxF_sss[k*2]) + ((int32_t)rxF_sss[k*2 + 1]*rxF_sss[k*2 + 1])); + nb_nulls++; + + } + + //+ve spectrum from SSS + for(k = k_right; k < k_right + k_length; k++){ + + #ifdef DEBUG_MEAS_RRC + LOG_I(PHY, "In %s +rxF_sss %d %d\n", __FUNCTION__, rxF_sss[k*2], rxF_sss[k*2 + 1]); + #endif + + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[k*2]*rxF_sss[k*2]) + ((int32_t)rxF_sss[k*2 + 1]*rxF_sss[k*2 + 1])); + nb_nulls++; + + } + + ue->measurements.n0_power[aarx] /= nb_nulls; + ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]); + ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; + + } + + ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/aarx); + LOG_I(PHY, "In %s slot %d Noise Level %d ue->measurements.n0_power_tot_dB %d \n", __FUNCTION__, slot, ue->measurements.n0_power_tot, ue->measurements.n0_power_tot_dB); + +} diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 924da8e30e..2f903dc6dd 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -230,14 +230,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } -void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0..6] - PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t eNB_id, - uint16_t slot, // slot index of each radio frame [0..19] - runmode_t mode) -{ - LOG_D(PHY,"ue_measurement_procedures l %u Ncp %d\n",l,ue->frame_parms.Ncp); +void nr_ue_measurement_procedures(uint16_t l, + PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t eNB_id, + uint16_t slot, + runmode_t mode){ NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; int frame_rx = proc->frame_rx; @@ -245,18 +243,14 @@ void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0 VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); if (l==2) { - // UE measurements on symbol 0 - LOG_D(PHY,"Calling measurements nr_slot_rx %d, rxdata %p\n",nr_slot_rx,ue->common_vars.rxdata); -/* - nr_ue_measurements(ue, - proc, - 0, - 0, - 0, - 0, - nr_slot_rx); -*/ - //(nr_slot_rx*frame_parms->samples_per_slot+ue->rx_offset) % frame_parms->samples_per_frame + + LOG_D(PHY,"Doing UE measurement procedures in symbol l %u Ncp %d nr_slot_rx %d, rxdata %p\n", + l, + ue->frame_parms.Ncp, + nr_slot_rx, + ue->common_vars.rxdata); + + nr_ue_measurements(ue, proc, nr_slot_rx); #if T_TRACER if(slot == 0) @@ -1761,6 +1755,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, 0, 16384); } + + LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); + nr_ue_rrc_measurements(ue, proc, nr_slot_rx); } if ((frame_rx%64 == 0) && (nr_slot_rx==0)) { @@ -1865,19 +1862,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, ue->dlsch[proc->thread_id][gNB_id][0], NULL); - //printf("phy procedure pdsch start measurement\n"); - nr_ue_measurement_procedures(2,ue,proc,gNB_id,nr_slot_rx,mode); - - /* - write_output("rxF.m","rxF",&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],fp->ofdm_symbol_size*14,1,1); - write_output("rxF_ch.m","rxFch",&ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates[0][0],fp->ofdm_symbol_size*14,1,1); - write_output("rxF_ch_ext.m","rxFche",&ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0][2*50*12],50*12,1,1); - write_output("rxF_ext.m","rxFe",&ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_ext[0][0],50*12*14,1,1); - write_output("rxF_comp.m","rxFc",&ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0][0],fp->N_RB_DL*12*14,1,1); - write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0); - */ - - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx, mode); } // do procedures for SI-RNTI