simplifly, reegroup functions in tools_defs.h

This commit is contained in:
Laurent THOMAS
2025-04-25 14:47:59 +02:00
parent 04fc2fbb2e
commit 95ae7772bf
20 changed files with 452 additions and 663 deletions
-6
View File
@@ -814,8 +814,6 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/INIT/lte_parms.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
@@ -947,8 +945,6 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.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
@@ -998,8 +994,6 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.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
-2
View File
@@ -2241,8 +2241,6 @@ 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 \
@@ -188,9 +188,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 << 1),
phy_vars_ue->ch_est_alpha,
dl_bf_ch - (frame_parms->ofdm_symbol_size << 1),
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
}
@@ -659,8 +660,9 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
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 << 1),
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) {
@@ -673,17 +675,41 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
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 + (2 * (frame_parms->ofdm_symbol_size)),
frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch,
6554,
dl_bf_ch_prev + (2 * (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 * 2 * (frame_parms->ofdm_symbol_size)),
frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch,
13107,
dl_bf_ch - (3 * 2 * (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) << 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)),
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 - (2 * (frame_parms->ofdm_symbol_size)),
frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch,
26214,
dl_bf_ch - (2 * (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)];
#ifdef DEBUG_BF_CH
@@ -691,11 +717,23 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
#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 + (2 * (frame_parms->ofdm_symbol_size)),
frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch,
10923,
dl_bf_ch_prev + (2 * (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) << 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)),
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)];
@@ -703,21 +741,45 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
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 + (2 * (frame_parms->ofdm_symbol_size)),
frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch,
10923,
dl_bf_ch_prev + (2 * (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) << 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)),
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)];
// 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 + (2 * (frame_parms->ofdm_symbol_size)),
frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch,
10923,
dl_bf_ch_prev + (2 * (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) << 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)),
frame_parms->ofdm_symbol_size);
}
} else {
@@ -184,9 +184,10 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
memset(dl_ch,0,4*(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 << 1),
ue->ch_est_alpha,
dl_ch - (ue->frame_parms.ofdm_symbol_size << 1),
ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
@@ -545,27 +546,25 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
} 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];
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 << 1), 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);
dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p << 1) + aarx][pilot3 * (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);
mult_complex_vector_real_scalar(dl_ch_prev, 10923, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
}
interpolateS11S12 = 1;
@@ -583,60 +582,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 + (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, 328, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 32440, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 8192, dl_ch_prev + (3 * 2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 32440, dl_ch_prev + (3 * 2 * (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 + (2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 8192, dl_ch_prev + (2 * (symb_sz)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 16384, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 16384, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 8192, dl_ch_prev + (3 * 2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 24576, dl_ch_prev + (3 * 2 * (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 + (2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + (2 * (symb_sz)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 21845, dl_ch_prev + (2 * (symb_sz) << 1), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 10923, dl_ch_prev + (2 * ((symb_sz) << 1)), 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);
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot1 * (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);
mult_complex_vector_real_scalar(dl_ch_prev, 10923, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + (2 * ((symb_sz) << 1)), 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)];
dl_ch_prev = (int16_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 + (2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 8192, dl_ch_prev + (2 * (symb_sz)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 16384, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 16384, dl_ch_prev + (2 * ((symb_sz) << 1)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 8192, dl_ch_prev + (3 * 2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 24576, dl_ch_prev + (3 * 2 * (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 + (2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + (2 * (symb_sz)), symb_sz);
mult_complex_vector_real_scalar(dl_ch_prev, 21845, dl_ch_prev + (2 * (symb_sz) << 1), symb_sz);
multadd_complex_vector_real_scalar(dl_ch, 10923, dl_ch_prev + (2 * ((symb_sz) << 1)), 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 +643,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;
@@ -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);
ch_prev = (short *)&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 + (2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(ch, 8192, ch_prev + (2 * (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 + (4 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(ch, 16384, ch_prev + (4 * (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 + (6 * ((symb_sz))), symb_sz);
multadd_complex_vector_real_scalar(ch, 24576, ch_prev + (6 * ((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)];
ch_prev = (short *)&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 + (2 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(ch, 8192, ch_prev + (2 * (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 + (4 * (symb_sz)), symb_sz);
multadd_complex_vector_real_scalar(ch, 16384, ch_prev + (4 * (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 + (6 * ((symb_sz))), symb_sz);
multadd_complex_vector_real_scalar(ch, 24576, ch_prev + (6 * ((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 = (short *)&dl_ch_estimates[aarx][10 * (symb_sz)];
ch11 = (short *)&dl_ch_estimates[aarx][11 * (symb_sz)];
memcpy(ch11, ch_prev, 4 * symb_sz);
}
}
@@ -272,8 +272,14 @@ int32_t lte_ul_channel_estimation(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);
mult_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],
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],
Msc_RS);
/*
if ((k<pilot_pos1) || ((k>pilot_pos2))) {
@@ -495,8 +501,14 @@ 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);
mult_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],
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],
Msc_RS);
}
} //for(k=...
@@ -579,12 +591,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);
@@ -440,19 +440,8 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
//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((int16_t *)ul_ch128,
(int16_t *)rxdataF128,
(int16_t *)rxdataF_comp128,
12 * nb_rb,
output_shift,
0);
/*
LOG_I(PHY, "Antenna %d:", aarx);
print_shorts("rx:",&rxdataF128[0]);
print_shorts("ch:",&ul_ch128[0]);
print_shorts("pack:",&rxdataF_comp128[0]);
*/
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);
@@ -249,15 +249,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((int16_t *)sic_data,
amp_tmp,
(int16_t *)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((c16_t *)rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0,
len,
13);
@@ -447,15 +446,14 @@ 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((int16_t *)sic_data,
amp_tmp,
(int16_t *)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((c16_t *)rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0,
len,
13);
@@ -679,15 +677,14 @@ 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((int16_t *)sic_data,
amp_tmp,
(int16_t *)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((c16_t *)rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0,
len,
13);
+20 -36
View File
@@ -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<nb_antenna_ports;p++){
if (p<nb_antenna_ports_eNB || p==5){
for (symbol=0; symbol<symbols_per_tti; symbol++){
multadd_cpx_vector((int16_t*)&txdataF[p][symbol*ofdm_symbol_size+re_offset],
(int16_t*)beam_weights[0][p][aa],
(int16_t*)&txdataF_BF[aa][symbol*ofdm_symbol_size],
0,
ofdm_symbol_size,
15);
/*
for (re=0; re<ofdm_symbol_size; re++){
// direct
((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>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);
}
+12 -12
View File
@@ -206,12 +206,12 @@ void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms,
&rot2,
this_symbol + frame_parms->first_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);
}
}
}
+1 -1
View File
@@ -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 */
@@ -372,12 +372,7 @@ static void nr_ulsch_conjch0_mult_ch1(int *ch0,
unsigned char output_shift0)
{
//This function is used to compute multiplications in H_hermitian * H matrix
mult_cpx_conj_vector((int16_t *)ch0,
(int16_t *)ch1,
(int16_t *)ch0conj_ch1,
12 * nb_rb,
output_shift0, 0);
mult_cpx_conj_vector((c16_t *)ch0, (c16_t *)ch1, (c16_t *)ch0conj_ch1, 12 * nb_rb, output_shift0);
}
static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x,
@@ -453,11 +453,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
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++)
+1 -6
View File
@@ -401,12 +401,7 @@ void nr_pdcch_channel_compensation(int32_t rx_size,
//printf("rxdataf_comp addr %p\n",&rxdataF_comp[(aatx<<1)+aarx][symbol*20*12]);
// multiply by conjugated channel
mult_cpx_conj_vector((int16_t *)dl_ch128,
(int16_t *)rxdataF128,
(int16_t *)rxdataF_comp128,
12 * coreset_nbr_rb,
output_shift,
0);
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 < 12 * coreset_nbr_rb; rb++) {
LOG_DDD("rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n",
@@ -942,22 +942,19 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
dl_ch128_2 = (simde__m128i *)dl_ch_estimates_ext[atx * frame_parms->nb_antennas_rx + aarx];
// multiply by conjugated channel
mult_cpx_conj_vector((int16_t *)dl_ch128,
(int16_t *)dl_ch128_2,
(int16_t *)rho128,
12 * nb_rb_0,
output_shift,
0);
mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)dl_ch128_2, (c16_t *)rho128, 12 * nb_rb_0, output_shift);
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]);
}
}
}
}
@@ -1514,11 +1511,7 @@ void nr_conjch0_mult_ch1(int *ch0,
unsigned char output_shift0)
{
//This function is used to compute multiplications in H_hermitian * H matrix
mult_cpx_conj_vector((int16_t *)ch0,
(int16_t *)ch1,
(int16_t *)ch0conj_ch1,
12 * nb_rb,
output_shift0, 0);
mult_cpx_conj_vector((c16_t *)ch0, (c16_t *)ch1, (c16_t *)ch0conj_ch1, 12 * nb_rb, output_shift0);
}
/*
+4 -5
View File
@@ -234,12 +234,11 @@ void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER
uint8_t output_shift)
{
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
mult_cpx_conj_vector((int16_t *)dl_ch_estimates_ext[aarx],
(int16_t *)rxdataF_ext[aarx],
(int16_t *)rxdataF_comp[aarx],
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,
0);
output_shift);
}
}
+1 -1
View File
@@ -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((int16_t *)mod_ptrs, beta_ptrs * AMP, (int16_t *)mod_ptrs_amp, p.nb_rb);
}
map_current_symbol(p,
dmrs_symbol,
-262
View File
@@ -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 <simde/simde-common.h>
#include <simde/x86/sse.h>
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<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);
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<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
}
#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<L<<1; i++)
printf("output[i]=%d\n",input[i]);
}
#endif //MAIN
-131
View File
@@ -1,131 +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"
void 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
simde__m128i *x1_128 = (simde__m128i *)x1;
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_conj(x1_128[i], x2_128[i], output_shift);
if (madd==1)
result = simde_mm_adds_epi16(y_128[i], result);
y_128[i] = result;
}
}
void 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
simde__m128i *x1_128 = (simde__m128i *)x1;
simde__m128i *x2_128 = (simde__m128i *)x2;
simde__m128i *y_128 = (simde__m128i *)y;
//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);
}
}
void 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
simde__m128i *x1_128 = (simde__m128i *)x1;
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);
if (zero_flag == 0)
result = simde_mm_adds_epi16(y_128[i], result);
y_128[i] = result;
}
}
+196 -27
View File
@@ -316,7 +316,24 @@ 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);
static inline void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha, int16_t *y, uint32_t N)
{
// 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 (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);
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)));
}
}
// Same with correct types
static inline void multaddRealVectorComplexScalar(const c16_t *in, const c16_t alpha, c16_t *out, uint32_t N)
@@ -434,11 +451,36 @@ 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(int16_t *x, int16_t alpha, int16_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] += (x[offset + n] * alpha) >> 16;
}
}
static inline void mult_complex_vector_real_scalar(int16_t *x, int16_t alpha, int16_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] = 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] = (x[offset + n] * alpha) >> 16;
}
}
/*!\fn void init_fft(uint16_t size,uint8_t logsize,uint16_t *rev)
\brief Initialize the FFT engine for a given size
@@ -447,7 +489,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)|
@@ -455,17 +496,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, uint32_t N, 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;
void 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.
@@ -478,19 +521,34 @@ void 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,
uint32_t N,
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;
void 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);
}
}
void 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, uint32_t N, 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,
@@ -697,7 +755,118 @@ 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
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!!
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