diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c73f9a2a5..f7e7828285 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -812,18 +812,14 @@ set(PHY_SRC_COMMON ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c ${OPENAIR1_DIR}/PHY/INIT/init_top.c ${OPENAIR1_DIR}/PHY/INIT/lte_parms.c - ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/dfts_load.c ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c - ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c - ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c ${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c - ${OPENAIR1_DIR}/PHY/TOOLS/lut.c - ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c ${OPENAIR1_DIR}/PHY/TOOLS/get_sin_cos.c + ${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c ) set(PHY_SRC @@ -948,16 +944,12 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_freq_equalization.c ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c - ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c - ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c - ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c ${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c - ${OPENAIR1_DIR}/PHY/TOOLS/lut.c - ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c + ${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} ${PHY_NRLDPC_CODINGIF} @@ -1001,16 +993,12 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c - ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c - ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c - ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c ${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c - ${OPENAIR1_DIR}/PHY/TOOLS/lut.c - ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c + ${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c ${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} diff --git a/doc/Doxyfile b/doc/Doxyfile index c2a4f20245..6399f7107c 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -2241,18 +2241,14 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cdot_prod.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/oai_dfts_neon.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cmult_vv.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cmult_sv.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/dB_routines.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/dfts_load.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/log2_approx.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/simde_operations.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/lut.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/lte_phy_scope.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cadd_vv.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/signal_energy.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/oai_dfts.c \ diff --git a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c index e32c86f20e..5b14c8efa0 100644 --- a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c +++ b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c @@ -287,9 +287,9 @@ void init_fde() { } void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int32_t **ul_ch_mag, - int32_t **ul_ch_magb, + c16_t **rxdataF_comp, + c16_t **ul_ch_mag, + c16_t **ul_ch_magb, uint8_t symbol, uint16_t Msc_RS, uint8_t Qm) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c index e7f46eb5ef..e5e21fe68a 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c @@ -41,12 +41,10 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, int8_t uespec_nushift, uespec_poffset=0, pil_offset=0; uint8_t pilot0,pilot1,pilot2,pilot3; - short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev; - short *fl=NULL, *fm=NULL, *fr=NULL, *fl_dc=NULL, *fm_dc=NULL, *fr_dc=NULL, *f1, *f2l=NULL, *f2r=NULL; + int16_t *fl = NULL, *fm = NULL, *fr = NULL, *fl_dc = NULL, *fm_dc = NULL, *fr_dc = NULL, *f1, *f2l = NULL, *f2r = NULL; - unsigned int *rballoc; + unsigned int *rballoc; int **rxdataF; - int32_t **dl_bf_ch_estimates; int uespec_pilot[300]; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; @@ -64,7 +62,8 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[Ns>>1]].rxdataF; - dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[Ns>>1]][eNB_id]->dl_bf_ch_estimates; + c16_t **dl_bf_ch_estimates = + (c16_t **)phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[Ns >> 1]][eNB_id]->dl_bf_ch_estimates; beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; if (phy_vars_ue->high_speed_flag == 0) // use second channel estimate position for temporary storage @@ -177,10 +176,9 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, for (aarx=0; aarxnb_antennas_rx; aarx++) { - - rxF = (short *)&rxdataF[aarx][pil_offset + frame_parms->first_carrier_offset + symbol*frame_parms->ofdm_symbol_size]; - pil = (short *)uespec_pilot; - dl_bf_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset]; + c16_t *rxF = (c16_t *)&rxdataF[aarx][pil_offset + frame_parms->first_carrier_offset + symbol * frame_parms->ofdm_symbol_size]; + c16_t *pil = (c16_t *)uespec_pilot; + c16_t *dl_bf_ch = &dl_bf_ch_estimates[aarx][ch_offset]; memset(dl_bf_ch,0,4*(frame_parms->ofdm_symbol_size)); //memset(dl_bf_ch,0,2*(frame_parms->ofdm_symbol_size)); @@ -188,9 +186,10 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, if (phy_vars_ue->high_speed_flag==0) { // multiply previous channel estimate by ch_est_alpha if (frame_parms->Ncp==0){ - multadd_complex_vector_real_scalar(dl_bf_ch-(frame_parms->ofdm_symbol_size<<1), - phy_vars_ue->ch_est_alpha,dl_bf_ch-(frame_parms->ofdm_symbol_size<<1), - 1,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch - frame_parms->ofdm_symbol_size, + phy_vars_ue->ch_est_alpha, + dl_bf_ch - frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); } else { LOG_E(PHY,"lte_dl_bf_channel_estimation: beamforming channel estimation not supported for TM7 Extended CP.\n"); // phy_vars_ue->ch_est_beta should be defined equaling 1/3 } @@ -213,25 +212,16 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, // For second half of RBs skip DC carrier if (rb==(frame_parms->N_RB_DL>>1)) { - rxF = (short *)&rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; + rxF = (c16_t *)&rxdataF[aarx][1 + symbol * frame_parms->ofdm_symbol_size]; } if (rb_alloc_ind==1) { if (uespec_pilots==1) { if (beamforming_mode==7) { if (frame_parms->Ncp==0) { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fl,ch,dl_bf_ch,16); - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(fm,ch,dl_bf_ch,16); - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(fr,ch,dl_bf_ch,16); + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil, rxF[0], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fm, c16mulShift(*pil, rxF[4], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil, rxF[8], 15), dl_bf_ch, 16); } else { LOG_E(PHY,"lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):TM7 beamgforming channel estimation not supported for extented CP\n"); exit(-1); @@ -242,8 +232,8 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, } } - rxF+=24; - dl_bf_ch+=24; + rxF += 12; + dl_bf_ch += 12; } } else { // Odd number of RBs for (rb=0; rbN_RB_DL>>1; rb++) { @@ -319,71 +309,22 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, if (frame_parms->Ncp==0) { if (skip_half==1) { if (pil_offset<2) { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16); - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); - pil+=2; - + multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); } else { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16); - pil+=2; + multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); } } else if (skip_half==2) { if (pil_offset<2) { - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16); - pil+=2; - + multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16); } else { - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16); - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); - pil+=2; - + multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16); } } else { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fl,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(fm,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - printf("symbol=%d,rxF[4]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[8],rxF[9],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(fr,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - printf("symbol=%d,rxF[8]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[16],rxF[17],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2; - + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16); } } else { LOG_E(PHY,"lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):TM7 beamgforming channel estimation not supported for extented CP\n"); @@ -394,10 +335,9 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, LOG_E(PHY,"lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):transmission mode not supported.\n"); } } - } - - rxF+=24; - dl_bf_ch+=24; + } + rxF += 12; + dl_bf_ch += 12; } // first half loop // Do middle RB (around DC) @@ -439,65 +379,25 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, //printf("DC rb %d (%p)\n",rb,rxF); if (rb_alloc_ind==1) { if (pil_offset<2) { - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fl_dc,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - //printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2;; - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(fm_dc,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - //printf("symbol=%d,rxF[4]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[8],rxF[9],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2;; + multadd_real_vector_complex_scalar(fl_dc, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fm_dc, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); - rxF = (short *)&rxdataF[aarx][symbol*(frame_parms->ofdm_symbol_size)]; - - ch[0] = (short)(((int)pil[0]*rxF[6] - (int)pil[1]*rxF[7])>>15); - ch[1] = (short)(((int)pil[0]*rxF[7] + (int)pil[1]*rxF[6])>>15); - multadd_real_vector_complex_scalar(fr_dc,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - //printf("symbol=%d,rxF[3]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[6],rxF[7],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2;; + rxF = (c16_t *)&rxdataF[aarx][symbol * (frame_parms->ofdm_symbol_size)]; + multadd_real_vector_complex_scalar(fr_dc, c16mulShift(*pil++, rxF[3], 15), dl_bf_ch, 16); } else { - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fl_dc,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - //printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2;; - - rxF = (short *)&rxdataF[aarx][symbol*(frame_parms->ofdm_symbol_size)]; + multadd_real_vector_complex_scalar(fl_dc, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); - ch[0] = (short)(((int)pil[0]*rxF[2] - (int)pil[1]*rxF[3])>>15); - ch[1] = (short)(((int)pil[0]*rxF[3] + (int)pil[1]*rxF[2])>>15); - multadd_real_vector_complex_scalar(fm_dc,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - //printf("symbol=%d,rxF[1]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[2],rxF[3],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2;; - - ch[0] = (short)(((int)pil[0]*rxF[10] - (int)pil[1]*rxF[11])>>15); - ch[1] = (short)(((int)pil[0]*rxF[11] + (int)pil[1]*rxF[10])>>15); - multadd_real_vector_complex_scalar(fr_dc,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - //printf("symbol=%d,rxF[5]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[10],rxF[11],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2;; + rxF = (c16_t *)&rxdataF[aarx][symbol * (frame_parms->ofdm_symbol_size)]; + multadd_real_vector_complex_scalar(fm_dc, c16mulShift(*pil++, rxF[1], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fr_dc, c16mulShift(*pil++, rxF[5], 15), dl_bf_ch, 16); } } // rballoc==1 else { - rxF = (short *)&rxdataF[aarx][pil_offset+((symbol*(frame_parms->ofdm_symbol_size)))]; + rxF = (c16_t *)&rxdataF[aarx][pil_offset + symbol * frame_parms->ofdm_symbol_size]; } - rxF+=14+2*pil_offset; - dl_bf_ch+=24; + rxF += 7 + pil_offset; + dl_bf_ch += 12; rb++; for (; rbN_RB_DL; rb++) { @@ -566,72 +466,22 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, if (frame_parms->Ncp==0) { if (skip_half==1) { if (pil_offset<2) { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16); - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); - pil+=2; - - + multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); } else { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16); - pil+=2; + multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); } } else if (skip_half==2) { if (pil_offset<2) { - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16); - pil+=2; - + multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16); } else { - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16); - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); - pil+=2; - + multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16); } } else { - - ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fl,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); - ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); - multadd_real_vector_complex_scalar(fm,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - printf("symbol=%d,rxF[4]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[8],rxF[9],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2; - - ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15); - ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15); - multadd_real_vector_complex_scalar(fr,ch,dl_bf_ch,16); -#ifdef DEBUG_BF_CH - printf("symbol=%d,rxF[8]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[16],rxF[17],pil[0],pil[1],ch[0],ch[1]); -#endif - pil+=2; - + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16); + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16); } } else { LOG_E(PHY,"lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):TM7 beamgforming channel estimation not supported for extented CP\n"); @@ -644,23 +494,23 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, } } - rxF+=24; - dl_bf_ch+=24; + rxF += 12; + dl_bf_ch += 12; } // second half of RBs } // odd number of RBs // Temporal Interpolation if (phy_vars_ue->perfect_ce == 0) { - - dl_bf_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset]; + dl_bf_ch = &dl_bf_ch_estimates[aarx][ch_offset]; #ifdef DEBUG_BF_CH printf("[dlsch_bf_ch_est.c]:symbol %d, dl_bf_ch (%d,%d)\n",symbol,dl_bf_ch[0],dl_bf_ch[1]); #endif if (phy_vars_ue->high_speed_flag == 0) { multadd_complex_vector_real_scalar(dl_bf_ch, - 32767-phy_vars_ue->ch_est_alpha, - dl_bf_ch-(frame_parms->ofdm_symbol_size<<1),0,frame_parms->ofdm_symbol_size); + 32767 - phy_vars_ue->ch_est_alpha, + dl_bf_ch - frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); //printf("dlsch_bf_ch_est.c:symbol %d,dl_bf_ch (%d,%d)\n",symbol,*(dl_bf_ch-512*2),*(dl_bf_ch-512*2+1)); } else { // high_speed_flag == 1 if (beamforming_mode==7) { @@ -668,56 +518,116 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, if (symbol == pilot0) { // printf("Interpolating %d->0\n",4-phy_vars_ue->lte_frame_parms.Ncp); // dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][(4-phy_vars_ue->lte_frame_parms.Ncp)*(frame_parms->ofdm_symbol_size)]; - dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot3*(frame_parms->ofdm_symbol_size)]; + c16_t *dl_bf_ch_prev = (c16_t *)&dl_bf_ch_estimates[aarx][pilot3 * (frame_parms->ofdm_symbol_size)]; #ifdef DEBUG_BF_CH printf("[dlsch_bf_ch_est.c] symbol=%d, dl_bf_ch_prev=(%d,%d), dl_bf_ch=(%d,%d)\n", symbol, dl_bf_ch_prev[0], dl_bf_ch_prev[1], dl_bf_ch[0], dl_bf_ch[1]); #endif // pilot spacing 5 symbols (1/5,2/5,3/5,4/5 combination) - multadd_complex_vector_real_scalar(dl_bf_ch_prev,26214,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,6554,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 26214, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 6554, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch_prev,19661,dl_bf_ch-(3*2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,13107,dl_bf_ch-(3*2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 19661, + dl_bf_ch - 3 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 13107, + dl_bf_ch - 3 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch_prev,13107,dl_bf_ch-(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,19661,dl_bf_ch-(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 13107, + dl_bf_ch - 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 19661, + dl_bf_ch - 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch_prev,6554,dl_bf_ch-(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,26214,dl_bf_ch-(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 6554, + dl_bf_ch - frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 26214, + dl_bf_ch - frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); } else if (symbol == pilot1) { - dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot0*(frame_parms->ofdm_symbol_size)]; + c16_t *dl_bf_ch_prev = &dl_bf_ch_estimates[aarx][pilot0 * (frame_parms->ofdm_symbol_size)]; #ifdef DEBUG_BF_CH printf("[dlsch_bf_ch_est.c] symbol=%d, dl_bf_ch_prev=(%d,%d), dl_bf_ch=(%d,%d)\n", symbol, dl_bf_ch_prev[0], dl_bf_ch_prev[1], dl_bf_ch[0], dl_bf_ch[1]); #endif // pilot spacing 3 symbols (1/3,2/3 combination) - multadd_complex_vector_real_scalar(dl_bf_ch_prev,21845,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,10923,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 21845, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 10923, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch_prev,10923,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,21845,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 10923, + dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 21845, + dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); } else if (symbol == pilot2) { - dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot1*(frame_parms->ofdm_symbol_size)]; + c16_t *dl_bf_ch_prev = &dl_bf_ch_estimates[aarx][pilot1 * frame_parms->ofdm_symbol_size]; #ifdef DEBUG_BF_CH printf("[dlsch_bf_ch_est.c] symbol=%d, dl_bf_ch_prev=(%d,%d), dl_bf_ch=(%d,%d)\n", symbol, dl_bf_ch_prev[0], dl_bf_ch_prev[1], dl_bf_ch[0], dl_bf_ch[1]); #endif - multadd_complex_vector_real_scalar(dl_bf_ch_prev,21845,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,10923,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 21845, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 10923, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch_prev,10923,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,21845,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 10923, + dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 21845, + dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); } else { // symbol == pilot3 // printf("Interpolating 0->%d\n",4-phy_vars_ue->lte_frame_parms.Ncp); - dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot2*(frame_parms->ofdm_symbol_size)]; + c16_t *dl_bf_ch_prev = &dl_bf_ch_estimates[aarx][pilot2 * frame_parms->ofdm_symbol_size]; // pilot spacing 3 symbols (1/3,2/3 combination) - multadd_complex_vector_real_scalar(dl_bf_ch_prev,21845,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,10923,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 21845, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 10923, + dl_bf_ch_prev + frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch_prev,10923,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_bf_ch,21845,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_bf_ch_prev, + 10923, + dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_bf_ch, + 21845, + dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size, + frame_parms->ofdm_symbol_size); } } else { @@ -728,12 +638,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, } } } - } //aarx - -#ifdef DEBUG_BF_CH - printf("[dlsch_bf_ch_est.c]: dl_bf_estimates[0][600] %d, %d \n",*(short *)&dl_bf_ch_estimates[0][600],*(short*)&phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0][600]); -#endif - + } // aarx return(0); } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c index fe995885cb..3c11dbe921 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c @@ -39,7 +39,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, unsigned char nu,aarx; unsigned short k; unsigned int rb,pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev,*f,*f2,*fl,*f2l2,*fr,*f2r2,*f2_dc,*f_dc; + int16_t *f, *f2, *fl, *f2l2, *fr, *f2r2, *f2_dc, *f_dc; int ch_offset,symbol_offset; // unsigned int n; // int i; @@ -177,16 +177,17 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, p); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[p][0]; - rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+k+ue->frame_parms.first_carrier_offset))]; - dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; + c16_t *pil = (c16_t *)&pilot[p][0]; + c16_t *rxF = (c16_t *)&rxdataF[aarx][symbol_offset + k + ue->frame_parms.first_carrier_offset]; + c16_t *dl_ch = (c16_t *)&dl_ch_estimates[(p << 1) + aarx][ch_offset]; // if (eNb_id==0) - memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); + memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size); if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha - multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), - ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), - 1,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_ch - ue->frame_parms.ofdm_symbol_size, + ue->ch_est_alpha, + dl_ch - ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.ofdm_symbol_size); #ifdef DEBUG_CH printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); @@ -195,383 +196,126 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, if ((ue->frame_parms.N_RB_DL==6) || (ue->frame_parms.N_RB_DL==50) || (ue->frame_parms.N_RB_DL==100)) { - //First half of pilots - // Treat first 2 pilots specially (left edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(f2l2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + // First half of pilots + // Treat first 2 pilots specially (left edge) + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2l2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; - for (pilot_cnt=2; pilot_cnt<((ue->frame_parms.N_RB_DL)-1); pilot_cnt+=2) { - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); //Re - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); //Im -#ifdef DEBUG_CH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + for (pilot_cnt = 2; pilot_cnt < ((ue->frame_parms.N_RB_DL) - 1); pilot_cnt += 2) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } - - // printf("Second half\n"); // Second half of RBs k = (nu + nushift)%6; - - if (k > 6) - k -=6; - - rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; -#ifdef DEBUG_CH - printf("second half k %d\n",k); -#endif - - for (pilot_cnt=0; pilot_cnt<((ue->frame_parms.N_RB_DL)-3); pilot_cnt+=2) { - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + rxF = (c16_t *)&rxdataF[aarx][symbol_offset + 1 + k]; + for (pilot_cnt = 0; pilot_cnt < ((ue->frame_parms.N_RB_DL) - 3); pilot_cnt += 2) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2r2, c16mulShift(*pil, rxF[0], 15), dl_ch, 24); + } else if (ue->frame_parms.N_RB_DL == 25) { + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2l2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(f2r2, - ch, - dl_ch, - 24); - } else if (ue->frame_parms.N_RB_DL==25) { - //printf("Channel estimation\n"); - // Treat first 2 pilots specially (left edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f2l2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; - - for (pilot_cnt=2; pilot_cnt<24; pilot_cnt+=2) { - // printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]); - // printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]); - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + for (pilot_cnt = 2; pilot_cnt < 24; pilot_cnt += 2) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 24: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f_dc, - ch, - dl_ch, - 24); - pil+=2; // Re Im - dl_ch+=8; - // printf("Second half\n"); + multadd_real_vector_complex_scalar(f_dc, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + dl_ch += 4; // Second half of RBs - rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 25: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f2_dc, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; - - for (pilot_cnt=0; pilot_cnt<22; pilot_cnt+=2) { - // printf("* pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]); - // printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]); - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",26+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot %u : rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",27+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + rxF = (c16_t *)&rxdataF[aarx][symbol_offset + 1 + k]; + multadd_real_vector_complex_scalar(f2_dc, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; + for (pilot_cnt = 0; pilot_cnt < 22; pilot_cnt += 2) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 49: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - printf("pilot 50: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - // ch[0] = 1024; - // ch[1] = -128; -#endif - multadd_real_vector_complex_scalar(f2r2, - ch, - dl_ch, - 24); - } else if (ue->frame_parms.N_RB_DL==15) { - //printf("First Half\n"); - for (rb=0; rb<28; rb+=4) { - //printf("aarx=%d\n",aarx); - //printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]); - //printf("rx[%d][%d] -> (%d,%d)\n",p, - // ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p), - // rxF[0], - // rxF[1]); - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - //printf("ch -> (%d,%d)\n",ch[0],ch[1]); - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - //printf("ch -> (%d,%d)\n",ch[0],ch[1]); - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2r2, c16mulShift(*pil, rxF[0], 15), dl_ch, 24); + } else if (ue->frame_parms.N_RB_DL == 15) { + for (rb = 0; rb < 28; rb += 4) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - // printf("ch -> (%d,%d)\n",ch[0],ch[1]); - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; // Re Im - dl_ch+=8; - //printf("Second half\n"); + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + dl_ch += 4; //Second half of RBs - rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + rxF = (c16_t *)&rxdataF[aarx][((symbol_offset + 1 + nushift + (3 * p)))]; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; - for (rb=0; rb<28; rb+=4) { - //printf("aarx=%d\n",aarx); - //printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]); - //printf("rx[%d][%d] -> (%d,%d)\n",p, - // ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p), - // rxF[0], - // rxF[1]); - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + for (rb = 0; rb < 28; rb += 4) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } } else { LOG_E(PHY,"channel estimation not implemented for ue->frame_parms.N_RB_DL = %d\n",ue->frame_parms.N_RB_DL); } - + int symb_sz = ue->frame_parms.ofdm_symbol_size; if (ue->perfect_ce == 0) { // Temporal Interpolation // printf("ch_offset %d\n",ch_offset); - dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; + dl_ch = (c16_t *)&dl_ch_estimates[(p << 1) + aarx][ch_offset]; if (ue->high_speed_flag == 0) { - multadd_complex_vector_real_scalar(dl_ch, - 32767-ue->ch_est_alpha, - dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),0,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch, 32767 - ue->ch_est_alpha, dl_ch - symb_sz, symb_sz); } else { // high_speed_flag == 1 if (symbol == 0) { // printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp); - // dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)]; + // dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(symb_sz)]; if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12)) { //LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns); - dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + c16_t *dl_ch_prev = (c16_t *)&dl_ch_estimates_previous[(p << 1) + aarx][pilot3 * (symb_sz)]; + mult_complex_vector_real_scalar(dl_ch_prev, 21845, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 10923, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 10923, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + 2 * symb_sz, symb_sz); } interpolateS11S12 = 1; } // this is 1/3,2/3 combination for pilots spaced by 3 symbols else if (symbol == pilot1) { - dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0]; + c16_t *dl_ch_prev = (c16_t *)&dl_ch_estimates[(p << 1) + aarx][0]; //LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns); if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) @@ -583,60 +327,60 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, previous_subframe = ((Ns>>1) - 1 )%9; if((subframe_select(&ue->frame_parms,previous_subframe) == SF_UL)) { - multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_ch_prev, 328, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 32440, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 328, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 32440, dl_ch_prev + 2 * symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 8192, dl_ch_prev + 3 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 32440, dl_ch_prev + 3 * symb_sz, symb_sz); } else { - multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_ch_prev, 24576, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 8192, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 16384, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 16384, dl_ch_prev + 2 * symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 8192, dl_ch_prev + 3 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 24576, dl_ch_prev + 3 * symb_sz, symb_sz); } } else { - multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_ch_prev, 328, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 21845, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 10923, dl_ch_prev + 2 * symb_sz, symb_sz); } // pilot spacing 3 symbols (1/3,2/3 combination) } else if (symbol == pilot2) { - dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)]; - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + c16_t *dl_ch_prev = (c16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot1 * symb_sz]; + mult_complex_vector_real_scalar(dl_ch_prev, 21845, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 10923, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 10923, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + 2 * symb_sz, symb_sz); } else { // symbol == pilot3 // printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp); - dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)]; + c16_t *dl_ch_prev = (c16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot2 * symb_sz]; if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) - multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_ch_prev, 24576, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 8192, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 16384, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 16384, dl_ch_prev + 2 * symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 8192, dl_ch_prev + 3 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 24576, dl_ch_prev + 3 * symb_sz, symb_sz); } else { - multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(dl_ch_prev, 10923, dl_ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + symb_sz, symb_sz); + mult_complex_vector_real_scalar(dl_ch_prev, 21845, dl_ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar(dl_ch, 10923, dl_ch_prev + 2 * symb_sz, symb_sz); } // pilot spacing 3 symbols (1/3,2/3 combination) if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) { //LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns); interpolateS11S12 = 0; //LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol); - int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; - int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)]; + int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot3 * symb_sz]; + int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot2 * symb_sz]; // interpolate ofdm s12: 5/4*ofdms11 + -1/4*ofdms7 5/4 q1.15 40960 -1/4 q1.15 8192 - int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][12*ue->frame_parms.ofdm_symbol_size]; + int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][12 * symb_sz]; - for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) { + for (int i = 0; i < (2 * symb_sz); i++) { int64_t tmp_mult = 0; tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 40960 - (int64_t)dlChEst_ofdm7[i] * 8192); tmp_mult = tmp_mult >> 15; @@ -644,9 +388,9 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, } // interpolate ofdm s13: 3/2*ofdms11 + -1/2*ofdms7 3/2 q1.15 49152 1/2 q1.15 16384 - int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][13*ue->frame_parms.ofdm_symbol_size]; + int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][13 * symb_sz]; - for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) { + for (int i = 0; i < (2 * symb_sz); i++) { int64_t tmp_mult = 0; tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 49152 - (int64_t)dlChEst_ofdm7[i] * 16384); tmp_mult = tmp_mult >> 15; diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c index 90606c63c4..5893afc907 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c @@ -46,7 +46,7 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue, int pilot[600] __attribute__((aligned(16))); unsigned char aarx,aa; unsigned int rb; - short *pil,*rxF,*ch,*ch0,*ch1,*ch11,*chp,*ch_prev; + short *pil, *rxF, *ch, *ch0, *ch1, *ch11, *chp; int ch_offset,symbol_offset; // unsigned int n; // int i; @@ -680,42 +680,43 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue, } //------------------------Temporal Interpolation ------------------------------ + int symb_sz = ue->frame_parms.ofdm_symbol_size; if (l==6) { ch = (short *)&dl_ch_estimates[aarx][ch_offset]; // printf("Interpolating ch 2,6 => %d\n",ch_offset); - ch_prev = (short *)&dl_ch_estimates[aarx][2*(ue->frame_parms.ofdm_symbol_size)]; - ch0 = (short *)&dl_ch_estimates[aarx][0*(ue->frame_parms.ofdm_symbol_size)]; - memcpy(ch0,ch_prev,4*ue->frame_parms.ofdm_symbol_size); - ch1 = (short *)&dl_ch_estimates[aarx][1*(ue->frame_parms.ofdm_symbol_size)]; - memcpy(ch1,ch_prev,4*ue->frame_parms.ofdm_symbol_size); + c16_t *ch_prev = (c16_t *)&dl_ch_estimates[aarx][2 * symb_sz]; + ch0 = (short *)&dl_ch_estimates[aarx][0 * (symb_sz)]; + memcpy(ch0, ch_prev, 4 * symb_sz); + ch1 = (short *)&dl_ch_estimates[aarx][1 * (symb_sz)]; + memcpy(ch1, ch_prev, 4 * symb_sz); // 3/4 ch2 + 1/4 ch6 => ch3 - multadd_complex_vector_real_scalar(ch_prev,24576,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(ch,8192,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_prev, 24576, ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar((c16_t *)ch, 8192, ch_prev + symb_sz, symb_sz); // 1/2 ch2 + 1/2 ch6 => ch4 - multadd_complex_vector_real_scalar(ch_prev,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(ch,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_prev, 16384, ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar((c16_t *)ch, 16384, ch_prev + 2 * symb_sz, symb_sz); // 1/4 ch2 + 3/4 ch6 => ch5 - multadd_complex_vector_real_scalar(ch_prev,8192,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(ch,24576,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_prev, 8192, ch_prev + 3 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar((c16_t *)ch, 24576, ch_prev + 3 * symb_sz, symb_sz); } if (l==10) { ch = (short *)&dl_ch_estimates[aarx][ch_offset]; - ch_prev = (short *)&dl_ch_estimates[aarx][6*(ue->frame_parms.ofdm_symbol_size)]; + c16_t *ch_prev = (c16_t *)&dl_ch_estimates[aarx][6 * symb_sz]; // 3/4 ch6 + 1/4 ch10 => ch7 - multadd_complex_vector_real_scalar(ch_prev,24576,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(ch,8192,ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_prev, 24576, ch_prev + symb_sz, symb_sz); + multadd_complex_vector_real_scalar((c16_t *)ch, 8192, ch_prev + symb_sz, symb_sz); // 1/2 ch6 + 1/2 ch10 => ch8 - multadd_complex_vector_real_scalar(ch_prev,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(ch,16384,ch_prev+(4*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_prev, 16384, ch_prev + 2 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar((c16_t *)ch, 16384, ch_prev + 2 * symb_sz, symb_sz); // 1/4 ch6 + 3/4 ch10 => ch9 - multadd_complex_vector_real_scalar(ch_prev,8192,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(ch,24576,ch_prev+(6*((ue->frame_parms.ofdm_symbol_size))),0,ue->frame_parms.ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_prev, 8192, ch_prev + 3 * symb_sz, symb_sz); + multadd_complex_vector_real_scalar((c16_t *)ch, 24576, ch_prev + 3 * symb_sz, symb_sz); // 5/4 ch10 - 1/4 ch6 => ch11 // Ch11 - ch_prev = (short *)&dl_ch_estimates[aarx][10*(ue->frame_parms.ofdm_symbol_size)]; - ch11 = (short *)&dl_ch_estimates[aarx][11*(ue->frame_parms.ofdm_symbol_size)]; - memcpy(ch11,ch_prev,4*ue->frame_parms.ofdm_symbol_size); + ch_prev = (c16_t *)&dl_ch_estimates[aarx][10 * (symb_sz)]; + ch11 = (short *)&dl_ch_estimates[aarx][11 * (symb_sz)]; + memcpy(ch11, ch_prev, 4 * symb_sz); } } @@ -763,13 +764,10 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, int subframe) { int pilot_khz_1dot25[2*2*600] __attribute__((aligned(16))); unsigned char aarx,aa; - //unsigned int rb; - int16_t ch[2]; - short *pil,*rxF,*dl_ch/*,*ch0,*ch1,*ch11,*chp,*ch_prev*/; + // unsigned int rb; int ch_offset,symbol_offset; int pilot_cnt; - int16_t *f,*f2,*fl,*f2l2,*fr,*f2r2/*,*f2_dc,*f_dc*/; - unsigned int k; + int16_t *f, *f2, *fl, *f2l2, *fr, *f2r2 /*,*f2_dc,*f_dc*/; // unsigned int n; // int i; int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0]; @@ -800,101 +798,46 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { // generate pilot - lte_dl_mbsfn_khz_1dot25_rx(ue, - &pilot_khz_1dot25[0], - subframe); - pil = (short *)&pilot_khz_1dot25[0]; - rxF = (short *)&rxdataF[aarx][((ue->frame_parms.first_carrier_offset_khz_1dot25))]; - dl_ch = (short *)&dl_ch_estimates[aarx][ch_offset]; - memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size_khz_1dot25)); + lte_dl_mbsfn_khz_1dot25_rx(ue, pilot_khz_1dot25, subframe); + c16_t *pil = (c16_t *)pilot_khz_1dot25; + c16_t *dl_ch = (c16_t *)&dl_ch_estimates[aarx][ch_offset]; + memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size_khz_1dot25); - if( (subframe&0x1) == 0) { - rxF+=0; - k=0; - } else { - rxF+=6;//2*3; - k=3; - } + unsigned int k = (subframe & 0x1) == 0 ? 0 : 3; + c16_t *rxF = (c16_t *)&rxdataF[aarx][ue->frame_parms.first_carrier_offset_khz_1dot25 + k]; - if(1/*ue->frame_parms.N_RB_DL==25*/) { - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2l2, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=16; + if (1 /*ue->frame_parms.N_RB_DL==25*/) { + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2l2, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; - for(pilot_cnt=2; pilot_cntframe_parms.N_RB_DL*12-1/*299*/; pilot_cnt+=2) { - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + for (pilot_cnt = 2; pilot_cnt < ue->frame_parms.N_RB_DL * 12 - 1 /*299*/; pilot_cnt += 2) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } - rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; //Skip DC offset + rxF = (c16_t *)&rxdataF[aarx][symbol_offset + 1 + k]; // Skip DC offset - for(pilot_cnt=0; pilot_cntframe_parms.N_RB_DL*12-3/*297*/; pilot_cnt+=2) { - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2, - ch, - dl_ch, - 24); - pil+=2; - rxF+=12; - dl_ch+=16; + for (pilot_cnt = 0; pilot_cnt < ue->frame_parms.N_RB_DL * 12 - 3 /*297*/; pilot_cnt += 2) { + multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 8; } - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 24); - pil+=2; // Re Im - rxF+=12; - dl_ch+=8; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(f2r2, - ch, - dl_ch, - 24); + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 24); + rxF += 6; + dl_ch += 4; + multadd_real_vector_complex_scalar(f2r2, c16mulShift(*pil, *rxF, 15), dl_ch, 24); } } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h index 4bc9b5d875..46d2f2993e 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h +++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h @@ -53,9 +53,7 @@ The algorithm uses a time domain correlation with a downsampled version of the r \param eNB_id return value with the eNb_id \return sync_pos Position of the sync within the frame (downsampled) if successfull and -1 if there was an error or no peak was detected. */ -int lte_sync_time(int **rxdata, - LTE_DL_FRAME_PARMS *frame_parms, - int *eNB_id); +int lte_sync_time(c16_t **rxdata, LTE_DL_FRAME_PARMS *frame_parms, int *eNB_id); /*! \brief This function performs the coarse frequency and PSS synchronization. @@ -194,19 +192,19 @@ void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue, unsigned char eNB_id); int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, - L1_rxtx_proc_t *proc, - LTE_eNB_ULSCH_t * ulsch, - int32_t **ul_ch_estimates, - int32_t **ul_ch_estimates_time, - int32_t **rxdataF_ext, - module_id_t UE_id, - uint8_t l, - uint8_t Ns); + L1_rxtx_proc_t *proc, + LTE_eNB_ULSCH_t *ulsch, + c16_t **ul_ch_estimates, + c16_t **ul_ch_estimates_time, + c16_t **rxdataF_ext, + module_id_t UE_id, + uint8_t l, + uint8_t Ns); int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **ul_ch_estimates, - int32_t **ul_ch_estimates_time, - int32_t **rxdataF_ext, + c16_t **ul_ch_estimates, + c16_t **ul_ch_estimates_time, + c16_t **rxdataF_ext, int N_rb_alloc, int frame_rx, int subframe_rx, @@ -217,9 +215,7 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, int interpolate, uint16_t rnti); -int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, - int32_t *ul_ch_estimates, - uint16_t nb_rb); +int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, c16_t *ul_ch_estimates, uint16_t nb_rb); int lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, LTE_eNB_COMMON *eNB_common_vars, @@ -235,8 +231,7 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms, unsigned char number_of_cards, short coef); -int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **ul_ch_estimates_time); +int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms, c16_t **ul_ch_estimates_time); void lte_eNB_I0_measurements(PHY_VARS_eNB *phy_vars_eNB, int subframe, @@ -252,11 +247,10 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *phy_vars_eNBy, module_id_t UE_id, unsigned char init_averaging); - void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - int **ul_ch_mag, - int **ul_ch_mag_b, + c16_t **rxdataF_comp, + c16_t **ul_ch_mag, + c16_t **ul_ch_mag_b, unsigned char symbol, unsigned short Msc_RS, unsigned char Qm); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index 4a1980af8c..9a7c8d6c83 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -114,7 +114,7 @@ void lte_sync_time_free(void) { #define SHIFT 17 -int lte_sync_time(int **rxdata, LTE_DL_FRAME_PARMS *frame_parms, int *eNB_id) +int lte_sync_time(c16_t **rxdata, LTE_DL_FRAME_PARMS *frame_parms, int *eNB_id) { // perform a time domain correlation using the oversampled sync sequence unsigned int n, ar, s, peak_pos, peak_val, sync_source; @@ -135,8 +135,8 @@ int lte_sync_time(int **rxdata, LTE_DL_FRAME_PARMS *frame_parms, int *eNB_id) //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; for (int i = 0; i < sizeofArray(primary_synch_time); i++) for (ar = 0; ar < frame_parms->nb_antennas_rx; ar++) { - c32_t result = dot_product(primary_synch_time[i], (c16_t *)&(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT); - c32_t result2 = dot_product(primary_synch_time[i], (c16_t *)&(rxdata[ar][n + length]), frame_parms->ofdm_symbol_size, SHIFT); + c32_t result = dot_product(primary_synch_time[i], rxdata[ar] + n, frame_parms->ofdm_symbol_size, SHIFT); + c32_t result2 = dot_product(primary_synch_time[i], rxdata[ar] + n + length, frame_parms->ofdm_symbol_size, SHIFT); sync_out[i].r += result.r; sync_out[i].i += result.i; sync_out2[i].r += result2.r; @@ -228,9 +228,7 @@ int ru_sync_time(RU_t *ru, // circular copy of beginning to end of rxdata buffer. Note: buffer should be big enough upon calling this function for (int ar=0; arnb_rx; ar++) - memcpy((void *)&ru->common.rxdata[ar][2*length], - (void *)&ru->common.rxdata[ar][0], - frame_parms->ofdm_symbol_size); + memcpy(ru->common.rxdata[ar] + 2 * length, ru->common.rxdata[ar], frame_parms->ofdm_symbol_size); int32_t maxlev0=0; int maxpos0=0; diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c index bfda00607f..426d0d9134 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c @@ -55,9 +55,7 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq) int32_t *rxp; int16_t *sp; simde__m128i *sp2 = NULL; - simde__m128i s; int re,re256; - simde__m128i mmtmp00, mmtmp01, mmtmp02, mmtmp10, mmtmp11, mmtmp12; int maxcorr[3],minamp,pos=0,pssind; int16_t *pss6144_0 = NULL, *pss6144_1 = NULL, *pss6144_2 = NULL; @@ -129,25 +127,10 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq) re256=32; for (re = 0; re<256/4; re++) { // loop over 256 points of upsampled PSS - // printf("f %d, re %d\n",f,re); - s = sp2[re]; - mmtmp00 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_0)[re], s), 15); - mmtmp01 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_1)[re], s), 15); - mmtmp02 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_2)[re], s), 15); - - s = simde_mm_shufflelo_epi16(s, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - s = simde_mm_shufflehi_epi16(s, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - s = simde_mm_sign_epi16(s, *(simde__m128i *)&conjugate[0]); - mmtmp10 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_0)[re], s), 15); - mmtmp11 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_1)[re], s), 15); - mmtmp12 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_2)[re], s), 15); - - autocorr0[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp00, mmtmp10), simde_mm_unpackhi_epi32(mmtmp00, mmtmp10)); - autocorr1[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp01, mmtmp11), simde_mm_unpackhi_epi32(mmtmp01, mmtmp11)); - autocorr2[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp02, mmtmp12), simde_mm_unpackhi_epi32(mmtmp02, mmtmp12)); + simde__m128i s = sp2[re]; + autocorr0[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_0)[re], 15); + autocorr1[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_1)[re], 15); + autocorr2[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_2)[re], 15); re256 = (re256+1)&0x3f; } @@ -188,28 +171,10 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq) re256 = 32; for (re = 0; re<(-f+3)/4; re++) { // loop over 256 points of upsampled PSS - s = sp2[re]; - /* printf("re %d, %p\n",re,&sp2[re]); - print_shorts("s",&s); - print_shorts("pss",&((simde__m128i*)pss6144_0)[re]);*/ - - mmtmp00 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_0)[re], s), 15); - mmtmp01 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_1)[re], s), 15); - mmtmp02 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_2)[re], s), 15); - - s = simde_mm_shufflelo_epi16(s, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - s = simde_mm_shufflehi_epi16(s, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - s = simde_mm_sign_epi16(s, *(simde__m128i *)&conjugate[0]); - mmtmp10 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_0)[re], s), 15); - mmtmp11 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_1)[re], s), 15); - mmtmp12 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_2)[re], s), 15); - - autocorr0[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp00, mmtmp10), simde_mm_unpackhi_epi32(mmtmp00, mmtmp10)); - autocorr1[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp01, mmtmp11), simde_mm_unpackhi_epi32(mmtmp01, mmtmp11)); - autocorr2[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp02, mmtmp12), simde_mm_unpackhi_epi32(mmtmp02, mmtmp12)); + simde__m128i s = sp2[re]; + autocorr0[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_0)[re], 15); + autocorr1[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_1)[re], 15); + autocorr2[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_2)[re], 15); re256 = (re256+1)&0x3f; } @@ -246,27 +211,10 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq) } for (re = 0; re<(256+f)/4; re++) { // loop over 256 points of upsampled PSS - s = sp2[re]; - /* printf("re %d %p\n",re,&sp2[re]); - print_shorts("s",&s); - print_shorts("pss",&((simde__m128i*)pss6144_0)[re]);*/ - mmtmp00 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_0)[re], s), 15); - mmtmp01 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_1)[re], s), 15); - mmtmp02 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_2)[re], s), 15); - - s = simde_mm_shufflelo_epi16(s, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - s = simde_mm_shufflehi_epi16(s, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - s = simde_mm_sign_epi16(s, *(simde__m128i *)&conjugate[0]); - mmtmp10 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_0)[re], s), 15); - mmtmp11 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_1)[re], s), 15); - mmtmp12 = simde_mm_srai_epi32(simde_mm_madd_epi16(((simde__m128i *)pss6144_2)[re], s), 15); - - autocorr0[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp00, mmtmp10), simde_mm_unpackhi_epi32(mmtmp00, mmtmp10)); - autocorr1[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp01, mmtmp11), simde_mm_unpackhi_epi32(mmtmp01, mmtmp11)); - autocorr2[re256] = - simde_mm_packs_epi32(simde_mm_unpacklo_epi32(mmtmp02, mmtmp12), simde_mm_unpackhi_epi32(mmtmp02, mmtmp12)); + simde__m128i s = sp2[re]; + autocorr0[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_0)[re], 15); + autocorr1[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_1)[re], 15); + autocorr2[re256] = oai_mm_cpx_mult_conj(s, ((simde__m128i *)pss6144_2)[re], 15); re256 = (re256+1)&0x3f; } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 6abe02c941..3dc55ef1f6 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -187,7 +187,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, uint16_t off; uint8_t previous_thread_id = ue->current_thread_id[subframe]==0 ? (RX_NB_TH-1):(ue->current_thread_id[subframe]-1); - //uint8_t isPss; // indicate if this is a slot for extracting PSS + //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 @@ -460,56 +460,40 @@ void conjch0_mult_ch1(int *ch0, unsigned char output_shift0) { //This function is used to compute multiplications in Hhermitian * H matrix - unsigned short rb; - simde__m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + simde__m128i *dl_ch0_128 = (simde__m128i *)ch0; + simde__m128i *dl_ch1_128 = (simde__m128i *)ch1; - dl_ch0_128 = (simde__m128i *)ch0; - dl_ch1_128 = (simde__m128i *)ch1; + simde__m128i *ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1; - ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1; + for (unsigned short rb=0; rb<3*nb_rb; rb++) { - for (rb=0; rb<3*nb_rb; rb++) { - - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)&conjugate[0]); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,dl_ch1_128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - ch0conj_ch1_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); + ch0conj_ch1_128[rb] = oai_mm_cpx_mult_conj(dl_ch0_128[rb], dl_ch1_128[rb], output_shift0); #ifdef DEBUG_RANK_EST printf("\n Computing conjugates \n"); - print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]); - print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]); - print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]); + print_shorts("ch0:",(int16_t*)&dl_ch0_128[rb]); + print_shorts("ch1:",(int16_t*)&dl_ch1_128[rb]); + print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[rb]); #endif - dl_ch0_128+=1; - dl_ch1_128+=1; - ch0conj_ch1_128+=1; } } void construct_HhH_elements(int *ch0conj_ch0, //00_00 - int *ch1conj_ch1,//01_01 - int *ch2conj_ch2,//11_11 - int *ch3conj_ch3,//10_10 - int *ch0conj_ch1,//00_01 - int *ch1conj_ch0,//01_00 - int *ch2conj_ch3,//10_11 - int *ch3conj_ch2,//11_10 + int *ch1conj_ch1, //01_01 + int *ch2conj_ch2, //11_11 + int *ch3conj_ch3, //10_10 + int *ch0conj_ch1, //00_01 + int *ch1conj_ch0, //01_00 + int *ch2conj_ch3, //10_11 + int *ch3conj_ch2, //11_10 int32_t *after_mf_00, int32_t *after_mf_01, int32_t *after_mf_10, int32_t *after_mf_11, unsigned short nb_rb) { - unsigned short rb; + simde__m128i *ch0conj_ch0_128, *ch1conj_ch1_128, *ch2conj_ch2_128, *ch3conj_ch3_128; simde__m128i *ch0conj_ch1_128, *ch1conj_ch0_128, *ch2conj_ch3_128, *ch3conj_ch2_128; simde__m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128; @@ -527,13 +511,11 @@ void construct_HhH_elements(int *ch0conj_ch0, //00_00 after_mf_10_128 = (simde__m128i *)after_mf_10; after_mf_11_128 = (simde__m128i *)after_mf_11; - for (rb=0; rb<3*nb_rb; rb++) { - after_mf_00_128[0] = - simde_mm_adds_epi16(ch0conj_ch0_128[0], - ch3conj_ch3_128[0]); // simde_mm_adds_epi32(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); //00_00 + 10_10 - after_mf_11_128[0] =simde_mm_adds_epi16(ch1conj_ch1_128[0], ch2conj_ch2_128[0]); //01_01 + 11_11 - after_mf_01_128[0] =simde_mm_adds_epi16(ch0conj_ch1_128[0], ch2conj_ch3_128[0]);//00_01 + 10_11 - after_mf_10_128[0] =simde_mm_adds_epi16(ch1conj_ch0_128[0], ch3conj_ch2_128[0]);//01_00 + 11_10 + for (unsigned short rb=0; rb<3*nb_rb; rb++) { + after_mf_00_128[0] = simde_mm_adds_epi16(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); //00_00 + 10_10 simde_mm_adds_epi32(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); + after_mf_11_128[0] = simde_mm_adds_epi16(ch1conj_ch1_128[0], ch2conj_ch2_128[0]); //01_01 + 11_11 + after_mf_01_128[0] = simde_mm_adds_epi16(ch0conj_ch1_128[0], ch2conj_ch3_128[0]); //00_01 + 10_11 + after_mf_10_128[0] = simde_mm_adds_epi16(ch1conj_ch0_128[0], ch3conj_ch2_128[0]); //01_00 + 11_10 #ifdef DEBUG_RANK_EST printf(" \n construct_HhH_elements \n"); @@ -572,13 +554,13 @@ void squared_matrix_element(int32_t *Hh_h_00, int32_t *Hh_h_00_sq, unsigned short nb_rb) { - unsigned short rb; + simde__m128i *Hh_h_00_128,*Hh_h_00_sq_128; Hh_h_00_128 = (simde__m128i *)Hh_h_00; Hh_h_00_sq_128 = (simde__m128i *)Hh_h_00_sq; - for (rb=0; rb<3*nb_rb; rb++) { + for (unsigned short rb=0; rb<3*nb_rb; rb++) { Hh_h_00_sq_128[0] = simde_mm_madd_epi16(Hh_h_00_128[0],Hh_h_00_128[0]); @@ -649,7 +631,7 @@ void numer(int32_t *Hh_h_00_sq, unsigned short nb_rb) { - unsigned short rb; + simde__m128i *h_h_00_sq_128, *h_h_01_sq_128, *h_h_10_sq_128, *h_h_11_sq_128; simde__m128i *num_fin_128, sq_a_plus_sq_d_128, sq_b_plus_sq_c_128; @@ -660,7 +642,7 @@ void numer(int32_t *Hh_h_00_sq, num_fin_128 = (simde__m128i *)num_fin; - for (rb=0; rb<3*nb_rb; rb++) { + for (unsigned short rb=0; rb<3*nb_rb; rb++) { sq_a_plus_sq_d_128 = simde_mm_add_epi32(h_h_00_sq_128[0],h_h_11_sq_128[0]); sq_b_plus_sq_c_128 = simde_mm_add_epi32(h_h_01_sq_128[0],h_h_10_sq_128[0]); @@ -694,8 +676,6 @@ void dlsch_channel_level_TM34_meas(int *ch00, unsigned short nb_rb) { - - short rb; unsigned char nre=12; simde__m128i *ch00_128, *ch01_128, *ch10_128, *ch11_128; simde__m128i avg_0_row0_128D, avg_1_row0_128D, avg_0_row1_128D, avg_1_row1_128D; @@ -716,7 +696,7 @@ void dlsch_channel_level_TM34_meas(int *ch00, avg_0_row1_128D = simde_mm_setzero_si128(); avg_1_row1_128D = simde_mm_setzero_si128(); - for (rb=0; rb<3*nb_rb; rb++) { + for (short rb=0; rb<3*nb_rb; rb++) { ch00_128_tmp = simde_mm_load_si128(&ch00_128[0]); ch01_128_tmp = simde_mm_load_si128(&ch01_128[0]); ch10_128_tmp = simde_mm_load_si128(&ch10_128[0]); @@ -1223,16 +1203,9 @@ void lte_ue_measurements(PHY_VARS_UE *ue, // multiply by conjugated channel // print_ints("ch0",&dl_ch0_128[0]); // print_ints("ch1",&dl_ch1_128[0]); - mmtmpPMI0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); // print_ints("re",&mmtmpPMI0); - mmtmpPMI1 = simde_mm_shufflelo_epi16(dl_ch1_128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - // print_ints("_mm_shufflelo_epi16",&mmtmpPMI1); - mmtmpPMI1 = simde_mm_shufflehi_epi16(mmtmpPMI1, SIMDE_MM_SHUFFLE(2,3,0,1)); - // print_ints("_mm_shufflehi_epi16",&mmtmpPMI1); - mmtmpPMI1 = simde_mm_sign_epi16(mmtmpPMI1,*(simde__m128i*)&conjugate[0]); - // print_ints("_mm_sign_epi16",&mmtmpPMI1); - mmtmpPMI1 = simde_mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]); + mmtmpPMI1 = simde_mm_madd_epi16(oai_mm_swap(oai_mm_conj(dl_ch1_128[0])),dl_ch0_128[0]); // print_ints("mm_madd_epi16",&mmtmpPMI1); // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) pmi128_re = simde_mm_add_epi32(pmi128_re,mmtmpPMI0); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index a2c6494534..591c589b49 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -27,6 +27,7 @@ #include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "lte_estimation.h" #include "openair1/PHY/LTE_TRANSPORT/transport_vars.h" +#include "openair1/PHY/LTE_TRANSPORT/pucch_extern.h" // round(exp(sqrt(-1)*(pi/2)*[0:1:N-1]/N)*pow2(15)) static const int16_t ru_90[2 * 128] = { @@ -68,28 +69,26 @@ static const int16_t ru_90c[2 * 128] = { int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, L1_rxtx_proc_t *proc, - LTE_eNB_ULSCH_t * ulsch, - int32_t **ul_ch_estimates, - int32_t **ul_ch_estimates_time, - int32_t **rxdataF_ext, + LTE_eNB_ULSCH_t *ulsch, + c16_t **ul_ch_estimates, + c16_t **ul_ch_estimates_time, + c16_t **rxdataF_ext, module_id_t UE_id, unsigned char l, - unsigned char Ns) { + unsigned char Ns) +{ AssertFatal(ul_ch_estimates != NULL, "ul_ch_estimates is null "); AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n"); int subframe = proc->subframe_rx; - uint8_t harq_pid; + uint8_t harq_pid; int16_t delta_phase = 0; - const int16_t *ru1 = ru_90; - const int16_t *ru2 = ru_90; int16_t current_phase1,current_phase2; uint16_t aa,Msc_RS,Msc_RS_idx; uint16_t *Msc_idx_ptr; int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp; - int32_t *ul_ch1=NULL, *ul_ch2=NULL; - int16_t ul_ch_estimates_re,ul_ch_estimates_im; + c16_t *ul_ch1 = NULL, *ul_ch2 = NULL; //uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB; uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; uint8_t cyclic_shift; @@ -97,12 +96,9 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, uint32_t u=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[Ns+(subframe<<1)]; uint32_t v=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[Ns+(subframe<<1)]; int symbol_offset,i; - //debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift); - const int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377}; - const int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0, -16384, -28378, -32768, -28378, -16384}; + // debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift); simde__m128i *rxdataF128, *ul_ref128, *ul_ch128; - simde__m128i mmtmpU0, mmtmpU1, mmtmpU2, mmtmpU3; - int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); + c16_t temp_in_ifft_0[2048 * 2] __attribute__((aligned(32))); if (ulsch->ue_type > 0) harq_pid = 0; else { @@ -110,7 +106,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, } uint16_t N_rb_alloc = ulsch->harq_processes[harq_pid]->nb_rb; - int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(32))); + c16_t tmp_estimates[N_rb_alloc * 12] __attribute__((aligned(32))); Msc_RS = N_rb_alloc*12; cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + ulsch->harq_processes[harq_pid]->n_DMRS2 + @@ -142,49 +138,8 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, ul_ch128 = (simde__m128i *)&ul_ch_estimates[aa][symbol_offset]; ul_ref128 = (simde__m128i *)ul_ref_sigs_rx[u][v][Msc_RS_idx]; - for (i = 0; i < Msc_RS / 12; i++) { - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ref128[0], rxdataF128[0]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ref128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1, *(simde__m128i *)&conjugate[0]); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1, rxdataF128[0]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0, 15); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1, 15); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0, mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0, mmtmpU1); - ul_ch128[0] = simde_mm_packs_epi32(mmtmpU2, mmtmpU3); - // printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]); - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ref128[1], rxdataF128[1]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ref128[1], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1, *(simde__m128i *)conjugate); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1, rxdataF128[1]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0, 15); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1, 15); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0, mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0, mmtmpU1); - ul_ch128[1] = simde_mm_packs_epi32(mmtmpU2, mmtmpU3); - mmtmpU0 = simde_mm_madd_epi16(ul_ref128[2], rxdataF128[2]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ref128[2], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1, *(simde__m128i *)conjugate); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1, rxdataF128[2]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0, 15); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1, 15); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0, mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0, mmtmpU1); - ul_ch128[2] = simde_mm_packs_epi32(mmtmpU2, mmtmpU3); - ul_ch128+=3; - ul_ref128+=3; - rxdataF128+=3; + for (i = 0; i < Msc_RS >> 2; i++) { + ul_ch128[i] = oai_mm_cpx_mult_conj(ul_ref128[i], rxdataF128[i], 15); } alpha_ind = 0; @@ -196,16 +151,8 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, #endif for(i=symbol_offset; i>15); - //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im; - ((int16_t *) ul_ch_estimates[aa])[(i<<1)+1] = - (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) - - (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15); + c16_t alpha = (c16_t){alphaTBL_re[alpha_ind], alphaTBL_im[alpha_ind]}; + ul_ch_estimates[aa][i] = c16MulConjShift(alpha, ul_ch_estimates[aa][i], 15); alpha_ind+=cyclic_shift; if (alpha_ind>11) @@ -221,7 +168,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); for(i=0; iN_RB_DL) { case 6: @@ -296,26 +243,20 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, current_phase2 = (delta_phase/7)*(k-pilot_pos2); // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2); // set the right quadrant - (current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c); - (current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c); + c16_t *ru1 = (c16_t *)(current_phase1 > 0 ? ru_90 : ru_90c); + c16_t *ru2 = (c16_t *)(current_phase2 > 0 ? ru_90 : ru_90c); // take absolute value and clip current_phase1 = cmin(abs(current_phase1),127); - current_phase2 = cmin(abs(current_phase2),127); - // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); + current_phase2 = cmin(abs(current_phase2), 127); // rotate channel estimates by estimated phase - rotate_cpx_vector((c16_t *) ul_ch1, - (c16_t *)&ru1[2*current_phase1], - (c16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], - Msc_RS, - 15); - rotate_cpx_vector((c16_t *) ul_ch2, - (c16_t *)&ru2[2*current_phase2], - (c16_t *) tmp_estimates, - Msc_RS, - 15); + rotate_cpx_vector(ul_ch1, &ru1[current_phase1], &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS, 15); + rotate_cpx_vector(ul_ch2, &ru2[current_phase2], tmp_estimates, Msc_RS, 15); // Combine the two rotated estimates - multadd_complex_vector_real_scalar((int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS); - multadd_complex_vector_real_scalar((int16_t *) &tmp_estimates[0],SCALE,(int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS); + mult_complex_vector_real_scalar(&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], + SCALE, + &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], + Msc_RS); + multadd_complex_vector_real_scalar(tmp_estimates, SCALE, &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS); /* if ((kpilot_pos2))) { @@ -350,9 +291,9 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, } int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **ul_ch_estimates, - int32_t **ul_ch_estimates_time, - int32_t **rxdataF_ext, + c16_t **ul_ch_estimates, + c16_t **ul_ch_estimates_time, + c16_t **rxdataF_ext, int N_rb_alloc, int frame_rx, int subframe_rx, @@ -361,26 +302,21 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, uint32_t cyclic_shift, unsigned char l, int interpolate, - uint16_t rnti) { + uint16_t rnti) +{ int16_t delta_phase = 0; - const int16_t *ru1 = ru_90; - const int16_t *ru2 = ru_90; int16_t current_phase1,current_phase2; uint16_t aa,Msc_RS,Msc_RS_idx; uint16_t *Msc_idx_ptr; int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp; - int32_t *ul_ch1=NULL, *ul_ch2=NULL; - int16_t ul_ch_estimates_re,ul_ch_estimates_im; + c16_t *ul_ch1 = NULL, *ul_ch2 = NULL; uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; uint32_t alpha_ind; - int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16))); + c16_t tmp_estimates[N_rb_alloc * 12] __attribute__((aligned(16))); int symbol_offset,i; - //debug_msg("lte_ul_channel_estimation_RRU: cyclic shift %d\n",cyclicShift); - const int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377}; - const int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0, -16384, -28378, -32768, -28378, -16384}; + // debug_msg("lte_ul_channel_estimation_RRU: cyclic shift %d\n",cyclicShift); simde__m128i *rxdataF128, *ul_ref128, *ul_ch128; - simde__m128i mmtmpU0, mmtmpU1, mmtmpU2, mmtmpU3; - int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); + c16_t temp_in_ifft_0[2048 * 2] __attribute__((aligned(32))); AssertFatal(l==pilot_pos1 || l==pilot_pos2,"%d is not a valid symbol for DMRS, should be %d or %d\n", l,pilot_pos1,pilot_pos2); Msc_RS = N_rb_alloc*12; @@ -412,49 +348,8 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, ul_ch128 = (simde__m128i *)&ul_ch_estimates[aa][symbol_offset]; ul_ref128 = (simde__m128i *)ul_ref_sigs_rx[u][v][Msc_RS_idx]; - for (i = 0; i < Msc_RS / 12; i++) { - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ref128[0], rxdataF128[0]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ref128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1, *(simde__m128i *)&conjugate[0]); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1, rxdataF128[0]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0, 15); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1, 15); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0, mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0, mmtmpU1); - ul_ch128[0] = simde_mm_packs_epi32(mmtmpU2, mmtmpU3); - // printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]); - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ref128[1], rxdataF128[1]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ref128[1], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1, *(simde__m128i *)conjugate); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1, rxdataF128[1]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0, 15); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1, 15); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0, mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0, mmtmpU1); - ul_ch128[1] = simde_mm_packs_epi32(mmtmpU2, mmtmpU3); - mmtmpU0 = simde_mm_madd_epi16(ul_ref128[2], rxdataF128[2]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ref128[2], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1, *(simde__m128i *)conjugate); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1, rxdataF128[2]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0, 15); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1, 15); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0, mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0, mmtmpU1); - ul_ch128[2] = simde_mm_packs_epi32(mmtmpU2, mmtmpU3); - ul_ch128+=3; - ul_ref128+=3; - rxdataF128+=3; + for (i = 0; i < Msc_RS >> 2; i++) { + ul_ch128[i] = oai_mm_cpx_mult_conj(ul_ref128[i], rxdataF128[i], 15); } alpha_ind = 0; @@ -466,16 +361,8 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, #endif for(i=symbol_offset; i>15); - //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im; - ((int16_t *) ul_ch_estimates[aa])[(i<<1)+1] = - (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) - - (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15); + c16_t alpha = (c16_t){alphaTBL_re[alpha_ind], alphaTBL_im[alpha_ind]}; + ul_ch_estimates[aa][i] = c16MulConjShift(alpha, ul_ch_estimates[aa][i], 15); alpha_ind+=cyclic_shift; if (alpha_ind>11) @@ -492,7 +379,7 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); for(i=0; iN_RB_DL) { case 6: @@ -561,26 +448,20 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, current_phase2 = (delta_phase/7)*(k-pilot_pos2); // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2); // set the right quadrant - (current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c); - (current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c); + c16_t *ru1 = (c16_t *)(current_phase1 > 0 ? ru_90 : ru_90c); + c16_t *ru2 = (c16_t *)(current_phase2 > 0 ? ru_90 : ru_90c); // take absolute value and clip current_phase1 = cmin(abs(current_phase1),127); - current_phase2 = cmin(abs(current_phase2),127); - // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); + current_phase2 = cmin(abs(current_phase2), 127); // rotate channel estimates by estimated phase - rotate_cpx_vector((c16_t *) ul_ch1, - (c16_t *) &ru1[2*current_phase1], - (c16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], - Msc_RS, - 15); - rotate_cpx_vector((c16_t *) ul_ch2, - (c16_t *) &ru2[2*current_phase2], - (c16_t *) &tmp_estimates[0], - Msc_RS, - 15); + rotate_cpx_vector(ul_ch1, &ru1[current_phase1], &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS, 15); + rotate_cpx_vector(ul_ch2, &ru2[current_phase2], tmp_estimates, Msc_RS, 15); // Combine the two rotated estimates - multadd_complex_vector_real_scalar((int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS); - multadd_complex_vector_real_scalar((int16_t *) &tmp_estimates[0],SCALE,(int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS); + mult_complex_vector_real_scalar(&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], + SCALE, + &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], + Msc_RS); + multadd_complex_vector_real_scalar(tmp_estimates, SCALE, &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS); } } //for(k=... @@ -592,16 +473,16 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, for (k=0; ksymbols_per_tti>>1; k++) { if (k==pilot_pos1) k++; - memcpy((void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], - (void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1], - frame_parms->N_RB_UL*12*sizeof(int)); + memcpy((void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], + (void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * pilot_pos1], + frame_parms->N_RB_UL * 12 * sizeof(int)); } else if (interpolate == 0 && l == pilot_pos2) { for (k=0; ksymbols_per_tti>>1; k++) { if (k==pilot_pos2) k++; - memcpy((void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*(k+(frame_parms->symbols_per_tti>>1))], - (void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2], - frame_parms->N_RB_UL*12*sizeof(int)); + memcpy((void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * (k + (frame_parms->symbols_per_tti >> 1))], + (void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * pilot_pos2], + frame_parms->N_RB_UL * 12 * sizeof(int)); } delta_phase = lte_ul_freq_offset_estimation(frame_parms, @@ -663,12 +544,11 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, #endif //LOG_M("eNB_rxF.m","rxF",&common_vars->rxdataF[0][aa][2*frame_parms->ofdm_symbol_size*symbol],2*(frame_parms->ofdm_symbol_size),2,1); //LOG_M("eNB_srs.m","srs_eNB",common_vars->srs,(frame_parms->ofdm_symbol_size),1,1); - mult_cpx_conj_vector((int16_t *) &common_vars->rxdataF[aa][2*frame_parms->ofdm_symbol_size*symbol], - (int16_t *) srs_vars->srs, - (int16_t *) srs_vars->srs_ch_estimates[aa], + mult_cpx_conj_vector((c16_t *)&common_vars->rxdataF[aa][2 * frame_parms->ofdm_symbol_size * symbol], + (c16_t *)srs_vars->srs, + (c16_t *)srs_vars->srs_ch_estimates[aa], frame_parms->ofdm_symbol_size, - 15, - 0); + 15); #ifdef DEBUG_SRS sprintf(fname,"srs_ch_est%d.m",aa); sprintf(vname,"srs_est%d",aa); @@ -685,9 +565,8 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, return(0); } -int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t *ul_ch_estimates, uint16_t nb_rb) +int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, c16_t *ul_ch_estimates, uint16_t nb_rb) { - int k, rb; int a_idx = 64; uint8_t conj_flag = 0; uint8_t output_shift; @@ -700,7 +579,6 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t * Ravg[0]=0; Ravg[1]=0; int16_t iv, rv, phase_idx = 0; - simde__m128i R[3], mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3; simde__m128 avg128U1, avg128U2; // round(tan((pi/4)*[1:1:N]/N)*pow2(15)) @@ -709,7 +587,7 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t * avg128U1 = simde_mm_setzero_ps(); avg128U2 = simde_mm_setzero_ps(); - for (rb=0; rbN_RB_UL * 12]; // correlate and average the 2 channel estimates ul_ch1*ul_ch2 - for (rb=0; rb>15)) ? (a_idx -= 32>>k) : (a_idx += 32>>k); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 2506853705..843864251a 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -45,8 +45,6 @@ static const short jitter[8] __attribute__ ((aligned(16))) = {1,0,0,1,0,1,1,0}; static const short jitterc[8] __attribute__ ((aligned(16))) = {0,1,1,0,1,0,0,1}; -static const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; -static const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) { @@ -93,38 +91,38 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) { // conjugate input for (i=0; i<(Msc_PUSCH>>2); i++) { - * &(((simde__m128i *)z0)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z0)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z1)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z1)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z2)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z2)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z3)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z3)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z4)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z4)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z5)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z5)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z6)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z6)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z7)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z7)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z8)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z8)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z9)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z9)[i]),*(simde__m128i *)&conjugate2[0]); + ((simde__m128i *)z0)[i] = oai_mm_conj(((simde__m128i *)z0)[i]); + ((simde__m128i *)z1)[i] = oai_mm_conj(((simde__m128i *)z1)[i]); + ((simde__m128i *)z2)[i] = oai_mm_conj(((simde__m128i *)z2)[i]); + ((simde__m128i *)z3)[i] = oai_mm_conj(((simde__m128i *)z3)[i]); + ((simde__m128i *)z4)[i] = oai_mm_conj(((simde__m128i *)z4)[i]); + ((simde__m128i *)z5)[i] = oai_mm_conj(((simde__m128i *)z5)[i]); + ((simde__m128i *)z6)[i] = oai_mm_conj(((simde__m128i *)z6)[i]); + ((simde__m128i *)z7)[i] = oai_mm_conj(((simde__m128i *)z7)[i]); + ((simde__m128i *)z8)[i] = oai_mm_conj(((simde__m128i *)z8)[i]); + ((simde__m128i *)z9)[i] = oai_mm_conj(((simde__m128i *)z9)[i]); if (frame_parms->Ncp==NORMAL) { - * &(((simde__m128i *)z10)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z10)[i]),*(simde__m128i *)&conjugate2[0]); - * &(((simde__m128i *)z11)[i])=simde_mm_sign_epi16( *&(((simde__m128i *)z11)[i]),*(simde__m128i *)&conjugate2[0]); + ((simde__m128i *)z10)[i] = oai_mm_conj(((simde__m128i *)z10)[i]); + ((simde__m128i *)z11)[i] = oai_mm_conj(((simde__m128i *)z11)[i]); } } for (i=0,ip=0; iNcp==0) { - ((uint32_t *)idft_in2)[ip+2] = z10[i]; - ((uint32_t *)idft_in2)[ip+3] = z11[i]; + ((uint32_t *)idft_in2)[ip+2] = z10[i]; + ((uint32_t *)idft_in2)[ip+3] = z11[i]; } } dft_size_idx_t dftsize = get_dft(Msc_PUSCH); @@ -160,37 +158,37 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) { ((int16_t *)&idft_out0[ip+3])[0],((int16_t *)&idft_out0[ip+3])[1]); } - z1[i] = ((uint32_t *)idft_out0)[ip+1]; - z2[i] = ((uint32_t *)idft_out0)[ip+2]; - z3[i] = ((uint32_t *)idft_out0)[ip+3]; - z4[i] = ((uint32_t *)idft_out1)[ip+0]; - z5[i] = ((uint32_t *)idft_out1)[ip+1]; - z6[i] = ((uint32_t *)idft_out1)[ip+2]; - z7[i] = ((uint32_t *)idft_out1)[ip+3]; - z8[i] = ((uint32_t *)idft_out2)[ip]; - z9[i] = ((uint32_t *)idft_out2)[ip+1]; + z1[i] = ((uint32_t *)idft_out0)[ip+1]; + z2[i] = ((uint32_t *)idft_out0)[ip+2]; + z3[i] = ((uint32_t *)idft_out0)[ip+3]; + z4[i] = ((uint32_t *)idft_out1)[ip+0]; + z5[i] = ((uint32_t *)idft_out1)[ip+1]; + z6[i] = ((uint32_t *)idft_out1)[ip+2]; + z7[i] = ((uint32_t *)idft_out1)[ip+3]; + z8[i] = ((uint32_t *)idft_out2)[ip]; + z9[i] = ((uint32_t *)idft_out2)[ip+1]; if (frame_parms->Ncp==0) { - z10[i] = ((uint32_t *)idft_out2)[ip+2]; - z11[i] = ((uint32_t *)idft_out2)[ip+3]; + z10[i] = ((uint32_t *)idft_out2)[ip+2]; + z11[i] = ((uint32_t *)idft_out2)[ip+3]; } } // conjugate output for (i=0; i<(Msc_PUSCH>>2); i++) { - ((simde__m128i *)z0)[i]=simde_mm_sign_epi16(((simde__m128i *)z0)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z1)[i]=simde_mm_sign_epi16(((simde__m128i *)z1)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z2)[i]=simde_mm_sign_epi16(((simde__m128i *)z2)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z3)[i]=simde_mm_sign_epi16(((simde__m128i *)z3)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z4)[i]=simde_mm_sign_epi16(((simde__m128i *)z4)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z5)[i]=simde_mm_sign_epi16(((simde__m128i *)z5)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z6)[i]=simde_mm_sign_epi16(((simde__m128i *)z6)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z7)[i]=simde_mm_sign_epi16(((simde__m128i *)z7)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z8)[i]=simde_mm_sign_epi16(((simde__m128i *)z8)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z9)[i]=simde_mm_sign_epi16(((simde__m128i *)z9)[i],*(simde__m128i *)&conjugate2[0]); + ((simde__m128i *)z0)[i] = oai_mm_conj(((simde__m128i *)z0)[i]); + ((simde__m128i *)z1)[i] = oai_mm_conj(((simde__m128i *)z1)[i]); + ((simde__m128i *)z2)[i] = oai_mm_conj(((simde__m128i *)z2)[i]); + ((simde__m128i *)z3)[i] = oai_mm_conj(((simde__m128i *)z3)[i]); + ((simde__m128i *)z4)[i] = oai_mm_conj(((simde__m128i *)z4)[i]); + ((simde__m128i *)z5)[i] = oai_mm_conj(((simde__m128i *)z5)[i]); + ((simde__m128i *)z6)[i] = oai_mm_conj(((simde__m128i *)z6)[i]); + ((simde__m128i *)z7)[i] = oai_mm_conj(((simde__m128i *)z7)[i]); + ((simde__m128i *)z8)[i] = oai_mm_conj(((simde__m128i *)z8)[i]); + ((simde__m128i *)z9)[i] = oai_mm_conj(((simde__m128i *)z9)[i]); if (frame_parms->Ncp==NORMAL) { - ((simde__m128i *)z10)[i]=simde_mm_sign_epi16(((simde__m128i *)z10)[i],*(simde__m128i *)&conjugate2[0]); - ((simde__m128i *)z11)[i]=simde_mm_sign_epi16(((simde__m128i *)z11)[i],*(simde__m128i *)&conjugate2[0]); + ((simde__m128i *)z10)[i]=oai_mm_conj(((simde__m128i *)z10)[i]); + ((simde__m128i *)z11)[i]=oai_mm_conj(((simde__m128i *)z11)[i]); } } } @@ -266,10 +264,8 @@ void ulsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, } for (i=0; i<(nb_rb*3); i++) { - mmtmpU1 = simde_mm_abs_epi16(rxF[i]); - mmtmpU1 = simde_mm_subs_epi16(ch_mag[i],mmtmpU1); - mmtmpU2 = simde_mm_abs_epi16(mmtmpU1); - mmtmpU2 = simde_mm_subs_epi16(ch_magb[i],mmtmpU2); + mmtmpU1 = simde_mm_subs_epi16(ch_mag[i], simde_mm_abs_epi16(rxF[i])); + mmtmpU2 = simde_mm_subs_epi16(ch_magb[i], simde_mm_abs_epi16(mmtmpU1)); (*llrp32)[0] = simde_mm_extract_epi32(rxF[i],0); (*llrp32)[1] = simde_mm_extract_epi32(mmtmpU1,0); (*llrp32)[2] = simde_mm_extract_epi32(mmtmpU2,0); @@ -323,21 +319,21 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp128_0[i] = simde_mm_srai_epi16(simde_mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]),1); ul_ch_mag128_0[i] = simde_mm_srai_epi16(simde_mm_adds_epi16(ul_ch_mag128_0[i],ul_ch_mag128_1[i]),1); ul_ch_mag128_0b[i] = simde_mm_srai_epi16(simde_mm_adds_epi16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]),1); - rxdataF_comp128_0[i] = simde_mm_add_epi16(rxdataF_comp128_0[i],(*(simde__m128i *)&jitterc[0])); + rxdataF_comp128_0[i] = simde_mm_add_epi16(rxdataF_comp128_0[i], *(simde__m128i *)&jitterc[0]); } if (frame_parms->nb_antennas_rx==3) for (i=0; inb_antennas_rx==4) for (i=0; inb_antennas_rx; aarx++) { ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -427,92 +422,29 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128 = (simde__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb %d,%d,%d (output_shift %d)\n",aarx,symbol,rb,*((int16_t *)&ul_ch_mag128[0]),*((int16_t *)&ul_ch_mag128[1]),*((int16_t *)&ul_ch_mag128[2]),output_shift); - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpU0); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ch128[0],SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1,SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1,*(simde__m128i *)&conjugate[0]); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1,rxdataF128[0]); - // print_ints("im",&mmtmpU1); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0,output_shift); - // print_ints("re(shift)",&mmtmpU0); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1,output_shift); - // print_ints("im(shift)",&mmtmpU1); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - // print_ints("c0",&mmtmpU2); - // print_ints("c1",&mmtmpU3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpU2,mmtmpU3); - /* - LOG_I(PHY,"Antenna %d:",aarx); - print_shorts("rx:",&rxdataF128[0]); - print_shorts("ch:",&ul_ch128[0]); - print_shorts("pack:",&rxdataF_comp128[0]); - */ - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ch128[1],rxdataF128[1]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ch128[1],SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1,SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1,*(simde__m128i *)conjugate); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1,rxdataF128[1]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpU2,mmtmpU3); - /* - LOG_I(PHY,"Antenna %d:",aarx); - print_shorts("rx:",&rxdataF128[1]); - print_shorts("ch:",&ul_ch128[1]); - print_shorts("pack:",&rxdataF_comp128[1]); - */ - // multiply by conjugated channel - mmtmpU0 = simde_mm_madd_epi16(ul_ch128[2],rxdataF128[2]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = simde_mm_shufflelo_epi16(ul_ch128[2],SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = simde_mm_shufflehi_epi16(mmtmpU1,SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = simde_mm_sign_epi16(mmtmpU1,*(simde__m128i *)conjugate); - mmtmpU1 = simde_mm_madd_epi16(mmtmpU1,rxdataF128[2]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = simde_mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = simde_mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU2 = simde_mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = simde_mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - rxdataF_comp128[2] = simde_mm_packs_epi32(mmtmpU2,mmtmpU3); - /* - LOG_I(PHY,"Antenna %d:",aarx); - print_shorts("rx:",&rxdataF128[2]); - print_shorts("ch:",&ul_ch128[2]); - print_shorts("pack:",&rxdataF_comp128[2]); - */ - // Add a jitter to compensate for the saturation in "packs" resulting in a bias on the DC after IDFT - rxdataF_comp128[0] = simde_mm_add_epi16(rxdataF_comp128[0],(*(simde__m128i *)&jitter[0])); - rxdataF_comp128[1] = simde_mm_add_epi16(rxdataF_comp128[1],(*(simde__m128i *)&jitter[0])); - rxdataF_comp128[2] = simde_mm_add_epi16(rxdataF_comp128[2],(*(simde__m128i *)&jitter[0])); + for (uint16_t rb=0; rb < nb_rb; rb++) { - ul_ch128+=3; - ul_ch_mag128+=3; - rxdataF128+=3; - rxdataF_comp128+=3; + simde__m128i mmtmpU0,mmtmpU1,mmtmpU2; + + // just compute channel magnitude without scaling, this is done after equalization for SC-FDMA + mmtmpU0 = simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[3*rb + 0], ul_ch128[3*rb + 0]), output_shift); + mmtmpU1 = simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[3*rb + 1], ul_ch128[3*rb + 1]), output_shift); + mmtmpU2 = simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[3*rb + 2], ul_ch128[3*rb + 2]), output_shift); + + mmtmpU0 = simde_mm_packs_epi32(mmtmpU0, mmtmpU1); + mmtmpU1 = simde_mm_packs_epi32(mmtmpU2, mmtmpU2); + + ul_ch_mag128[3*rb + 0] = simde_mm_unpacklo_epi16(mmtmpU0, mmtmpU0); + ul_ch_mag128[3*rb + 1] = simde_mm_unpackhi_epi16(mmtmpU0, mmtmpU0); + ul_ch_mag128[3*rb + 2] = simde_mm_unpacklo_epi16(mmtmpU1, mmtmpU1); + //LOG_I(PHY, "comp: ant %d symbol %d rb %d => %d,%d,%d (output_shift %d)\n", aarx, symbol, rb, *((int16_t *)&ul_ch_mag128[0]), *((int16_t *)&ul_ch_mag128[1]), *((int16_t *)&ul_ch_mag128[2]), output_shift ); + + } + mult_cpx_conj_vector((c16_t *)ul_ch128, (c16_t *)rxdataF128, (c16_t *)rxdataF_comp128, 12 * nb_rb, output_shift); + + // Add a jitter to compensate for the saturation in "packs" resulting in a bias on the DC after IDFT + for (uint16_t rb = 0; rb < 3*nb_rb; rb++) { + rxdataF_comp128[rb] = simde_mm_add_epi16(rxdataF_comp128[rb], *(simde__m128i *)jitter); } } @@ -604,14 +536,15 @@ void rx_ulsch(PHY_VARS_eNB *eNB, l%(frame_parms->symbols_per_tti/2), l/(frame_parms->symbols_per_tti/2), frame_parms); - lte_ul_channel_estimation(&eNB->frame_parms,proc, - eNB->ulsch[UE_id], - eNB->pusch_vars[UE_id]->drs_ch_estimates, - eNB->pusch_vars[UE_id]->drs_ch_estimates_time, - eNB->pusch_vars[UE_id]->rxdataF_ext, + lte_ul_channel_estimation(&eNB->frame_parms, + proc, + eNB->ulsch[UE_id], + (c16_t **)eNB->pusch_vars[UE_id]->drs_ch_estimates, + (c16_t **)eNB->pusch_vars[UE_id]->drs_ch_estimates_time, + (c16_t **)eNB->pusch_vars[UE_id]->rxdataF_ext, UE_id, - l%(frame_parms->symbols_per_tti/2), - l/(frame_parms->symbols_per_tti/2)); + l % (frame_parms->symbols_per_tti / 2), + l / (frame_parms->symbols_per_tti / 2)); } int correction_factor = 1; @@ -705,11 +638,11 @@ void rx_ulsch(PHY_VARS_eNB *eNB, // if ((eNB->measurements.n0_power_dB[0]+3)ulsch_power[0]) if (23ulsch_power[0]) { freq_equalization(frame_parms, - pusch_vars->rxdataF_comp, - pusch_vars->ul_ch_mag, - pusch_vars->ul_ch_magb, + (c16_t **)pusch_vars->rxdataF_comp, + (c16_t **)pusch_vars->ul_ch_mag, + (c16_t **)pusch_vars->ul_ch_magb, l, - ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12, + ulsch[UE_id]->harq_processes[harq_pid]->nb_rb * 12, Qm); } } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c index f3d14b80ea..5dba6257df 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c @@ -890,185 +890,42 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext, uint8_t output_shift) { - uint16_t rb; - - simde__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; + simde__m128i *dl_ch128, *rxdataF128, *rxdataF_comp128; simde__m128i *dl_ch128_2, *rho128; - simde__m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3; - uint8_t aatx,aarx,pilots=0; - - - #ifdef DEBUG_DCI_DECODING LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol); #endif - if (symbol==0) - pilots=1; + int len_rb = (symbol == 0) ? 2 : 3; // pilots = 1 - for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { + for (uint8_t aatx=0; aatxnb_antenna_ports_eNB; aatx++) { //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB - for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (uint8_t aarx=0; aarxnb_antennas_rx; aarx++) { - dl_ch128 = (simde__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (simde__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - - for (rb=0; rbN_RB_DL; rb++) { + dl_ch128 = (simde__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (simde__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + for (uint16_t rb=0; rbN_RB_DL*len_rb; rb++) { // multiply by conjugated channel - mmtmpPD0 = simde_mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpPD0); - - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_shufflehi_epi16(mmtmpPD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_sign_epi16(mmtmpPD1,*(simde__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpPD1); - mmtmpPD1 = simde_mm_madd_epi16(mmtmpPD1,rxdataF128[0]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = simde_mm_srai_epi32(mmtmpPD0,output_shift); - // print_ints("re(shift)",&mmtmpPD0); - mmtmpPD1 = simde_mm_srai_epi32(mmtmpPD1,output_shift); - // print_ints("im(shift)",&mmtmpPD1); - mmtmpPD2 = simde_mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = simde_mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - // print_ints("c0",&mmtmpPD2); - // print_ints("c1",&mmtmpPD3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - - // multiply by conjugated channel - mmtmpPD0 = simde_mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_shufflehi_epi16(mmtmpPD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_sign_epi16(mmtmpPD1,*(simde__m128i*)conjugate); - mmtmpPD1 = simde_mm_madd_epi16(mmtmpPD1,rxdataF128[1]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = simde_mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = simde_mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = simde_mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = simde_mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - // multiply by conjugated channel - if (pilots == 0) { - mmtmpPD0 = simde_mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = simde_mm_shufflelo_epi16(dl_ch128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_shufflehi_epi16(mmtmpPD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_sign_epi16(mmtmpPD1,*(simde__m128i*)conjugate); - mmtmpPD1 = simde_mm_madd_epi16(mmtmpPD1,rxdataF128[2]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = simde_mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = simde_mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = simde_mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = simde_mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - rxdataF_comp128[2] = simde_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - } - - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - - if (pilots==0) { - dl_ch128+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { - dl_ch128+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } + rxdataF_comp128[rb] = oai_mm_cpx_mult_conj(dl_ch128[rb], rxdataF128[rb], output_shift); } } } - if (rho) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (uint8_t aarx=0; aarxnb_antennas_rx; aarx++) { rho128 = (simde__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128 = (simde__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128_2 = (simde__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rbN_RB_DL; rb++) { - + for (uint16_t rb=0; rbN_RB_DL*3; rb++) { // multiply by conjugated channel - mmtmpPD0 = simde_mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_shufflehi_epi16(mmtmpPD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_sign_epi16(mmtmpPD1,*(simde__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpPD1); - mmtmpPD1 = simde_mm_madd_epi16(mmtmpPD1,dl_ch128_2[0]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = simde_mm_srai_epi32(mmtmpPD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpPD1 = simde_mm_srai_epi32(mmtmpPD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpPD2 = simde_mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = simde_mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - // print_ints("c0",&mmtmpPD2); - // print_ints("c1",&mmtmpPD3); - rho128[0] = simde_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - - //print_shorts("rx:",dl_ch128_2); - //print_shorts("ch:",dl_ch128); - //print_shorts("pack:",rho128); - - // multiply by conjugated channel - mmtmpPD0 = simde_mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_shufflehi_epi16(mmtmpPD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_sign_epi16(mmtmpPD1,*(simde__m128i*)conjugate); - mmtmpPD1 = simde_mm_madd_epi16(mmtmpPD1,dl_ch128_2[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = simde_mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = simde_mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = simde_mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = simde_mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - - rho128[1] =simde_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - //print_shorts("rx:",dl_ch128_2+1); - //print_shorts("ch:",dl_ch128+1); - //print_shorts("pack:",rho128+1); - // multiply by conjugated channel - mmtmpPD0 = simde_mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = simde_mm_shufflelo_epi16(dl_ch128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_shufflehi_epi16(mmtmpPD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = simde_mm_sign_epi16(mmtmpPD1,*(simde__m128i*)conjugate); - mmtmpPD1 = simde_mm_madd_epi16(mmtmpPD1,dl_ch128_2[2]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = simde_mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = simde_mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = simde_mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = simde_mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - rho128[2] = simde_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - //print_shorts("rx:",dl_ch128_2+2); - //print_shorts("ch:",dl_ch128+2); - //print_shorts("pack:",rho128+2); - - dl_ch128+=3; - dl_ch128_2+=3; - rho128+=3; + rho128[rb] = oai_mm_cpx_mult_conj(dl_ch128[rb], dl_ch128_2[rb], output_shift); } } @@ -1081,17 +938,14 @@ void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, uint8_t symbol) { - uint8_t aatx; - simde__m128i *rxdataF_comp128_0,*rxdataF_comp128_1; - int32_t i; if (frame_parms->nb_antennas_rx>1) { - for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { + for (uint8_t aatx=0; aatxnb_antenna_ports_eNB; aatx++) { rxdataF_comp128_0 = (simde__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (simde__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; // MRC on each re of rb - for (i=0; iN_RB_DL*3; i++) { + for (int32_t i=0; iN_RB_DL*3; i++) { rxdataF_comp128_0[i] = simde_mm_adds_epi16(simde_mm_srai_epi16(rxdataF_comp128_0[i],1),simde_mm_srai_epi16(rxdataF_comp128_1[i],1)); } } @@ -1140,12 +994,10 @@ void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, for (re=0; re<12; re+=2) { // Alamouti RX combining - - rxF0[0] = rxF0[0] + rxF1[2]; - rxF0[1] = rxF0[1] - rxF1[3]; - - rxF0[2] = rxF0[2] - rxF1[0]; - rxF0[3] = rxF0[3] + rxF1[1]; + rxF0[0] += rxF1[2]; + rxF0[1] -= rxF1[3]; + rxF0[2] -= rxF1[0]; + rxF0[3] += rxF1[1]; rxF0+=4; rxF1+=4; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 0d13a1c38d..ac045480da 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -1263,7 +1263,7 @@ void dlsch_channel_compensation(int **rxdataF_ext, unsigned short rb; unsigned char aatx,aarx,symbol_mod,pilots=0; simde__m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; - simde__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0}; + simde__m128i QAM_amp128={0}; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { @@ -1298,101 +1298,54 @@ void dlsch_channel_compensation(int **rxdataF_ext, for (rb=0; rb2) { + simde__m128i mmtmpD0, mmtmpD1; // get channel amplitude if not QPSK - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0],dl_ch128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_madd_epi16(dl_ch128[1],dl_ch128[1]); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = simde_mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], dl_ch128[0]); + mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); + mmtmpD1 = simde_mm_madd_epi16(dl_ch128[1], dl_ch128[1]); + mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); + mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); // store channel magnitude here in a new field of dlsch - dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = simde_mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = simde_mm_slli_epi16(dl_ch_mag128[0],1); + dl_ch_mag128[0] = simde_mm_mulhi_epi16(dl_ch_mag128[0], QAM_amp128); + dl_ch_mag128[0] = simde_mm_slli_epi16(dl_ch_mag128[0], 1); //print_ints("Re(ch):",(int16_t*)&mmtmpD0); //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); - dl_ch_mag128[1] = simde_mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128[1] = simde_mm_unpackhi_epi16(mmtmpD0, mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = simde_mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = simde_mm_slli_epi16(dl_ch_mag128[1],1); + dl_ch_mag128[1] = simde_mm_mulhi_epi16(dl_ch_mag128[1], QAM_amp128); + dl_ch_mag128[1] = simde_mm_slli_epi16(dl_ch_mag128[1], 1); if (pilots==0) { - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[2],dl_ch128[2]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag128[2] = simde_mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + mmtmpD0 = simde_mm_madd_epi16(dl_ch128[2], dl_ch128[2]); + mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); + mmtmpD1 = simde_mm_packs_epi32(mmtmpD0, mmtmpD0); + dl_ch_mag128[2] = simde_mm_unpacklo_epi16(mmtmpD1, mmtmpD1); dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128[2] = simde_mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = simde_mm_slli_epi16(dl_ch_mag128[2],1); + dl_ch_mag128[2] = simde_mm_mulhi_epi16(dl_ch_mag128[2], QAM_amp128); + dl_ch_mag128[2] = simde_mm_slli_epi16(dl_ch_mag128[2], 1); } - dl_ch_mag128b[0] = simde_mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = simde_mm_slli_epi16(dl_ch_mag128b[0],1); - dl_ch_mag128b[1] = simde_mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = simde_mm_slli_epi16(dl_ch_mag128b[1],1); + dl_ch_mag128b[0] = simde_mm_mulhi_epi16(dl_ch_mag128b[0], QAM_amp128b); + dl_ch_mag128b[0] = simde_mm_slli_epi16(dl_ch_mag128b[0], 1); + dl_ch_mag128b[1] = simde_mm_mulhi_epi16(dl_ch_mag128b[1], QAM_amp128b); + dl_ch_mag128b[1] = simde_mm_slli_epi16(dl_ch_mag128b[1], 1); if (pilots==0) { - dl_ch_mag128b[2] = simde_mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = simde_mm_slli_epi16(dl_ch_mag128b[2],1); + dl_ch_mag128b[2] = simde_mm_mulhi_epi16(dl_ch_mag128b[2], QAM_amp128b); + dl_ch_mag128b[2] = simde_mm_slli_epi16(dl_ch_mag128b[2], 1); } } // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], rxdataF128[0], output_shift); + rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift); if (pilots==0) { // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + rxdataF_comp128[2] = oai_mm_cpx_mult_conj(dl_ch128[2], rxdataF128[2], output_shift); dl_ch128+=3; dl_ch_mag128+=3; dl_ch_mag128b+=3; @@ -1415,64 +1368,9 @@ void dlsch_channel_compensation(int **rxdataF_ext, dl_ch128 = (simde__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128_2 = (simde__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb>3; - - for (ii=0; ii>3; ++ii) { if (mod_order>2) { + simde__m128i mmtmpD0, mmtmpD1; // get channel amplitude if not QPSK - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0],dl_ch128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_madd_epi16(dl_ch128[1],dl_ch128[1]); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = simde_mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = oai_mm_smadd(dl_ch128[0], dl_ch128[0], output_shift); + mmtmpD1 = oai_mm_smadd(dl_ch128[1], dl_ch128[1], output_shift); + mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); // store channel magnitude here in a new field of dlsch - dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = simde_mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = simde_mm_slli_epi16(dl_ch_mag128[0],1); - //print_ints("Re(ch):",(int16_t*)&mmtmpD0); - //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); - //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); - dl_ch_mag128[1] = simde_mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128[0] = simde_mm_mulhi_epi16(dl_ch_mag128[0], QAM_amp128); + dl_ch_mag128[0] = simde_mm_slli_epi16(dl_ch_mag128[0], 1); + dl_ch_mag128[1] = simde_mm_unpackhi_epi16(mmtmpD0, mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = simde_mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = simde_mm_slli_epi16(dl_ch_mag128[1],1); - dl_ch_mag128b[0] = simde_mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = simde_mm_slli_epi16(dl_ch_mag128b[0],1); - dl_ch_mag128b[1] = simde_mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = simde_mm_slli_epi16(dl_ch_mag128b[1],1); + dl_ch_mag128[1] = simde_mm_mulhi_epi16(dl_ch_mag128[1], QAM_amp128); + dl_ch_mag128[1] = simde_mm_slli_epi16(dl_ch_mag128[1], 1); + dl_ch_mag128b[0] = simde_mm_mulhi_epi16(dl_ch_mag128b[0], QAM_amp128b); + dl_ch_mag128b[0] = simde_mm_slli_epi16(dl_ch_mag128b[0], 1); + dl_ch_mag128b[1] = simde_mm_mulhi_epi16(dl_ch_mag128b[1], QAM_amp128b); + dl_ch_mag128b[1] = simde_mm_slli_epi16(dl_ch_mag128b[1], 1); } // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - //print_shorts("pack:",rxdataF_comp128+1); + rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], rxdataF128[0], output_shift); + rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift); dl_ch128+=2; dl_ch_mag128+=2; dl_ch_mag128b+=2; @@ -1610,49 +1467,15 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, /*This part of code makes sense only for processing in 2x2 blocks*/ if (rho) { for (aarx=0; aarx>3; - - for (ii=0; ii>3; ++ii) { // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,dl_ch128_2[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rho128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - //print_shorts("rx:",dl_ch128_2); - //print_shorts("ch:",dl_ch128); - //print_shorts("pack:",rho128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,dl_ch128_2[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rho128[1] =simde_mm_packs_epi32(mmtmpD2,mmtmpD3); + rho128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], dl_ch128_2[0], output_shift); + rho128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], dl_ch128_2[1], output_shift); dl_ch128+=2; dl_ch128_2+=2; rho128+=2; @@ -1686,17 +1509,13 @@ void prec2A_TM56_128(unsigned char pmi,simde__m128i *ch0,simde__m128i *ch1) { break; case 2 : // +1 +j - ch1[0] = simde_mm_sign_epi16(ch1[0],*(simde__m128i *)&conjugate[0]); - ch1[0] = simde_mm_shufflelo_epi16(ch1[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - ch1[0] = simde_mm_shufflehi_epi16(ch1[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - ch0[0] = simde_mm_subs_epi16(ch0[0],ch1[0]); + ch1[0] = oai_mm_conj(oai_mm_swap(ch1[0])); + ch0[0] = simde_mm_subs_epi16(ch0[0], ch1[0]); break; // +1 -j case 3 : - ch1[0] = simde_mm_sign_epi16(ch1[0],*(simde__m128i *)&conjugate[0]); - ch1[0] = simde_mm_shufflelo_epi16(ch1[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - ch1[0] = simde_mm_shufflehi_epi16(ch1[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - ch0[0] = simde_mm_adds_epi16(ch0[0],ch1[0]); + ch1[0] = oai_mm_conj(oai_mm_swap(ch1[0])); + ch0[0] = simde_mm_adds_epi16(ch0[0], ch1[0]); break; } @@ -1757,9 +1576,7 @@ void prec2A_TM4_128(int pmi,simde__m128i *ch0,simde__m128i *ch1) { ch1[0] = simde_mm_subs_epi16(tmp0,tmp1); } else { //ch0+j*ch1 ch0-j*ch1 tmp0 = ch0[0]; - tmp1 = simde_mm_sign_epi16(ch1[0],*(simde__m128i *)&conjugate[0]); - tmp1 = simde_mm_shufflelo_epi16(tmp1, SIMDE_MM_SHUFFLE(2,3,0,1)); - tmp1 = simde_mm_shufflehi_epi16(tmp1, SIMDE_MM_SHUFFLE(2,3,0,1)); + tmp1 = oai_mm_conj(oai_mm_swap(ch1[0])); ch0[0] = simde_mm_subs_epi16(tmp0,tmp1); ch1[0] = simde_mm_add_epi16(tmp0,tmp1); } @@ -1796,7 +1613,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, simde__m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128; unsigned char aarx=0,symbol_mod,pilots=0; int precoded_signal_strength=0; - simde__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0}; + simde__m128i QAM_amp128={0}; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) @@ -1833,6 +1650,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, } if (mod_order>2) { + simde__m128i mmtmpD0,mmtmpD1; // get channel amplitude if not QPSK mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); @@ -1873,61 +1691,12 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, } // MF multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch0_128[0], rxdataF128[0], output_shift); + rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch0_128[1], rxdataF128[1], output_shift); if (pilots==0) { // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + rxdataF_comp128[2] = oai_mm_cpx_mult_conj(dl_ch0_128[2], rxdataF128[2], output_shift); dl_ch0_128+=3; dl_ch1_128+=3; dl_ch_mag128+=3; @@ -2047,7 +1816,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round]; unsigned char *pmi_ext = pdsch_vars->pmi_ext; - simde__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128={0},QAM_amp1_128={0}; + simde__m128i QAM_amp0_128={0}, QAM_amp1_128={0}; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) @@ -2074,13 +1843,13 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } for (aarx=0; aarxnb_antennas_rx; aarx++) { - dl_ch0_128 = (simde__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 + dl_ch0_128 = (simde__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 dl_ch1_128 = (simde__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 - dl_ch_mag0_128 = (simde__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 - dl_ch_mag0_128b = (simde__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 - dl_ch_mag1_128 = (simde__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 - dl_ch_mag1_128b = (simde__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 - rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2 + dl_ch_mag0_128 = (simde__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 + dl_ch_mag0_128b = (simde__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 + dl_ch_mag1_128 = (simde__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 + dl_ch_mag1_128b = (simde__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 + rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2 rxdataF_comp0_128 = (simde__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x1 on antenna of interest rxdataF_comp1_128 = (simde__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest @@ -2122,200 +1891,97 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } if (mod_order0>2) { + simde__m128i mmtmpD0, mmtmpD1; // get channel amplitude if not QPSK - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD0 = simde_mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag0_128[0] = simde_mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + mmtmpD0 = oai_mm_smadd(dl_ch0_128[0], dl_ch0_128[0], output_shift0); + mmtmpD1 = oai_mm_smadd(dl_ch0_128[1], dl_ch0_128[1], output_shift0); + mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); + dl_ch_mag0_128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0); dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; - dl_ch_mag0_128[0] = simde_mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); - dl_ch_mag0_128[0] = simde_mm_slli_epi16(dl_ch_mag0_128[0],1); + dl_ch_mag0_128[0] = simde_mm_mulhi_epi16(dl_ch_mag0_128[0], QAM_amp0_128); + dl_ch_mag0_128[0] = simde_mm_slli_epi16(dl_ch_mag0_128[0], 1); // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); - dl_ch_mag0_128[1] = simde_mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag0_128[1] = simde_mm_unpackhi_epi16(mmtmpD0, mmtmpD0); dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; - dl_ch_mag0_128[1] = simde_mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); - dl_ch_mag0_128[1] = simde_mm_slli_epi16(dl_ch_mag0_128[1],1); + dl_ch_mag0_128[1] = simde_mm_mulhi_epi16(dl_ch_mag0_128[1], QAM_amp0_128); + dl_ch_mag0_128[1] = simde_mm_slli_epi16(dl_ch_mag0_128[1], 1); if (pilots==0) { - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag0_128[2] = simde_mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + mmtmpD0 = oai_mm_smadd(dl_ch0_128[2], dl_ch0_128[2], output_shift0); + mmtmpD1 = simde_mm_packs_epi32(mmtmpD0, mmtmpD0); + dl_ch_mag0_128[2] = simde_mm_unpacklo_epi16(mmtmpD1, mmtmpD1); dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; - dl_ch_mag0_128[2] = simde_mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); - dl_ch_mag0_128[2] = simde_mm_slli_epi16(dl_ch_mag0_128[2],1); + dl_ch_mag0_128[2] = simde_mm_mulhi_epi16(dl_ch_mag0_128[2], QAM_amp0_128); + dl_ch_mag0_128[2] = simde_mm_slli_epi16(dl_ch_mag0_128[2], 1); } - dl_ch_mag0_128b[0] = simde_mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); - dl_ch_mag0_128b[0] = simde_mm_slli_epi16(dl_ch_mag0_128b[0],1); + dl_ch_mag0_128b[0] = simde_mm_mulhi_epi16(dl_ch_mag0_128b[0], QAM_amp0_128b); + dl_ch_mag0_128b[0] = simde_mm_slli_epi16(dl_ch_mag0_128b[0], 1); // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); - dl_ch_mag0_128b[1] = simde_mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); - dl_ch_mag0_128b[1] = simde_mm_slli_epi16(dl_ch_mag0_128b[1],1); + dl_ch_mag0_128b[1] = simde_mm_mulhi_epi16(dl_ch_mag0_128b[1], QAM_amp0_128b); + dl_ch_mag0_128b[1] = simde_mm_slli_epi16(dl_ch_mag0_128b[1], 1); if (pilots==0) { - dl_ch_mag0_128b[2] = simde_mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b); - dl_ch_mag0_128b[2] = simde_mm_slli_epi16(dl_ch_mag0_128b[2],1); + dl_ch_mag0_128b[2] = simde_mm_mulhi_epi16(dl_ch_mag0_128b[2], QAM_amp0_128b); + dl_ch_mag0_128b[2] = simde_mm_slli_epi16(dl_ch_mag0_128b[2], 1); } } if (mod_order1>2) { + simde__m128i mmtmpD0, mmtmpD1; // get channel amplitude if not QPSK - mmtmpD0 = simde_mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = simde_mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD0 = simde_mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag1_128[0] = simde_mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + mmtmpD0 = oai_mm_smadd(dl_ch1_128[0], dl_ch1_128[0], output_shift1); + mmtmpD1 = oai_mm_smadd(dl_ch1_128[1], dl_ch1_128[1], output_shift1); + mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); + dl_ch_mag1_128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0); dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; - dl_ch_mag1_128[0] = simde_mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); - dl_ch_mag1_128[0] = simde_mm_slli_epi16(dl_ch_mag1_128[0],1); + dl_ch_mag1_128[0] = simde_mm_mulhi_epi16(dl_ch_mag1_128[0], QAM_amp1_128); + dl_ch_mag1_128[0] = simde_mm_slli_epi16(dl_ch_mag1_128[0], 1); // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); - dl_ch_mag1_128[1] = simde_mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag1_128[1] = simde_mm_unpackhi_epi16(mmtmpD0, mmtmpD0); dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; - dl_ch_mag1_128[1] = simde_mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); - dl_ch_mag1_128[1] = simde_mm_slli_epi16(dl_ch_mag1_128[1],1); + dl_ch_mag1_128[1] = simde_mm_mulhi_epi16(dl_ch_mag1_128[1], QAM_amp1_128); + dl_ch_mag1_128[1] = simde_mm_slli_epi16(dl_ch_mag1_128[1], 1); if (pilots==0) { - mmtmpD0 = simde_mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = simde_mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag1_128[2] = simde_mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + mmtmpD0 = oai_mm_smadd(dl_ch1_128[2], dl_ch1_128[2], output_shift1); + mmtmpD1 = simde_mm_packs_epi32(mmtmpD0, mmtmpD0); + dl_ch_mag1_128[2] = simde_mm_unpacklo_epi16(mmtmpD1, mmtmpD1); dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; - dl_ch_mag1_128[2] = simde_mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); - dl_ch_mag1_128[2] = simde_mm_slli_epi16(dl_ch_mag1_128[2],1); + dl_ch_mag1_128[2] = simde_mm_mulhi_epi16(dl_ch_mag1_128[2], QAM_amp1_128); + dl_ch_mag1_128[2] = simde_mm_slli_epi16(dl_ch_mag1_128[2], 1); } - dl_ch_mag1_128b[0] = simde_mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); - dl_ch_mag1_128b[0] = simde_mm_slli_epi16(dl_ch_mag1_128b[0],1); + dl_ch_mag1_128b[0] = simde_mm_mulhi_epi16(dl_ch_mag1_128b[0], QAM_amp1_128b); + dl_ch_mag1_128b[0] = simde_mm_slli_epi16(dl_ch_mag1_128b[0], 1); // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); - dl_ch_mag1_128b[1] = simde_mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); - dl_ch_mag1_128b[1] = simde_mm_slli_epi16(dl_ch_mag1_128b[1],1); + dl_ch_mag1_128b[1] = simde_mm_mulhi_epi16(dl_ch_mag1_128b[1], QAM_amp1_128b); + dl_ch_mag1_128b[1] = simde_mm_slli_epi16(dl_ch_mag1_128b[1], 1); if (pilots==0) { - dl_ch_mag1_128b[2] = simde_mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b); - dl_ch_mag1_128b[2] = simde_mm_slli_epi16(dl_ch_mag1_128b[2],1); + dl_ch_mag1_128b[2] = simde_mm_mulhi_epi16(dl_ch_mag1_128b[2], QAM_amp1_128b); + dl_ch_mag1_128b[2] = simde_mm_slli_epi16(dl_ch_mag1_128b[2], 1); } } // layer 0 // MF multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)&conjugate[0]); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // print_ints("im",&mmtmpD1); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - // printf("Shift: %d\n",output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp0_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch0_128); - //print_shorts("pack:",rxdataF_comp0_128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp0_128[1] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch0_128+1); - // print_shorts("pack:",rxdataF_comp0_128+1); + rxdataF_comp0_128[0] = oai_mm_cpx_mult_conj(dl_ch0_128[0], rxdataF128[0], output_shift0); + rxdataF_comp0_128[1] = oai_mm_cpx_mult_conj(dl_ch0_128[1], rxdataF128[1], output_shift0); if (pilots==0) { // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp0_128[2] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch0_128+2); - // print_shorts("pack:",rxdataF_comp0_128+2); + rxdataF_comp0_128[2] = oai_mm_cpx_mult_conj(dl_ch0_128[2], rxdataF128[2], output_shift0); } // layer 1 // MF multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch1_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch1_128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift1); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift1); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp1_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch1_128); - // print_shorts("pack:",rxdataF_comp1_128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch1_128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch1_128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp1_128[1] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch1_128+1); - // print_shorts("pack:",rxdataF_comp1_128+1); + rxdataF_comp1_128[0] = oai_mm_cpx_mult_conj(dl_ch1_128[0], rxdataF128[0], output_shift1); + rxdataF_comp1_128[1] = oai_mm_cpx_mult_conj(dl_ch1_128[1], rxdataF128[1], output_shift1); if (pilots==0) { // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch1_128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch1_128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp1_128[2] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch1_128+2); - // print_shorts("pack:",rxdataF_comp1_128+2); + rxdataF_comp1_128[2] = oai_mm_cpx_mult_conj(dl_ch1_128[2], rxdataF128[2], output_shift1); dl_ch0_128+=3; dl_ch1_128+=3; dl_ch_mag0_128+=3; @@ -2360,7 +2026,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_rho_ext, unsigned char output_shift) { unsigned short rb; - simde__m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + simde__m128i *dl_ch128, *dl_ch128i, *dl_ch_rho128; unsigned char aarx,symbol_mod,pilots=0; // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -2383,53 +2049,12 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, for (rb=0; rbnb_antennas_rx>2) { simde__m128i *rxdataF_comp128_i2 = NULL; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c index 094b1ef8d5..fd1b2a3e9a 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c @@ -202,23 +202,21 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t mod_order_0, uint32_t rb_alloc) { - - int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; - int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; + c16_t rho_amp_x0[frame_parms->N_RB_DL * 12]; + c16_t rho_rho_amp_x0[frame_parms->N_RB_DL * 12]; uint16_t amp_tmp; uint16_t *llr16=(uint16_t*)dlsch_llr; int i, len, nsymb; uint8_t symbol, symbol_mod; - int len_acc=0; - uint16_t *sic_data; + int len_acc = 0; uint16_t pbch_pss_sss_adjust; nsymb = (frame_parms->Ncp==0) ? 14:12; for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]); - int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); - sic_data = (uint16_t*)&sic_buffer[0][((int16_t)len_acc)]; + uint16_t *rxF = (uint16_t *)&rxdataF_comp[0][symbol * frame_parms->N_RB_DL * 12]; + c16_t *rho_1 = (c16_t *)&rho_i[0][symbol * frame_parms->N_RB_DL * 12]; + c16_t *sic_data = (c16_t *)&sic_buffer[0][len_acc]; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -249,15 +247,14 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; //accumulated length; this is done because in sic_buffer we have only data symbols - multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + mult_complex_vector_real_scalar(sic_data, + amp_tmp, + rho_amp_x0, // this is in Q13 + len); - mult_cpx_vector((int16_t *)rho_1, //Q15 - (int16_t *)rho_amp_x0, //Q13 - (int16_t*)rho_rho_amp_x0, + mult_cpx_vector(rho_1, // Q15 + rho_amp_x0, // Q13 + rho_rho_amp_x0, len, 13); @@ -271,11 +268,11 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, symbol==nsymb-1 ? 14 : 13); #endif - sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, + sub_cpx_vector16((c16_t *)rxF, + rho_rho_amp_x0, //(int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + (c16_t *)rxF, + len * 2); #ifdef DEBUG_LLR_SIC LOG_M("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); @@ -407,14 +404,13 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, uint16_t mod_order_0, uint32_t rb_alloc) { - int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; - int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; + c16_t rho_amp_x0[frame_parms->N_RB_DL * 12]; + c16_t rho_rho_amp_x0[frame_parms->N_RB_DL * 12]; uint16_t amp_tmp; uint32_t *llr32=(uint32_t*)dlsch_llr; int i, len, nsymb; uint8_t symbol, symbol_mod; - int len_acc=0; - uint16_t *sic_data; + int len_acc = 0; uint16_t pbch_pss_sss_adjust; unsigned char len_mod4=0; simde__m128i llr128[2]; @@ -422,10 +418,10 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, nsymb = (frame_parms->Ncp==0) ? 14:12; for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]); - int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); - ch_mag = (simde__m128i*)(&dl_ch_mag[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); - sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]); + uint16_t *rxF = (uint16_t *)&rxdataF_comp[0][symbol * frame_parms->N_RB_DL * 12]; + c16_t *rho_1 = (c16_t *)&rho_i[0][symbol * frame_parms->N_RB_DL * 12]; + ch_mag = (simde__m128i *)&dl_ch_mag[0][symbol * frame_parms->N_RB_DL * 12]; + c16_t *sic_data = (c16_t *)&sic_buffer[0][len_acc]; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -447,23 +443,22 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; - multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + mult_complex_vector_real_scalar(sic_data, + amp_tmp, + rho_amp_x0, // this is in Q13 + len); - mult_cpx_vector((int16_t *)rho_1, //Q15 - (int16_t *)rho_amp_x0, //Q13 - (int16_t*)rho_rho_amp_x0, + mult_cpx_vector(rho_1, // Q15 + rho_amp_x0, // Q13 + rho_rho_amp_x0, len, 13); - sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - //(int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + sub_cpx_vector16((c16_t *)rxF, + rho_rho_amp_x0, + //(int16_t *)clean_x1, + (c16_t *)rxF, + len * 2); len_mod4 = len&3; len>>=2; // length in quad words (4 REs) @@ -637,14 +632,13 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t mod_order_0, uint32_t rb_alloc) { - int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; - int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; + c16_t rho_amp_x0[frame_parms->N_RB_DL * 12]; + c16_t rho_rho_amp_x0[frame_parms->N_RB_DL * 12]; uint16_t amp_tmp; uint16_t *llr32=(uint16_t*)dlsch_llr; int i, len, nsymb, len2; uint8_t symbol, symbol_mod; - int len_acc=0; - uint16_t *sic_data; + int len_acc = 0; uint16_t pbch_pss_sss_adjust; unsigned char len_mod4=0; uint16_t *llr2; @@ -653,11 +647,11 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, nsymb = (frame_parms->Ncp==0) ? 14:12; for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]); - int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); - ch_mag = (simde__m128i*)(&dl_ch_mag[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); - ch_magb = (simde__m128i*)(&dl_ch_magb[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); - sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]); + uint16_t *rxF = (uint16_t *)(&rxdataF_comp[0][symbol * frame_parms->N_RB_DL * 12]); + c16_t *rho_1 = (c16_t *)(&rho_i[0][symbol * frame_parms->N_RB_DL * 12]); + ch_mag = (simde__m128i *)(&dl_ch_mag[0][symbol * frame_parms->N_RB_DL * 12]); + ch_magb = (simde__m128i *)(&dl_ch_magb[0][symbol * frame_parms->N_RB_DL * 12]); + c16_t *sic_data = (c16_t *)(&sic_buffer[0][len_acc]); symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -679,23 +673,22 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; - multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + mult_complex_vector_real_scalar(sic_data, + amp_tmp, + rho_amp_x0, // this is in Q13 + len); - mult_cpx_vector((int16_t *)rho_1, //Q15 - (int16_t *)rho_amp_x0, //Q13 - (int16_t*)rho_rho_amp_x0, + mult_cpx_vector(rho_1, // Q15 + rho_amp_x0, // Q13 + rho_rho_amp_x0, len, 13); - sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - //(int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + sub_cpx_vector16((c16_t *)rxF, + rho_rho_amp_x0, + //(int16_t *)clean_x1, + (c16_t *)rxF, + len * 2); llr2 = llr32; llr32 += (len*6); @@ -864,17 +857,9 @@ void qpsk_qpsk(short *stream0_in, // put (rho_r + rho_i)/2sqrt2 in rho_rpi // put (rho_r - rho_i)/2sqrt2 in rho_rmi + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts( &xmm2, &xmm3, xmm0, xmm1); - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -887,16 +872,9 @@ void qpsk_qpsk(short *stream0_in, xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts( &y0r, &y0i, xmm0, xmm1); simde__m128i y0r_over2 = simde_mm_srai_epi16(y0r, 1); // divide by 2 simde__m128i y0i_over2 = simde_mm_srai_epi16(y0i, 1); // divide by 2 @@ -904,16 +882,8 @@ void qpsk_qpsk(short *stream0_in, xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts( &y1r, &y1i, xmm0, xmm1); simde__m128i y1r_over2 = simde_mm_srai_epi16(y1r, 1); // divide by 2 simde__m128i y1i_over2 = simde_mm_srai_epi16(y1i, 1); // divide by 2 @@ -1090,18 +1060,9 @@ void qpsk_qam16(int16_t *stream0_in, simde__m128i xmm0 = rho01_128i[i]; // 4 symbols simde__m128i xmm1 = rho01_128i[i + 1]; - // put (rho_r + rho_i)/2sqrt2 in rho_rpi - // put (rho_r - rho_i)/2sqrt2 in rho_rmi - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1117,16 +1078,8 @@ void qpsk_qam16(int16_t *stream0_in, xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts( &y0r, &y0i, xmm0, xmm1); // divide by sqrt(2) simde__m128i y0r_over2 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_2); @@ -1141,16 +1094,8 @@ void qpsk_qam16(int16_t *stream0_in, xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); xmm0 = simde_mm_setzero_si128(); // ZERO @@ -1175,15 +1120,8 @@ void qpsk_qam16(int16_t *stream0_in, // Rearrange interfering channel magnitudes xmm2 = ch_mag_128i_i[i]; xmm3 = ch_mag_128i_i[i+1]; + oai_mm_separate_real_imag_parts(&ch_mag_int, NULL, xmm2, xmm3); - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_int = simde_mm_unpacklo_epi64(xmm2, xmm3); simde__m128i tmp_result, tmp_result2; // calculate optimal interference amplitudes interference_abs_epi16(psi_r_p1_p1 , ch_mag_int, a_r_p1_p1 , ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); @@ -1347,16 +1285,9 @@ void qpsk_qam64(short *stream0_in, // put (rho_r + rho_i)/sqrt2 in rho_rpi // put (rho_r - rho_i)/sqrt2 in rho_rmi - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1372,16 +1303,8 @@ void qpsk_qam64(short *stream0_in, xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // divide by sqrt(2) simde__m128i y0r_over2 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_2); @@ -1396,16 +1319,8 @@ void qpsk_qam64(short *stream0_in, xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); xmm0 = simde_mm_setzero_si128(); // ZERO @@ -1430,15 +1345,8 @@ void qpsk_qam64(short *stream0_in, // Rearrange interfering channel magnitudes xmm2 = ch_mag_128i_i[i]; xmm3 = ch_mag_128i_i[i+1]; + oai_mm_separate_real_imag_parts(&ch_mag_int, NULL, xmm2, xmm3); - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_int = simde_mm_unpacklo_epi64(xmm2,xmm3); ch_mag_int_with_sigma2 = simde_mm_srai_epi16(ch_mag_int, 1); // *2 two_ch_mag_int_with_sigma2 = ch_mag_int; // *4 three_ch_mag_int_with_sigma2 = simde_mm_adds_epi16(ch_mag_int_with_sigma2, two_ch_mag_int_with_sigma2); // *6 @@ -1572,16 +1480,9 @@ void qam16_qpsk(short *stream0_in, // Get rho simde__m128i xmm0 = rho01_128i[i]; simde__m128i xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1610,16 +1511,8 @@ void qam16_qpsk(short *stream0_in, // Rearrange interfering MF output xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); xmm0 = simde_mm_setzero_si128(); // ZERO xmm2 = simde_mm_subs_epi16(rho_rpi_1_1, y1r); // = [Re(rho)+ Im(rho)]/sqrt(10) - y1r @@ -1691,28 +1584,13 @@ void qam16_qpsk(short *stream0_in, // Rearrange desired MF output xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // Rearrange desired channel magnitudes xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) xmm3 = ch_mag_128i[i+1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_des = simde_mm_unpacklo_epi64(xmm2,xmm3); // = [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) + oai_mm_separate_real_imag_parts(&ch_mag_des, NULL, xmm2, xmm3); // Scale MF output of desired signal y0r_over_sqrt10 = simde_mm_mulhi_epi16(y0r,ONE_OVER_SQRT_10); @@ -2065,16 +1943,9 @@ void qam16_qam16(short *stream0_in, // Get rho simde__m128i xmm0 = rho01_128i[i]; simde__m128i xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -2103,16 +1974,8 @@ void qam16_qam16(short *stream0_in, // Rearrange interfering MF output xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); xmm0 = simde_mm_setzero_si128(); // ZERO xmm2 = simde_mm_subs_epi16(rho_rpi_1_1, y1r); // = [Re(rho)+ Im(rho)]/sqrt(10) - y1r @@ -2184,41 +2047,18 @@ void qam16_qam16(short *stream0_in, // Rearrange desired MF output xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // Rearrange desired channel magnitudes xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) xmm3 = ch_mag_128i[i+1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_des = simde_mm_unpacklo_epi64(xmm2,xmm3); // = [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) + oai_mm_separate_real_imag_parts(&ch_mag_des, NULL, xmm2, xmm3); // Rearrange interfering channel magnitudes xmm2 = ch_mag_128i_i[i]; xmm3 = ch_mag_128i_i[i+1]; - - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_int = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_int, NULL, xmm2, xmm3); // Scale MF output of desired signal y0r_over_sqrt10 = simde_mm_mulhi_epi16(y0r,ONE_OVER_SQRT_10); @@ -2615,16 +2455,9 @@ void qam16_qam64(int16_t *stream0_in, // Get rho simde__m128i xmm0 = rho01_128i[i]; simde__m128i xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -2653,16 +2486,8 @@ void qam16_qam64(int16_t *stream0_in, // Rearrange interfering MF output xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); xmm0 = simde_mm_setzero_si128(); // ZERO xmm2 = simde_mm_subs_epi16(rho_rpi_1_1, y1r); // = [Re(rho)+ Im(rho)]/sqrt(10) - y1r @@ -2734,41 +2559,18 @@ void qam16_qam64(int16_t *stream0_in, // Rearrange desired MF output xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // Rearrange desired channel magnitudes xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) xmm3 = ch_mag_128i[i+1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_des = simde_mm_unpacklo_epi64(xmm2,xmm3); // = [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) + oai_mm_separate_real_imag_parts(&ch_mag_des, NULL, xmm2, xmm3); // Rearrange interfering channel magnitudes xmm2 = ch_mag_128i_i[i]; xmm3 = ch_mag_128i_i[i+1]; - - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - - ch_mag_int = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_int, NULL, xmm2, xmm3); // Scale MF output of desired signal y0r_over_sqrt10 = simde_mm_mulhi_epi16(y0r,ONE_OVER_SQRT_10); @@ -3248,16 +3050,9 @@ void qam64_qpsk(int16_t *stream0_in, // Get rho simde__m128i xmm0 = rho01_128i[i]; simde__m128i xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -3320,16 +3115,8 @@ void qam64_qpsk(int16_t *stream0_in, // Rearrange interfering MF output xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm_setzero_si128(); // ZERO for abs_pi16 @@ -3597,27 +3384,13 @@ void qam64_qpsk(int16_t *stream0_in, // Rearrange desired MF output xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // Rearrange desired channel magnitudes xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) xmm3 = ch_mag_128i[i+1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - ch_mag_des = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_des, NULL, xmm2, xmm3); y0r_one_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, THREE_OVER_SQRT_42); @@ -4759,16 +4532,9 @@ void qam64_qam16(short *stream0_in, // Get rho simde__m128i xmm0 = rho01_128i[i]; simde__m128i xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -4831,16 +4597,8 @@ void qam64_qam16(short *stream0_in, // Rearrange interfering MF output xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm_setzero_si128(); // ZERO for abs_pi16 @@ -5108,38 +4866,18 @@ void qam64_qam16(short *stream0_in, // Rearrange desired MF output xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // Rearrange desired channel magnitudes xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) xmm3 = ch_mag_128i[i+1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - ch_mag_des = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_des, NULL, xmm2, xmm3); // Rearrange interfering channel magnitudes xmm2 = ch_mag_128i_i[i]; xmm3 = ch_mag_128i_i[i+1]; - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - ch_mag_int = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_int, NULL, xmm2, xmm3); y0r_one_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, THREE_OVER_SQRT_42); @@ -6287,16 +6025,9 @@ void qam64_qam64(short *stream0_in, // Get rho simde__m128i xmm0 = rho01_128i[i]; simde__m128i xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde__m128i xmm2, xmm3; + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, xmm0, xmm1); + simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -6359,16 +6090,8 @@ void qam64_qam64(short *stream0_in, // Rearrange interfering MF output xmm0 = stream1_128i_in[i]; xmm1 = stream1_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde__m128i y1r, y1i; + oai_mm_separate_real_imag_parts(&y1r, &y1i, xmm0, xmm1); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm_setzero_si128(); // ZERO for abs_pi16 @@ -6636,38 +6359,18 @@ void qam64_qam64(short *stream0_in, // Rearrange desired MF output xmm0 = stream0_128i_in[i]; xmm1 = stream0_128i_in[i+1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde__m128i y0r, y0i; + oai_mm_separate_real_imag_parts(&y0r, &y0i, xmm0, xmm1); // Rearrange desired channel magnitudes xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) xmm3 = ch_mag_128i[i+1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - ch_mag_des = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_des, NULL, xmm2, xmm3); // Rearrange interfering channel magnitudes xmm2 = ch_mag_128i_i[i]; xmm3 = ch_mag_128i_i[i+1]; - xmm2 = simde_mm_shufflelo_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - ch_mag_int = simde_mm_unpacklo_epi64(xmm2,xmm3); + oai_mm_separate_real_imag_parts(&ch_mag_int, NULL, xmm2, xmm3); y0r_one_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, THREE_OVER_SQRT_42); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c index 72422d4dcf..0877b2ba7e 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c @@ -199,22 +199,8 @@ void qam64_qam16_avx2(short *stream0_in, for (i=0; icommon_vars.rxdata, - frame_parms, - (int *)&ue->common_vars.eNb_id); + sync_pos = lte_sync_time((c16_t **)ue->common_vars.rxdata, frame_parms, (int *)&ue->common_vars.eNb_id); // LOG_M("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); if (sync_pos >= frame_parms->nb_prefix_samples) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c index 9eefe212c7..b6f2178d8a 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c @@ -104,9 +104,9 @@ uint16_t pbch_extract(int **rxdataF, for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) { if (high_speed_flag == 1) - dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset+(symbol*(frame_parms->ofdm_symbol_size))]; + dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset+(symbol*(frame_parms->ofdm_symbol_size))]; else - dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset]; + dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset]; dl_ch0_ext = &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*(6*12)]; @@ -188,14 +188,13 @@ int pbch_channel_level(int **dl_ch_estimates_ext, return(avg2); } -simde__m128i mmtmpP0, mmtmpP1, mmtmpP2, mmtmpP3; void pbch_channel_compensation(int **rxdataF_ext, int **dl_ch_estimates_ext, int **rxdataF_comp, LTE_DL_FRAME_PARMS *frame_parms, uint8_t symbol, uint8_t output_shift) { - uint16_t rb,nb_rb=6; + uint16_t nb_rb=6; uint8_t aatx, aarx, symbol_mod; simde__m128i *dl_ch128, *rxdataF128, *rxdataF_comp128; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -206,72 +205,10 @@ void pbch_channel_compensation(int **rxdataF_ext, rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol_mod * 6 * 12]; rxdataF_comp128 = (simde__m128i *)&rxdataF_comp[(aatx << 1) + aarx][symbol_mod * 6 * 12]; - for (rb=0; rb 1) ? 3 : 2; + for (uint16_t rb=0; rb1) { - // multiply by conjugated channel - mmtmpP0 = simde_mm_madd_epi16(dl_ch128[2], rxdataF128[2]); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - mmtmpP1 = simde_mm_shufflelo_epi16(dl_ch128[2], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpP1 = simde_mm_shufflehi_epi16(mmtmpP1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpP1 = simde_mm_sign_epi16(mmtmpP1, *(simde__m128i *)&conjugate[0]); - mmtmpP1 = simde_mm_madd_epi16(mmtmpP1, rxdataF128[2]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = simde_mm_srai_epi32(mmtmpP0, output_shift); - mmtmpP1 = simde_mm_srai_epi32(mmtmpP1, output_shift); - mmtmpP2 = simde_mm_unpacklo_epi32(mmtmpP0, mmtmpP1); - mmtmpP3 = simde_mm_unpackhi_epi32(mmtmpP0, mmtmpP1); - rxdataF_comp128[2] = simde_mm_packs_epi32(mmtmpP2, mmtmpP3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - dl_ch128+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { - dl_ch128+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } + rxdataF_comp128[rb] = oai_mm_cpx_mult_conj(dl_ch128[rb], rxdataF128[rb], output_shift); } } @@ -343,10 +280,10 @@ void pbch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, for (rb=0; rb<6; rb++) { for (re=0; re<12; re+=2) { // Alamouti RX combining - rxF0[0] = rxF0[0] + rxF1[2]; - rxF0[1] = rxF0[1] - rxF1[3]; - rxF0[2] = rxF0[2] - rxF1[0]; - rxF0[3] = rxF0[3] + rxF1[1]; + rxF0[0] += rxF1[2]; + rxF0[1] -= rxF1[3]; + rxF0[2] -= rxF1[0]; + rxF0[3] += rxF1[1]; rxF0+=4; rxF1+=4; } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c index 04546b2a19..81ddb264ff 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c @@ -298,7 +298,7 @@ void mch_channel_compensation(int **rxdataF_ext, unsigned char output_shift) { int aarx, nre, i; simde__m128i *dl_ch128, *dl_ch_mag128, *dl_ch_mag128b, *rxdataF128, *rxdataF_comp128; - simde__m128i mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3, QAM_amp128 = {0}, QAM_amp128b = {0}; + simde__m128i QAM_amp128 = {0}, QAM_amp128b = {0}; if ((symbol == 2) || (symbol == 6) || (symbol == 10)) nre = frame_parms->N_RB_DL*6; @@ -322,11 +322,10 @@ void mch_channel_compensation(int **rxdataF_ext, for (i=0; i<(nre>>2); i+=2) { if (mod_order>2) { + simde__m128i mmtmpD0, mmtmpD1; // get channel amplitude if not QPSK - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], dl_ch128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_madd_epi16(dl_ch128[1], dl_ch128[1]); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); + mmtmpD0 = oai_mm_smadd(dl_ch128[0], dl_ch128[0], output_shift); + mmtmpD1 = oai_mm_smadd(dl_ch128[1], dl_ch128[1], output_shift); mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); // store channel magnitude here in a new field of dlsch dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0); @@ -344,43 +343,9 @@ void mch_channel_compensation(int **rxdataF_ext, } // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], rxdataF128[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[1], rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], rxdataF128[0], output_shift); + rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift); + dl_ch128+=2; dl_ch_mag128+=2; dl_ch_mag128b+=2; @@ -404,7 +369,7 @@ void mch_channel_compensation_khz_1dot25(int **rxdataF_ext, unsigned char output_shift) { int aarx, nre, i; simde__m128i *dl_ch128, *dl_ch_mag128, *dl_ch_mag128b, *rxdataF128, *rxdataF_comp128; - simde__m128i mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3, QAM_amp128 = {0}, QAM_amp128b = {0}; + simde__m128i QAM_amp128 = {0}, QAM_amp128b = {0}; /*if ((symbol == 2) || (symbol == 6) || (symbol == 10)) nre = frame_parms->N_RB_DL*6; else @@ -428,11 +393,10 @@ void mch_channel_compensation_khz_1dot25(int **rxdataF_ext, for (i=0; i<(nre>>2); i+=2) { if (mod_order>2) { + simde__m128i mmtmpD0, mmtmpD1; // get channel amplitude if not QPSK - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], dl_ch128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_madd_epi16(dl_ch128[1], dl_ch128[1]); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); + mmtmpD0 = oai_mm_smadd(dl_ch128[0], dl_ch128[0], output_shift); + mmtmpD1 = oai_mm_smadd(dl_ch128[1], dl_ch128[1], output_shift); mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); // store channel magnitude here in a new field of dlsch dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0); @@ -450,43 +414,9 @@ void mch_channel_compensation_khz_1dot25(int **rxdataF_ext, } // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], rxdataF128[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[1], rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], rxdataF128[0], output_shift); + rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift); + dl_ch128+=2; dl_ch_mag128+=2; dl_ch_mag128b+=2; diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 97bb9abb5b..398f5a0b6f 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -66,21 +66,19 @@ int beam_precoding(int32_t **txdataF, int rb_offset_neg = (subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti) + rb_offset_neg0; int rb_offset_pos = (subframe*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti); - - multadd_cpx_vector((int16_t*)&txdataF[p][rb_offset_neg+(symbol*frame_parms->ofdm_symbol_size)], - (int16_t*)&beam_weights[l1_id][p][aa][rb_offset_neg0], - (int16_t*)&txdataF_BF[aa][rb_offset_neg0+(symbol*frame_parms->ofdm_symbol_size)], - 0, - 6*frame_parms->N_RB_DL, - 15); - multadd_cpx_vector((int16_t*)&txdataF[p][rb_offset_pos+(symbol*frame_parms->ofdm_symbol_size)], - (int16_t*)&beam_weights[l1_id][p][aa][0], - (int16_t*)&txdataF_BF[aa][(symbol*frame_parms->ofdm_symbol_size)], - 0, - 7*frame_parms->N_RB_DL, // to allow for extra RE at the end, 12 useless multipy-adds (first one at DC and 11 at end) + multadd_cpx_vector((c16_t *)&txdataF[p][rb_offset_neg + (symbol * frame_parms->ofdm_symbol_size)], + (c16_t *)&beam_weights[l1_id][p][aa][rb_offset_neg0], + (c16_t *)&txdataF_BF[aa][rb_offset_neg0 + (symbol * frame_parms->ofdm_symbol_size)], + 6 * frame_parms->N_RB_DL, 15); + multadd_cpx_vector( + (c16_t *)&txdataF[p][rb_offset_pos + (symbol * frame_parms->ofdm_symbol_size)], + (c16_t *)&beam_weights[l1_id][p][aa][0], + (c16_t *)&txdataF_BF[aa][(symbol * frame_parms->ofdm_symbol_size)], + 7 * frame_parms->N_RB_DL, // to allow for extra RE at the end, 12 useless multipy-adds (first one at DC and 11 at end) + 15); - return 0; + return 0; } @@ -111,25 +109,12 @@ int beam_precoding_one_eNB(int32_t **txdataF, for(p=0;p>15); - ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); - ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); - ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); - } - */ - } + multadd_cpx_vector((c16_t *)&txdataF[p][symbol * ofdm_symbol_size + re_offset], + (c16_t *)beam_weights[0][p][aa], + (c16_t *)&txdataF_BF[aa][symbol * ofdm_symbol_size], + ofdm_symbol_size, + 15); + } } } } @@ -151,10 +136,9 @@ void nr_beam_precoding(c16_t **txdataF, memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, sizeof(c16_t) *(frame_parms->ofdm_symbol_size)); for (int p = 0; p < nb_antenna_ports; p++) { - multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset], - (int16_t*)beam_weights[p][aa], - (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], - 0, + multadd_cpx_vector((c16_t *)&txdataF[p][(symbol * frame_parms->ofdm_symbol_size) + offset], + (c16_t *)beam_weights[p][aa], + (c16_t *)&txdataF_BF[aa][symbol * frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 15); } diff --git a/openair1/PHY/MODULATION/compute_bf_weights.c b/openair1/PHY/MODULATION/compute_bf_weights.c index 2bf5a08316..6510fbf18d 100644 --- a/openair1/PHY/MODULATION/compute_bf_weights.c +++ b/openair1/PHY/MODULATION/compute_bf_weights.c @@ -3,32 +3,6 @@ #include #include "PHY/defs_common.h" -int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs){ - - FILE *calibF_fd; - int i,j,calibF_e; - - calibF_fd = fopen(calibF_fname,"r"); - - if (calibF_fd) { - printf("Loading Calibration matrix from %s\n", calibF_fname); - - for(i=0;ifirst_carrier_offset - 6, (nb_rb + 1) * 6, 15); - multadd_cpx_vector((int16_t *)this_symbol, (int16_t *)shift_rot, (int16_t *)this_symbol, - 1, (nb_rb + 1) * 6, 15); - multadd_cpx_vector((int16_t *)(this_symbol + frame_parms->first_carrier_offset - 6), - (int16_t *)(shift_rot + frame_parms->first_carrier_offset - 6), - (int16_t *)(this_symbol + frame_parms->first_carrier_offset - 6), - 1, (nb_rb + 1) * 6, 15); + mult_cpx_vector(this_symbol, shift_rot, this_symbol, (nb_rb + 1) * 6, 15); + mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6, + shift_rot + frame_parms->first_carrier_offset - 6, + this_symbol + frame_parms->first_carrier_offset - 6, + (nb_rb + 1) * 6, + 15); } else { rotate_cpx_vector(this_symbol, &rot2, this_symbol, nb_rb * 6, 15); @@ -219,12 +219,12 @@ void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms, &rot2, this_symbol + frame_parms->first_carrier_offset, nb_rb * 6, 15); - multadd_cpx_vector((int16_t *)this_symbol, (int16_t *)shift_rot, (int16_t *)this_symbol, - 1, nb_rb * 6, 15); - multadd_cpx_vector((int16_t *)(this_symbol + frame_parms->first_carrier_offset), - (int16_t *)(shift_rot + frame_parms->first_carrier_offset), - (int16_t *)(this_symbol + frame_parms->first_carrier_offset), - 1, nb_rb * 6, 15); + mult_cpx_vector(this_symbol, shift_rot, this_symbol, nb_rb * 6, 15); + mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset, + shift_rot + frame_parms->first_carrier_offset, + this_symbol + frame_parms->first_carrier_offset, + nb_rb * 6, + 15); } } } diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c index db3fd533eb..9dbacc4335 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c @@ -27,90 +27,59 @@ void remove_7_5_kHz(RU_t *ru,uint8_t slot) { + c16_t **rxdata=(c16_t **)ru->common.rxdata; + c16_t **rxdata_7_5kHz=(c16_t **)ru->common.rxdata_7_5kHz; + int16_t *kHz7_5; - int32_t **rxdata=ru->common.rxdata; - int32_t **rxdata_7_5kHz=ru->common.rxdata_7_5kHz; - uint16_t len; - uint32_t *kHz7_5ptr; - simde__m128i *rxptr128, *rxptr128_7_5kHz, *kHz7_5ptr128, kHz7_5_2, mmtmp_re, mmtmp_im, mmtmp_re2, mmtmp_im2; - uint32_t slot_offset,slot_offset2; - uint8_t aa; - uint32_t i; LTE_DL_FRAME_PARMS *frame_parms=ru->frame_parms; switch (frame_parms->N_RB_UL) { case 6: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s6n_kHz_7_5 : (uint32_t*)s6e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s6n_kHz_7_5 : s6e_kHz_7_5; break; case 15: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s15n_kHz_7_5 : (uint32_t*)s15e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s15n_kHz_7_5 : s15e_kHz_7_5; break; case 25: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_kHz_7_5 : (uint32_t*)s25e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s25n_kHz_7_5 : s25e_kHz_7_5; break; case 50: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s50n_kHz_7_5 : (uint32_t*)s50e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s50n_kHz_7_5 : s50e_kHz_7_5; break; case 75: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s75n_kHz_7_5 : (uint32_t*)s75e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s75n_kHz_7_5 : s75e_kHz_7_5; break; case 100: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s100n_kHz_7_5 : (uint32_t*)s100e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s100n_kHz_7_5 : s100e_kHz_7_5; break; default: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_kHz_7_5 : (uint32_t*)s25e_kHz_7_5; + kHz7_5 = (frame_parms->Ncp==0) ? s25n_kHz_7_5 : s25e_kHz_7_5; break; } + uint32_t slot_offset = ((uint32_t)slot * frame_parms->samples_per_tti/2)-ru->N_TA_offset; + uint32_t slot_offset2 = (uint32_t)(slot&1) * frame_parms->samples_per_tti/2; - slot_offset = ((uint32_t)slot * frame_parms->samples_per_tti/2)-ru->N_TA_offset; - slot_offset2 = (uint32_t)(slot&1) * frame_parms->samples_per_tti/2; + uint16_t len = frame_parms->samples_per_tti/2; - len = frame_parms->samples_per_tti/2; - - for (aa=0; aanb_rx; aa++) { - rxptr128 = (simde__m128i *)&rxdata[aa][slot_offset]; - rxptr128_7_5kHz = (simde__m128i *)&rxdata_7_5kHz[aa][slot_offset2]; - kHz7_5ptr128 = (simde__m128i *)kHz7_5ptr; + for (uint8_t aa=0; aanb_rx; aa++) { + c16_t *rxptr = rxdata[aa]+slot_offset; + c16_t *rxptr_7_5kHz = rxdata_7_5kHz[aa]+slot_offset2; // apply 7.5 kHz - - // if (((slot>>1)&1) == 0) { // apply the sinusoid from the table directly - for (i=0; i<(len>>2); i++) { - kHz7_5_2 = simde_mm_sign_epi16(*kHz7_5ptr128, *(simde__m128i *)&conjugate75_2[0]); - mmtmp_re = simde_mm_madd_epi16(*rxptr128, kHz7_5_2); - // Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work) - mmtmp_im = simde_mm_shufflelo_epi16(kHz7_5_2, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmp_im = simde_mm_shufflehi_epi16(mmtmp_im, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmp_im = simde_mm_sign_epi16(mmtmp_im, *(simde__m128i *)&conjugate75[0]); - mmtmp_im = simde_mm_madd_epi16(mmtmp_im, rxptr128[0]); - mmtmp_re = simde_mm_srai_epi32(mmtmp_re, 15); - mmtmp_im = simde_mm_srai_epi32(mmtmp_im, 15); - mmtmp_re2 = simde_mm_unpacklo_epi32(mmtmp_re, mmtmp_im); - mmtmp_im2 = simde_mm_unpackhi_epi32(mmtmp_re, mmtmp_im); - - rxptr128_7_5kHz[0] = simde_mm_packs_epi32(mmtmp_re2, mmtmp_im2); - rxptr128++; - rxptr128_7_5kHz++; - kHz7_5ptr128++; - } + mult_complex_vectors((c16_t*)kHz7_5,rxptr,rxptr_7_5kHz,len, 15); // undo 7.5 kHz offset for symbol 3 in case RU is slave (for OTA synchronization) if (ru->is_slave == 1 && slot == 2){ - memcpy((void*)&rxdata_7_5kHz[aa][(3*frame_parms->ofdm_symbol_size)+ - (2*frame_parms->nb_prefix_samples)+ - frame_parms->nb_prefix_samples0], - (void*)&rxdata[aa][slot_offset+ru->N_TA_offset+ - (3*frame_parms->ofdm_symbol_size)+ - (2*frame_parms->nb_prefix_samples)+ - frame_parms->nb_prefix_samples0], - (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples)*sizeof(int32_t)); -} + int offset=3*frame_parms->ofdm_symbol_size+2*frame_parms->nb_prefix_samples+frame_parms->nb_prefix_samples0; + memcpy(rxdata_7_5kHz[aa]+offset, + rxdata[aa]+offset, + (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples)*sizeof(c16_t)); + } + } } -} - diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c b/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c index 81d01e2dc1..4172b66925 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c @@ -28,13 +28,9 @@ void apply_7_5_kHz(PHY_VARS_UE *ue,int32_t*txdata,uint8_t slot) { - - uint16_t len; uint32_t *kHz7_5ptr; - simde__m128i *txptr128, *kHz7_5ptr128, mmtmp_re, mmtmp_im, mmtmp_re2, mmtmp_im2; - uint32_t slot_offset; - // uint8_t aa; - uint32_t i; + simde__m128i *txptr128, *kHz7_5ptr128; + LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; switch (frame_parms->N_RB_UL) { @@ -68,31 +64,17 @@ void apply_7_5_kHz(PHY_VARS_UE *ue,int32_t*txdata,uint8_t slot) break; } - slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2; - len = frame_parms->samples_per_tti/2; + uint32_t slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2; + uint16_t len = frame_parms->samples_per_tti/2; txptr128 = (simde__m128i *)&txdata[slot_offset]; kHz7_5ptr128 = (simde__m128i *)kHz7_5ptr; // apply 7.5 kHz - for (i = 0; i < (len >> 2); i++) { - mmtmp_re = simde_mm_madd_epi16(*txptr128, *kHz7_5ptr128); + for (uint32_t i = 0; i < (len >> 2); i++) { // Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work) - mmtmp_im = simde_mm_shufflelo_epi16(*kHz7_5ptr128, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmp_im = simde_mm_shufflehi_epi16(mmtmp_im, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmp_im = simde_mm_sign_epi16(mmtmp_im, *(simde__m128i *)&conjugate75[0]); - mmtmp_im = simde_mm_madd_epi16(mmtmp_im, txptr128[0]); - mmtmp_re = simde_mm_srai_epi32(mmtmp_re, 15); - mmtmp_im = simde_mm_srai_epi32(mmtmp_im, 15); - mmtmp_re2 = simde_mm_unpacklo_epi32(mmtmp_re, mmtmp_im); - mmtmp_im2 = simde_mm_unpackhi_epi32(mmtmp_re, mmtmp_im); - - txptr128[0] = simde_mm_packs_epi32(mmtmp_re2, mmtmp_im2); - txptr128++; - kHz7_5ptr128++; + txptr128[i] = oai_mm_cpx_mult_conj(kHz7_5ptr128[i], txptr128[i], 15); } - //} } - diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 1f1e36ddef..728e59e510 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -253,7 +253,7 @@ static void nr_pusch_antenna_processing(void *arg) pil++; c16_t ch = c16addShift(ch0, ch1, 1); *max_ch = max(abs(ch.r), abs(ch.i)); - multadd_real_four_symbols_vector_complex_scalar(filt8_rep4, &ch, &ul_ls_est[n]); + multadd_real_four_symbols_vector_complex_scalar(filt8_rep4, ch, &ul_ls_est[n]); ul_ls_est[n + 4] = ch; ul_ls_est[n + 5] = ch; noise_amp2 += c16amp2(c16sub(ch0, ch)); diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index c632585389..f73a01a2d6 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -241,7 +241,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, c16_t ptrs_ch_p[(1 + sc_per_symbol / 4) * 4]; /*Multiple compensated data with conj of PTRS */ - mult_cpx_vector((int16_t*)dmrs_comp_p, (int16_t*)ptrs_p, (int16_t*)ptrs_ch_p, (1 + sc_per_symbol/4)*4, 15); // 2^15 shifted + mult_cpx_vector((c16_t *)dmrs_comp_p, (c16_t *)ptrs_p, (c16_t *)ptrs_ch_p, (1 + sc_per_symbol / 4) * 4, 15); // 2^15 shifted /* loop over all ptrs sub carriers in a symbol */ /* sum the error vector */ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 59c459561b..1201dfb033 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -27,7 +27,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) if ((Msc_PUSCH % 1536) > 0) { // conjugate input for (i = 0; i < (Msc_PUSCH>>2); i++) { - *&(((simde__m128i*)z)[i]) = simde_mm_sign_epi16(*&(((simde__m128i*)z)[i]), *(simde__m128i*)&conjugate2[0]); + ((simde__m128i*)z)[i] = oai_mm_conj( ((simde__m128i*)z)[i] ); } for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) ((uint32_t*)idft_in0)[ip+0] = z[i]; @@ -55,7 +55,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) // conjugate output for (i = 0; i < (Msc_PUSCH>>2); i++) { - ((simde__m128i*)z)[i] = simde_mm_sign_epi16(((simde__m128i*)z)[i], *(simde__m128i*)&conjugate2[0]); + ((simde__m128i*)z)[i] = oai_mm_conj(((simde__m128i*)z)[i]); } } } @@ -238,9 +238,9 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext, uint32_t buffer_length, uint32_t output_shift) { - int mod_order = rel15_ul->qam_mod_order; + int mod_order = rel15_ul->qam_mod_order; int nrOfLayers = rel15_ul->nrOfLayers; - int nb_rx_ant = frame_parms->nb_antennas_rx; + int nb_rx_ant = frame_parms->nb_antennas_rx; simde__m256i QAM_ampa_256 = simde_mm256_setzero_si256(); simde__m256i QAM_ampb_256 = simde_mm256_setzero_si256(); @@ -262,12 +262,8 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext, QAM_ampc_256 = simde_mm256_set1_epi16(QAM256_n3); } - simde__m256i xmmp0, xmmp1, xmmp2, xmmp3, xmmp4; - simde__m256i complex_shuffle256 = simde_mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2); - simde__m256i conj256 = simde_mm256_set_epi16(1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1); - for (int aatx = 0; aatx < nrOfLayers; aatx++) { - simde__m256i *rxComp_256 = (simde__m256i*) &rxComp[aatx * nb_rx_ant][symbol * buffer_length]; + simde__m256i *rxComp_256 = (simde__m256i*)&rxComp[aatx * nb_rx_ant][symbol * buffer_length]; simde__m256i *rxF_ch_maga_256 = (simde__m256i*)&ul_ch_maga[aatx * buffer_length]; simde__m256i *rxF_ch_magb_256 = (simde__m256i*)&ul_ch_magb[aatx * buffer_length]; simde__m256i *rxF_ch_magc_256 = (simde__m256i*)&ul_ch_magc[aatx * buffer_length]; @@ -277,35 +273,24 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext, for (int i = 0; i < buffer_length >> 3; i++) { - xmmp0 = simde_mm256_madd_epi16(chF_256[i], rxF_256[i]); - // xmmp0 contains real part of 4 consecutive outputs (32-bit) of conj(H_m[i])*R_m[i] - xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256); - xmmp1 = simde_mm256_sign_epi16(xmmp1, conj256); - xmmp1 = simde_mm256_madd_epi16(xmmp1, rxF_256[i]); - // xmmp1 contains imag part of 4 consecutive outputs (32-bit) of conj(H_m[i])*R_m[i] - xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift); - xmmp1 = simde_mm256_srai_epi32(xmmp1, output_shift); - xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1); - xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1); - xmmp4 = simde_mm256_packs_epi32(xmmp2, xmmp3); + // MRC + simde__m256i comp = oai_mm256_cpx_mult_conj(chF_256[i], rxF_256[i], output_shift); + rxComp_256[i] = simde_mm256_add_epi16(rxComp_256[i], comp); - xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF_256[i]); // |h|^2 - xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift); - xmmp0 = simde_mm256_packs_epi32(xmmp0, xmmp0); - xmmp1 = simde_mm256_unpacklo_epi16(xmmp0, xmmp0); + if (mod_order > 2) { + simde__m256i mag = oai_mm256_smadd(chF_256[i], chF_256[i], output_shift); // |h|^2 + // pack and duplicate + mag = simde_mm256_packs_epi32(mag, mag); + mag = simde_mm256_unpacklo_epi16(mag, mag); - xmmp2 = simde_mm256_mulhrs_epi16(xmmp1, QAM_ampa_256); - xmmp3 = simde_mm256_mulhrs_epi16(xmmp1, QAM_ampb_256); - xmmp1 = simde_mm256_mulhrs_epi16(xmmp1, QAM_ampc_256); + rxF_ch_maga_256[i] = simde_mm256_add_epi16(rxF_ch_maga_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampa_256)); - // MRC - rxComp_256[i] = simde_mm256_add_epi16(rxComp_256[i], xmmp4); - if (mod_order > 2) - rxF_ch_maga_256[i] = simde_mm256_add_epi16(rxF_ch_maga_256[i], xmmp2); - if (mod_order > 4) - rxF_ch_magb_256[i] = simde_mm256_add_epi16(rxF_ch_magb_256[i], xmmp3); - if (mod_order > 6) - rxF_ch_magc_256[i] = simde_mm256_add_epi16(rxF_ch_magc_256[i], xmmp1); + if (mod_order > 4) + rxF_ch_magb_256[i] = simde_mm256_add_epi16(rxF_ch_magb_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampb_256)); + + if (mod_order > 6) + rxF_ch_magc_256[i] = simde_mm256_add_epi16(rxF_ch_magc_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampc_256)); + } } if (rho != NULL) { for (int atx = 0; atx < nrOfLayers; atx++) { @@ -313,19 +298,7 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext, simde__m256i *chF_256 = (simde__m256i *)&chFext[(aatx * nb_rx_ant + aarx) * buffer_length]; simde__m256i *chF2_256 = (simde__m256i *)&chFext[ (atx * nb_rx_ant + aarx) * buffer_length]; for (int i = 0; i < buffer_length >> 3; i++) { - // multiply by conjugated channel - xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF2_256[i]); - // xmmp0 contains real part of 4 consecutive outputs (32-bit) - xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256); - xmmp1 = simde_mm256_sign_epi16(xmmp1, conj256); - xmmp1 = simde_mm256_madd_epi16(xmmp1, chF2_256[i]); - // xmmp0 contains imag part of 4 consecutive outputs (32-bit) - xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift); - xmmp1 = simde_mm256_srai_epi32(xmmp1, output_shift); - xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1); - xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1); - - rho_256[i] = simde_mm256_adds_epi16(rho_256[i], simde_mm256_packs_epi32(xmmp2, xmmp3)); + rho_256[i] = simde_mm256_adds_epi16(rho_256[i], oai_mm256_cpx_mult_conj(chF_256[i], chF2_256[i], output_shift)); } } } @@ -335,17 +308,15 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext, } // Zero Forcing Rx function: nr_det_HhH() -static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a - int32_t *after_mf_01,//b - int32_t *after_mf_10,//c - int32_t *after_mf_11,//d - uint32_t *det_fin,//1/ad-bc - unsigned short nb_rb, - unsigned char symbol, - int32_t shift) +static void nr_ulsch_det_HhH(c16_t *after_mf_00, // a + c16_t *after_mf_01, // b + c16_t *after_mf_10, // c + c16_t *after_mf_11, // d + uint32_t *det_fin, // 1/ad-bc + unsigned short nb_rb, + unsigned char symbol, + int32_t shift) { - int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; - unsigned short rb; simde__m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; //ad_im_128, bc_im_128; simde__m128i *det_fin_128, det_re_128; //det_im_128, tmp_det0, tmp_det1; @@ -356,23 +327,17 @@ static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a det_fin_128 = (simde__m128i *)det_fin; - for (rb=0; rb<3*nb_rb; rb++) { + for (unsigned short rb=0; rb<3*nb_rb; rb++) { //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d) //The imag part is often zero, we compute only the real part - ad_re_128 = simde_mm_sign_epi16(after_mf_00_128[0],*(simde__m128i*)&nr_conjug2[0]); - ad_re_128 = simde_mm_madd_epi16(ad_re_128,after_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 - //ad_im_128 = simde_mm_shufflelo_epi16(after_mf_00_128[0], SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits - //ad_im_128 = simde_mm_shufflehi_epi16(ad_im_128, SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits - //ad_im_128 = simde_mm_madd_epi16(ad_im_128,after_mf_11_128[0]);//Im: (Q_aI_d + I_aQ_d) + ad_re_128 = simde_mm_madd_epi16(oai_mm_conj(after_mf_00_128[0]),after_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 + //ad_im_128 = simde_mm_madd_epi16(oai_mm_swap(after_mf_00_128[0]),after_mf_11_128[0]);//Im: (Q_aI_d + I_aQ_d) //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c) //The imag part is often zero, we compute only the real part - bc_re_128 = simde_mm_sign_epi16(after_mf_01_128[0],*(simde__m128i*)&nr_conjug2[0]); - bc_re_128 = simde_mm_madd_epi16(bc_re_128,after_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 - //bc_im_128 = simde_mm_shufflelo_epi16(after_mf_01_128[0], SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits - //bc_im_128 = simde_mm_shufflehi_epi16(bc_im_128, SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits - //bc_im_128 = simde_mm_madd_epi16(bc_im_128,after_mf_10_128[0]);//Im: (Q_bI_c + I_bQ_c) + bc_re_128 = simde_mm_madd_epi16(oai_mm_conj(after_mf_01_128[0]),after_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 + //bc_im_128 = simde_mm_madd_epi16(oai_mm_swap(after_mf_01_128[0]),after_mf_10_128[0]);//Im: (Q_bI_c + I_bQ_c) det_re_128 = simde_mm_sub_epi32(ad_re_128, bc_re_128); //det_im_128 = simde_mm_sub_epi32(ad_im_128, bc_im_128); @@ -399,45 +364,11 @@ static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a * * * */ -static void nr_ulsch_conjch0_mult_ch1(int *ch0, - int *ch1, - int32_t *ch0conj_ch1, - unsigned short nb_rb, - unsigned char output_shift0) +// TODO: This function is just a wrapper, can be removed. +static void nr_ulsch_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0) { //This function is used to compute multiplications in H_hermitian * H matrix - short nr_conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; - unsigned short rb; - simde__m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; - - dl_ch0_128 = (simde__m128i *)ch0; - dl_ch1_128 = (simde__m128i *)ch1; - - ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1; - - for (rb=0; rb<3*nb_rb; rb++) { - - mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[0], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)&nr_conjugate[0]); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,dl_ch1_128[0]); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - ch0conj_ch1_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - - /*printf("\n Computing conjugates \n"); - print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]); - print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]); - print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]);*/ - - dl_ch0_128+=1; - dl_ch1_128+=1; - ch0conj_ch1_128+=1; - } + mult_cpx_conj_vector(ch0, ch1, ch0conj_ch1, 12 * nb_rb, output_shift0); } static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x, @@ -446,34 +377,19 @@ static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x, simde__m128i input_z, simde__m128i det) { - int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; - - simde__m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128; - simde__m128i output, tmp_z0, tmp_z1; // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im) - // the real part - xy_re_128 = simde_mm_sign_epi16(input_x,*(simde__m128i*)&nr_conjug2[0]); - xy_re_128 = simde_mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im) - - // the imag part - xy_im_128 = simde_mm_shufflelo_epi16(input_x, SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits - xy_im_128 = simde_mm_shufflehi_epi16(xy_im_128, SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits - xy_im_128 = simde_mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im) - // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im) // the real part - wz_re_128 = simde_mm_sign_epi16(input_w,*(simde__m128i*)&nr_conjug2[0]); - wz_re_128 = simde_mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im) + simde__m128i xy_re_128 = simde_mm_madd_epi16(oai_mm_conj(input_x), input_y); //Re: (x_re*y_re - x_im*y_im) + simde__m128i wz_re_128 = simde_mm_madd_epi16(oai_mm_conj(input_w), input_z); //Re: (w_re*z_re - w_im*z_im) + xy_re_128 = simde_mm_sub_epi32(xy_re_128, wz_re_128); // the imag part - wz_im_128 = simde_mm_shufflelo_epi16(input_w, SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits - wz_im_128 = simde_mm_shufflehi_epi16(wz_im_128, SIMDE_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits - wz_im_128 = simde_mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im) - - - xy_re_128 = simde_mm_sub_epi32(xy_re_128, wz_re_128); + simde__m128i xy_im_128 = simde_mm_madd_epi16(oai_mm_swap(input_x), input_y); //Im: (x_im*y_re + x_re*y_im) + simde__m128i wz_im_128 = simde_mm_madd_epi16(oai_mm_swap(input_w), input_z); //Im: (w_im*z_re + w_re*z_im) xy_im_128 = simde_mm_sub_epi32(xy_im_128, wz_im_128); + //print_ints("rx_re:",(int32_t*)&xy_re_128[0]); //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]); //divide by matrix det and convert back to Q15 before packing @@ -493,11 +409,7 @@ static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x, xy_im_128 = simde_mm_slli_epi32(xy_im_128, -b); } - tmp_z0 = simde_mm_unpacklo_epi32(xy_re_128,xy_im_128); - //print_ints("unpack lo:",&tmp_z0[0]); - tmp_z1 = simde_mm_unpackhi_epi32(xy_re_128,xy_im_128); - //print_ints("unpack hi:",&tmp_z1[0]); - output = simde_mm_packs_epi32(tmp_z0,tmp_z1); + simde__m128i output = oai_mm_pack(xy_re_128, xy_im_128); return(output); } @@ -506,79 +418,72 @@ static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x, * * * */ -static void nr_ulsch_construct_HhH_elements(int *conjch00_ch00, - int *conjch01_ch01, - int *conjch11_ch11, - int *conjch10_ch10,// - int *conjch20_ch20, - int *conjch21_ch21, - int *conjch30_ch30, - int *conjch31_ch31, - int *conjch00_ch01,//00_01 - int *conjch01_ch00,//01_00 - int *conjch10_ch11,//10_11 - int *conjch11_ch10,//11_10 - int *conjch20_ch21, - int *conjch21_ch20, - int *conjch30_ch31, - int *conjch31_ch30, - int32_t *after_mf_00, - int32_t *after_mf_01, - int32_t *after_mf_10, - int32_t *after_mf_11, +static void nr_ulsch_construct_HhH_elements(c16_t *conjch00_ch00, + c16_t *conjch01_ch01, + c16_t *conjch11_ch11, + c16_t *conjch10_ch10, // + c16_t *conjch20_ch20, + c16_t *conjch21_ch21, + c16_t *conjch30_ch30, + c16_t *conjch31_ch31, + c16_t *conjch00_ch01, // 00_01 + c16_t *conjch01_ch00, // 01_00 + c16_t *conjch10_ch11, // 10_11 + c16_t *conjch11_ch10, // 11_10 + c16_t *conjch20_ch21, + c16_t *conjch21_ch20, + c16_t *conjch30_ch31, + c16_t *conjch31_ch30, + c16_t *after_mf_00, + c16_t *after_mf_01, + c16_t *after_mf_10, + c16_t *after_mf_11, unsigned short nb_rb, unsigned char symbol) { //This function is used to construct the (H_hermitian * H matrix) matrix elements - unsigned short rb; - simde__m128i *conjch00_ch00_128, *conjch01_ch01_128, *conjch11_ch11_128, *conjch10_ch10_128; - simde__m128i *conjch20_ch20_128, *conjch21_ch21_128, *conjch30_ch30_128, *conjch31_ch31_128; - simde__m128i *conjch00_ch01_128, *conjch01_ch00_128, *conjch10_ch11_128, *conjch11_ch10_128; - simde__m128i *conjch20_ch21_128, *conjch21_ch20_128, *conjch30_ch31_128, *conjch31_ch30_128; - simde__m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128; + simde__m128i *conjch00_ch00_128 = (simde__m128i *)conjch00_ch00; + simde__m128i *conjch01_ch01_128 = (simde__m128i *)conjch01_ch01; + simde__m128i *conjch11_ch11_128 = (simde__m128i *)conjch11_ch11; + simde__m128i *conjch10_ch10_128 = (simde__m128i *)conjch10_ch10; - conjch00_ch00_128 = (simde__m128i *)conjch00_ch00; - conjch01_ch01_128 = (simde__m128i *)conjch01_ch01; - conjch11_ch11_128 = (simde__m128i *)conjch11_ch11; - conjch10_ch10_128 = (simde__m128i *)conjch10_ch10; + simde__m128i *conjch20_ch20_128 = (simde__m128i *)conjch20_ch20; + simde__m128i *conjch21_ch21_128 = (simde__m128i *)conjch21_ch21; + simde__m128i *conjch30_ch30_128 = (simde__m128i *)conjch30_ch30; + simde__m128i *conjch31_ch31_128 = (simde__m128i *)conjch31_ch31; - conjch20_ch20_128 = (simde__m128i *)conjch20_ch20; - conjch21_ch21_128 = (simde__m128i *)conjch21_ch21; - conjch30_ch30_128 = (simde__m128i *)conjch30_ch30; - conjch31_ch31_128 = (simde__m128i *)conjch31_ch31; + simde__m128i *conjch00_ch01_128 = (simde__m128i *)conjch00_ch01; + simde__m128i *conjch01_ch00_128 = (simde__m128i *)conjch01_ch00; + simde__m128i *conjch10_ch11_128 = (simde__m128i *)conjch10_ch11; + simde__m128i *conjch11_ch10_128 = (simde__m128i *)conjch11_ch10; - conjch00_ch01_128 = (simde__m128i *)conjch00_ch01; - conjch01_ch00_128 = (simde__m128i *)conjch01_ch00; - conjch10_ch11_128 = (simde__m128i *)conjch10_ch11; - conjch11_ch10_128 = (simde__m128i *)conjch11_ch10; + simde__m128i *conjch20_ch21_128 = (simde__m128i *)conjch20_ch21; + simde__m128i *conjch21_ch20_128 = (simde__m128i *)conjch21_ch20; + simde__m128i *conjch30_ch31_128 = (simde__m128i *)conjch30_ch31; + simde__m128i *conjch31_ch30_128 = (simde__m128i *)conjch31_ch30; - conjch20_ch21_128 = (simde__m128i *)conjch20_ch21; - conjch21_ch20_128 = (simde__m128i *)conjch21_ch20; - conjch30_ch31_128 = (simde__m128i *)conjch30_ch31; - conjch31_ch30_128 = (simde__m128i *)conjch31_ch30; + simde__m128i *after_mf_00_128 = (simde__m128i *)after_mf_00; + simde__m128i *after_mf_01_128 = (simde__m128i *)after_mf_01; + simde__m128i *after_mf_10_128 = (simde__m128i *)after_mf_10; + simde__m128i *after_mf_11_128 = (simde__m128i *)after_mf_11; - after_mf_00_128 = (simde__m128i *)after_mf_00; - after_mf_01_128 = (simde__m128i *)after_mf_01; - after_mf_10_128 = (simde__m128i *)after_mf_10; - after_mf_11_128 = (simde__m128i *)after_mf_11; + for (unsigned short rb=0; rb<3*nb_rb; rb++) { - for (rb=0; rb<3*nb_rb; rb++) { + after_mf_00_128[0] = simde_mm_adds_epi16(conjch00_ch00_128[0], conjch10_ch10_128[0]); //00_00 + 10_10 + if (conjch20_ch20 != NULL) after_mf_00_128[0] = simde_mm_adds_epi16(after_mf_00_128[0], conjch20_ch20_128[0]); + if (conjch30_ch30 != NULL) after_mf_00_128[0] = simde_mm_adds_epi16(after_mf_00_128[0], conjch30_ch30_128[0]); - after_mf_00_128[0] =simde_mm_adds_epi16(conjch00_ch00_128[0],conjch10_ch10_128[0]);//00_00 + 10_10 - if (conjch20_ch20 != NULL) after_mf_00_128[0] =simde_mm_adds_epi16(after_mf_00_128[0],conjch20_ch20_128[0]); - if (conjch30_ch30 != NULL) after_mf_00_128[0] =simde_mm_adds_epi16(after_mf_00_128[0],conjch30_ch30_128[0]); + after_mf_11_128[0] = simde_mm_adds_epi16(conjch01_ch01_128[0], conjch11_ch11_128[0]); //01_01 + 11_11 + if (conjch21_ch21 != NULL) after_mf_11_128[0] = simde_mm_adds_epi16(after_mf_11_128[0], conjch21_ch21_128[0]); + if (conjch31_ch31 != NULL) after_mf_11_128[0] = simde_mm_adds_epi16(after_mf_11_128[0], conjch31_ch31_128[0]); - after_mf_11_128[0] =simde_mm_adds_epi16(conjch01_ch01_128[0], conjch11_ch11_128[0]); //01_01 + 11_11 - if (conjch21_ch21 != NULL) after_mf_11_128[0] =simde_mm_adds_epi16(after_mf_11_128[0],conjch21_ch21_128[0]); - if (conjch31_ch31 != NULL) after_mf_11_128[0] =simde_mm_adds_epi16(after_mf_11_128[0],conjch31_ch31_128[0]); + after_mf_01_128[0] = simde_mm_adds_epi16(conjch00_ch01_128[0], conjch10_ch11_128[0]); //00_01 + 10_11 + if (conjch20_ch21 != NULL) after_mf_01_128[0] = simde_mm_adds_epi16(after_mf_01_128[0], conjch20_ch21_128[0]); + if (conjch30_ch31 != NULL) after_mf_01_128[0] = simde_mm_adds_epi16(after_mf_01_128[0], conjch30_ch31_128[0]); - after_mf_01_128[0] =simde_mm_adds_epi16(conjch00_ch01_128[0], conjch10_ch11_128[0]);//00_01 + 10_11 - if (conjch20_ch21 != NULL) after_mf_01_128[0] =simde_mm_adds_epi16(after_mf_01_128[0],conjch20_ch21_128[0]); - if (conjch30_ch31 != NULL) after_mf_01_128[0] =simde_mm_adds_epi16(after_mf_01_128[0],conjch30_ch31_128[0]); - - after_mf_10_128[0] =simde_mm_adds_epi16(conjch01_ch00_128[0], conjch11_ch10_128[0]);//01_00 + 11_10 - if (conjch21_ch20 != NULL) after_mf_10_128[0] =simde_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]); - if (conjch31_ch30 != NULL) after_mf_10_128[0] =simde_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]); + after_mf_10_128[0] = simde_mm_adds_epi16(conjch01_ch00_128[0], conjch11_ch10_128[0]); //01_00 + 11_10 + if (conjch21_ch20 != NULL) after_mf_10_128[0] = simde_mm_adds_epi16(after_mf_10_128[0], conjch21_ch20_128[0]); + if (conjch31_ch30 != NULL) after_mf_10_128[0] = simde_mm_adds_epi16(after_mf_10_128[0], conjch31_ch30_128[0]); #ifdef DEBUG_DLSCH_DEMOD if ((rb<=30)) @@ -623,52 +528,54 @@ static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms, int **ul_ch_mag, int **ul_ch_magb, int **ul_ch_magc, - int **ul_ch_estimates_ext, + int nb_layer, + int nb_rx_ant, + uint32_t buffer_length, + c16_t ul_ch_estimates_ext[nb_layer][nb_rx_ant][buffer_length], unsigned short nb_rb, unsigned char n_rx, unsigned char mod_order, int shift, unsigned char symbol, int length, - uint32_t noise_var, - uint32_t buffer_length) + uint32_t noise_var) { - int *ch00, *ch01, *ch10, *ch11; - int *ch20, *ch30, *ch21, *ch31; + c16_t *ch00, *ch01, *ch10, *ch11; + c16_t *ch20, *ch30, *ch21, *ch31; uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); /* we need at least alignment to 16 bytes, let's put 32 to be sure * (maybe not necessary but doesn't hurt) */ - int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32))); - int32_t conjch31_ch30[12*nb_rb] __attribute__((aligned(32))); + c16_t conjch00_ch01[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch01_ch00[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch10_ch11[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch11_ch10[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch00_ch00[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch01_ch01[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch10_ch10[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch11_ch11[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch20_ch20[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch21_ch21[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch30_ch30[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch31_ch31[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch20_ch21[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch30_ch31[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch21_ch20[12 * nb_rb] __attribute__((aligned(32))); + c16_t conjch31_ch30[12 * nb_rb] __attribute__((aligned(32))); - int32_t af_mf_00[12*nb_rb] __attribute__((aligned(32))); - int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32))); - int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32))); - int32_t af_mf_11[12*nb_rb] __attribute__((aligned(32))); + c16_t af_mf_00[12 * nb_rb] __attribute__((aligned(32))); + c16_t af_mf_01[12 * nb_rb] __attribute__((aligned(32))); + c16_t af_mf_10[12 * nb_rb] __attribute__((aligned(32))); + c16_t af_mf_11[12 * nb_rb] __attribute__((aligned(32))); uint32_t determ_fin[12*nb_rb] __attribute__((aligned(32))); switch (n_rx) { case 2:// - ch00 = &((int *)ul_ch_estimates_ext)[0 * buffer_length]; - ch01 = &((int *)ul_ch_estimates_ext)[2 * buffer_length]; - ch10 = &((int *)ul_ch_estimates_ext)[1 * buffer_length]; - ch11 = &((int *)ul_ch_estimates_ext)[3 * buffer_length]; + ch00 = ul_ch_estimates_ext[0][0]; + ch01 = ul_ch_estimates_ext[1][0]; + ch10 = ul_ch_estimates_ext[0][1]; + ch11 = ul_ch_estimates_ext[1][1]; ch20 = NULL; ch21 = NULL; ch30 = NULL; @@ -676,14 +583,14 @@ static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms, break; case 4:// - ch00 = &((int *)ul_ch_estimates_ext)[0 * buffer_length]; - ch01 = &((int *)ul_ch_estimates_ext)[4 * buffer_length]; - ch10 = &((int *)ul_ch_estimates_ext)[1 * buffer_length]; - ch11 = &((int *)ul_ch_estimates_ext)[5 * buffer_length]; - ch20 = &((int *)ul_ch_estimates_ext)[2 * buffer_length]; - ch21 = &((int *)ul_ch_estimates_ext)[6 * buffer_length]; - ch30 = &((int *)ul_ch_estimates_ext)[3 * buffer_length]; - ch31 = &((int *)ul_ch_estimates_ext)[7 * buffer_length]; + ch00 = ul_ch_estimates_ext[0][0]; + ch01 = ul_ch_estimates_ext[1][0]; + ch10 = ul_ch_estimates_ext[0][1]; + ch11 = ul_ch_estimates_ext[1][1]; + ch20 = ul_ch_estimates_ext[2][0]; + ch21 = ul_ch_estimates_ext[2][1]; + ch30 = ul_ch_estimates_ext[3][0]; + ch31 = ul_ch_estimates_ext[3][1]; break; default: @@ -1122,15 +1029,17 @@ static void inner_rx(PHY_VARS_gNB *gNB, (int **)rxF_ch_maga, (int **)rxF_ch_magb, (int **)rxF_ch_magc, - (int **)chFext, + nb_layer, + nb_rx_ant, + buffer_length, + chFext, rel15_ul->rb_size, frame_parms->nb_antennas_rx, rel15_ul->qam_mod_order, pusch_vars->log2_maxh, symbol, pusch_vars->ul_valid_re_per_slot[symbol], - nvar, - buffer_length); + nvar); } } if (nb_layer != 2 || rel15_ul->qam_mod_order > 6) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index ef935e4269..d6a5f78beb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -93,7 +93,7 @@ void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, int16_t *stream0_o /// Compute real and imaginary parts of MF output for stream 0 (desired stream) simde__m128i y0r, y0i; - simde_mm128_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); + oai_mm_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); simde__m128i y0r_over2 = simde_mm_mulhi_epi16(y0r, ONE_OVER_2_SQRT_2); y0r_over2 = simde_mm_slli_epi16(y0r_over2, 1); // y0r_over2 = Re(y0) / sqrt(2) simde__m128i y0i_over2 = simde_mm_mulhi_epi16(y0i, ONE_OVER_2_SQRT_2); @@ -101,13 +101,13 @@ void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, int16_t *stream0_o /// Compute real and imaginary parts of MF output for stream 1 (interference stream) simde__m128i y1r_over2, y1i_over2; - simde_mm128_separate_real_imag_parts(&y1r_over2, &y1i_over2, stream1_128i_in[i], stream1_128i_in[i + 1]); + oai_mm_separate_real_imag_parts(&y1r_over2, &y1i_over2, stream1_128i_in[i], stream1_128i_in[i + 1]); y1r_over2 = simde_mm_srai_epi16(y1r_over2, 1); // y1r_over2 = Re(y1) / 2 y1i_over2 = simde_mm_srai_epi16(y1i_over2, 1); // y1i_over2 = Im(y1) / 2 /// Get real and imaginary parts of rho simde__m128i rhor, rhoi; - simde_mm128_separate_real_imag_parts(&rhor, &rhoi, rho01_128i[i], rho01_128i[i + 1]); + oai_mm_separate_real_imag_parts(&rhor, &rhoi, rho01_128i[i], rho01_128i[i + 1]); /// Compute |psi_r| and |psi_i| @@ -243,7 +243,7 @@ void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, int16_t *stream0_o /// Compute real and imaginary parts of MF output for stream 0 (desired stream) simde__m256i y0r, y0i; - simde_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); + oai_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); simde__m256i y0r_over2 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_2_SQRT_2); y0r_over2 = simde_mm256_slli_epi16(y0r_over2, 1); // y0r_over2 = Re(y0) / sqrt(2) simde__m256i y0i_over2 = simde_mm256_mulhi_epi16(y0i, ONE_OVER_2_SQRT_2); @@ -251,13 +251,13 @@ void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, int16_t *stream0_o /// Compute real and imaginary parts of MF output for stream 1 (interference stream) simde__m256i y1r_over2, y1i_over2; - simde_mm256_separate_real_imag_parts(&y1r_over2, &y1i_over2, stream1_256i_in[i], stream1_256i_in[i + 1]); + oai_mm256_separate_real_imag_parts(&y1r_over2, &y1i_over2, stream1_256i_in[i], stream1_256i_in[i + 1]); y1r_over2 = simde_mm256_srai_epi16(y1r_over2, 1); // y1r_over2 = Re(y1) / 2 y1i_over2 = simde_mm256_srai_epi16(y1i_over2, 1); // y1i_over2 = Im(y1) / 2 /// Get real and imaginary parts of rho simde__m256i rhor, rhoi; - simde_mm256_separate_real_imag_parts(&rhor, &rhoi, rho01_256i[i], rho01_256i[i + 1]); + oai_mm256_separate_real_imag_parts(&rhor, &rhoi, rho01_256i[i], rho01_256i[i + 1]); /// Compute |psi_r| and |psi_i| @@ -666,7 +666,7 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, for (int i = 0; i < length >> 2; i += 2) { // Get rho - simde_mm128_separate_real_imag_parts(&xmm2, &xmm3, rho01_128i[i], rho01_128i[i + 1]); + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, rho01_128i[i], rho01_128i[i + 1]); rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -691,7 +691,7 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, rho_rs[6] = simde_mm_subs_epi16(xmm6, xmm7); // Rearrange interfering MF output - simde_mm128_separate_real_imag_parts(&y1r, &y1i, stream1_128i_in[i], stream1_128i_in[i + 1]); + oai_mm_separate_real_imag_parts(&y1r, &y1i, stream1_128i_in[i], stream1_128i_in[i + 1]); // | [Re(rho)+ Im(rho)]/sqrt(10) - y1r | for(int j=0; j<8; j++){ // psi_rs[0~7], rho_rs[0~7] @@ -709,14 +709,14 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, } // Rearrange desired MF output - simde_mm128_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); + oai_mm_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); // Rearrange desired channel magnitudes // [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) - simde_mm128_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_128i[i], ch_mag_128i[i + 1]); + oai_mm_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_128i[i], ch_mag_128i[i + 1]); // Rearrange interfering channel magnitudes - simde_mm128_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_128i_i[i], ch_mag_128i_i[i + 1]); + oai_mm_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_128i_i[i], ch_mag_128i_i[i + 1]); // Scale MF output of desired signal y0r_over_sqrt10 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_10); @@ -877,7 +877,7 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, for (int i = 0; i < length >> 3; i += 2) { // Get rho - simde_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); + oai_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); rho_rpi = simde_mm256_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) rho_rmi = simde_mm256_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -902,7 +902,7 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, rho_rs[6] = simde_mm256_subs_epi16(xmm6, xmm7); // Rearrange interfering MF output - simde_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); + oai_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); // | [Re(rho)+ Im(rho)]/sqrt(10) - y1r | for(int j=0; j<8; j++){ // psi_rs[0~7], rho_rs[0~7] @@ -920,14 +920,14 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, } // Rearrange desired MF output - simde_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); + oai_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); // Rearrange desired channel magnitudes // [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) - simde_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); + oai_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); // Rearrange interfering channel magnitudes - simde_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); + oai_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); // Scale MF output of desired signal y0r_over_sqrt10 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_SQRT_10); @@ -1125,7 +1125,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Get rho simde__m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; - simde_mm128_separate_real_imag_parts(&xmm2, &xmm3, rho01_128i[i], rho01_128i[i + 1]); + oai_mm_separate_real_imag_parts(&xmm2, &xmm3, rho01_128i[i], rho01_128i[i + 1]); simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1189,7 +1189,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Rearrange interfering MF output simde__m128i y1r, y1i; - simde_mm128_separate_real_imag_parts(&y1r, &y1i, stream1_128i_in[i], stream1_128i_in[i + 1]); + oai_mm_separate_real_imag_parts(&y1r, &y1i, stream1_128i_in[i], stream1_128i_in[i + 1]); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm_set1_epi16(0); // ZERO for abs_pi16 @@ -1219,15 +1219,15 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Rearrange desired MF output simde__m128i y0r, y0i; - simde_mm128_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); + oai_mm_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); // Rearrange desired channel magnitudes // [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2),...,,|h|^2(7),|h|^2(7)]*(2/sqrt(10)) // xmm2 is dummy variable that contains the same values as ch_mag_des - simde_mm128_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_128i[i], ch_mag_128i[i + 1]); + oai_mm_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_128i[i], ch_mag_128i[i + 1]); // Rearrange interfering channel magnitudes - simde_mm128_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_128i_i[i], ch_mag_128i_i[i + 1]); + oai_mm_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_128i_i[i], ch_mag_128i_i[i + 1]); y0r_one_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm_mulhi_epi16(y0r, THREE_OVER_SQRT_42); @@ -1471,7 +1471,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Get rho simde__m256i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; - simde_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); + oai_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); simde__m256i rho_rpi = simde_mm256_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m256i rho_rmi = simde_mm256_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1535,7 +1535,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Rearrange interfering MF output simde__m256i y1r, y1i; - simde_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); + oai_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm256_broadcastw_epi16(simde_mm_set1_epi16(0)); // ZERO for abs_pi16 @@ -1565,15 +1565,15 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Rearrange desired MF output simde__m256i y0r, y0i; - simde_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); + oai_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); // Rearrange desired channel magnitudes // [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2),...,,|h|^2(7),|h|^2(7)]*(2/sqrt(10)) // xmm2 is dummy variable that contains the same values as ch_mag_des - simde_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); + oai_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); // Rearrange interfering channel magnitudes - simde_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); + oai_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); y0r_one_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, THREE_OVER_SQRT_42); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 1f7fe8707d..79e39fa7c1 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -915,8 +915,6 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, nfapi_nr_pucch_pdu_t* pucch_pdu) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - const simde__m256i conj256 = simde_mm256_set_epi16(-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1); - //pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); const int nb_symbols=pucch_pdu->nr_of_symbols; @@ -1081,7 +1079,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, c16_t pil_dmrs[nb_re_dmrs] __attribute__((aligned(32))); uint8_t *sGold8 = (uint8_t *)(sGold + pucch_pdu->prb_start / 4); for (int group = 0; group < nb_re_dmrs; group += 4) - *(simde__m128i *)(pil_dmrs + group) = simde_mm_sign_epi16(byte2m128i[*sGold8++], *(simde__m128i *)&conj256); + *(simde__m128i *)(pil_dmrs + group) = oai_mm_conj(byte2m128i[*sGold8++]); // Compute delay c16_t ch_ls[128] __attribute__((aligned(32))) = {0}; @@ -1160,7 +1158,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, for (simde__m256i *ptr = (simde__m256i *)r_ext[aa][symb], *ptr2 = (simde__m256i *)r_ext2[aa][symb]; pil_ptr < end; ptr++, pil_ptr++, ptr2++) { simde__m256i tmp = simde_mm256_srai_epi16(*ptr, scaling); - *ptr2 = simde_mm256_sign_epi16(simde_mm256_sign_epi16(simde_mm256_shuffle_epi8(tmp, swap), *pil_ptr), conj256); + *ptr2 = oai_mm256_conj(simde_mm256_sign_epi16(simde_mm256_shuffle_epi8(tmp, swap), *pil_ptr)); *ptr = simde_mm256_sign_epi16(tmp, *pil_ptr); } } diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index 0c84dbc87a..3f0f70526e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -20,16 +20,15 @@ */ #ifndef __FILT16A_H__ #define __FILT16A_H__ -static const c16_t filt16a_l0[8] = {{16384, 12288}, {8192, 4096}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; +static const short filt16a_l0[16] = {16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const short filt16a_mm0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0}; -static const c16_t filt16a_r0[8] = {{0, 0}, {0, 0}, {0, 4096}, {8192, 12288}, {16384, 20480}, {24576, 28672}, {0, 0}, {0, 0}}; +static const short filt16a_r0[16] = {0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 0, 0, 0, 0}; -static const c16_t filt16a_m0[8] = - {{0, 4096}, {8192, 12288}, {16384, 12288}, {8192, 4096}, {0, -4096}, {-8192, -12288}, {0, 0}, {0, 0}}; +static const short filt16a_m0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, -12288, 0, 0, 0, 0}; -static const c16_t filt16a_l1[8] = {{20480, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; +static const short filt16a_l1[16] = {20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const short filt16a_mm1[16] = {0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0}; @@ -37,12 +36,11 @@ static const short filt16a_ml1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288, static const short filt16a_mr1[16] = {0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0}; -static const c16_t filt16a_r1[8] = {{0, 0}, {0, 0}, {0, 0}, {4096, 8192}, {12288, 16384}, {20480, 24576}, {0, 0}, {0, 0}}; +static const short filt16a_r1[16] = {0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 24576, 0, 0, 0, 0}; -static const c16_t filt16a_m1[8] = - {{-4096, 0}, {4096, 8192}, {12288, 16384}, {12288, 8192}, {4096, 0}, {-4096, -8192}, {0, 0}, {0, 0}}; +static const short filt16a_m1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0}; -static const c16_t filt16a_l2[8] = {{24576, 20480}, {16384, 12288}, {8192, 4096}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; +static const short filt16a_l2[16] = {24576, 20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const short filt16a_mm2[16] = {0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0}; @@ -50,21 +48,19 @@ static const short filt16a_ml2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384, static const short filt16a_mr2[16] = {0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0}; -static const c16_t filt16a_r2[8] = {{0, 0}, {0, 0}, {0, 0}, {0, 4096}, {8192, 12288}, {16384, 20480}, {0, 0}, {0, 0}}; +static const short filt16a_r2[16] = {0, 0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 0, 0, 0, 0}; -static const c16_t filt16a_m2[8] = - {{-8192, -4096}, {0, 4096}, {8192, 12288}, {16384, 12288}, {8192, 4096}, {0, -4096}, {0, 0}, {0, 0}}; +static const short filt16a_m2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0}; -static const c16_t filt16a_l3[8] = {{28672, 24576}, {20480, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; +static const short filt16a_l3[16] = {28672, 24576, 20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const short filt16a_mm3[16] = {0, 0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0}; static const short filt16a_ml3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0}; -static const c16_t filt16a_r3[8] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {4096, 8192}, {12288, 16384}, {0, 0}, {0, 0}}; +static const short filt16a_r3[16] = {0, 0, 0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 0, 0, 0, 0}; -static const c16_t filt16a_m3[8] = - {{-12288, -8192}, {-4096, 0}, {4096, 8192}, {12288, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}}; +static const short filt16a_m3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0}; static const short filt16a_l0_dc[16] = {16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index cb7a2d3604..d405e86263 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -91,17 +91,15 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int slot_prs = (proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame; - int16_t *rxF, *pil; c16_t mod_prs[NR_MAX_PRS_LENGTH]; const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr; - int16_t ch[2] = {0}, noiseFig[2] = {0}; int16_t k_prime = 0, k = 0; int32_t ch_pwr = 0, snr = 0, rsrp = 0, mean_val = 0, prs_toa = 0; double ch_pwr_dbm = 0.0f; #ifdef DEBUG_PRS_CHEST char filename[64] = {0}, varname[64] = {0}; #endif - int16_t *ch_tmp = (int16_t *)ch_tmp_buf; + c16_t *ch_tmp = ch_tmp_buf; int16_t scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15); int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB; int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset; @@ -149,9 +147,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset; // Channel estimation and interpolation - pil = (int16_t *)mod_prs; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - + c16_t *pil = (c16_t *)mod_prs; + c16_t *rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + if(prs_cfg->CombSize == 2) { // Choose the interpolation filters @@ -181,101 +179,79 @@ int nr_prs_channel_estimation(uint8_t gNB_id, } //Start pilot - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); - multadd_real_vector_complex_scalar(fl, - ch, - ch_tmp, - 8); + c16_t ch = c16MulConjShift(*pil, *rxF, 15); + multadd_real_vector_complex_scalar(fl, ch, ch_tmp, 8); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); + rsrp += squaredMod(*rxF); + c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, 0, snr, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - pil +=2; + pil++; k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + //Middle pilots - for(int pIdx = 1; pIdx < num_pilots-1; pIdx+=2) - { - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); - if(pIdx == 1) // 2nd pilot - { - multadd_real_vector_complex_scalar(fml, - ch, - ch_tmp, - 8); - } - else - { - multadd_real_vector_complex_scalar(fm, - ch, - ch_tmp, - 8); - } + for (int pIdx = 1; pIdx < num_pilots - 1; pIdx += 2) { + c16_t ch = c16MulConjShift(*pil, *rxF, 15); + multadd_real_vector_complex_scalar(pIdx == 1 ? fml : fm, ch, ch_tmp, 8); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig)); + rsrp += squaredMod(*rxF); + c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS - printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, pIdx, snr/(pIdx+1), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", + rxAnt, + pIdx, + snr / (pIdx + 1), + rxF[0], + rxF[1], + &rxF[0], + ch[0], + ch[1], + pil[0], + pil[1]); #endif - pil +=2; - k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); - if(pIdx == (num_pilots-3)) // 2nd last pilot - { - multadd_real_vector_complex_scalar(fmr, - ch, - ch_tmp, - 8); - } - else - { - multadd_real_vector_complex_scalar(fmm, - ch, - ch_tmp, - 8); - } + pil++; + k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size; + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + ch = c16MulConjShift(*pil, *rxF, 15); + multadd_real_vector_complex_scalar(pIdx == (num_pilots - 3) ? fmr : fmm, ch, ch_tmp, 8); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + rsrp += squaredMod(*rxF); + noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS - printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, pIdx+1, snr/(pIdx+2), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", + rxAnt, + pIdx + 1, + snr / (pIdx + 2), + rxF[0], + rxF[1], + &rxF[0], + ch[0], + ch[1], + pil[0], + pil[1]); #endif - pil +=2; - k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - ch_tmp +=8; + pil++; + k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size; + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + ch_tmp += 4; } //End pilot - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); - multadd_real_vector_complex_scalar(fr, - ch, - ch_tmp, - 8); + ch = c16MulConjShift(*pil, *rxF, 15); + multadd_real_vector_complex_scalar(fr, ch, ch_tmp, 8); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0] * pil[0] - (int32_t)ch[1] * pil[1]) >> 15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1] * pil[0] + (int32_t)ch[0] * pil[1]) >> 15); - snr += 10 * log10(squaredMod(*((c16_t *)rxF)) - squaredMod(*((c16_t *)noiseFig))) - 10 * log10(squaredMod(*((c16_t *)noiseFig))); + rsrp += squaredMod(*rxF); + noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, @@ -295,39 +271,39 @@ int nr_prs_channel_estimation(uint8_t gNB_id, // Choose the interpolation filters switch (k_prime) { case 0: - fl = (short int *)filt16a_l0; + fl = filt16a_l0; fml = filt16a_mm0; fmm = filt16a_mm0; - fmr = (short int *)filt16a_m0; - fm = (short int *)filt16a_m0; - fr = (short int *)filt16a_r0; + fmr = filt16a_m0; + fm = filt16a_m0; + fr = filt16a_r0; break; case 1: - fl = (short int *)filt16a_l1; + fl = filt16a_l1; fml = filt16a_ml1; fmm = filt16a_mm1; fmr = filt16a_mr1; - fm = (short int *)filt16a_m1; - fr = (short int *)filt16a_r1; + fm = filt16a_m1; + fr = filt16a_r1; break; case 2: - fl = (short int *)filt16a_l2; + fl = filt16a_l2; fml = filt16a_ml2; fmm = filt16a_mm2; fmr = filt16a_mr2; - fm = (short int *)filt16a_m2; - fr = (short int *)filt16a_r2; + fm = filt16a_m2; + fr = filt16a_r2; break; case 3: - fl = (short int *)filt16a_l3; + fl = filt16a_l3; fml = filt16a_ml3; fmm = filt16a_mm3; fmr = filt16a_mm3; - fm = (short int *)filt16a_m3; - fr = (short int *)filt16a_r3; + fm = filt16a_m3; + fr = filt16a_r3; break; default: @@ -337,101 +313,89 @@ int nr_prs_channel_estimation(uint8_t gNB_id, } //Start pilot - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); + c16_t ch = c16MulConjShift(*pil, *rxF, 15); multadd_real_vector_complex_scalar(fl, ch, ch_tmp, 16); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + rsrp += squaredMod(*rxF); + c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, 0, snr, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - pil +=2; + pil++; k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + ch = c16MulConjShift(*pil, *rxF, 15); multadd_real_vector_complex_scalar(fml, ch, ch_tmp, 16); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + rsrp += squaredMod(*rxF); + noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, 1, snr/2, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - pil +=2; + pil++; k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - ch_tmp +=8; + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + ch_tmp += 4; //Middle pilots for(int pIdx = 2; pIdx < num_pilots-2; pIdx++) { - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); + c16_t ch = c16MulConjShift(*pil, *rxF, 15); multadd_real_vector_complex_scalar(fmm, ch, ch_tmp, 16); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + rsrp += squaredMod(*rxF); + c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, pIdx, snr/(pIdx+1), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - pil +=2; + pil++; k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - ch_tmp +=8; + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + ch_tmp += 4; } //End pilot - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); + ch = c16MulConjShift(*pil, *rxF, 15); multadd_real_vector_complex_scalar(fmr, ch, ch_tmp, 16); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + rsrp += squaredMod(*rxF); + noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, num_pilots-2, snr/(num_pilots-1), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif - pil +=2; + pil++; k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; - - ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); - ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15); + rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; + ch = c16MulConjShift(*pil, *rxF, 15); multadd_real_vector_complex_scalar(fr, ch, ch_tmp, 16); // SNR & RSRP estimation - rsrp += squaredMod(*((c16_t *)rxF)); - noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); - noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); - snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig))); + rsrp += squaredMod(*rxF); + noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15)); + snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig)); #ifdef DEBUG_PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, +%d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif @@ -446,18 +410,14 @@ int nr_prs_channel_estimation(uint8_t gNB_id, prs_meas[rxAnt]->rsrp = rsrp / (float)num_pilots; //reset channel pointer - ch_tmp = (int16_t*)ch_tmp_buf; + ch_tmp = (c16_t *)ch_tmp_buf; } // for rxAnt } //for l for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++) { // scale by averaging factor 1/NumPrsSymbols - multadd_complex_vector_real_scalar(ch_tmp, - scale_factor, - ch_tmp, - 1, - frame_params->ofdm_symbol_size); + mult_complex_vector_real_scalar(ch_tmp, scale_factor, ch_tmp, frame_params->ofdm_symbol_size); #ifdef DEBUG_PRS_PRINTS for (int rb = 0; rb < prs_cfg->NumRB; rb++) @@ -700,31 +660,31 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, k, symbol); - const c16_t *fl, *fm, *fr; + const int16_t *fl, *fm, *fr; switch (k) { case 0: - fl = filt16a_l0; - fm = filt16a_m0; - fr = filt16a_r0; + fl = (int16_t *)filt16a_l0; + fm = (int16_t *)filt16a_m0; + fr = (int16_t *)filt16a_r0; break; case 1: - fl = filt16a_l1; - fm = filt16a_m1; - fr = filt16a_r1; + fl = (int16_t *)filt16a_l1; + fm = (int16_t *)filt16a_m1; + fr = (int16_t *)filt16a_r1; break; case 2: - fl = filt16a_l2; - fm = filt16a_m2; - fr = filt16a_r2; + fl = (int16_t *)filt16a_l2; + fm = (int16_t *)filt16a_m2; + fr = (int16_t *)filt16a_r2; break; case 3: - fl = filt16a_l3; - fm = filt16a_m3; - fr = filt16a_r3; + fl = (int16_t *)filt16a_l3; + fm = (int16_t *)filt16a_m3; + fr = (int16_t *)filt16a_r3; break; default: @@ -752,21 +712,21 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, c16_t ch; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot 0: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); - multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); + multadd_real_vector_complex_scalar(fl, ch, dl_ch, 16); pil++; re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot 1: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); - multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); + multadd_real_vector_complex_scalar(fm, ch, dl_ch, 16); pil++; re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot 2: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); - multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); + multadd_real_vector_complex_scalar(fr, ch, dl_ch, 16); pil++; re_offset = (re_offset + 4) % fp->ofdm_symbol_size; dl_ch += 12; @@ -790,7 +750,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, ch.i, pil->r, pil->i); - multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); + multadd_real_vector_complex_scalar(fl, ch, dl_ch, 16); pil++; re_offset = (re_offset + 4) % fp->ofdm_symbol_size; @@ -803,7 +763,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, ch.i, pil->r, pil->i); - multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); + multadd_real_vector_complex_scalar(fm, ch, dl_ch, 16); pil++; re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); @@ -815,7 +775,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, ch.i, pil->r, pil->i); - multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); + multadd_real_vector_complex_scalar(fr, ch, dl_ch, 16); pil++; re_offset = (re_offset + 4) % fp->ofdm_symbol_size; dl_ch += 12; @@ -847,7 +807,6 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch; int ch_offset,symbol_offset; ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -887,19 +846,19 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) dmrs_ref = BWPStart; // generate pilot - int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); + c16_t pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS const uint32_t *gold = nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol); - nr_pdcch_dmrs_rx(ue, slot, gold, (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref)); + nr_pdcch_dmrs_rx(ue, slot, gold, pilot, 2000, (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { k = coreset_start_subcarrier; - pil = (int16_t *)&pilot[dmrs_ref*3]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; - dl_ch = (int16_t *)&pdcch_dl_ch_estimates[aarx][ch_offset]; + c16_t *pil = &pilot[dmrs_ref * 3]; + c16_t *rxF = &rxdataF[aarx][symbol_offset + k + 1]; + c16_t *dl_ch = &pdcch_dl_ch_estimates[aarx][ch_offset]; - memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); + memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size); #ifdef DEBUG_PDCCH printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[dmrs_ref*3], ue->frame_parms.N_RB_DL); @@ -911,160 +870,60 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, #if CH_INTERP // if ((ue->frame_parms.N_RB_DL&1)==0) { // Treat first 2 pilots specially (left edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PDCCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 16); - pil += 2; - rxF += 8; - k += 4; + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); + rxF += 4; + k += 2; if (k >= ue->frame_parms.ofdm_symbol_size) { k -= ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; + rxF = &rxdataF[aarx][(symbol_offset + k + 1)]; } + multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); + k = (k + 4) % ue->frame_parms.ofdm_symbol_size; + rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PDCCH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fm, - ch, - dl_ch, - 16); - pil += 2; - rxF += 8; - k += 4; - - if (k >= ue->frame_parms.ofdm_symbol_size) { - k -= ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; - } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PDCCH - printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); -#ifdef DEBUG_PDCCH - for (int m =0; m<12; m++) - printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); -#endif - dl_ch += 24; - - pil += 2; - rxF += 8; - k += 4; + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); + dl_ch += 12; + k = (k + 4) % ue->frame_parms.ofdm_symbol_size; + rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt += 3) { + multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); + k = (k + 4) % ue->frame_parms.ofdm_symbol_size; + rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; - if (k >= ue->frame_parms.ofdm_symbol_size) { - k -= ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; - } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PDCCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 16); - - //for (int i= 0; i<8; i++) - // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); - - pil += 2; - rxF += 8; - k += 4; - - if (k >= ue->frame_parms.ofdm_symbol_size) { - k -= ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; - } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PDCCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fm, - ch, - dl_ch, - 16); - pil += 2; - rxF += 8; - k += 4; - - if (k >= ue->frame_parms.ofdm_symbol_size) { - k -= ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; - } - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PDCCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); -#ifdef DEBUG_PDCCH - for (int m =0; m<12; m++) - printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); -#endif - dl_ch += 24; - - pil += 2; - rxF += 8; - k += 4; + multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); + k = (k + 4) % ue->frame_parms.ofdm_symbol_size; + rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); + dl_ch += 12; + k = (k + 4) % ue->frame_parms.ofdm_symbol_size; + rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; } #else //ELSE CH_INTERP - int ch_sum[2] = {0, 0}; + c32_t ch_sum = {0, 0}; for (pilot_cnt = 0; pilot_cnt < 3*nb_rb_coreset; pilot_cnt++) { - if (k >= ue->frame_parms.ofdm_symbol_size) { - k -= ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; - } + #ifdef DEBUG_PDCCH printf("pilot[%u] = (%d, %d)\trxF[%d] = (%d, %d)\n", pilot_cnt, pil[0], pil[1], k+1, rxF[0], rxF[1]); #endif - ch_sum[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch_sum[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - pil += 2; - rxF += 8; - k += 4; + c16_t ch = c16mulShift(*pil++, *rxF, 15); + ch_sum.r += ch.r; + ch_sum.i += ch.i; + k = (k + 4) % ue->frame_parms.ofdm_symbol_size; + rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; if (pilot_cnt % 3 == 2) { - ch[0] = ch_sum[0] / 3; - ch[1] = ch_sum[1] / 3; + ch.r = ch_sum.r / 3; + ch.i = ch_sum.i / 3; multadd_real_vector_complex_scalar(filt16a_1, ch, dl_ch, 16); #ifdef DEBUG_PDCCH for (int m =0; m<12; m++) printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); #endif - dl_ch += 24; - ch_sum[0] = 0; - ch_sum[1] = 0; + dl_ch += 12; + ch_sum = (c32_t){0}; } } #endif //END CH_INTERP diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index c80bc4e5f2..e1ad1bf0b1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -53,8 +53,6 @@ void nr_det_A_MF_2x2(int32_t *a_mf_00, int32_t *det_fin, const unsigned short nb_rb) { - int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; - simde__m128i ad_re_128, bc_re_128, det_re_128; simde__m128i *a_mf_00_128 = (simde__m128i *)a_mf_00; @@ -67,13 +65,11 @@ void nr_det_A_MF_2x2(int32_t *a_mf_00, //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d) //The imag part is often zero, we compute only the real part - ad_re_128 = simde_mm_sign_epi16(a_mf_00_128[0],*(simde__m128i*)&nr_conjug2[0]); - ad_re_128 = simde_mm_madd_epi16(ad_re_128,a_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 + ad_re_128 = simde_mm_madd_epi16(oai_mm_conj(a_mf_00_128[0]), a_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c) //The imag part is often zero, we compute only the real part - bc_re_128 = simde_mm_sign_epi16(a_mf_01_128[0],*(simde__m128i*)&nr_conjug2[0]); - bc_re_128 = simde_mm_madd_epi16(bc_re_128,a_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 + bc_re_128 = simde_mm_madd_epi16(oai_mm_conj(a_mf_01_128[0]), a_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 det_re_128 = simde_mm_sub_epi32(ad_re_128, bc_re_128); @@ -267,20 +263,21 @@ uint32_t calc_power_csirs(const uint16_t *x, const fapi_nr_dl_config_csirs_pdu_r return sum_x2 / size - (sum_x / size) * (sum_x / size); } -static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, - const UE_nr_rxtx_proc_t *proc, - const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, - const nr_csi_info_t *nr_csi_info, - const int32_t **csi_rs_generated_signal, - const int32_t csi_rs_received_signal[][fp->samples_per_slot_wCP], - const csi_mapping_parms_t *csi_mapping, - const int CDM_group_size, - uint8_t mem_offset, - int32_t csi_rs_ls_estimated_channel[][csi_mapping->ports][fp->ofdm_symbol_size], - int32_t csi_rs_estimated_channel_freq[][csi_mapping->ports][fp->ofdm_symbol_size + FILTER_MARGIN], - int16_t *log2_re, - int16_t *log2_maxh, - uint32_t *noise_power) +static int nr_csi_rs_channel_estimation( + const NR_DL_FRAME_PARMS *fp, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const int32_t **csi_rs_generated_signal, + const int32_t csi_rs_received_signal[][fp->samples_per_slot_wCP], + const csi_mapping_parms_t *csi_mapping, + const int CDM_group_size, + uint8_t mem_offset, + c16_t csi_rs_ls_estimated_channel[][csi_mapping->ports][fp->ofdm_symbol_size], + c16_t csi_rs_estimated_channel_freq[][csi_mapping->ports][fp->ofdm_symbol_size + FILTER_MARGIN], + int16_t *log2_re, + int16_t *log2_maxh, + uint32_t *noise_power) { const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP; *noise_power = 0; @@ -292,7 +289,7 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, /// LS channel estimation for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { - memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, fp->ofdm_symbol_size*sizeof(int32_t)); + memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, fp->ofdm_symbol_size * sizeof(c16_t)); } for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -319,15 +316,11 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, uint64_t symbol_offset = symb * fp->ofdm_symbol_size; c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; - - int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].r + (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].i)>>nr_csi_info->csi_rs_generated_signal_bits); - int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].i - (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].r)>>nr_csi_info->csi_rs_generated_signal_bits); - + c16_t tmp = c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits); // This is not just the LS estimation for each (k,l), but also the sum of the different contributions // for the sake of optimizing the memory used. - csi_rs_ls_estimated_channel16[kinit].r += csi_rs_ls_estimated_channel_re; - csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im; + csi_rs_ls_estimated_channel[ant_rx][port_tx][kinit].r += tmp.r; + csi_rs_ls_estimated_channel[ant_rx][port_tx][kinit].i += tmp.i; } } } @@ -345,7 +338,7 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, uint64_t symbol_offset = symb * fp->ofdm_symbol_size; c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *csi_rs_ls_estimated_channel16 = csi_rs_ls_estimated_channel[ant_rx][port_tx]; printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ", port_tx+3000, ant_rx, tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i, @@ -360,7 +353,7 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, /// Channel interpolation for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { - memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, (fp->ofdm_symbol_size + FILTER_MARGIN) * sizeof(int32_t)); + memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, (fp->ofdm_symbol_size + FILTER_MARGIN) * sizeof(c16_t)); } for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -375,15 +368,15 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, uint16_t k = (fp->first_carrier_offset + rb * NR_NB_SC_PER_RB) % fp->ofdm_symbol_size; uint16_t k_offset = k + mem_offset; for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel16 = (int16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; - int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset]; + c16_t csi_rs_ls_estimated_channel16 = csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; + c16_t *csi_rs_estimated_channel16 = &csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset]; if( (k == 0) || (k == fp->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16, 24); } else if(((k + NR_NB_SC_PER_RB) >= fp->ofdm_symbol_size) || (rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1))) { // End of OFDM symbol case or Last occupied subcarrier case - multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); + multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 12, 24); } else { // Middle case - multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); + multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 12, 24); } } } @@ -399,8 +392,8 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, uint16_t k = (fp->first_carrier_offset + rb*NR_NB_SC_PER_RB) % fp->ofdm_symbol_size; uint16_t k_offset = k + mem_offset; for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { - c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; - c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset]; + c16_t *csi_rs_ls_estimated_channel16 = &csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; + c16_t *csi_rs_estimated_channel16 = &csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset]; noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->r-csi_rs_estimated_channel16->r); noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->i-csi_rs_estimated_channel16->i); maxh = cmax3(maxh, abs(csi_rs_estimated_channel16->r), abs(csi_rs_estimated_channel16->i)); @@ -417,8 +410,8 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, (k + fp->ofdm_symbol_size - fp->first_carrier_offset)/NR_NB_SC_PER_RB; LOG_I(NR_PHY, "(k = %4d) |\t", k); for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { - c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; - c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][mem_offset]; + c16_t *csi_rs_ls_estimated_channel16 = &csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *csi_rs_estimated_channel16 = &csi_rs_estimated_channel_freq[ant_rx][port_tx][mem_offset]; printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ", port_tx+3000, ant_rx, csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i, @@ -447,10 +440,10 @@ int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue, const nr_csi_info_t *nr_csi_info, const uint8_t N_ports, uint8_t mem_offset, - int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN], + c16_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN], const int16_t log2_maxh, - uint8_t *rank_indicator) { - + uint8_t *rank_indicator) +{ const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; const int16_t cond_dB_threshold = 5; int count = 0; @@ -469,7 +462,8 @@ int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue, * | conjch01 conjch11 | | ch10 ch11 | | conjch01*ch00+conjch11*ch10 conjch01*ch01+conjch11*ch11 | */ - int32_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32))); + c16_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports] + [frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32))); int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32))); int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32))); int32_t csi_rs_estimated_determ_fin[frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32))); @@ -579,14 +573,14 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, const nr_csi_info_t *nr_csi_info, const uint8_t N_ports, uint8_t mem_offset, - const int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN], + const c16_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN], const uint32_t interference_plus_noise_power, const uint8_t rank_indicator, const int16_t log2_re, uint8_t *i1, uint8_t *i2, - uint32_t *precoded_sinr_dB) { - + uint32_t *precoded_sinr_dB) +{ const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; // i1 is a three-element vector in the form of [i11 i12 i13], when CodebookType is specified as 'Type1SinglePanel'. @@ -603,12 +597,9 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, } if(rank_indicator == 0 || rank_indicator == 1) { - - int32_t sum_re[4] = {0}; - int32_t sum_im[4] = {0}; - int32_t sum2_re[4] = {0}; - int32_t sum2_im[4] = {0}; - int32_t tested_precoded_sinr[4] = {0}; + c64_t sum[4] = {0}; + c64_t sum2[4] = {0}; + int64_t tested_precoded_sinr[4] = {0}; for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -618,41 +609,41 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; uint16_t k_offset = k + mem_offset; for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { - c16_t *csi_rs_estimated_channel_p0 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][0][k_offset]; - c16_t *csi_rs_estimated_channel_p1 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][1][k_offset]; + const c16_t p0 = csi_rs_estimated_channel_freq[ant_rx][0][k_offset]; + const c16_t p1 = csi_rs_estimated_channel_freq[ant_rx][1][k_offset]; // H_p0 + 1*H_p1 = (H_p0_re + H_p1_re) + 1j*(H_p0_im + H_p1_im) - sum_re[0] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r); - sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i); - sum2_re[0] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r))>>log2_re; - sum2_im[0] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i))>>log2_re; + sum[0].r += (p0.r + p1.r); + sum[0].i += (p0.i + p1.i); + sum2[0].r += (sum[0].r * sum[0].r) >> log2_re; + sum2[0].i += (sum[0].i * sum[0].i) >> log2_re; // H_p0 + 1j*H_p1 = (H_p0_re - H_p1_im) + 1j*(H_p0_im + H_p1_re) - sum_re[1] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i); - sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r); - sum2_re[1] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i))>>log2_re; - sum2_im[1] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r))>>log2_re; + sum[1].r += (p0.r - p1.i); + sum[1].i += (p0.i + p1.r); + sum2[1].r += (sum[1].r * sum[1].r) >> log2_re; + sum2[1].i += (sum[1].i * sum[1].i) >> log2_re; // H_p0 - 1*H_p1 = (H_p0_re - H_p1_re) + 1j*(H_p0_im - H_p1_im) - sum_re[2] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r); - sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i); - sum2_re[2] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r))>>log2_re; - sum2_im[2] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i))>>log2_re; + sum[2].r += (p0.r - p1.r); + sum[2].i += (p0.i - p1.i); + sum2[2].r += (sum[2].r * sum[2].r) >> log2_re; + sum2[2].i += (sum[2].i * sum[2].i) >> log2_re; // H_p0 - 1j*H_p1 = (H_p0_re + H_p1_im) + 1j*(H_p0_im - H_p1_re) - sum_re[3] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i); - sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r); - sum2_re[3] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i))>>log2_re; - sum2_im[3] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r))>>log2_re; + sum[3].r += (p0.r + p1.i); + sum[3].i += (p0.i - p1.r); + sum2[3].r += (sum[3].r * sum[3].r) >> log2_re; + sum2[3].i += (sum[3].i * sum[3].i) >> log2_re; } } // We should perform >>nr_csi_info->log2_re here for all terms, but since sum2_re and sum2_im can be high values, // we performed this above. for(int p = 0; p<4; p++) { - int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re); - int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>log2_re); - tested_precoded_sinr[p] = (power_re+power_im)/(int32_t)interference_plus_noise_power; + int64_t power_re = sum2[p].r - (sum[p].r >> log2_re) * (sum[p].r >> log2_re); + int64_t power_im = sum2[p].i - (sum[p].i >> log2_re) * (sum[p].i >> log2_re); + tested_precoded_sinr[p] = (power_re + power_im) / interference_plus_noise_power; } if(rank_indicator == 0) { @@ -913,8 +904,9 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, csi_info->csi_rs_generated_signal_bits = log2_approx(AMP); - int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][mapping_parms.ports][frame_parms->ofdm_symbol_size]; - int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][mapping_parms.ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN]; + c16_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][mapping_parms.ports][frame_parms->ofdm_symbol_size]; + c16_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][mapping_parms.ports] + [frame_parms->ofdm_symbol_size + FILTER_MARGIN]; // (long)&csi_rs_estimated_channel_freq[0][0][frame_parms->first_carrier_offset] & 0x1F // gives us the remainder of the integer division by 32 of the memory address diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index bc87b3de7f..a027b042ca 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -399,79 +399,22 @@ void nr_pdcch_channel_compensation(int32_t rx_size, //printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*20*12]); //printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol); //printf("rxdataf_comp addr %p\n",&rxdataF_comp[(aatx<<1)+aarx][symbol*20*12]); + + // multiply by conjugated channel + mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)rxdataF128, (c16_t *)rxdataF_comp128, 12 * coreset_nbr_rb, output_shift); - for (int rb = 0; rb < (coreset_nbr_rb * 3) >> 2; rb++) { - // multiply by conjugated channel - simde__m128i mmtmpP0 = simde_mm_madd_epi16(dl_ch128[0], rxdataF128[0]); - //print_ints("re",&mmtmpP0); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - simde__m128i mmtmpP1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpP1 = simde_mm_shufflehi_epi16(mmtmpP1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = simde_mm_sign_epi16(mmtmpP1,*(simde__m128i *)&conjugate[0]); - //print_ints("im",&mmtmpP1); - mmtmpP1 = simde_mm_madd_epi16(mmtmpP1,rxdataF128[0]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = simde_mm_srai_epi32(mmtmpP0,output_shift); - // print_ints("re(shift)",&mmtmpP0); - mmtmpP1 = simde_mm_srai_epi32(mmtmpP1,output_shift); - // print_ints("im(shift)",&mmtmpP1); - simde__m128i mmtmpP2 = simde_mm_unpacklo_epi32(mmtmpP0, mmtmpP1); - simde__m128i mmtmpP3 = simde_mm_unpackhi_epi32(mmtmpP0, mmtmpP1); - //print_ints("c0",&mmtmpP2); - //print_ints("c1",&mmtmpP3); - rxdataF_comp128[0] = simde_mm_packs_epi32(mmtmpP2,mmtmpP3); -// print_shorts("rx:",(int16_t*)rxdataF128); -// print_shorts("ch:",(int16_t*)dl_ch128); -// print_shorts("pack:",(int16_t*)rxdataF_comp128); - // multiply by conjugated channel - mmtmpP0 = simde_mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - mmtmpP1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = simde_mm_shufflehi_epi16(mmtmpP1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = simde_mm_sign_epi16(mmtmpP1,*(simde__m128i *)&conjugate[0]); - mmtmpP1 = simde_mm_madd_epi16(mmtmpP1,rxdataF128[1]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = simde_mm_srai_epi32(mmtmpP0,output_shift); - mmtmpP1 = simde_mm_srai_epi32(mmtmpP1,output_shift); - mmtmpP2 = simde_mm_unpacklo_epi32(mmtmpP0,mmtmpP1); - mmtmpP3 = simde_mm_unpackhi_epi32(mmtmpP0,mmtmpP1); - rxdataF_comp128[1] = simde_mm_packs_epi32(mmtmpP2,mmtmpP3); - //print_shorts("rx:",rxdataF128+1); - //print_shorts("ch:",dl_ch128+1); - //print_shorts("pack:",rxdataF_comp128+1); - // multiply by conjugated channel - mmtmpP0 = simde_mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - mmtmpP1 = simde_mm_shufflelo_epi16(dl_ch128[2], SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = simde_mm_shufflehi_epi16(mmtmpP1, SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = simde_mm_sign_epi16(mmtmpP1,*(simde__m128i *)&conjugate[0]); - mmtmpP1 = simde_mm_madd_epi16(mmtmpP1,rxdataF128[2]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = simde_mm_srai_epi32(mmtmpP0,output_shift); - mmtmpP1 = simde_mm_srai_epi32(mmtmpP1,output_shift); - mmtmpP2 = simde_mm_unpacklo_epi32(mmtmpP0,mmtmpP1); - mmtmpP3 = simde_mm_unpackhi_epi32(mmtmpP0,mmtmpP1); - rxdataF_comp128[2] = simde_mm_packs_epi32(mmtmpP2,mmtmpP3); - /////////////////////////////////////////////////////////////////////////////////////////////// - //print_shorts("rx:",rxdataF128+2); - //print_shorts("ch:",dl_ch128+2); - //print_shorts("pack:",rxdataF_comp128+2); - - for (int i=0; i<12 ; i++) + for (int rb = 0; rb < 12 * coreset_nbr_rb; rb++) { LOG_DDD("rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", - (rb * 12) + i, - ((c16_t *)rxdataF128)[i].r, - ((c16_t *)rxdataF128)[i].i, - (rb * 12) + i, - ((c16_t *)dl_ch128)[i].r, - ((c16_t *)dl_ch128)[i].i, - (rb * 12) + i, - ((c16_t *)rxdataF_comp128)[i].r, - ((c16_t *)rxdataF_comp128)[i].i); + rb, + ((c16_t *)rxdataF128)[rb].r, + ((c16_t *)rxdataF128)[rb].i, + rb, + ((c16_t *)dl_ch128)[rb].r, + ((c16_t *)dl_ch128)[rb].i, + rb, + ((c16_t *)rxdataF_comp128)[rb].r, + ((c16_t *)rxdataF_comp128)[rb].i); - dl_ch128+=3; - rxdataF128+=3; - rxdataF_comp128+=3; } } } @@ -479,12 +422,14 @@ void nr_pdcch_channel_compensation(int32_t rx_size, static void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, int32_t rx_size, c16_t rxdataF_comp[][rx_size], int symbol) { if (frame_parms->nb_antennas_rx>1) { - simde__m128i *rxdataF_comp128_0 = (simde__m128i *)&rxdataF_comp[0][symbol * frame_parms->N_RB_DL * 12]; - simde__m128i *rxdataF_comp128_1 = (simde__m128i *)&rxdataF_comp[1][symbol * frame_parms->N_RB_DL * 12]; - const int sz = frame_parms->N_RB_DL * 3; + const int sz = frame_parms->N_RB_DL * 12; + + simde__m128i *rxdataF_comp128_0 = (simde__m128i *)&rxdataF_comp[0][symbol * sz]; + simde__m128i *rxdataF_comp128_1 = (simde__m128i *)&rxdataF_comp[1][symbol * sz]; + // MRC on each re of rb - for (int i = 0; i < sz; i++) { - rxdataF_comp128_0[i] = simde_mm_adds_epi16(simde_mm_srai_epi16(rxdataF_comp128_0[i],1),simde_mm_srai_epi16(rxdataF_comp128_1[i],1)); + for (int i = 0; i < sz >> 2; i++) { + rxdataF_comp128_0[i] = simde_mm_adds_epi16(simde_mm_srai_epi16(rxdataF_comp128_0[i], 1), simde_mm_srai_epi16(rxdataF_comp128_1[i], 1)); } } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index fddc2a7654..a690c85ee3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -825,20 +825,6 @@ void nr_dlsch_deinterleaving(uint8_t symbol, // Pre-processing for LLR computation //============================================================================================== -simde__m128i nr_dlsch_a_mult_conjb(simde__m128i a, simde__m128i b, unsigned char output_shift) -{ - simde__m128i mmtmpD0 = simde_mm_madd_epi16(b, a); - simde__m128i mmtmpD1 = simde_mm_shufflelo_epi16(b, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)&conjugate[0]); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, a); - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - simde__m128i mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - simde__m128i mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - return simde_mm_packs_epi32(mmtmpD2, mmtmpD3); -} - static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, int nbRx, c16_t rxdataF_ext[][rx_size_symbol], @@ -859,7 +845,7 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, PHY_NR_MEASUREMENTS *measurements) { simde__m128i *dl_ch128, *dl_ch128_2, *dl_ch_mag128, *dl_ch_mag128b, *dl_ch_mag128r, *rxdataF128, *rxdataF_comp128, *rho128; - simde__m128i mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3, QAM_amp128 = {0}, QAM_amp128b = {0}, QAM_amp128r = {0}; + simde__m128i mmtmpD0, mmtmpD1, QAM_amp128 = {0}, QAM_amp128b = {0}, QAM_amp128r = {0}; uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0); @@ -928,9 +914,9 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, } // Multiply received data by conjugated channel - rxdataF_comp128[0] = nr_dlsch_a_mult_conjb(rxdataF128[0], dl_ch128[0], output_shift); - rxdataF_comp128[1] = nr_dlsch_a_mult_conjb(rxdataF128[1], dl_ch128[1], output_shift); - rxdataF_comp128[2] = nr_dlsch_a_mult_conjb(rxdataF128[2], dl_ch128[2], output_shift); + rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], rxdataF128[0], output_shift); + rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift); + rxdataF_comp128[2] = oai_mm_cpx_mult_conj(dl_ch128[2], rxdataF128[2], output_shift); dl_ch128 += 3; dl_ch_mag128 += 3; @@ -954,78 +940,21 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, rho128 = (simde__m128i *)&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12]; dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[l * frame_parms->nb_antennas_rx + aarx]; dl_ch128_2 = (simde__m128i *)dl_ch_estimates_ext[atx * frame_parms->nb_antennas_rx + aarx]; + + // multiply by conjugated channel + mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)dl_ch128_2, (c16_t *)rho128, 12 * nb_rb_0, output_shift); - for (int rb = 0; rb < nb_rb_0; rb++) { - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], dl_ch128_2[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, dl_ch128_2[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rho128[0] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",dl_ch128_2); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rho128); - - // multiply by conjugated channel - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[1], dl_ch128_2[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[1], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, dl_ch128_2[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - rho128[1] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",dl_ch128_2+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rho128+1); - - mmtmpD0 = simde_mm_madd_epi16(dl_ch128[2], dl_ch128_2[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch128[2], SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)conjugate); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, dl_ch128_2[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1); - - rho128[2] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3); - // print_shorts("rx:",dl_ch128_2+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rho128+2); - - dl_ch128+=3; - dl_ch128_2+=3; - rho128+=3; - } - if (first_symbol_flag) { - //rho_nm = H_arx_n.conj(H_arx_m) - //rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][l*n_layers+atx][symbol*nb_rb*12] - measurements->rx_correlation[0][aarx][l * n_layers + atx] = signal_energy(&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12],length); - //avg_rho_re[aarx][l*n_layers+atx] = 16*avg_rho_re[aarx][l*n_layers+atx]/length; - //avg_rho_im[aarx][l*n_layers+atx] = 16*avg_rho_im[aarx][l*n_layers+atx]/length; - //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, l,atx, avg_rho_re[aarx][l*n_layers+atx], avg_rho_im[aarx][l*n_layers+atx]); - //printf("rho_corr[rx]%d tx%d tx%d = %d ...\n",aarx, l,atx, measurements->rx_correlation[0][aarx][l*n_layers+atx]); - } + if (first_symbol_flag) { + // rho_nm = H_arx_n.conj(H_arx_m) + // rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][l*n_layers+atx][symbol*nb_rb*12] + measurements->rx_correlation[0][aarx][l * n_layers + atx] = + signal_energy(&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12], length); + // avg_rho_re[aarx][l*n_layers+atx] = 16*avg_rho_re[aarx][l*n_layers+atx]/length; + // avg_rho_im[aarx][l*n_layers+atx] = 16*avg_rho_im[aarx][l*n_layers+atx]/length; + // printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, l,atx, avg_rho_re[aarx][l*n_layers+atx], + // avg_rho_im[aarx][l*n_layers+atx]); printf("rho_corr[rx]%d tx%d tx%d = %d ...\n",aarx, l,atx, + // measurements->rx_correlation[0][aarx][l*n_layers+atx]); + } } } } @@ -1067,14 +996,14 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol, for (rb=0;rbnb_antennas_rx; aarx++) { - simde__m128i *dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[aarx]; - simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx]; - simde__m128i *rxdataF_comp128 = (simde__m128i *)rxdataF_comp[aarx]; - - for (int re = 0; re < nb_re; re += 4) { - *rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift); - } + mult_cpx_conj_vector((c16_t *)dl_ch_estimates_ext[aarx], + (c16_t *)rxdataF_ext[aarx], + (c16_t *)rxdataF_comp[aarx], + nb_re, + output_shift); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index bf68a69492..fee1f4cabb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -59,11 +59,7 @@ void nr_dlsch_deinterleaving(uint8_t symbol, uint16_t *llr_deint, uint16_t nb_rb_pdsch); -void nr_conjch0_mult_ch1(int *ch0, - int *ch1, - int32_t *ch0conj_ch1, - unsigned short nb_rb, - unsigned char output_shift0); +void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0); /** \brief This is the alternative top-level entry point for DLSCH decoding in UE. It handles all the HARQ processes in only one call. The routine first diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 299eeb6c64..72fac53825 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -451,7 +451,7 @@ static void map_symbols(const nr_phy_pxsch_params_t p, c16_t mod_ptrs[ALNARS_16_4(p.nb_rb)] __attribute((aligned(16))); nr_modulation(gold, p.nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); const unsigned int beta_ptrs = 1; // temp value until power control is implemented - multadd_complex_vector_real_scalar((int16_t *)mod_ptrs, beta_ptrs * AMP, (int16_t *)mod_ptrs_amp, 1, p.nb_rb); + mult_complex_vector_real_scalar(mod_ptrs, beta_ptrs * AMP, mod_ptrs_amp, p.nb_rb); } map_current_symbol(p, dmrs_symbol, diff --git a/openair1/PHY/TOOLS/cadd_vv.c b/openair1/PHY/TOOLS/cadd_vv.c deleted file mode 100644 index 7eade29bb0..0000000000 --- a/openair1/PHY/TOOLS/cadd_vv.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "PHY/defs_common.h" -#include "tools_defs.h" - - -int32_t sub_cpx_vector16(int16_t *x, - int16_t *y, - int16_t *z, - uint32_t N) -{ - unsigned int i; // loop counter - - simde__m128i *x_128; - simde__m128i *y_128; - simde__m128i *z_128; - - x_128 = (simde__m128i *)&x[0]; - y_128 = (simde__m128i *)&y[0]; - z_128 = (simde__m128i *)&z[0]; - - for(i=0; i<(N>>3); i++) { - z_128[0] = simde_mm_subs_epi16(x_128[0],y_128[0]); - - x_128++; - y_128++; - z_128++; - - } - - return(0); -} - - - -#ifdef MAIN -#include - -main () -{ - - short input[256] __attribute__((aligned(16))); - short output[256] __attribute__((aligned(16))); - - int i; - c16_t alpha; - - memset(output,0,256*2); - - input[0] = 100; - input[1] = 200; - input[2] = 100; - input[3] = 200; - input[4] = 1234; - input[5] = -1234; - input[6] = 1234; - input[7] = -1234; - input[8] = 100; - input[9] = 200; - input[10] = 100; - input[11] = 200; - input[12] = 1000; - input[13] = 2000; - input[14] = 1000; - input[15] = 2000; - - alpha.r = 10; - alpha.i = -10; - - add_cpx_vector(input,(short*) &alpha,input,8); - - for (i=0; i<16; i+=2) - printf("output[%d] = %d + %d i\n",i,input[i],input[i+1]); - -} - -#endif //MAIN diff --git a/openair1/PHY/TOOLS/cdot_prod.c b/openair1/PHY/TOOLS/cdot_prod.c index ccac6f5a7e..aca19c7085 100644 --- a/openair1/PHY/TOOLS/cdot_prod.c +++ b/openair1/PHY/TOOLS/cdot_prod.c @@ -33,33 +33,48 @@ c32_t dot_product(const c16_t *x, const c16_t *y, const uint32_t N, const int output_shift) { - const int16_t reflip[32] __attribute__((aligned(32))) = {1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1}; - const int8_t imshuffle[64] __attribute__((aligned(32))) = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13, 18, 19, 16, 17, 22, 23, 20, 21, 26, 27, 24, 25, 30, 31, 28, 29}; - const c16_t *end = x + N; - simde__m256i cumul_re = {0}, cumul_im = {0}; - while (x < end) { - const simde__m256i in1 = simde_mm256_loadu_si256((simde__m256i *)x); - const simde__m256i in2 = simde_mm256_loadu_si256((simde__m256i *)y); - const simde__m256i tmpRe = simde_mm256_madd_epi16(in1, in2); - cumul_re = simde_mm256_add_epi32(cumul_re, simde_mm256_srai_epi32(tmpRe, output_shift)); - const simde__m256i tmp1 = simde_mm256_shuffle_epi8(in2, *(simde__m256i *)imshuffle); - const simde__m256i tmp2 = simde_mm256_sign_epi16(tmp1, *(simde__m256i *)reflip); - const simde__m256i tmpIm = simde_mm256_madd_epi16(in1, tmp2); - cumul_im = simde_mm256_add_epi32(cumul_im, simde_mm256_srai_epi32(tmpIm, output_shift)); - x += 8; - y += 8; - } - - // this gives Re Re Im Im Re Re Im Im - const simde__m256i cumulTmp = simde_mm256_hadd_epi32(cumul_re, cumul_im); - const simde__m256i cumul = simde_mm256_hadd_epi32(cumulTmp, cumulTmp); c32_t ret; - ret.r = simde_mm256_extract_epi32(cumul, 0) + simde_mm256_extract_epi32(cumul, 4); - ret.i = simde_mm256_extract_epi32(cumul, 1) + simde_mm256_extract_epi32(cumul, 5); + + const c16_t *end = x + N; + +#if defined(__x86_64__) || defined(__i386__) + if (__builtin_cpu_supports("avx2")) { + + simde__m256i cumul_re = simde_mm256_setzero_si256(); + simde__m256i cumul_im = simde_mm256_setzero_si256(); + + simde__m256i *x256 = (simde__m256i *)x; + simde__m256i *y256 = (simde__m256i *)y; + + for (int i = 0; i < N >> 3; i++ ) { + const simde__m256i in1 = simde_mm256_loadu_si256(&x256[i]); + const simde__m256i in2 = simde_mm256_loadu_si256(&y256[i]); + + const simde__m256i tmpRe = oai_mm256_smadd(in1, in2, output_shift); + const simde__m256i tmpIm = oai_mm256_smadd(oai_mm256_swap(oai_mm256_conj(in1)), in2, output_shift); + //const simde__m256i tmpIm = oai_mm256_smadd(in1, oai_mm256_conj(oai_mm256_swap(in2)), output_shift); // alternative way + + cumul_re = simde_mm256_add_epi32(cumul_re, tmpRe); + cumul_im = simde_mm256_add_epi32(cumul_im, tmpIm); + } + + // this gives Re Re Im Im Re Re Im Im + const simde__m256i cumulTmp = simde_mm256_hadd_epi32(cumul_re, cumul_im); + const simde__m256i cumul = simde_mm256_hadd_epi32(cumulTmp, cumulTmp); + + ret.r = simde_mm256_extract_epi32(cumul, 0) + simde_mm256_extract_epi32(cumul, 4); + ret.i = simde_mm256_extract_epi32(cumul, 1) + simde_mm256_extract_epi32(cumul, 5); + + // update pointers + x += (N & ~7); + y += (N & ~7); + + } +#endif + + // tail processing if (x!=end) { - x-=8; - y-=8; for ( ; x r*y->r)>>output_shift) + ((x->i*y->i)>>output_shift); ret.i += ((x->r*y->i)>>output_shift) - ((x->i*y->r)>>output_shift); diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c deleted file mode 100644 index c20bd24f71..0000000000 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "PHY/sse_intrin.h" -#include "tools_defs.h" -#include -#include - -void multadd_complex_vector_real_scalar(int16_t *x, - int16_t alpha, - int16_t *y, - uint8_t zero_flag, - uint32_t N) -{ - simd_q15_t alpha_128,*x_128=(simd_q15_t *)x,*y_128=(simd_q15_t*)y; - int n; - - alpha_128 = set1_int16(alpha); - const uint32_t num_simd_adds = N / 4; - const uint32_t num_adds = N % 4; - - if (zero_flag == 1) { - for (n = 0; n < num_simd_adds; n++) { - y_128[n] = mulhi_int16(x_128[n],alpha_128); - } - for (n = 0; n < num_adds; n++) { - const uint32_t offset = num_simd_adds * 4; - y[offset + n] = (x[offset + n] * alpha) >> 16; - } - } else { - for (n = 0; n < num_simd_adds; n++) { - y_128[n] = adds_int16(y_128[n],mulhi_int16(x_128[n],alpha_128)); - } - for (n = 0; n < num_adds; n++) { - const uint32_t offset = num_simd_adds * 4; - y[offset + n] += (x[offset + n] * alpha) >> 16; - } - } -} - -void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha, int16_t *y, uint32_t N) -{ - - uint32_t i; - - // do 8 multiplications at a time - simd_q15_t *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y; - - // printf("alpha = %d,%d\n",alpha[0],alpha[1]); - const simd_q15_t alpha_r_128 = set1_int16(alpha[0]); - const simd_q15_t alpha_i_128 = set1_int16(alpha[1]); - for (i=0; i>3; i++) { - const simd_q15_t yr = mulhi_s1_int16(alpha_r_128,x_128[i]); - const simd_q15_t yi = mulhi_s1_int16(alpha_i_128,x_128[i]); - const simd_q15_t tmp = simde_mm_loadu_si128(y_128); - simde_mm_storeu_si128(y_128++,simde_mm_adds_epi16(tmp, simde_mm_unpacklo_epi16(yr, yi))); - const simd_q15_t tmp2 = simde_mm_loadu_si128(y_128); - simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp2, simde_mm_unpackhi_epi16(yr, yi))); - } -} - -void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, uint32_t N, uint16_t output_shift) -{ - // multiply a complex vector with a complex value (alpha) - // stores result in y - // N is the number of complex numbers - // output_shift reduces the result of the multiplication by this number of bits -#if defined(__x86_64__) || defined (__i386__) - if ( __builtin_cpu_supports("avx2")) { - // output is 32 bytes aligned, but not the input - - const c16_t for_re = {alpha->r, -alpha->i}; - const simde__m256i alpha_for_real = simde_mm256_set1_epi32(*(uint32_t *)&for_re); - const c16_t for_im = {alpha->i, alpha->r}; - const simde__m256i alpha_for_im = simde_mm256_set1_epi32(*(uint32_t *)&for_im); - const simde__m256i perm_mask = simde_mm256_set_epi8(31, - 30, - 23, - 22, - 29, - 28, - 21, - 20, - 27, - 26, - 19, - 18, - 25, - 24, - 17, - 16, - 15, - 14, - 7, - 6, - 13, - 12, - 5, - 4, - 11, - 10, - 3, - 2, - 9, - 8, - 1, - 0); - simde__m256i *xd = (simde__m256i *)x; - const simde__m256i *end = xd + N / 8; - for (simde__m256i *yd = (simde__m256i *)y; xd < end; yd++, xd++) { - const simde__m256i y256 = simde_mm256_lddqu_si256(xd); - const simde__m256i xre = simde_mm256_srai_epi32(simde_mm256_madd_epi16(y256, alpha_for_real), output_shift); - const simde__m256i xim = simde_mm256_srai_epi32(simde_mm256_madd_epi16(y256, alpha_for_im), output_shift); - // a bit faster than unpacklo+unpackhi+packs - const simde__m256i tmp = simde_mm256_packs_epi32(xre, xim); - simde_mm256_storeu_si256(yd, simde_mm256_shuffle_epi8(tmp, perm_mask)); - } - c16_t* alpha16=(c16_t*) alpha, *yLast; - yLast=((c16_t*)y)+(N/8)*8; - for (c16_t* xTail=(c16_t*) end; - xTail<((c16_t*) x)+N; - xTail++, yLast++) { - *yLast=c16mulShift(*xTail,*alpha16,output_shift); - } - } else { -#endif - // Multiply elementwise two complex vectors of N elements - // x - input 1 in the format |Re0 Im0 |,......,|Re(N-1) Im(N-1)| - // We assume x1 with a dynamic of 15 bit maximum - // - // alpha - input 2 in the format |Re0 Im0| - // We assume x2 with a dynamic of 15 bit maximum - // - // y - output in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0) - // WARNING: log2_amp>0 can cause overflow!! - - uint32_t i; // loop counter - - - simd_q15_t *y_128,alpha_128; - int32_t *xd=(int32_t *)x; - - simde__m128i shift = simde_mm_cvtsi32_si128(output_shift); - - ((int16_t *)&alpha_128)[0] = alpha->r; - ((int16_t *)&alpha_128)[1] = -alpha->i; - ((int16_t *)&alpha_128)[2] = alpha->i; - ((int16_t *)&alpha_128)[3] = alpha->r; - ((int16_t *)&alpha_128)[4] = alpha->r; - ((int16_t *)&alpha_128)[5] = -alpha->i; - ((int16_t *)&alpha_128)[6] = alpha->i; - ((int16_t *)&alpha_128)[7] = alpha->r; - y_128 = (simd_q15_t *) y; - - - for(i=0; i>2; i++) { - y_128[i] = simde_mm_packs_epi32( // pack in 16bit integers with saturation [re im re im re im re im] - simde_mm_sra_epi32( // shift right by shift in order to compensate for the input amplitude - simde_mm_madd_epi16( // complex multiply. result is 32bit [Re Im Re Im] - simde_mm_setr_epi32( xd[0+i*4], xd[0+i*4], xd[1+i*4], xd[1+i*4]), - alpha_128 - ), - shift - ), - simde_mm_sra_epi32( // shift right by shift in order to compensate for the input amplitude - simde_mm_madd_epi16( // complex multiply. result is 32bit [Re Im Re Im] - simde_mm_setr_epi32( xd[2+i*4], xd[2+i*4], xd[3+i*4], xd[3+i*4]), - alpha_128 - ), - shift - ) - ); - //print_ints("y_128[0]=", &y_128[0]); - } -#if defined(__x86__) || defined(__x86_64__) - } -#endif -} - -#ifdef MAIN -#define L 8 - -main () -{ - - int16_t input[256] __attribute__((aligned(16))); - int16_t input2[256] __attribute__((aligned(16))); - int16_t output[256] __attribute__((aligned(16))); - c16_t alpha; - - int i; - - input[0] = 100; - input[1] = 200; - input[2] = -200; - input[3] = 100; - input[4] = 1000; - input[5] = 2000; - input[6] = -2000; - input[7] = 1000; - input[8] = 100; - input[9] = 200; - input[10] = -200; - input[11] = 100; - input[12] = 1000; - input[13] = 2000; - input[14] = -2000; - input[15] = 1000; - - input2[0] = 1; - input2[1] = 2; - input2[2] = 1; - input2[3] = 2; - input2[4] = 10; - input2[5] = 20; - input2[6] = 10; - input2[7] = 20; - input2[8] = 1; - input2[9] = 2; - input2[10] = 1; - input2[11] = 2; - input2[12] = 1000; - input2[13] = 2000; - input2[14] = 1000; - input2[15] = 2000; - - alpha->r=32767; - alpha->i=0; - - //mult_cpx_vector(input,input2,output,L,0); - rotate_cpx_vector_norep(input,alpha,input,L,15); - - for(i=0; i - -static const int16_t conjug[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; -static const int16_t conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; - -#define simd_q15_t simde__m128i -#define set1_int16(a) simde_mm_set1_epi16(a) -#define setr_int16(a0, a1, a2, a3, a4, a5, a6, a7) simde_mm_setr_epi16(a0, a1, a2, a3, a4, a5, a6, a7 ) - -int mult_cpx_conj_vector(int16_t *x1, - int16_t *x2, - int16_t *y, - uint32_t N, - int output_shift, - int madd) -{ - // Multiply elementwise the complex conjugate of x1 with x2. - // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // We assume x1 with a dinamic of 15 bit maximum - // - // x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // We assume x2 with a dinamic of 14 bit maximum - /// - // y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // output_shift - shift to be applied to generate output - // - // madd - add the output to y - - uint32_t i; // loop counter - - simd_q15_t *x1_128; - simd_q15_t *x2_128; - simd_q15_t *y_128; - simd_q15_t tmp_re,tmp_im; - simd_q15_t tmpy0,tmpy1; - - x1_128 = (simd_q15_t *)&x1[0]; - x2_128 = (simd_q15_t *)&x2[0]; - y_128 = (simd_q15_t *)&y[0]; - - - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>2); i++) { - tmp_re = simde_mm_madd_epi16(*x1_128,*x2_128); - tmp_im = simde_mm_shufflelo_epi16(*x1_128, SIMDE_MM_SHUFFLE(2,3,0,1)); - tmp_im = simde_mm_shufflehi_epi16(tmp_im, SIMDE_MM_SHUFFLE(2,3,0,1)); - tmp_im = simde_mm_sign_epi16(tmp_im,*(simde__m128i*)&conjug[0]); - tmp_im = simde_mm_madd_epi16(tmp_im,*x2_128); - tmp_re = simde_mm_srai_epi32(tmp_re,output_shift); - tmp_im = simde_mm_srai_epi32(tmp_im,output_shift); - tmpy0 = simde_mm_unpacklo_epi32(tmp_re,tmp_im); - tmpy1 = simde_mm_unpackhi_epi32(tmp_re,tmp_im); - if (madd==0) - *y_128 = simde_mm_packs_epi32(tmpy0,tmpy1); - else - *y_128 += simde_mm_packs_epi32(tmpy0,tmpy1); - x1_128++; - x2_128++; - y_128++; - } - - - - return(0); -} - -int mult_cpx_vector(int16_t *x1, //Q15 - int16_t *x2,//Q13 - int16_t *y, - uint32_t N, - int output_shift) -{ - // Multiply elementwise x1 with x2. - // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // We assume x1 with a dinamic of 15 bit maximum - // - // x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // We assume x2 with a dinamic of 14 bit maximum - /// - // y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // output_shift - shift to be applied to generate output - uint32_t i; // loop counter - simd_q15_t *x1_128; - simd_q15_t *x2_128; - simd_q15_t *y_128; - simd_q15_t tmp_re,tmp_im; - simd_q15_t tmpy0,tmpy1; - x1_128 = (simd_q15_t *)&x1[0]; - x2_128 = (simd_q15_t *)&x2[0]; - y_128 = (simd_q15_t *)&y[0]; - //print_shorts("x1_128:",&x1_128[0]); - // print_shorts("x2_128:",&x2_128[0]); - - //right shift by 13 while p_a * x0 and 15 while - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>2); i++) { - tmp_re = simde_mm_sign_epi16(*x1_128,*(simde__m128i*)&conjug2[0]);// Q15 - //print_shorts("tmp_re1:",&tmp_re[i]); - tmp_re = simde_mm_madd_epi16(tmp_re,*x2_128); //Q28 - //print_ints("tmp_re2:",&tmp_re[i]); - tmp_im = simde_mm_shufflelo_epi16(*x1_128, SIMDE_MM_SHUFFLE(2,3,0,1)); //Q15 - //print_shorts("tmp_im1:",&tmp_im[i]); - tmp_im = simde_mm_shufflehi_epi16(tmp_im, SIMDE_MM_SHUFFLE(2,3,0,1)); //Q15 - //print_shorts("tmp_im2:",&tmp_im[i]); - tmp_im = simde_mm_madd_epi16(tmp_im, *x2_128); //Q28 - //print_ints("tmp_im3:",&tmp_im[i]); - tmp_re = simde_mm_srai_epi32(tmp_re,output_shift);//Q(28-shift) - //print_ints("tmp_re shifted:",&tmp_re[i]); - tmp_im = simde_mm_srai_epi32(tmp_im,output_shift); //Q(28-shift) - //print_ints("tmp_im shifted:",&tmp_im[i]); - tmpy0 = simde_mm_unpacklo_epi32(tmp_re,tmp_im); //Q(28-shift) - //print_ints("unpack lo :",&tmpy0[i]); - tmpy1 = simde_mm_unpackhi_epi32(tmp_re,tmp_im); //Q(28-shift) - //print_ints("mrc rho0:",&tmpy1[i]); - *y_128 = simde_mm_packs_epi32(tmpy0,tmpy1); //must be Q15 - //print_shorts("*y_128:",&y_128[i]); - x1_128++; - x2_128++; - y_128++; - } - return(0); -} - -int multadd_cpx_vector(int16_t *x1, - int16_t *x2, - int16_t *y, - uint8_t zero_flag, - uint32_t N, - int output_shift) -{ - // Multiply elementwise the complex conjugate of x1 with x2. - // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // We assume x1 with a dinamic of 15 bit maximum - // - // x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // We assume x2 with a dinamic of 14 bit maximum - /// - // y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - // - // zero_flag - Set output (y) to zero prior to disable accumulation - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // output_shift - shift to be applied to generate output - uint32_t i; // loop counter - simd_q15_t *x1_128; - simd_q15_t *x2_128; - simd_q15_t *y_128; - simd_q15_t tmp_re,tmp_im; - simd_q15_t tmpy0,tmpy1; - x1_128 = (simd_q15_t *)&x1[0]; - x2_128 = (simd_q15_t *)&x2[0]; - y_128 = (simd_q15_t *)&y[0]; - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>2); i++) { - tmp_re = simde_mm_sign_epi16(*x1_128,*(simde__m128i*)&conjug2[0]); - tmp_re = simde_mm_madd_epi16(tmp_re,*x2_128); - tmp_im = simde_mm_shufflelo_epi16(*x1_128, SIMDE_MM_SHUFFLE(2,3,0,1)); - tmp_im = simde_mm_shufflehi_epi16(tmp_im, SIMDE_MM_SHUFFLE(2,3,0,1)); - tmp_im = simde_mm_madd_epi16(tmp_im,*x2_128); - tmp_re = simde_mm_srai_epi32(tmp_re,output_shift); - tmp_im = simde_mm_srai_epi32(tmp_im,output_shift); - tmpy0 = simde_mm_unpacklo_epi32(tmp_re,tmp_im); - //print_ints("unpack lo:",&tmpy0[i]); - tmpy1 = simde_mm_unpackhi_epi32(tmp_re,tmp_im); - //print_ints("unpack hi:",&tmpy1[i]); - if (zero_flag == 1) - *y_128 = simde_mm_packs_epi32(tmpy0,tmpy1); - else - *y_128 = simde_mm_adds_epi16(*y_128,simde_mm_packs_epi32(tmpy0,tmpy1)); - //print_shorts("*y_128:",&y_128[i]); - x1_128++; - x2_128++; - y_128++; - } - return(0); -} diff --git a/openair1/PHY/TOOLS/lut.c b/openair1/PHY/TOOLS/lut.c deleted file mode 100644 index f58a06c8ae..0000000000 --- a/openair1/PHY/TOOLS/lut.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -double interp(double x, double *xs, double *ys, int count) -{ - int i; - double dx, dy; - - if (x < xs[0]) { - return 1.0; /* return minimum element */ - } - - if (x > xs[count-1]) { - return 0.0; /* return maximum */ - } - - /* find i, such that xs[i] <= x < xs[i+1] */ - for (i = 0; i < count-1; i++) { - if (xs[i+1] > x) { - break; - } - } - - /* interpolate */ - dx = xs[i+1] - xs[i]; - dy = ys[i+1] - ys[i]; - return ys[i] + (x - xs[i]) * dy / dx; -} diff --git a/openair1/PHY/TOOLS/oai_arith_operations.c b/openair1/PHY/TOOLS/oai_arith_operations.c new file mode 100644 index 0000000000..8233029c02 --- /dev/null +++ b/openair1/PHY/TOOLS/oai_arith_operations.c @@ -0,0 +1,96 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include + +#define SHUFFLE_MASK SIMDE_MM_SHUFFLE(3, 1, 2, 0) // 0xD8 + +// Helper function for 128-bit vectors +static inline simde__m128i +oai_mm_presort_complex(simde__m128i x) { + return simde_mm_shuffle_epi32(simde_mm_shufflehi_epi16(simde_mm_shufflelo_epi16(x, SHUFFLE_MASK), SHUFFLE_MASK), SHUFFLE_MASK); +} + +// Helper function for 256-bit vectors +static inline simde__m256i +oai_mm256_presort_complex(simde__m256i x) { + return simde_mm256_shuffle_epi32(simde_mm256_shufflehi_epi16(simde_mm256_shufflelo_epi16(x, SHUFFLE_MASK), SHUFFLE_MASK), SHUFFLE_MASK); +} + +void oai_mm_separate_real_imag_parts(simde__m128i *out_re, simde__m128i *out_im, simde__m128i in0, simde__m128i in1) +{ + // presort real and imag part + simde__m128i xmm0 = oai_mm_presort_complex(in0); + simde__m128i xmm1 = oai_mm_presort_complex(in1); + + if (out_re) + *out_re = simde_mm_unpacklo_epi64(xmm0, xmm1); + + if (out_im) + *out_im = simde_mm_unpackhi_epi64(xmm0, xmm1); + +} + +void oai_mm256_separate_real_imag_parts(simde__m256i *out_re, simde__m256i *out_im, simde__m256i in0, simde__m256i in1) +{ + + // presort + simde__m256i xmm0 = oai_mm256_presort_complex(in0); + simde__m256i xmm1 = oai_mm256_presort_complex(in1); + + if (out_re) + *out_re = simde_mm256_permute4x64_epi64(simde_mm256_unpacklo_epi64(xmm0, xmm1), SHUFFLE_MASK); + + if (out_im) + *out_im = simde_mm256_permute4x64_epi64(simde_mm256_unpackhi_epi64(xmm0, xmm1), SHUFFLE_MASK); + +} + +// Function to separate the real and imaginary parts from the combined 256-bit vector +//__attribute__((always_inline)) static inline +void oai_mm256_separate_vectors(simde__m256i combined, simde__m128i *re, simde__m128i *im) { + + // presort + simde__m256i xmm0 = oai_mm256_presort_complex(combined); + + // Unpack the low and high parts of the combined vector to extract real and imaginary parts + simde__m128i lo = simde_mm256_extractf128_si256(xmm0, 0); // Extract the lower 128 bits (real part) + simde__m128i hi = simde_mm256_extractf128_si256(xmm0, 1); // Extract the higher 128 bits (imaginary part) + + // Now we need to separate the real and imaginary parts within each 128-bit part. + simde__m128i xmmre = simde_mm_unpacklo_epi16(lo, hi); // Real part of the low half + simde__m128i xmmim = simde_mm_unpackhi_epi16(lo, hi); // Imaginary part of the high half + + *re = oai_mm_presort_complex(xmmre); + *im = oai_mm_presort_complex(xmmim); + +} + +// Function to perform interleaving and combining re and im to a complex vector +//__attribute__((always_inline)) static inline +void oai_mm256_combine_vectors(simde__m128i re, simde__m128i im, simde__m256i *combined) { + *combined = simde_mm256_set_m128i( + simde_mm_unpackhi_epi16(re, im), + simde_mm_unpacklo_epi16(re, im) + ); +} + +#undef SHUFFLE_MASK diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c index 36bae5bd3d..1a86bfdc27 100644 --- a/openair1/PHY/TOOLS/oai_dfts.c +++ b/openair1/PHY/TOOLS/oai_dfts.c @@ -1512,9 +1512,7 @@ const static int16_t tw64c[96] __attribute__((aligned(32))) = { 23170,-23170,15447,-28898,6393,-32138,-3211,-32610, -12539,-30273,-20787,-25330,-27244,-18205,-31356,-9512 }; -#define simd_q15_t simde__m128i -#define shiftright_int16(a,shift) simde_mm_srai_epi16(a,shift) -#define mulhi_int16(a,b) simde_mm_mulhrs_epi16 (a,b) + #define simd256_q15_t simde__m256i #define shiftright_int16_simd256(a,shift) simde_mm256_srai_epi16(a,shift) #define set1_int16_simd256(a) simde_mm256_set1_epi16(a); diff --git a/openair1/PHY/TOOLS/read_F.c b/openair1/PHY/TOOLS/read_F.c deleted file mode 100644 index 155b72c851..0000000000 --- a/openair1/PHY/TOOLS/read_F.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -int f_read(char *calibF_fname, int nb_antM, int nb_freq, int16_t (*calibF_mtx)[nb_freq*2]){ - - FILE *calibF_fd; - int i,j,l,calibF_e; - - calibF_fd = fopen(calibF_fname,"r"); - - if (calibF_fd) { - printf("Loading Calibration matrix from %s\n", calibF_fname); - - for(i=0;i - -void simde_mm128_separate_real_imag_parts(simde__m128i *out_re, simde__m128i *out_im, simde__m128i in0, simde__m128i in1) -{ - // Put in0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - in0 = simde_mm_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - in1 = simde_mm_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - *out_re = simde_mm_unpacklo_epi64(in0, in1); - *out_im = simde_mm_unpackhi_epi64(in0, in1); -} - -void simde_mm256_separate_real_imag_parts(simde__m256i *out_re, simde__m256i *out_im, simde__m256i in0, simde__m256i in1) -{ - // Put in0 = [Re(0,1,2,3) Im(0,1,2,3) Re(4,5,6,7) Im(4,5,6,7)] - in0 = simde_mm256_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm256_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm256_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // Put in1 = [Re(8,9,10,11) Im(8,9,10,11) Re(12,13,14,15) Im(12,13,14,15)] - in1 = simde_mm256_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm256_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm256_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // Put tmp0 =[Re(0,1,2,3) Re(8,9,10,11) Re(4,5,6,7) Re(12,13,14,15)] - simde__m256i tmp0 = simde_mm256_unpacklo_epi64(in0, in1); - - // Put tmp1 = [Im(0,1,2,3) Im(8,9,10,11) Im(4,5,6,7) Im(12,13,14,15)] - simde__m256i tmp1 = simde_mm256_unpackhi_epi64(in0, in1); - - *out_re = simde_mm256_permute4x64_epi64(tmp0, 0xd8); - *out_im = simde_mm256_permute4x64_epi64(tmp1, 0xd8); -} diff --git a/openair1/PHY/TOOLS/tests/CMakeLists.txt b/openair1/PHY/TOOLS/tests/CMakeLists.txt index f5bdf24421..9a73f1ae8e 100644 --- a/openair1/PHY/TOOLS/tests/CMakeLists.txt +++ b/openair1/PHY/TOOLS/tests/CMakeLists.txt @@ -16,7 +16,6 @@ add_dependencies(tests test_log2_approx) add_test(NAME test_log2_approx COMMAND ./test_log2_approx --gtest_filter=-log2_approx.complete) - add_executable(dft_test test_dft.c ../dfts_load.c) target_link_libraries(dft_test minimal_lib shlib_loader SIMU m) add_dependencies(tests dft_test) @@ -28,3 +27,15 @@ target_link_libraries(test_vector_op PRIVATE LOG minimal_lib) add_dependencies(tests test_vector_op) add_test(NAME test_vector_op COMMAND test_vector_op) + +add_executable(test_oai_arith_operations test_oai_arith_operations.cpp ../oai_arith_operations.c) +target_link_libraries(test_oai_arith_operations PRIVATE GTest::gtest LOG minimal_lib) +add_dependencies(tests test_oai_arith_operations) +add_test(NAME test_oai_arith_operations + COMMAND ./test_oai_arith_operations) + +add_executable(test_sse_intrinsics test_sse_intrinsics.cpp) +target_link_libraries(test_sse_intrinsics PRIVATE GTest::gtest LOG minimal_lib) +add_dependencies(tests test_sse_intrinsics) +add_test(NAME test_sse_intrinsics + COMMAND ./test_sse_intrinsics) \ No newline at end of file diff --git a/openair1/PHY/TOOLS/tests/test_oai_arith_operations.cpp b/openair1/PHY/TOOLS/tests/test_oai_arith_operations.cpp new file mode 100644 index 0000000000..b9e0b41695 --- /dev/null +++ b/openair1/PHY/TOOLS/tests/test_oai_arith_operations.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +extern "C" { + void oai_mm_separate_real_imag_parts(simde__m128i *out_re, simde__m128i *out_im, simde__m128i in0, simde__m128i in1); + void oai_mm256_separate_real_imag_parts(simde__m256i *out_re, simde__m256i *out_im, simde__m256i in0, simde__m256i in1); + void oai_mm256_separate_vectors(simde__m256i combined, simde__m128i *re, simde__m128i *im); + void oai_mm256_combine_vectors(simde__m128i re, simde__m128i im, simde__m256i *combined); +} + +TEST(separate_real_imag_parts, 128) { + + // Create two 128-bit input vectosr with 8 16-bit integers + simde__m128i in0 = simde_mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); + simde__m128i in1 = simde_mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15); + + // Create two 128-bit output vectors + simde__m128i out_re, out_im; + + // Call function to test + oai_mm_separate_real_imag_parts(&out_re, &out_im, in0, in1); + + // Store the results for comparison + int16_t re_result[8], im_result[8]; + simde_mm_storeu_si128(reinterpret_cast(re_result), out_re); + simde_mm_storeu_si128(reinterpret_cast(im_result), out_im); + + // Create the expected vectors + int16_t re_expected[8] = {0, 2, 4, 6, 8, 10, 12, 14}; + int16_t im_expected[8] = {1, 3, 5, 7, 9, 11, 13, 15}; + + for (int i = 0; i < 8; i++) { + EXPECT_EQ(re_result[i], re_expected[i]) << "Real part mismatch on index " << i; + EXPECT_EQ(im_result[i], im_expected[i]) << "Imag part mismatch on index " << i; + } +} + +TEST(separate_real_imag_parts, 256) { + + // Create two 256-bit input vectosr with 16 16-bit integers + simde__m256i in0 = simde_mm256_setr_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + simde__m256i in1 = simde_mm256_setr_epi16(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31); + + // Create two 256-bit output vectors + simde__m256i out_re, out_im; + + // Call function to test + oai_mm256_separate_real_imag_parts(&out_re, &out_im, in0, in1); + + // Store the results for comparison + int16_t re_result[16], im_result[16]; + simde_mm256_storeu_si256(reinterpret_cast(re_result), out_re); + simde_mm256_storeu_si256(reinterpret_cast(im_result), out_im); + + // Create the expected vectors + int16_t re_expected[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; + int16_t im_expected[16] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}; + + for (int i = 0; i < 16; i++) { + EXPECT_EQ(re_result[i], re_expected[i]) << "Real part mismatch on index " << i; + EXPECT_EQ(im_result[i], im_expected[i]) << "Imag part mismatch on index " << i; + } +} + +TEST(complex_vectors, separate) { + + // Create a 256-bit input vector with 16 16-bit integers in natural order. + simde__m256i combined = simde_mm256_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + + // Create two 128-bit output vectors + simde__m128i re, im; + + // Call function to test + oai_mm256_separate_vectors(combined, &re, &im); + + // Store the results for comparison + int16_t re_result[8], im_result[8]; + simde_mm_storeu_si128((simde__m128i*)re_result, re); + simde_mm_storeu_si128((simde__m128i*)im_result, im); + + // Create the expected vectors + int16_t re_expected[8] = {0, 2, 4, 6, 8, 10, 12, 14}; + int16_t im_expected[8] = {1, 3, 5, 7, 9, 11, 13, 15}; + + for (int i = 0; i < 8; i++) { + EXPECT_EQ(re_result[i], re_expected[i]) << "Real part mismatch on index " << i; + EXPECT_EQ(im_result[i], im_expected[i]) << "Imag part mismatch on index " << i; + } +} + +TEST(complex_vectors, combine) { + + // Create two 128-bit input vectosr with 8 16-bit integers + simde__m128i re = simde_mm_setr_epi16(0, 2, 4, 6, 8, 10, 12, 14); + simde__m128i im = simde_mm_setr_epi16(1, 3, 5, 7, 9, 11, 13, 15); + + // Create 256-bit output vector + simde__m256i c; + + // Call function to test + oai_mm256_combine_vectors(re, im, &c); + + // Store the results for comparison + int16_t c_result[16]; + simde_mm256_storeu_si256((simde__m256i*)c_result, c); + + // Create the expected vector + int16_t c_expected[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + + for (int i = 0; i < 8; i++) { + EXPECT_EQ(c_result[2*i+0], c_expected[2*i+0]) << "Real part mismatch on index " << 2*i+0; + EXPECT_EQ(c_result[2*i+1], c_expected[2*i+1]) << "Imag part mismatch on index " << 2*i+1; + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/openair1/PHY/TOOLS/tests/test_sse_intrinsics.cpp b/openair1/PHY/TOOLS/tests/test_sse_intrinsics.cpp new file mode 100644 index 0000000000..33cee22e71 --- /dev/null +++ b/openair1/PHY/TOOLS/tests/test_sse_intrinsics.cpp @@ -0,0 +1,374 @@ +#include +#include +#include "../../sse_intrin.h" + +TEST(conj_vectors, 128) { + + // Create a 128-bit input vector with 8 16-bit integers in natural order. + simde__m128i in = simde_mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); + + // Call function to test + simde__m128i out = oai_mm_conj(in); + + // Store the results for comparison + int16_t out_result[8]; + simde_mm_storeu_si128((simde__m128i*)out_result, out); + + // Create the expected vectors + int16_t out_expected[8] = {0, -1, 2, -3, 4, -5, 6, -7}; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(out_result[i], out_expected[i]) << "Conjugate mismatch on index " << i; + } +} + +TEST(conj_vectors, 256) { + + // Create a 256-bit input vector with 16 16-bit integers in natural order. + simde__m256i in = simde_mm256_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + + // Call function to test + simde__m256i out = oai_mm256_conj(in); + + // Store the results for comparison + int16_t out_result[16]; + simde_mm256_storeu_si256((simde__m256i*)out_result, out); + + // Create the expected vectors + int16_t out_expected[16] = {0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15}; + + // Check for mismatch + for (int i = 0; i < 16; i++) { + EXPECT_EQ(out_result[i], out_expected[i]) << "Conjugate mismatch on index " << i; + } +} + +TEST(swap_vectors, 128) { + + // Create a 128-bit input vector with 8 16-bit integers in natural order. + simde__m128i in = simde_mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); + + // Call function to test + simde__m128i out = oai_mm_swap(in); + + // Store the results for comparison + int16_t out_result[8]; + simde_mm_storeu_si128((simde__m128i*)out_result, out); + + // Create the expected vectors + int16_t out_expected[8] = {1, 0, 3, 2, 5, 4, 7, 6}; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(out_result[i], out_expected[i]) << "IQ swap mismatch on index " << i; + } +} + +TEST(swap_vectors, 256) { + + // Create a 256-bit input vector with 16 16-bit integers in natural order. + simde__m256i in = simde_mm256_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + + // Call function to test + simde__m256i out = oai_mm256_swap(in); + + // Store the results for comparison + int16_t out_result[16]; + simde_mm256_storeu_si256((simde__m256i*)out_result, out); + + // Create the expected vector + int16_t out_expected[16] = {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}; + + // Check for mismatch + for (int i = 0; i < 16; i++) { + EXPECT_EQ(out_result[i], out_expected[i]) << "Conjugate mismatch on index " << i; + } +} + +TEST(ShiftedMultiplyAndAdd, 128) { + + // Set up two 128-bit vectors with 8 16-bit elements each. + simde__m128i vec1 = simde_mm_setr_epi16( 1, 2, 3, 4, -5, -6, 7, 8); + simde__m128i vec2 = simde_mm_setr_epi16(10, 20, 30, 40, 50, 60, 70, 80); + + // Call function to test + int shift = 1; + simde__m128i res = oai_mm_smadd(vec1, vec2, shift); + + // Store the results for comparison + int32_t output[4]; + simde_mm_storeu_si128((simde__m128i*)output, res); + + // Create the expected vector + // Pair 0: 1*10 + 2*20 = 10 + 40 = 50>>1 = 25 + // Pair 1: 3*30 + 4*40 = 90 + 160 = 250>>1 = 125 + // Pair 2: -5*50 + -6*60 = -250 + -360 = -610>>1 = -305 + // Pair 3: 7*70 + 8*80 = 490 + 640 = 1130>>1 = 565 + int32_t expected[4] = {25, 125, -305, 565}; + + // Check for mismatch + for (int i = 0; i < 4; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(ShiftedMultiplyAndAdd, 256) { + + // Set up two 128-bit vectors with 16 16-bit elements each. + simde__m256i vec1 = simde_mm256_setr_epi16( 1, 2, 3, 4, 5, 6, -7, -8, 9, 10, 11, 12, 13, 14, 15, 16); + simde__m256i vec2 = simde_mm256_setr_epi16(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160); + + // Call function to test + int shift = 1; + simde__m256i res = oai_mm256_smadd(vec1, vec2, shift); + + // Store the results for comparison + int32_t output[8]; + simde_mm256_storeu_si256((simde__m256i*)output, res); + + // Create the expected vector + // Pair 0: 1* 10 + 2* 20 = 50>>1 = 25 + // Pair 1: 3* 30 + 4* 40 = 250>>1 = 125 + // Pair 2: 5* 50 + 6* 60 = 610>>1 = 305 + // Pair 3: -7* 70 + -8* 80 = -1130>>1 = -565 + // Pair 4: 9* 90 + 10*100 = 1810>>1 = 905 + // Pair 5: 11*110 + 12*120 = 2650>>1 = 1325 + // Pair 6: 13*130 + 14*140 = 3650>>1 = 1825 + // Pair 7: 15*150 + 16*160 = 4810>>1 = 2405 + int32_t expected[8] = {25, 125, 305, -565, 905, 1325, 1825, 2405}; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(Pack, 128normal) { + + // Set up two 128-bit vectors containing 4 32-bit integers each. + simde__m128i a = simde_mm_setr_epi32(1000, 2000, 3000, 4000); + simde__m128i b = simde_mm_setr_epi32(5000, 6000, 7000, 8000); + + // Call function to test + simde__m128i res = oai_mm_pack(a, b); + + // Store the results for comparison + int16_t result[8]; + simde_mm_storeu_si128((simde__m128i*) result, res); + + // Create the expected vector (here without saturation) + int16_t expected[8] = {1000, 5000, 2000, 6000, 3000, 7000, 4000, 8000}; + + for (int i = 0; i < 8; i++) { + EXPECT_EQ(result[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(Pack, 128saturation) { + + // Set up two 128-bit vectors containing 4 32-bit integers each. + simde__m128i a = simde_mm_setr_epi32(-40000, 40000, -1000, 1000); + simde__m128i b = simde_mm_setr_epi32(-50000, 50000, -2000, 2000); + + // Call function to test + simde__m128i res = oai_mm_pack(a, b); + + // Store the results for comparison + int16_t result[8]; + simde_mm_storeu_si128((simde__m128i*) result, res); + + // Create the expected vector (here saturation occours) + int16_t expected[8] = { + -32768, -32768, 32767, 32767, // saturation applied to the first unpacked vector + -1000, -2000, 1000, 2000 // values remain unchanged for the second unpacked vector + }; + + for (int i = 0; i < 8; i++) { + EXPECT_EQ(result[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(Pack, 256normal) { + + // Set up two 256-bit vectors with 16 16-bit values each. + simde__m256i vec1 = simde_mm256_setr_epi16( 1, 2, 3, 4, 5, 6, -7, -8, 9, 10, 11, 12, 13, 14, 15, 16); + simde__m256i vec2 = simde_mm256_setr_epi16(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160); + + // Call function to test with arithmetic shift by 1 (i.e. divide by 2). + int shift = 1; + simde__m256i res = oai_mm256_smadd(vec1, vec2, shift); + + // Store the results for comparison + int32_t output[8]; + simde_mm256_storeu_si256((simde__m256i*)output, res); + + // The expected results are calculated as follows: + // Pair 0: 1* 10 + 2* 20 = 50>>1 = 25 + // Pair 1: 3* 30 + 4* 40 = 250>>1 = 125 + // Pair 2: 5* 50 + 6* 60 = 610>>1 = 305 + // Pair 3: -7* 70 + -8* 80 = -1130>>1 = -565 + // Pair 4: 9* 90 + 10*100 = 1810>>1 = 905 + // Pair 5: 11*110 + 12*120 = 2650>>1 = 1325 + // Pair 6: 13*130 + 14*140 = 3650>>1 = 1825 + // Pair 7: 15*150 + 16*160 = 4810>>1 = 2405 + int32_t expected[8] = {25, 125, 305, -565, 905, 1325, 1825, 2405}; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(Pack, 256saturation) { + + // Set up two 256-bit vectors with 16 16-bit values each. + simde__m256i vec1 = simde_mm256_setr_epi16(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16); + simde__m256i vec2 = simde_mm256_setr_epi16(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160); + + // Call function to test with arithmetic shift by 1 (i.e. divide by 2). + int shift = 1; + simde__m256i res = oai_mm256_smadd(vec1, vec2, shift); + + // Store the results for comparison + int32_t output[8]; + simde_mm256_storeu_si256((simde__m256i*)output, res); + + // The expected results are calculated as follows: + // Pair 0: -1* 10 + -2* 20 = -50>>1 = -25 + // Pair 1: -3* 30 + -4* 40 = -250>>1 = -125 + // Pair 2: -5* 50 + -6* 60 = -610>>1 = -305 + // Pair 3: -7* 70 + -8* 80 = -1130>>1 = -565 + // Pair 4: -9* 90 + -10*100 = -1810>>1 = -905 + // Pair 5: -11*110 + -12*120 = -2650>>1 = -1325 + // Pair 6: -13*130 + -14*140 = -3650>>1 = -1825 + // Pair 7: -15*150 + -16*160 = -4810>>1 = -2405 + int32_t expected[8] = {-25, -125, -305, -565, -905, -1325, -1825, -2405}; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(ComplexMultiply, 128) { + + // Set up two 128-bit vectors with 8 16-bit elements each. + simde__m128i z1 = simde_mm_setr_epi16( 3, 4, 5, 6, 7, 8, 9, 10); + simde__m128i z2 = simde_mm_setr_epi16(11, 12, 13, 14, 15, 16, 17, 18); + + // Call function to test with arithmetic shift by 1 (i.e. divide by 2). + int shift = 1; + simde__m128i result = oai_mm_cpx_mult(z1, z2, shift); + + // Store the results for comparison + int16_t output[8]; + simde_mm_storeu_si128((simde__m128i*)output, result); + + // Expected results calculated manually: + // Pair 0: (3 + 4i) * (11 + 12i) = (-15 + 80i)>>1 = -8 + 40i + // Pair 1: (5 + 6i) * (13 + 14i) = (-19 + 148i)>>1 = -10 + 74i + // Pair 2: (7 + 8i) * (15 + 16i) = (-23 + 232i)>>1 = -12 + 116i + // Pair 3: (9 + 10i) * (17 + 18i) = (-27 + 332i)>>1 = -14 + 166i + int16_t expected[8] = { -8, 40, -10, 74, -12, 116, -14, 166 }; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(ComplexMultiply, 256) { + + // Set up two 256-bit vectors with 16 16-bit elements each. + simde__m256i z1 = simde_mm256_setr_epi16( 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18); + simde__m256i z2 = simde_mm256_setr_epi16(19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34); + + // Call function to test with arithmetic shift by 1 (i.e. divide by 2). + int shift = 1; + simde__m256i result = oai_mm256_cpx_mult(z1, z2, shift); + + // Store the results for comparison + int16_t output[16]; + simde_mm256_storeu_si256((simde__m256i*)output, result); + + // Expected results calculated manually: + // Pair 0: ( 3 + 4i) * (19 + 20i) = (-23 + 136i)>>1 = -12 + 68i + // Pair 1: ( 5 + 6i) * (21 + 22i) = (-27 + 236i)>>1 = -14 + 118i + // Pair 2: ( 7 + 8i) * (23 + 24i) = (-31 + 352i)>>1 = -16 + 176i + // Pair 3: ( 9 + 10i) * (25 + 26i) = (-35 + 484i)>>1 = -18 + 242i + // Pair 4: (11 + 12i) * (27 + 28i) = (-39 + 632i)>>1 = -20 + 316i + // Pair 5: (13 + 14i) * (29 + 30i) = (-43 + 796i)>>1 = -22 + 398i + // Pair 6: (15 + 16i) * (31 + 32i) = (-47 + 976i)>>1 = -24 + 488i + // Pair 7: (17 + 18i) * (33 + 34i) = (-51 + 1172i)>>1 = -26 + 586i + int16_t expected[16] = {-12, 68, -14, 118, -16, 176, -18, 242, -20, 316, -22, 398, -24, 488, -26, 586}; + + // Check for mismatch + for (int i = 0; i < 16; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(ComplexMultiplyConjugatedInput, 128) { + + // Set up two 128-bit vectors with 8 16-bit elements each. + simde__m128i a = simde_mm_setr_epi16( 3, 4, 5, 6, 7, 8, 9, 10); + simde__m128i b = simde_mm_setr_epi16(11, 12, 13, 14, 15, 16, 17, 18); + + // Call function to test with arithmetic shift by 1 (i.e. divide by 2). + int shift = 1; + simde__m128i result = oai_mm_cpx_mult_conj(a, b, shift); + + // Store the results for comparison + int16_t output[8]; + simde_mm_storeu_si128((simde__m128i*)output, result); + + // Expected results calculated manually: + // Pair 0: ( 3 - 4i) * (11 + 12i) = ( 81 - 8i)>>1 = 40 - 4i + // Pair 1: ( 5 - 6i) * (13 + 14i) = (149 - 8i)>>1 = 74 - 4i + // Pair 2: ( 7 - 8i) * (15 + 16i) = (233 - 8i)>>1 = 116 - 4i + // Pair 3: ( 9 - 10i) * (17 + 18i) = (333 - 8i)>>1 = 166 - 4i + int16_t expected[8] = {40, -4, 74, -4, 116, -4, 166, -4}; + + // Check for mismatch + for (int i = 0; i < 8; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +TEST(ComplexMultiplyConjugatedInput, 256) { + + // Set up two 256-bit vectors with 16 16-bit elements each. + simde__m256i a = simde_mm256_setr_epi16( 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18); + simde__m256i b = simde_mm256_setr_epi16(19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34); + + // Call function to test with arithmetic shift by 1 (i.e. divide by 2). + int shift = 1; + simde__m256i result = oai_mm256_cpx_mult_conj(a, b, shift); + + // Store the results for comparison + int16_t output[16]; + simde_mm256_storeu_si256((simde__m256i*)output, result); + + // Expected results calculated manually: + // Pair 0: ( 3 - 4i) * (19 + 20i) = ( 137 - 16i)>>1 = 68 - 8i + // Pair 1: ( 5 - 6i) * (21 + 22i) = ( 237 - 16i)>>1 = 118 - 8i + // Pair 2: ( 7 - 8i) * (23 + 24i) = ( 353 - 16i)>>1 = 176 - 8i + // Pair 3: ( 9 - 10i) * (25 + 26i) = ( 485 - 16i)>>1 = 242 - 8i + // Pair 4: (11 - 12i) * (27 + 28i) = ( 633 - 16i)>>1 = 316 - 8i + // Pair 5: (13 - 14i) * (29 + 30i) = ( 797 - 16i)>>1 = 398 - 8i + // Pair 6: (15 - 16i) * (31 + 32i) = ( 977 - 16i)>>1 = 488 - 8i + // Pair 7: (17 - 18i) * (33 + 34i) = (1173 - 16i)>>1 = 586 - 8i + int16_t expected[16] = {68, -8, 118, -8, 176, -8, 242, -8, 316, -8, 398, -8, 488, -8, 586, -8}; + + // Check for mismatch + for (int i = 0; i < 16; i++) { + EXPECT_EQ(output[i], expected[i]) << "Mismatch at index " << i; + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 34d7b73fc7..64e5061476 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -32,12 +32,11 @@ #include #include #include + #include "PHY/sse_intrin.h" + #include "common/utils/assertions.h" #include "common/utils/utils.h" -#include -#include -#include #include "common/utils/LOG/log.h" #define simd_q15_t simde__m128i @@ -299,14 +298,13 @@ extern "C" { const simde__m256i x_mul_alpha_shift15 =simde_mm256_mulhrs_epi16(alpha256, x_duplicate_ordered); // Existing multiplication normalization is weird, constant table in alpha need to be doubled const simde__m256i x_mul_alpha_x2= simde_mm256_adds_epi16(x_mul_alpha_shift15,x_mul_alpha_shift15); - *y128= simde_mm_adds_epi16(simde_mm256_extracti128_si256(x_mul_alpha_x2,0),*y128); + *y128 = simde_mm_adds_epi16(simde_mm256_extracti128_si256(x_mul_alpha_x2,0),*y128); y128++; *y128= simde_mm_adds_epi16(simde_mm256_extracti128_si256(x_mul_alpha_x2,1),*y128); y128++; x128++; } } -//cmult_sv.h /*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N) This function performs componentwise multiplication and accumulation of a complex scalar and a real vector. @@ -317,18 +315,16 @@ This function performs componentwise multiplication and accumulation of a comple The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$ */ - void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha, int16_t *y, uint32_t N); - // Same with correct types - static inline void multaddRealVectorComplexScalar(const c16_t *in, const c16_t alpha, c16_t *out, uint32_t N) + static inline void multadd_real_vector_complex_scalar(const int16_t *x, const c16_t alpha, c16_t *y, const uint32_t N) { // do 8 multiplications at a time - simd_q15_t *x_128 = (simd_q15_t *)in, *y_128 = (simd_q15_t *)out; + simd_q15_t *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y; // printf("alpha = %d,%d\n",alpha[0],alpha[1]); const simd_q15_t alpha_r_128 = set1_int16(alpha.r); const simd_q15_t alpha_i_128 = set1_int16(alpha.i); - for (unsigned int i = 0; i < N >> 3; i++) { + for (uint32_t i = 0; i < N >> 3; i++) { const simd_q15_t yr = mulhi_s1_int16(alpha_r_128, x_128[i]); const simd_q15_t yi = mulhi_s1_int16(alpha_i_128, x_128[i]); const simd_q15_t tmp = simde_mm_loadu_si128(y_128); @@ -339,17 +335,17 @@ The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$ } static __attribute__((always_inline)) inline void multadd_real_four_symbols_vector_complex_scalar(const int16_t *x, - c16_t *alpha, + const c16_t alpha, c16_t *y) { // do 8 multiplications at a time - const simd_q15_t alpha_r_128 = set1_int16(alpha->r); - const simd_q15_t alpha_i_128 = set1_int16(alpha->i); + const simd_q15_t alpha_r_128 = set1_int16(alpha.r); + const simd_q15_t alpha_i_128 = set1_int16(alpha.i); const simd_q15_t *x_128 = (const simd_q15_t *)x; + // fixme: this loads too much data after pointer x (8 * int16_t instead of 4 * int16_t) const simd_q15_t yr = mulhi_s1_int16(alpha_r_128, *x_128); const simd_q15_t yi = mulhi_s1_int16(alpha_i_128, *x_128); - simd_q15_t y_128 = simde_mm_loadu_si128((simd_q15_t *)y); y_128 = simde_mm_adds_epi16(y_128, simde_mm_unpacklo_epi16(yr, yi)); y_128 = simde_mm_adds_epi16(y_128, simde_mm_unpackhi_epi16(yr, yi)); @@ -435,11 +431,38 @@ This function performs componentwise multiplication and accumulation of a real s The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$ */ -void multadd_complex_vector_real_scalar(int16_t *x, - int16_t alpha, - int16_t *y, - uint8_t zero_flag, - uint32_t N); +static inline void multadd_complex_vector_real_scalar(const c16_t *x, const int16_t alpha, c16_t *y, uint32_t N) +{ + simd_q15_t alpha_128, *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y; + alpha_128 = set1_int16(alpha); + const uint32_t num_simd_adds = N / 4; + const uint32_t num_adds = N % 4; + for (uint32_t n = 0; n < num_simd_adds; n++) { + y_128[n] = adds_int16(y_128[n], mulhi_int16(x_128[n], alpha_128)); + } + for (uint32_t n = 0; n < num_adds; n++) { + const uint32_t offset = num_simd_adds * 4; + y[offset + n].r += (x[offset + n].r * alpha) >> 16; + y[offset + n].i += (x[offset + n].i * alpha) >> 16; + } +} + +static inline void mult_complex_vector_real_scalar(const c16_t *x, const int16_t alpha, c16_t *y, const uint32_t N) +{ + simd_q15_t alpha_128, *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y; + + alpha_128 = set1_int16(alpha); + const uint32_t num_simd_adds = N / 4; + const uint32_t num_adds = N % 4; + for (uint32_t n = 0; n < num_simd_adds; n++) { + y_128[n] = mulhi_int16(x_128[n], alpha_128); + } + for (uint32_t n = 0; n < num_adds; n++) { + const uint32_t offset = num_simd_adds * 4; + y[offset + n].r = (x[offset + n].r * alpha) >> 16; + y[offset + n].i = (x[offset + n].i * alpha) >> 16; + } +} /*!\fn void init_fft(uint16_t size,uint8_t logsize,uint16_t *rev) \brief Initialize the FFT engine for a given size @@ -448,7 +471,6 @@ void multadd_complex_vector_real_scalar(int16_t *x, @param rev Pointer to bit-reversal permutation array */ -//cmult_vv.c /*! Multiply elementwise the complex conjugate of x1 with x2. @param x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| @@ -456,17 +478,19 @@ void multadd_complex_vector_real_scalar(int16_t *x, @param x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| We assume x2 with a dinamic of 14 bit maximum @param y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| - @param N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; + @param N - the size f the vectors (this function does N cpx mpy. WARNING: N%4==0; @param output_shift - shift to be applied to generate output - @param madd - if not zero result is added to output */ +static inline void mult_cpx_conj_vector(const c16_t *x1, const c16_t *x2, c16_t *y, const uint32_t N, int const output_shift) +{ + const simde__m128i *x1_128 = (simde__m128i *)x1; + const simde__m128i *x2_128 = (simde__m128i *)x2; + simde__m128i *y_128 = (simde__m128i *)y; -int mult_cpx_conj_vector(int16_t *x1, - int16_t *x2, - int16_t *y, - uint32_t N, - int output_shift, - int madd); + // SSE compute 4 cpx multiply for each loop + for (uint32_t i = 0; i < (N >> 2); i++) + y_128[i] = oai_mm_cpx_mult_conj(x1_128[i], x2_128[i], output_shift); +} /*! Element-wise multiplication and accumulation of two complex vectors x1 and x2. @@ -479,19 +503,34 @@ int mult_cpx_conj_vector(int16_t *x1, @param N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; @param output_shift - shift to be applied to generate output */ +static inline void mult_cpx_vector(const c16_t *x1, // Q15 + const c16_t *x2, // Q13 + c16_t *y, + const uint32_t N, + const int output_shift) +{ + const simde__m128i *x1_128 = (simde__m128i *)x1; + const simde__m128i *x2_128 = (simde__m128i *)x2; + simde__m128i *y_128 = (simde__m128i *)y; -int multadd_cpx_vector(int16_t *x1, - int16_t *x2, - int16_t *y, - uint8_t zero_flag, - uint32_t N, - int output_shift); + // right shift by 13 while p_a * x0 and 15 while + // SSE compute 4 cpx multiply for each loop + for (uint32_t i = 0; i < (N >> 2); i++) { + y_128[i] = oai_mm_cpx_mult(x1_128[i], x2_128[i], output_shift); + } +} -int mult_cpx_vector(int16_t *x1, - int16_t *x2, - int16_t *y, - uint32_t N, - int output_shift); +static inline void multadd_cpx_vector(const c16_t *x1, const c16_t *x2, c16_t *y, const uint32_t N, const int output_shift) +{ + const simde__m128i *x1_128 = (simde__m128i *)x1; + const simde__m128i *x2_128 = (simde__m128i *)x2; + simde__m128i *y_128 = (simde__m128i *)y; + // SSE compute 4 cpx multiply for each loop + for (uint32_t i = 0; i < (N >> 2); i++) { + simde__m128i result = oai_mm_cpx_mult(x1_128[i], x2_128[i], output_shift); + y_128[i] = simde_mm_adds_epi16(y_128[i], result); + } +} // lte_dfts.c void init_fft(uint16_t size, @@ -698,28 +737,138 @@ This function performs componentwise multiplication of a vector with a complex s The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$ */ -void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, uint32_t N, uint16_t output_shift); +static inline void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, uint32_t N, uint16_t output_shift) +{ + // multiply a complex vector with a complex value (alpha) + // stores result in y + // N is the number of complex numbers + // output_shift reduces the result of the multiplication by this number of bits +#if defined(__x86_64__) || defined(__i386__) + if (__builtin_cpu_supports("avx2")) { + // output is 32 bytes aligned, but not the input -//cadd_sv.c + const c16_t for_re = {alpha->r, (int16_t)-alpha->i}; + const simde__m256i alpha_for_real = simde_mm256_set1_epi32(*(uint32_t *)&for_re); + const c16_t for_im = {alpha->i, alpha->r}; + const simde__m256i alpha_for_im = simde_mm256_set1_epi32(*(uint32_t *)&for_im); + const simde__m256i perm_mask = simde_mm256_set_epi8(31, + 30, + 23, + 22, + 29, + 28, + 21, + 20, + 27, + 26, + 19, + 18, + 25, + 24, + 17, + 16, + 15, + 14, + 7, + 6, + 13, + 12, + 5, + 4, + 11, + 10, + 3, + 2, + 9, + 8, + 1, + 0); + simde__m256i *xd = (simde__m256i *)x; + const simde__m256i *end = xd + N / 8; + for (simde__m256i *yd = (simde__m256i *)y; xd < end; yd++, xd++) { + const simde__m256i y256 = simde_mm256_lddqu_si256(xd); + const simde__m256i xre = simde_mm256_srai_epi32(simde_mm256_madd_epi16(y256, alpha_for_real), output_shift); + const simde__m256i xim = simde_mm256_srai_epi32(simde_mm256_madd_epi16(y256, alpha_for_im), output_shift); + // a bit faster than unpacklo+unpackhi+packs + const simde__m256i tmp = simde_mm256_packs_epi32(xre, xim); + simde_mm256_storeu_si256(yd, simde_mm256_shuffle_epi8(tmp, perm_mask)); + } + c16_t *alpha16 = (c16_t *)alpha, *yLast; + yLast = ((c16_t *)y) + (N / 8) * 8; + for (c16_t *xTail = (c16_t *)end; xTail < ((c16_t *)x) + N; xTail++, yLast++) { + *yLast = c16mulShift(*xTail, *alpha16, output_shift); + } + } else { +#endif + // Multiply elementwise two complex vectors of N elements + // x - input 1 in the format |Re0 Im0 |,......,|Re(N-1) Im(N-1)| + // We assume x1 with a dynamic of 15 bit maximum + // + // alpha - input 2 in the format |Re0 Im0| + // We assume x2 with a dynamic of 15 bit maximum + // + // y - output in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)| + // + // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; + // + // log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0) + // WARNING: log2_amp>0 can cause overflow!! -/*!\fn int32_t add_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N) -This function performs componentwise addition of a vector with a complex scalar. + uint32_t i; // loop counter + + simd_q15_t *y_128, alpha_128; + int32_t *xd = (int32_t *)x; + + simde__m128i shift = simde_mm_cvtsi32_si128(output_shift); + + ((int16_t *)&alpha_128)[0] = alpha->r; + ((int16_t *)&alpha_128)[1] = -alpha->i; + ((int16_t *)&alpha_128)[2] = alpha->i; + ((int16_t *)&alpha_128)[3] = alpha->r; + ((int16_t *)&alpha_128)[4] = alpha->r; + ((int16_t *)&alpha_128)[5] = -alpha->i; + ((int16_t *)&alpha_128)[6] = alpha->i; + ((int16_t *)&alpha_128)[7] = alpha->r; + y_128 = (simd_q15_t *)y; + + for (i = 0; i < N >> 2; i++) { + y_128[i] = simde_mm_packs_epi32( // pack in 16bit integers with saturation [re im re im re im re im] + simde_mm_sra_epi32( // shift right by shift in order to compensate for the input amplitude + simde_mm_madd_epi16( // complex multiply. result is 32bit [Re Im Re Im] + simde_mm_setr_epi32(xd[0 + i * 4], xd[0 + i * 4], xd[1 + i * 4], xd[1 + i * 4]), + alpha_128), + shift), + simde_mm_sra_epi32( // shift right by shift in order to compensate for the input amplitude + simde_mm_madd_epi16( // complex multiply. result is 32bit [Re Im Re Im] + simde_mm_setr_epi32(xd[2 + i * 4], xd[2 + i * 4], xd[3 + i * 4], xd[3 + i * 4]), + alpha_128), + shift)); + // print_ints("y_128[0]=", &y_128[0]); + } +#if defined(__x86__) || defined(__x86_64__) + } +#endif +} + +/*!\fn int32_t sub_cpx_vector16(c16_t *x,c16_t *y, c16_t z, uint32_t N) +This function performs componentwise subsctraction of complex vectors @param x Vector input (Q1.15) in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| -@param alpha Scalar input (Q1.15) in the format |Re0 Im0| @param y Output (Q1.15) in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| @param N Length of x WARNING: N>=4 The function implemented is : \f$\mathbf{y} = \alpha + \mathbf{x}\f$ */ -int32_t add_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N); -int32_t sub_cpx_vector16(int16_t *x, - int16_t *y, - int16_t *z, - uint32_t N); +static inline int32_t sub_cpx_vector16(const c16_t *x, const c16_t *y, c16_t *z, uint32_t N) +{ + simde__m128i *x_128 = (simde__m128i *)x; + simde__m128i *y_128 = (simde__m128i *)y; + simde__m128i *z_128 = (simde__m128i *)z; + + for (uint32_t i = 0; i < (N >> 3); i++) + z_128[i] = simde_mm_subs_epi16(x_128[i], y_128[i]); + return (0); +} /*!\fn int32_t signal_energy(int *,uint32_t); \brief Computes the signal energy per subcarrier @@ -754,31 +903,12 @@ uint32_t angle(struct complex16 perrror); /// computes the number of factors 2 in x unsigned char factor2(unsigned int x); -/*!\fn int32_t phy_phase_compensation_top (uint32_t pilot_type, uint32_t initial_pilot, - uint32_t last_pilot, int32_t ignore_prefix); -Compensate the phase rotation of the RF. WARNING: This function is currently unused. It has not been tested! -@param pilot_type indicates whether it is a CHBCH (=0) or a SCH (=1) pilot -@param initial_pilot index of the first pilot (which serves as reference) -@param last_pilot index of the last pilot in the range of pilots to correct the phase -@param ignore_prefix set to 1 if cyclic prefix has not been removed (by the hardware) - -*/ - - int8_t dB_fixed(uint32_t x); - uint8_t dB_fixed64(uint64_t x); - int8_t dB_fixed2(uint32_t x,uint32_t y); - int16_t dB_fixed_times10(uint32_t x); int16_t dB_fixed_x10(uint32_t x); -int32_t phy_phase_compensation_top(uint32_t pilot_type, - uint32_t initial_pilot, - uint32_t last_pilot, - int32_t ignore_prefix); - c32_t dot_product(const c16_t *x, const c16_t *y, const uint32_t N, // must be a multiple of 8 @@ -786,11 +916,8 @@ c32_t dot_product(const c16_t *x, /** @} */ - -double interp(double x, double *xs, double *ys, int count); - -void simde_mm128_separate_real_imag_parts(simde__m128i *out_re, simde__m128i *out_im, simde__m128i in0, simde__m128i in1); -void simde_mm256_separate_real_imag_parts(simde__m256i *out_re, simde__m256i *out_im, simde__m256i in0, simde__m256i in1); +void oai_mm_separate_real_imag_parts(simde__m128i *out_re, simde__m128i *out_im, simde__m128i in0, simde__m128i in1); +void oai_mm256_separate_real_imag_parts(simde__m256i *out_re, simde__m256i *out_im, simde__m256i in0, simde__m256i in1); void InitSinLUT(void); diff --git a/openair1/PHY/phy_extern.h b/openair1/PHY/phy_extern.h index f1e4bb5bcd..f982daa584 100644 --- a/openair1/PHY/phy_extern.h +++ b/openair1/PHY/phy_extern.h @@ -29,9 +29,6 @@ extern int number_of_cards; -static const short conjugate[8] __attribute__((aligned(16))) = {-1, 1, -1, 1, -1, 1, -1, 1}; -static const short conjugate2[8] __attribute__((aligned(16))) = {1, -1, 1, -1, 1, -1, 1, -1}; - static const short primary_synch0[144] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767, 0, -26120, -19785, 11971, -30502, -24020, -22288, 32117, 6492, 31311, 9658, -16384, -28378, 25100, -21063, -7292, -31946, 20429, 25618, 14948, 29158, diff --git a/openair1/PHY/sse_intrin.h b/openair1/PHY/sse_intrin.h index 25337d557a..e39f141c3f 100644 --- a/openair1/PHY/sse_intrin.h +++ b/openair1/PHY/sse_intrin.h @@ -30,7 +30,7 @@ * Has been changed in August 2022 to rely on SIMD Everywhere (SIMDE) from MIT * by bruno.mongazon-cazavet@nokia-bell-labs.com * - * All AVX22 code is mapped to SIMDE which transparently relies on AVX2 HW (avx2-capable host) or SIMDE emulation + * All AVX2 code is mapped to SIMDE which transparently relies on AVX2 HW (avx2-capable host) or SIMDE emulation * (non-avx2-capable host). * To force using SIMDE emulation on avx2-capable host use the --noavx2 flag. * avx512 code is not mapped to SIMDE. It depends on --noavx512 flag. @@ -48,60 +48,55 @@ #ifndef SSE_INTRIN_H #define SSE_INTRIN_H - +#include #include #include -#if defined(__x86_64) || defined(__i386__) - -/* x86 processors */ #if defined(__AVX512BW__) || defined(__AVX512F__) #include +// a solution should be found to use simde package for also AVX512, but it is C++ implementation, difficult to use in OAI +typedef struct { + union { + __m512i v; + int16_t i16[32]; + int8_t i8[64]; + }; +} oai512_t; #endif -#elif defined(__arm__) || defined(__aarch64__) +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__arm__) || defined(__aarch64__) /* ARM processors */ // note this fails on some x86 machines, with an error like: // /usr/lib/gcc/x86_64-redhat-linux/8/include/gfniintrin.h:57:1: error: inlining failed in call to always_inline ‘_mm_gf2p8affine_epi64_epi8’: target specific option mismatch #include #endif // x86_64 || i386 + #include #include "assertions.h" /* - * OAI specific + * OAI specific SSE section */ -static const short minusConjug128[8] __attribute__((aligned(16))) = {-1, 1, -1, 1, -1, 1, -1, 1}; -static inline simde__m128i mulByConjugate128(simde__m128i *a, simde__m128i *b, int8_t output_shift) -{ - simde__m128i realPart = simde_mm_madd_epi16(*a, *b); - realPart = simde_mm_srai_epi32(realPart, output_shift); - simde__m128i imagPart = simde_mm_shufflelo_epi16(*b, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - imagPart = simde_mm_shufflehi_epi16(imagPart, SIMDE_MM_SHUFFLE(2, 3, 0, 1)); - imagPart = simde_mm_sign_epi16(imagPart, *(simde__m128i *)minusConjug128); - imagPart = simde_mm_madd_epi16(imagPart, *a); - imagPart = simde_mm_srai_epi32(imagPart, output_shift); - simde__m128i lowPart = simde_mm_unpacklo_epi32(realPart, imagPart); - simde__m128i highPart = simde_mm_unpackhi_epi32(realPart, imagPart); - return (simde_mm_packs_epi32(lowPart, highPart)); -} - -#define displaySamples128(vect) \ - { \ - simde__m128i x = vect; \ - printf("vector: %s = (%hd,%hd) (%hd,%hd) (%hd,%hd) (%hd,%hd)\n", \ - #vect, \ - simde_mm_extract_epi16(x, 0), \ - simde_mm_extract_epi16(x, 1), \ - simde_mm_extract_epi16(x, 2), \ - simde_mm_extract_epi16(x, 3), \ - simde_mm_extract_epi16(x, 4), \ - simde_mm_extract_epi16(x, 5), \ - simde_mm_extract_epi16(x, 6), \ - simde_mm_extract_epi16(x, 7)); \ - } +typedef struct { + union { + simde__m128i v; + int16_t i16[8]; + int8_t i8[16]; + }; +} oai128_t; +typedef struct { + union { + simde__m256i v; + int16_t i16[16]; + int8_t i8[32]; + }; +} oai256_t; __attribute__((always_inline)) static inline int64_t simde_mm_average_sse(simde__m128i *a, int length, int shift) { @@ -170,4 +165,196 @@ __attribute__((always_inline)) static inline int32_t simde_mm_average(simde__m12 return (uint32_t)(avg / scale); } +/** + * Perform element-wise conjugation on a 128-bit SIMD vector of 16-bit integers. + * + * The flips the sign of imaginary part of each complex element in the vector: + * Input: [r0, i0, ..., r3, i3] + * Output: [r0, -i0, ..., r3, -i3] + * + * @param 128-bit SIMD vector of 4x complex 16-bit integers. + * @return Complex conjugated 128-bit SIMD vector. + */ +__attribute__((always_inline)) static inline simde__m128i oai_mm_conj(simde__m128i a) +{ + const oai128_t neg_imag = {.i16 = {1, -1, 1, -1, 1, -1, 1, -1}}; + return simde_mm_sign_epi16(a, neg_imag.v); +} + +/** + * Perform element-wise IQ swap on a 128-bit SIMD vector of 16-bit integers. + * + * The swap imag and real part of each complex element in the vector: + * Input: [r0, i0, ..., r3, i3] + * Output: [i0, r0, ..., i3, r3] + * + * @param 128-bit SIMD vector of 16-bit integers. + * @return Swaped 128-bit SIMD vector. + */ +__attribute__((always_inline)) static inline +simde__m128i oai_mm_swap(simde__m128i a) +{ + // Shuffle mask to swap bytes for IQ swapping + const oai128_t shuffle_mask_swap = {.i8 = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13}}; + return simde_mm_shuffle_epi8(a, shuffle_mask_swap.v); +} + +__attribute__((always_inline)) static inline +simde__m128i oai_mm_smadd(simde__m128i z1, simde__m128i z2, int shift) +{ + return simde_mm_srai_epi32(simde_mm_madd_epi16(z1, z2), shift); +} + +__attribute__((always_inline)) static inline +simde__m128i oai_mm_pack(simde__m128i a, simde__m128i b) +{ + return simde_mm_packs_epi32( + simde_mm_unpacklo_epi32(a, b), // real + simde_mm_unpackhi_epi32(a, b) // imag + ); +} + +/** + * Perform a COMPLEX MULTIPLICATION on a 128-bit SIMD vector of complex 16-bit integers. + * + * Input: z1 = (a + bi) [ a0, b0, ..., a3, b3] + * Input: z2 = (c + di) [ c0, d0, ..., c3, d3] + * Output: z3 = (e + fi) [ e0, f0, ..., e3, f3] + * + * conj(z1) [ a0, -b0, ..., a3, -b3] + * swap(z1) [ b0, a0, ..., b3, a3] + * + * z3 = z1 * z2 = + (ac-bd) + (ad+bc)i + * + * @param 128-bit SIMD vector of four complex 16-bit integers. + * @return a 128-bit SIMD vector. + */ +__attribute__((always_inline)) static inline +simde__m128i oai_mm_cpx_mult(simde__m128i z1, simde__m128i z2, int shift) +{ + simde__m128i re = oai_mm_smadd(oai_mm_conj(z1), z2, shift); + simde__m128i im = oai_mm_smadd(oai_mm_swap(z1), z2, shift); + return oai_mm_pack(re, im); +} + +/** + * Perform a CONJUGATE multiplication on a 128-bit SIMD vector of 16-bit integers. + * + * Input: z1 = (a + bi) [ a0, b0, ..., a3, b3] + * Input: z2 = (c + di) [ c0, d0, ..., c3, d3] + * Output: z3 = (e + fi) [ e0, f0, ..., e3, f3] + * z3 = z1 * conj(z2) = + (ac+bd) + i(bc-ad) + * + * @param 128-bit SIMD vector of four complex 16-bit integers. + * @return a 128-bit SIMD vector. + */ +__attribute__((always_inline)) static inline +simde__m128i oai_mm_cpx_mult_conj(simde__m128i a, simde__m128i b, int shift) +{ + simde__m128i re = oai_mm_smadd(a, b, shift); + simde__m128i im = oai_mm_smadd(oai_mm_swap(oai_mm_conj(a)), b, shift); + return oai_mm_pack(re, im); +} + +/* + * OAI specific AVX2 section + */ + +/** + * Perform element-wise conjugation on a 256-bit SIMD vector of 16-bit integers. + * + * The flips the sign of imaginary part of each complex element in the vector: + * Input: [r0, i0, ..., r7, i7] + * Output: [r0, -i0, ..., r7, -i7] + * + * @param 256-bit SIMD vector of 8x complex 16-bit integers. + * @return Complex conjugated 256-bit SIMD vector. + */ +__attribute__((always_inline)) static inline simde__m256i oai_mm256_conj(simde__m256i a) +{ + const oai256_t neg_imag = {.i16 = {1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1}}; + return simde_mm256_sign_epi16(a, neg_imag.v); +} + +/** + * Perform element-wise IQ swap on a 256-bit SIMD vector of 16-bit integers. + * + * This swaps the real and imaginary parts of each complex element in the vector: + * Input: [r0, i0, ..., r7, i7] + * Output: [i0, r0, ..., i7, r7] + * + * @param 256-bit SIMD vector of 16-bit integers. + * @return Swapped 256-bit SIMD vector. + */ +__attribute__((always_inline)) static inline simde__m256i oai_mm256_swap(simde__m256i a) +{ + // Shuffle mask to swap bytes for IQ swapping + const oai256_t shuffle_mask_swap = {.i8 = { + 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13, // Low bytes + 18, 19, 16, 17, 22, 23, 20, 21, 26, 27, 24, 25, 30, 31, 28, 29 // High bytes + }}; + return simde_mm256_shuffle_epi8(a, shuffle_mask_swap.v); +} + +__attribute__((always_inline)) static inline +simde__m256i oai_mm256_smadd(simde__m256i z1, simde__m256i z2, int shift) +{ + return simde_mm256_srai_epi32(simde_mm256_madd_epi16(z1, z2), shift); +} + +__attribute__((always_inline)) static inline +simde__m256i oai_mm256_pack(simde__m256i a, simde__m256i b) +{ + return simde_mm256_packs_epi32( + simde_mm256_unpacklo_epi32(a, b), // real + simde_mm256_unpackhi_epi32(a, b) // imag + ); +} + +/** + * Perform a COMPLEX MULTIPLICATION on a 256-bit SIMD vector of complex 16-bit integers. + * + * Input: z1 = (a + bi) [ a0, b0, ..., a7, b7 ] + * Input: z2 = (c + di) [ c0, d0, ..., c7, d7 ] + * Output: z3 = (e + fi) [ e0, f0, ..., e7, f7] + * + * conj(z1) [ a0, -b0, ..., a7, -b7] + * swap(z1) [ b0, a0, ..., b7, a7] + * + * z3 = z1 * z2 = + (ac-bd) + (ad+bc)i + * + * @param 256-bit SIMD vector of eight complex 16-bit integers. + * @return a 256-bit SIMD vector. + */ +__attribute__((always_inline)) static inline +simde__m256i oai_mm256_cpx_mult(simde__m256i z1, simde__m256i z2, int shift) +{ + simde__m256i re = oai_mm256_smadd(oai_mm256_conj(z1), z2, shift); + simde__m256i im = oai_mm256_smadd(oai_mm256_swap(z1), z2, shift); + return oai_mm256_pack(re, im); +} + +/** + * Perform a CONJUGATE multiplication on a 256-bit SIMD vector of complex 16-bit integers. + * + * Input: z1 = (a + bi) [ a0, b0, ..., a3, b3] + * Input: z2 = (c + di) [ c0, d0, ..., c3, d3] + * Output: z3 = (e + fi) [ e0, f0, ..., e3, f3] + * z3 = z1 * conj(z2) = (ac+bd) + i(bc-ad) + * + * @param 256-bit SIMD vector of eight complex 16-bit integers. + * @return a 256-bit SIMD vector. + */ +__attribute__((always_inline)) static inline +simde__m256i oai_mm256_cpx_mult_conj(simde__m256i a, simde__m256i b, int shift) +{ + simde__m256i re = oai_mm256_smadd(a, b, shift); + simde__m256i im = oai_mm256_smadd(oai_mm256_swap(oai_mm256_conj(a)), b, shift); + return oai_mm256_pack(re, im); +} + +#ifdef __cplusplus +} +#endif + #endif // SSE_INTRIN_H diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 5d885cac91..5d6d62c8b9 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -375,7 +375,7 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB, stop_meas(&eNB->dlsch_encoding_stats); if (eNB->dlsch_encoding_stats.p_time > 500 * 3000 && cpu_meas_enabled) { - print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); + print_meas_now(&eNB->dlsch_encoding_stats, "total coding", stdout); } #ifdef PHY_TX_THREAD @@ -1465,7 +1465,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, pdu->rx_indication_rel8.length); // estimate timing advance for MAC - sync_pos = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[ULSCH_id]->drs_ch_estimates_time); + sync_pos = lte_est_timing_advance_pusch(&eNB->frame_parms, (c16_t **)eNB->pusch_vars[ULSCH_id]->drs_ch_estimates_time); timing_advance_update = sync_pos; for (int i=0;iofdm_mod_wait_stats); - wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); + wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); stop_meas(&ru->ofdm_mod_wait_stats); - /*if(cpu_meas_enabled == 1 && ru->ofdm_mod_wait_stats.p_time>30*3000){ - print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr); - printf("delay in feptx wait on condition in frame_rx: %d subframe_rx: %d \n", proc->frame_tx, proc->tti_tx); - }*/ stop_meas(&ru->ofdm_mod_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 ); @@ -574,10 +570,6 @@ static void *fep_thread(void *param) exit_fun( "ERROR pthread_cond_signal" ); return NULL; } - /*if(cpu_meas_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ - print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); - printf("delay in fep wakeup in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); - }*/ } return(NULL); } @@ -696,7 +688,7 @@ void ru_fep_full_2thread(RU_t *ru, wait_on_busy_condition(&proc->mutex_fep[0],&proc->cond_fep[0],&proc->instance_cnt_fep[0],"fep thread"); stop_meas(&ru->ofdm_demod_wait_stats); if (cpu_meas_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time > 30 * 3000) { - print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); + print_meas_now(&ru->ofdm_demod_wakeup_stats, "fep wakeup", stdout); printf("delay in fep wait on condition in frame_rx: %d subframe_rx: %d \n", proc->frame_rx, proc->tti_rx); } @@ -710,55 +702,57 @@ void ru_fep_full_2thread(RU_t *ru, 3%(fp->symbols_per_tti/2),// l = symbol within slot 3/(fp->symbols_per_tti/2),// Ns = slot number fp); - - lte_ul_channel_estimation_RRU(fp, - calibration->drs_ch_estimates, - calibration->drs_ch_estimates_time, - calibration->rxdataF_ext, - fp->N_RB_DL, //N_rb_alloc, + + lte_ul_channel_estimation_RRU(fp, + (c16_t **)calibration->drs_ch_estimates, + (c16_t **)calibration->drs_ch_estimates_time, + (c16_t **)calibration->rxdataF_ext, + fp->N_RB_DL, // N_rb_alloc, proc->frame_rx, - proc->tti_rx,//proc->subframe_rx, - 0,//u = 0..29 - 0,//v = 0,1 - /*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0, - 3,//l, - 0,//interpolate, + proc->tti_rx, // proc->subframe_rx, + 0, // u = 0..29 + 0, // v = 0,1 + /*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/ 0, + 3, // l, + 0, // interpolate, 0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/); - check_sync_pos = lte_est_timing_advance_pusch(ru->frame_parms, ru->calibration.drs_ch_estimates_time); - if (ru->state == RU_CHECK_SYNC) { - if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) { -// LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); - ru->wait_check++; - } - LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); + check_sync_pos = lte_est_timing_advance_pusch(ru->frame_parms, (c16_t **)ru->calibration.drs_ch_estimates_time); + if (ru->state == RU_CHECK_SYNC) { + if ((check_sync_pos >= 0 && check_sync_pos < 8) || (check_sync_pos < 0 && check_sync_pos > -8)) { + // LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); + ru->wait_check++; + } + LOG_I(PHY, "~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n", check_sync_pos, proc->frame_rx, ru->wait_check); - if (ru->wait_check==20) { - ru->state = RU_RUN; - ru->wait_check = 0; - // Send RRU_sync_ok - rru_config_msg.type = RRU_sync_ok; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len - LOG_I(PHY,"Sending RRU_sync_ok to RAU\n"); - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx); -/* - //LOG_I(PHY,"~~~~~~~~~ RU_RUN\n"); - LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1); - LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1); - //LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1); - LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1); - exit(-1);*/ - } - } else if (ru->state == RU_RUN) { - // check for synchronization error - if (check_sync_pos >= 8 || check_sync_pos<=-8) { - LOG_E(PHY,"~~~~~~~~~~~~~~ check_sync_pos %d, frame %d ---> LOST SYNC-EXIT\n", check_sync_pos, proc->frame_rx); + if (ru->wait_check == 20) { + ru->state = RU_RUN; + ru->wait_check = 0; + // Send RRU_sync_ok + rru_config_msg.type = RRU_sync_ok; + rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len + LOG_I(PHY, "Sending RRU_sync_ok to RAU\n"); + AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice, &rru_config_msg, rru_config_msg.len) != -1), + "Failed to send msg to RAU %d\n", + ru->idx); + /* + //LOG_I(PHY,"~~~~~~~~~ RU_RUN\n"); + LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1); + LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1); + //LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1); LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1); - exit(-1); - } - } else { - AssertFatal(1==0,"Should not get here\n"); - } + exit(-1);*/ + } + } else if (ru->state == RU_RUN) { + // check for synchronization error + if (check_sync_pos >= 8 || check_sync_pos <= -8) { + LOG_E(PHY, "~~~~~~~~~~~~~~ check_sync_pos %d, frame %d ---> LOST SYNC-EXIT\n", check_sync_pos, proc->frame_rx); + LOG_M("rxdata.m", "rxdata", &ru->common.rxdata[0][0], fp->samples_per_tti * 2, 1, 1); + exit(-1); + } + } else { + AssertFatal(1 == 0, "Should not get here\n"); + } } stop_meas(&ru->ofdm_demod_stats); diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 32e248d52b..0b336fdce6 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -1360,9 +1360,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue, ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag); if (ue->mac_enabled == 1) { - if ((ue->ulsch_Msg3_active[eNB_id] == 1) && - (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) && - (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3 + if ((ue->ulsch_Msg3_active[eNB_id] == 1) && (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) + && (ue->ulsch_Msg3_subframe[eNB_id] == (subframe_tx % 1024))) { // Initial Transmission of Msg3 ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index a8f97a2f00..36fe9daa50 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -64,8 +64,6 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4]; double cpuf; uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; -const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; -const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; // needed for some functions PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } }; uint16_t n_rnti = 0x1234; diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 701023a756..96840c27b2 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -60,8 +60,6 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4]; double cpuf; uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; -const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; -const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; // needed for some functions PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = {{NULL}}; static softmodem_params_t softmodem_params; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 76ab8f1871..f68f6885a6 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -68,8 +68,6 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); } nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; } uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; -const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; -const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; double cpuf; // needed for some functions