diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index e7ca3c99db..53ca4bf762 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -106,10 +106,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned char symbol, int ul_id, unsigned short bwp_start_subcarrier, - nfapi_nr_pusch_pdu_t *pusch_pdu) { - c16_t pilot[3280] __attribute__((aligned(16))); - int16_t *fdcl, *fdcr, *fdclh, *fdcrh; + nfapi_nr_pusch_pdu_t *pusch_pdu, + int *max_ch) { + c16_t pilot[3280] __attribute__((aligned(16))); const int chest_freq = gNB->chest_freq; #ifdef DEBUG_CH @@ -137,31 +137,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, k0, symbol); - switch (nushift) { - case 0: - fdcl = filt8_dcl0; - fdcr = filt8_dcr0; - fdclh = filt8_dcl0_h; - fdcrh = filt8_dcr0_h; - break; - - case 1: - fdcl = filt8_dcl1; - fdcr = filt8_dcr1; - fdclh = filt8_dcl1_h; - fdcrh = filt8_dcr1_h; - break; - - default: -#ifdef DEBUG_CH - if (debug_ch_est) - fclose(debug_ch_est); - -#endif - return(-1); - break; - } - //------------------generate DMRS------------------// if(pusch_pdu->ul_dmrs_scrambling_id != gNB->pusch_gold_init[pusch_pdu->scid]) { @@ -232,6 +207,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } c16_t ch16= {.r=(int16_t)ch.r, .i=(int16_t)ch.i}; + *max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i))); // Channel interpolation for (int k_line = 0; k_line <= 1; k_line++) { @@ -259,39 +235,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } } - // check if PRB crosses DC and improve estimates around DC - if ((bwp_start_subcarrier < symbolSize) && (bwp_start_subcarrier+nb_rb_pusch*12 >= symbolSize)) { - ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; - const uint16_t idxDC = symbolSize - bwp_start_subcarrier; - re_offset = k0; - pil = pilot + idxDC / 2 - 1; - ul_ch += idxDC - 2 ; - ul_ch = memset(ul_ch, 0, sizeof(*ul_ch)*5); - re_offset = (re_offset + idxDC - 2) % symbolSize; - const c16_t ch=c16mulShift(*pil, - rxdataF[soffset+nushift+re_offset], - 15); - - // for proper alignment of SIMD vectors - if((gNB->frame_parms.N_RB_UL&1)==0) { - c16multaddVectRealComplex(fdcl, &ch, ul_ch-2, 8); - pil += 2; - re_offset = (re_offset+4) % symbolSize; - const c16_t ch_tmp=c16mulShift(*pil, - rxdataF[nushift+re_offset], - 15); - c16multaddVectRealComplex(fdcr, &ch_tmp, ul_ch-2, 8); - } else { - c16multaddVectRealComplex(fdclh, &ch, ul_ch, 8); - pil += 2; - re_offset = (re_offset+4) % symbolSize; - const c16_t ch_tmp=c16mulShift(*pil, - rxdataF[soffset+nushift+re_offset], - 15); - c16multaddVectRealComplex(fdcrh, &ch_tmp, ul_ch, 8); - } - } - #ifdef DEBUG_PUSCH ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; @@ -304,8 +247,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, printf("\n"); } - #endif + } else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && chest_freq == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation"); c16_t *pil = pilot; @@ -332,6 +275,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, multadd_real_four_symbols_vector_complex_scalar(filt8_ml2, &ch_l, ul_ch); + *max_ch = max(*max_ch, max(abs(ch_l.r), abs(ch_l.i))); + re_offset = (re_offset+5)%symbolSize; ch_r=c16mulShift(*pil, rxdataF[soffset+nushift+re_offset], @@ -339,6 +284,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, multadd_real_four_symbols_vector_complex_scalar(filt8_mr2, &ch_r, ul_ch); + *max_ch = max(*max_ch, max(abs(ch_r.r), abs(ch_r.i))); + //for (int re_idx = 0; re_idx < 8; re_idx += 2) //printf("ul_ch = %d + j*%d\n", ul_ch[re_idx], ul_ch[re_idx+1]); ul_ch += 4; @@ -391,6 +338,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, for (int pilot_cnt=6; pilot_cnt<6*(nb_rb_pusch-1); pilot_cnt += 6) { ch=c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6); + *max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i))); #if NO_INTERP for (c16_t *end=ul_ch+12; ul_chofdm_symbol_size*2)]); rxF_ext_index +=2; } - + ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; ul_ch0_ext_index++; @@ -402,41 +402,42 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, uint8_t is_dmrs_symbol, uint32_t len, uint8_t nrOfLayers, - unsigned short nb_rb) + unsigned short nb_rb, + int shift_ch_ext) { #if defined(__x86_64__)||defined(__i386__) - short rb, ch_amp; - unsigned char aarx,aatx; - __m128i *ul_ch128, ch_amp128; - - uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); - // Determine scaling amplitude based the symbol + int b = 3; + short ch_amp = 1024 * 8; + if (shift_ch_ext > 3) { + b = 0; + ch_amp >>= (shift_ch_ext - 3); + if (ch_amp == 0) { + ch_amp = 1; + } + } else { + b -= shift_ch_ext; + } + __m128i ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 + LOG_D(PHY, "Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, is_dmrs_symbol, nb_rb, frame_parms->Ncp, symbol); - ch_amp = 1024*8; - - LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, is_dmrs_symbol, nb_rb, frame_parms->Ncp, symbol); - // printf("Scaling PUSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); - - ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 - - int off = ((nb_rb&1) == 1)? 4:0; - - for (aatx = 0; aatx < nrOfLayers; aatx++) { - for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { - ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; - for (rb=0;rb < nb_rb_0;rb++) { + uint32_t nb_rb_0 = len / 12 + ((len % 12) ? 1 : 0); + int off = ((nb_rb & 1) == 1) ? 4 : 0; + for (int aatx = 0; aatx < nrOfLayers; aatx++) { + for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + __m128i *ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx * frame_parms->nb_antennas_rx + aarx][symbol * (off + (nb_rb * NR_NB_SC_PER_RB))]; + for (int rb = 0; rb < nb_rb_0; rb++) { ul_ch128[0] = _mm_mulhi_epi16(ul_ch128[0], ch_amp128); - ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], 3); + ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], b); ul_ch128[1] = _mm_mulhi_epi16(ul_ch128[1], ch_amp128); - ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], 3); + ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], b); ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); - ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); - ul_ch128+=3; + ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], b); + ul_ch128 += 3; } } } @@ -1902,6 +1903,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //--------------------- Channel estimation --------------------- //---------------------------------------------------------- start_meas(&gNB->ulsch_channel_estimation_stats); + int max_ch = 0; for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); @@ -1918,7 +1920,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, symbol, ulsch_id, bwp_start_subcarrier, - rel15_ul); + rel15_ul, + &max_ch); } nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol,rel15_ul->nrOfLayers); @@ -1960,6 +1963,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, int off = ((rel15_ul->rb_size&1) == 1)? 4:0; uint32_t rxdataF_ext_offset = 0; + uint8_t shift_ch_ext = rel15_ul->nrOfLayers > 1 ? log2_approx(max_ch >> 11) : 0; uint8_t ad_shift = 1 + log2_approx(frame_parms->nb_antennas_rx >> 2) + (rel15_ul->nrOfLayers == 2); for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { @@ -2005,13 +2009,14 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //--------------------- Channel Scaling -------------------- //---------------------------------------------------------- nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, - frame_parms, - gNB->ulsch[ulsch_id], - symbol, - dmrs_symbol_flag, - nb_re_pusch, - rel15_ul->nrOfLayers, - rel15_ul->rb_size); + frame_parms, + gNB->ulsch[ulsch_id], + symbol, + dmrs_symbol_flag, + nb_re_pusch, + rel15_ul->nrOfLayers, + rel15_ul->rb_size, + shift_ch_ext); if (gNB->pusch_vars[ulsch_id]->cl_done==0) { nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,