From 4fe2d6d724c2d18cff17dd2ab67c6f86951d1d62 Mon Sep 17 00:00:00 2001 From: "Wilson W.K. Thong" <wilsonthong@astri.org> Date: Wed, 4 Jan 2017 11:22:45 +0800 Subject: [PATCH] fix noise power calculation and downlink CQI reporting see issue #177 --- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 97 +++++++++++++++---- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 47 ++++----- openair1/PHY/LTE_TRANSPORT/initial_sync.c | 2 +- openair1/PHY/LTE_TRANSPORT/proto.h | 27 ++++++ openair1/PHY/LTE_TRANSPORT/sss.c | 31 +++++- openair1/PHY/LTE_TRANSPORT/uci_tools.c | 1 + openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 2 + openair1/SCHED/phy_procedures_lte_ue.c | 14 ++- openair2/UTIL/LOG/vcd_signal_dumper.c | 3 + openair2/UTIL/LOG/vcd_signal_dumper.h | 3 + 10 files changed, 178 insertions(+), 49 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 90ebd07f60..51dc933db3 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -32,7 +32,8 @@ #define k1 ((long long int) 1000) #define k2 ((long long int) (1024-k1)) -//#define DEBUG_MEAS +//#define DEBUG_MEAS_RRC +//#define DEBUG_MEAS_UE #ifdef USER_MODE void print_shorts(char *s,short *x) @@ -165,23 +166,30 @@ int8_t set_RSRQ_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rs } void ue_rrc_measurements(PHY_VARS_UE *ue, - uint8_t subframe, - uint8_t abstraction_flag) + uint8_t slot, + uint8_t abstraction_flag) { - int aarx,rb; + uint8_t subframe = slot>>1; + int aarx,rb,n; int16_t *rxF,*rxF_pss,*rxF_sss; uint16_t Nid_cell = ue->frame_parms.Nid_cell; uint8_t eNB_offset,nu,l,nushift,k; uint16_t off; + uint8_t isPss; // indicate if this is a slot for extracting PSS + uint8_t isSss; // indicate if this is a slot for extracting SSS + int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS + int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS + int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation + int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value for (eNB_offset = 0; eNB_offset<1+ue->measurements.n_adj_cells; eNB_offset++) { if (eNB_offset==0) { ue->measurements.rssi = 0; - ue->measurements.n0_power_tot = 0; + //ue->measurements.n0_power_tot = 0; if (abstraction_flag == 0) { if ((ue->frame_parms.frame_type == FDD) && @@ -225,16 +233,66 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); - ue->measurements.n0_power_tot += 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/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); - } + } else { + LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n"); + } } - else if ((ue->frame_parms.frame_type == TDD) && - (subframe == 0)) { // TDD SSS, compute noise in DTX REs + else if ((ue->frame_parms.frame_type == TDD) && + ((slot == 2) || (slot == 12) || (slot == 1) || (slot == 11))) { // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation + +#if 1 // fixing REs extraction in noise power calculation + + // check if this slot has a PSS or SSS sequence + if ((slot == 2) || (slot == 12)) { + isPss = 1; + } else { + isPss = 0; + } + if ((slot == 1) || (slot == 11)) { + isSss = 1; + } else { + isSss = 0; + } + + if (isPss) { + pss_only_extract(ue, pss_ext); + xss_ext = pss_ext; + } + + if (isSss) { + sss_only_extract(ue, sss_ext); + xss_ext = sss_ext; + } + + // calculate noise power + int num_tot=0; // number of REs totally used in calculating noise power + for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { + + int num_per_rx=0; // number of REs used in caluclaing noise power for this RX antenna + ue->measurements.n0_power[aarx] = 0; + for (n=2; n<70; n++) { // skip the 2 REs next to PDSCH, i.e. n={0,1,70,71} + if (n==5) {n=67;} + re = (int16_t*)(&(xss_ext[aarx][n])); + im = re+1; + ue->measurements.n0_power[aarx] += (*re)*(*re) + (*im)*(*im); + num_per_rx++; + num_tot++; + } + + ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(num_per_rx)); + 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/(num_tot)); + ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); + +#else if (ue->frame_parms.Ncp==NORMAL) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { @@ -263,8 +321,9 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); - } - } + } +#endif + } } } // recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation @@ -286,7 +345,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, for (l=0,nu=0; l<=(4-ue->frame_parms.Ncp); l+=(4-ue->frame_parms.Ncp),nu=3) { k = (nu + nushift)%6; -#ifdef DEBUG_MEAS +#ifdef DEBUG_MEAS_RRC LOG_I(PHY,"[UE %d] Frame %d subframe %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",ue->Mod_id,ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,Nid_cell,nushift, eNB_offset,k,l); #endif @@ -364,7 +423,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, } -#ifdef DEBUG_MEAS +#ifdef DEBUG_MEAS_RRC // if (slot == 0) { @@ -498,10 +557,14 @@ void lte_ue_measurements(PHY_VARS_UE *ue, 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; -#ifdef DEBUG_MEAS - LOG_I(PHY,"[eNB %d] lte_ue_measurements: RSSI %d dBm, RSSI (digital) %d dB\n", - eNB_id,ue->measurements.rx_rssi_dBm[eNB_id], - ue->measurements.rx_power_avg_dB[eNB_id]); +#ifdef DEBUG_MEAS_UE + LOG_D(PHY,"[eNB %d] RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", + eNB_id, + 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_avg); #endif } diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1dfbc9d7df..0d27b1520f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5866,36 +5866,38 @@ uint8_t sinr2cqi(double sinr,uint8_t trans_mode) { // int flag_LA=0; + uint8_t retValue = 0; + if(flag_LA==0) { // Ideal Channel Estimation if (sinr<=-4.89) - return(0); + retValue = (0); else if (sinr < -3.53) - return(3); + retValue = (3); else if (sinr <= -1.93) - return(4); + retValue = (4); else if (sinr <= -0.43) - return(5); + retValue = (5); else if (sinr <= 1.11) - return(6); + retValue = (6); else if (sinr <= 3.26) - return(7); - else if (sinr <= 5) - return(8); - else if (sinr <= 7) - return(9); - else if (sinr <= 9) - return(10); - else if (sinr <= 11) - return(11); - else if (sinr <= 13) - return(12); + retValue = (7); + else if (sinr <= 5.0) + retValue = (8); + else if (sinr <= 7.0) + retValue = (9); + else if (sinr <= 9.0) + retValue = (10); + else if (sinr <= 11.0) + retValue = (11); + else if (sinr <= 13.0) + retValue = (12); else if (sinr <= 15.5) - return(13); + retValue = (13); else if (sinr <= 17.5) - return(14); - else if (sinr > 19.5) - return(15); + retValue = (14); + else + retValue = (15); } else { int h=0; int trans_mode_tmp; @@ -5909,11 +5911,12 @@ uint8_t sinr2cqi(double sinr,uint8_t trans_mode) for(h=0; h<16; h++) { if(sinr<=sinr_to_cqi[trans_mode_tmp][h]) - return(h); + retValue = (h); } } - return(0); + LOG_D(PHY, "sinr=%f trans_mode=%d cqi=%d\n", sinr, trans_mode, retValue); + return retValue; } //uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) { // diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c index 75c558f52c..9ba6f2e2ac 100644 --- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c @@ -88,7 +88,7 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) if (ue->frame_parms.frame_type == TDD) { ue_rrc_measurements(ue, - 1, + 2, 0); } else { diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 94aa21c717..325e4964f9 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1194,6 +1194,33 @@ int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars, MIMO_mode_t mimo_mode, uint32_t high_speed_flag, uint8_t is_secondary_ue); + +/*! \brief Extract PSS and SSS resource elements + @param phy_vars_ue Pointer to UE variables + @param[out] pss_ext contain the PSS signals after the extraction + @param[out] sss_ext contain the SSS signals after the extraction + @returns 0 on success +*/ +int pss_sss_extract(PHY_VARS_UE *phy_vars_ue, + int32_t pss_ext[4][72], + int32_t sss_ext[4][72]); + +/*! \brief Extract only PSS resource elements + @param phy_vars_ue Pointer to UE variables + @param[out] pss_ext contain the PSS signals after the extraction + @returns 0 on success +*/ +int pss_only_extract(PHY_VARS_UE *phy_vars_ue, + int32_t pss_ext[4][72]); + +/*! \brief Extract only SSS resource elements + @param phy_vars_ue Pointer to UE variables + @param[out] sss_ext contain the SSS signals after the extraction + @returns 0 on success +*/ +int sss_only_extract(PHY_VARS_UE *phy_vars_ue, + int32_t sss_ext[4][72]); + /*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix) @param phy_vars_ue Pointer to UE variables @param tot_metric Pointer to variable containing maximum metric under framing hypothesis (to be compared to other hypotheses diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c index 320d7ac75a..b3970a4429 100644 --- a/openair1/PHY/LTE_TRANSPORT/sss.c +++ b/openair1/PHY/LTE_TRANSPORT/sss.c @@ -146,9 +146,10 @@ int pss_ch_est(PHY_VARS_UE *ue, } -int pss_sss_extract(PHY_VARS_UE *ue, +int _do_pss_sss_extract(PHY_VARS_UE *ue, int32_t pss_ext[4][72], - int32_t sss_ext[4][72]) + int32_t sss_ext[4][72], + uint8_t doPss, uint8_t doSss) // add flag to indicate extracting only PSS, only SSS, or both { @@ -191,8 +192,8 @@ int pss_sss_extract(PHY_VARS_UE *ue, } for (i=0; i<12; i++) { - pss_rxF_ext[i]=pss_rxF[i]; - sss_rxF_ext[i]=sss_rxF[i]; + if (doPss) {pss_rxF_ext[i]=pss_rxF[i];} + if (doSss) {sss_rxF_ext[i]=sss_rxF[i];} } pss_rxF+=12; @@ -206,6 +207,28 @@ int pss_sss_extract(PHY_VARS_UE *ue, return(0); } +int pss_sss_extract(PHY_VARS_UE *phy_vars_ue, + int32_t pss_ext[4][72], + int32_t sss_ext[4][72]) +{ + return _do_pss_sss_extract(phy_vars_ue, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */); +} + +int pss_only_extract(PHY_VARS_UE *phy_vars_ue, + int32_t pss_ext[4][72]) +{ + static int32_t dummy[4][72]; + return _do_pss_sss_extract(phy_vars_ue, pss_ext, dummy, 1 /* doPss */, 0 /* doSss */); +} + + +int sss_only_extract(PHY_VARS_UE *phy_vars_ue, + int32_t sss_ext[4][72]) +{ + static int32_t dummy[4][72]; + return _do_pss_sss_extract(phy_vars_ue, dummy, sss_ext, 0 /* doPss */, 1 /* doSss */); +} + int16_t phase_re[7] = {16383, 25101, 30791, 32767, 30791, 25101, 16383}; int16_t phase_im[7] = {-28378, -21063, -11208, 0, 11207, 21062, 28377}; diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 37c5dc1432..467b1bbc9a 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -581,6 +581,7 @@ void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL) switch(uci_format) { case wideband_cqi_rank1_2A: #ifdef DEBUG_UCI + LOG_D(PHY,"[PRINT CQI] flat_LA %d\n", flag_LA); switch(N_RB_DL) { case 6: LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 4559aaa326..0aa0e75c67 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -260,6 +260,7 @@ uint32_t ulsch_encoding(uint8_t *a, // fill CQI/PMI information if (ulsch->O>0) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN); rnti = ue->pdcch_vars[eNB_id]->crnti; fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff); @@ -271,6 +272,7 @@ uint32_t ulsch_encoding(uint8_t *a, //LOG_I(PHY,"XXX saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi)); dlsch[0]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi; } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_OUT); } if (ulsch->O<=32) { diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 1c6aa6b20c..8b57d8706d 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -2042,7 +2042,11 @@ void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_f } } -void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) +void ue_measurement_procedures( + uint16_t l, // symbol index of each slot [0..6] + PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id, + uint16_t slot, // slot index of each radio frame [0..19] + uint8_t abstraction_flag,runmode_t mode) { LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; @@ -2074,7 +2078,7 @@ void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN); ue_rrc_measurements(ue, - subframe_rx, + slot, abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT); @@ -3379,7 +3383,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin stop_meas(&ue->ofdm_demod_stats); } - ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode); + ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); if ((l==pilot1) || ((pmch_flag==1)&(l==l2))) { LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); @@ -3392,7 +3396,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } } // for l=1..l2 - ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode); + ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); // If this is PMCH, call procedures and return if (pmch_flag == 1) { @@ -3483,7 +3487,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin stop_meas(&ue->ofdm_demod_stats); } - ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode); + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); } // for l=1..l2 diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c index 34fc8e97b8..d9142c6ea3 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.c +++ b/openair2/UTIL/LOG/vcd_signal_dumper.c @@ -283,6 +283,9 @@ const char* eurecomFunctionsNames[] = { "phy_ue_generate_prach", "phy_ue_ulsch_modulation", "phy_ue_ulsch_encoding", +#if 1 // add for debugging losing PDSCH immediately before and after reporting CQI + "phy_ue_ulsch_encoding_fill_cqi", +#endif "phy_ue_ulsch_scrambling", "phy_eNB_dlsch_modulation", "phy_eNB_dlsch_encoding", diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h index 0d1c507b74..95c5c9545f 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.h +++ b/openair2/UTIL/LOG/vcd_signal_dumper.h @@ -257,6 +257,9 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, +#if 1 // add for debugging losing PDSCH immediately before and after reporting CQI + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, +#endif VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_SCRAMBLING, VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, -- 2.26.2