mod: refactor PHY multiplications

This commit is contained in:
HHI
2025-04-25 14:47:59 +02:00
committed by Laurent THOMAS
parent 4da30019be
commit f470ea5946
29 changed files with 1070 additions and 2407 deletions
+14 -66
View File
@@ -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,26 +127,11 @@ 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_conjb(((simde__m128i *)pss6144_0)[re], s, 15);
autocorr1[re256] = oai_mm_cpx_mult_conjb(((simde__m128i *)pss6144_1)[re], s, 15);
autocorr2[re256] = oai_mm_cpx_mult_conjb(((simde__m128i *)pss6144_2)[re], s, 15);
re256 = (re256+1)&0x3f;
}
} else { // Split around DC, this is the negative frequencies
@@ -188,29 +171,11 @@ 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_conjb(((simde__m128i *)pss6144_0)[re], s, 15);
autocorr1[re256] = oai_mm_cpx_mult_conjb(((simde__m128i *)pss6144_1)[re], s, 15);
autocorr2[re256] = oai_mm_cpx_mult_conjb(((simde__m128i *)pss6144_2)[re], s, 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_conjb(((simde__m128i *)pss6144_0)[re], s, 15);
autocorr1[re256] = oai_mm_cpx_mult_conjb(((simde__m128i *)pss6144_1)[re], s, 15);
autocorr2[re256] = oai_mm_cpx_mult_conjb(((simde__m128i *)pss6144_2)[re], s, 15);
re256 = (re256+1)&0x3f;
}
@@ -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_conja(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);
@@ -101,7 +101,6 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
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};
simde__m128i *rxdataF128, *ul_ref128, *ul_ch128;
simde__m128i mmtmpU0, mmtmpU1, mmtmpU2, mmtmpU3;
int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32)));
if (ulsch->ue_type > 0) harq_pid = 0;
@@ -142,49 +141,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_conja(ul_ref128[i], rxdataF128[i], 15);
}
alpha_ind = 0;
@@ -304,12 +262,12 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
// 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]);
// rotate channel estimates by estimated phase
rotate_cpx_vector((c16_t *) ul_ch1,
(c16_t *)&ru1[2*current_phase1],
(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 *) &ru2[2*current_phase2],
(c16_t *) tmp_estimates,
Msc_RS,
15);
@@ -379,7 +337,6 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
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};
simde__m128i *rxdataF128, *ul_ref128, *ul_ch128;
simde__m128i mmtmpU0, mmtmpU1, mmtmpU2, mmtmpU3;
int32_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);
@@ -412,49 +369,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_conja(ul_ref128[i], rxdataF128[i], 15);
}
alpha_ind = 0;
@@ -579,8 +495,8 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
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);
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);
}
} //for(k=...
@@ -687,7 +603,6 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_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 +615,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 +623,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; rb<nb_rb; rb++) {
for (int rb=0; rb<nb_rb; rb++) {
avg128U1 = simde_mm_add_ps(avg128U1, simde_mm_cvtepi32_ps(simde_mm_madd_epi16(ul_ch1[0], ul_ch1[0])));
avg128U1 = simde_mm_add_ps(avg128U1, simde_mm_cvtepi32_ps(simde_mm_madd_epi16(ul_ch1[1], ul_ch1[1])));
avg128U1 = simde_mm_add_ps(avg128U1, simde_mm_cvtepi32_ps(simde_mm_madd_epi16(ul_ch1[2], ul_ch1[2])));
@@ -721,7 +635,8 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t *
ul_ch1+=3;
ul_ch2+=3;
}
// Horizontal add
avg[0] = (int)( (((float*)&avg128U1)[0] +
((float*)&avg128U1)[1] +
((float*)&avg128U1)[2] +
@@ -742,37 +657,13 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t *
ul_ch2 = (simde__m128i *)&ul_ch_estimates[pilot_pos2 * frame_parms->N_RB_UL * 12];
// correlate and average the 2 channel estimates ul_ch1*ul_ch2
for (rb=0; rb<nb_rb; rb++) {
mmtmpD0 = simde_mm_madd_epi16(ul_ch1[0], ul_ch2[0]);
mmtmpD1 = simde_mm_shufflelo_epi16(ul_ch1[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);
mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, ul_ch2[0]);
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);
R[0] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3);
mmtmpD0 = simde_mm_madd_epi16(ul_ch1[1], ul_ch2[1]);
mmtmpD1 = simde_mm_shufflelo_epi16(ul_ch1[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, ul_ch2[1]);
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);
R[1] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3);
mmtmpD0 = simde_mm_madd_epi16(ul_ch1[2], ul_ch2[2]);
mmtmpD1 = simde_mm_shufflelo_epi16(ul_ch1[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, ul_ch2[2]);
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);
R[2] = simde_mm_packs_epi32(mmtmpD2, mmtmpD3);
for (int rb=0; rb<nb_rb; rb++) {
simde__m128i R[3];
R[0] = oai_mm_cpx_mult_conja(ul_ch1[0], ul_ch2[0], output_shift);
R[1] = oai_mm_cpx_mult_conja(ul_ch1[1], ul_ch2[1], output_shift);
R[2] = oai_mm_cpx_mult_conja(ul_ch1[2], ul_ch2[2], output_shift);
// Horizontal add
R[0] = simde_mm_add_epi16(simde_mm_srai_epi16(R[0], 1), simde_mm_srai_epi16(R[1], 1));
R[0] = simde_mm_add_epi16(simde_mm_srai_epi16(R[0], 1), simde_mm_srai_epi16(R[2], 1));
Ravg[0] += (((short *)&R)[0] +
@@ -805,7 +696,7 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t *
// msg("rv = %d, iv = %d\n",rv,iv);
// msg("max_avg = %d, log2_approx = %d, shift = %d\n",avg[0], avg[1], output_shift);
for (k=0; k<6; k++) {
for (int k=0; k<6; k++) {
(iv<(((int32_t)(alpha[a_idx]*rv))>>15)) ? (a_idx -= 32>>k) : (a_idx += 32>>k);
}