set correct parameter type, and fuse funcions that do same real/complex vector operations, doing this, fix a lot of unitary multiplications (else there would be numerous cast operations

This commit is contained in:
Laurent THOMAS
2025-04-25 14:47:59 +02:00
parent 95ae7772bf
commit 7982a9da41
21 changed files with 766 additions and 1465 deletions
@@ -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)
@@ -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; aarx<frame_parms->nb_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,9 @@ 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){
mult_complex_vector_real_scalar(dl_bf_ch - (frame_parms->ofdm_symbol_size << 1),
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 << 1),
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
@@ -214,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);
@@ -243,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; rb<frame_parms->N_RB_DL>>1; rb++) {
@@ -320,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");
@@ -395,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)
@@ -440,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 (; rb<frame_parms->N_RB_DL; rb++) {
@@ -567,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");
@@ -645,15 +494,14 @@ 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
@@ -661,7 +509,7 @@ 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),
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
@@ -670,48 +518,48 @@ 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)
mult_complex_vector_real_scalar(dl_bf_ch_prev,
26214,
dl_bf_ch_prev + (2 * (frame_parms->ofdm_symbol_size)),
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 + (2 * (frame_parms->ofdm_symbol_size)),
dl_bf_ch_prev + frame_parms->ofdm_symbol_size,
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)),
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 * 2 * (frame_parms->ofdm_symbol_size)),
dl_bf_ch - 3 * frame_parms->ofdm_symbol_size,
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)),
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) << 1)),
dl_bf_ch - 2 * frame_parms->ofdm_symbol_size,
frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev,
6554,
dl_bf_ch - (2 * (frame_parms->ofdm_symbol_size)),
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 - (2 * (frame_parms->ofdm_symbol_size)),
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
@@ -719,66 +567,66 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// pilot spacing 3 symbols (1/3,2/3 combination)
mult_complex_vector_real_scalar(dl_bf_ch_prev,
21845,
dl_bf_ch_prev + (2 * (frame_parms->ofdm_symbol_size)),
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 + (2 * (frame_parms->ofdm_symbol_size)),
dl_bf_ch_prev + frame_parms->ofdm_symbol_size,
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)),
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) << 1)),
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
mult_complex_vector_real_scalar(dl_bf_ch_prev,
21845,
dl_bf_ch_prev + (2 * (frame_parms->ofdm_symbol_size)),
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 + (2 * (frame_parms->ofdm_symbol_size)),
dl_bf_ch_prev + frame_parms->ofdm_symbol_size,
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)),
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) << 1)),
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)
mult_complex_vector_real_scalar(dl_bf_ch_prev,
21845,
dl_bf_ch_prev + (2 * (frame_parms->ofdm_symbol_size)),
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 + (2 * (frame_parms->ofdm_symbol_size)),
dl_bf_ch_prev + frame_parms->ofdm_symbol_size,
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)),
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) << 1)),
dl_bf_ch_prev + 2 * frame_parms->ofdm_symbol_size,
frame_parms->ofdm_symbol_size);
}
@@ -790,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);
}
@@ -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,16 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
p);
for (aarx=0; aarx<ue->frame_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
mult_complex_vector_real_scalar(dl_ch - (ue->frame_parms.ofdm_symbol_size << 1),
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 << 1),
dl_ch - ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH
@@ -196,352 +196,97 @@ 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);
@@ -550,27 +295,27 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
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 - (symb_sz << 1), symb_sz);
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)*(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 * (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);
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)
@@ -582,56 +327,56 @@ 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)) {
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);
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 {
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);
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 {
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);
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 * (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);
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 * (symb_sz)];
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)
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);
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 {
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);
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 * (symb_sz)];
int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot2 * (symb_sz)];
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 * symb_sz];
@@ -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;
@@ -684,37 +684,37 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
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 * (symb_sz)];
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
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);
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
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);
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
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);
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 * (symb_sz)];
c16_t *ch_prev = (c16_t *)&dl_ch_estimates[aarx][6 * symb_sz];
// 3/4 ch6 + 1/4 ch10 => ch7
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);
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
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);
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
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);
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 * (symb_sz)];
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);
}
@@ -764,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];
@@ -801,101 +798,46 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
for (aarx=0; aarx<ue->frame_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_cnt<ue->frame_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_cnt<ue->frame_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);
}
}
+17 -23
View File
@@ -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);
+4 -6
View File
@@ -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; ar<ru->nb_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;
@@ -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,11 +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;
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 {
@@ -109,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 +
@@ -154,16 +151,8 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
#endif
for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
ul_ch_estimates_re = ((int16_t *) ul_ch_estimates[aa])[i<<1];
ul_ch_estimates_im = ((int16_t *) ul_ch_estimates[aa])[(i<<1)+1];
// ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
((int16_t *) ul_ch_estimates[aa])[i<<1] =
(int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>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)
@@ -179,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; i<Msc_RS; i++)
((int32_t *)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i];
temp_in_ifft_0[i] = ul_ch_estimates[aa][symbol_offset + i];
int len;
switch(frame_parms->N_RB_DL) {
case 6:
@@ -254,32 +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
mult_complex_vector_real_scalar((int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k],
mult_complex_vector_real_scalar(&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],
&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);
multadd_complex_vector_real_scalar(tmp_estimates, SCALE, &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS);
/*
if ((k<pilot_pos1) || ((k>pilot_pos2))) {
@@ -314,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,
@@ -325,25 +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;
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;
@@ -388,16 +361,8 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
#endif
for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
ul_ch_estimates_re = ((int16_t *) ul_ch_estimates[aa])[i<<1];
ul_ch_estimates_im = ((int16_t *) ul_ch_estimates[aa])[(i<<1)+1];
// ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
((int16_t *) ul_ch_estimates[aa])[i<<1] =
(int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>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)
@@ -414,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; i<Msc_RS; i++)
((int32_t *)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i];
temp_in_ifft_0[i] = ul_ch_estimates[aa][symbol_offset + i];
int len;
switch(frame_parms->N_RB_DL) {
case 6:
@@ -483,32 +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
mult_complex_vector_real_scalar((int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k],
mult_complex_vector_real_scalar(&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],
&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);
multadd_complex_vector_real_scalar(tmp_estimates, SCALE, &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS);
}
} //for(k=...
@@ -520,16 +473,16 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
for (k=0; k<frame_parms->symbols_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; k<frame_parms->symbols_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,
@@ -612,7 +565,7 @@ 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 a_idx = 64;
uint8_t conj_flag = 0;
+12 -11
View File
@@ -536,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;
@@ -637,11 +638,11 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
// if ((eNB->measurements.n0_power_dB[0]+3)<pusch_vars->ulsch_power[0])
if (23<pusch_vars->ulsch_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);
}
}
@@ -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; symbol<nsymb; symbol++) {
uint16_t *rxF = (uint16_t*)(&rxdataF_comp[0][((int16_t)symbol*frame_parms->N_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,14 +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
mult_complex_vector_real_scalar((int16_t *)sic_data,
mult_complex_vector_real_scalar(sic_data,
amp_tmp,
(int16_t *)rho_amp_x0, // this is in Q13
rho_amp_x0, // this is in Q13
len);
mult_cpx_vector((c16_t *)rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0,
mult_cpx_vector(rho_1, // Q15
rho_amp_x0, // Q13
rho_rho_amp_x0,
len,
13);
@@ -271,10 +269,10 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
#endif
sub_cpx_vector16((c16_t *)rxF,
(c16_t *)rho_rho_amp_x0,
rho_rho_amp_x0,
//(int16_t *)clean_x1,
(c16_t *)rxF,
len*2);
len * 2);
#ifdef DEBUG_LLR_SIC
LOG_M("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1);
@@ -406,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];
@@ -421,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; symbol<nsymb; symbol++) {
uint16_t *rxF = (uint16_t*)(&rxdataF_comp[0][((int16_t)symbol*frame_parms->N_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;
@@ -446,22 +443,22 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
len_acc+=len;
mult_complex_vector_real_scalar((int16_t *)sic_data,
mult_complex_vector_real_scalar(sic_data,
amp_tmp,
(int16_t *)rho_amp_x0, // this is in Q13
rho_amp_x0, // this is in Q13
len);
mult_cpx_vector((c16_t *)rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0,
mult_cpx_vector(rho_1, // Q15
rho_amp_x0, // Q13
rho_rho_amp_x0,
len,
13);
sub_cpx_vector16((c16_t *)rxF,
(c16_t *)rho_rho_amp_x0,
rho_rho_amp_x0,
//(int16_t *)clean_x1,
(c16_t *)rxF,
len*2);
len * 2);
len_mod4 = len&3;
len>>=2; // length in quad words (4 REs)
@@ -635,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;
@@ -651,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; symbol<nsymb; symbol++) {
uint16_t *rxF = (uint16_t*)(&rxdataF_comp[0][((int16_t)symbol*frame_parms->N_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;
@@ -677,22 +673,22 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
len_acc+=len;
mult_complex_vector_real_scalar((int16_t *)sic_data,
mult_complex_vector_real_scalar(sic_data,
amp_tmp,
(int16_t *)rho_amp_x0, // this is in Q13
rho_amp_x0, // this is in Q13
len);
mult_cpx_vector((c16_t *)rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0,
mult_cpx_vector(rho_1, // Q15
rho_amp_x0, // Q13
rho_rho_amp_x0,
len,
13);
sub_cpx_vector16((c16_t *)rxF,
(c16_t *)rho_rho_amp_x0,
//(int16_t *)clean_x1,
(c16_t *)rxF,
len*2);
rho_rho_amp_x0,
//(int16_t *)clean_x1,
(c16_t *)rxF,
len * 2);
llr2 = llr32;
llr32 += (len*6);
+1 -3
View File
@@ -297,9 +297,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) {
exit(-1);
*/
sync_pos = lte_sync_time(ue->common_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)
@@ -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));
@@ -308,14 +308,14 @@ 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)
{
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;
@@ -365,14 +365,10 @@ static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a
*
* */
// TODO: This function is just a wrapper, can be removed.
static void nr_ulsch_conjch0_mult_ch1(int *ch0,
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0)
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
mult_cpx_conj_vector((c16_t *)ch0, (c16_t *)ch1, (c16_t *)ch0conj_ch1, 12 * nb_rb, output_shift0);
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,
@@ -422,26 +418,26 @@ 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)
{
@@ -532,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;
@@ -585,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:
@@ -1031,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)
+12 -16
View File
@@ -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};
@@ -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,7 +410,7 @@ 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
@@ -696,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:
@@ -748,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;
@@ -786,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;
@@ -799,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);
@@ -811,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;
@@ -843,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;
@@ -883,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; aarx<ue->frame_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);
@@ -907,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
+64 -68
View File
@@ -263,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;
@@ -288,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++) {
@@ -315,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;
}
}
}
@@ -341,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,
@@ -356,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++) {
@@ -371,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);
}
}
}
@@ -395,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));
@@ -413,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,
@@ -443,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;
@@ -465,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)));
@@ -575,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'.
@@ -599,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++) {
@@ -614,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) {
@@ -909,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
@@ -1504,14 +1504,10 @@ uint8_t nr_matrix_inverse(int32_t size,
*
* */
// TODO: This function is just a wrapper, can be removed.
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)
{
//This function is used to compute multiplications in H_hermitian * H matrix
mult_cpx_conj_vector((c16_t *)ch0, (c16_t *)ch1, (c16_t *)ch0conj_ch1, 12 * nb_rb, output_shift0);
mult_cpx_conj_vector(ch0, ch1, ch0conj_ch1, 12 * nb_rb, output_shift0);
}
/*
@@ -1548,11 +1544,11 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
for (int rtx = 0; rtx < nl; rtx++) {//row
for (int ctx = 0; ctx < nl; ctx++) {//column
for (int aarx = 0; aarx < n_rx; aarx++) {
int *ch0r = (int *)dl_ch_estimates_ext[rtx * n_rx + aarx];
int *ch0c = (int *)dl_ch_estimates_ext[ctx * n_rx + aarx];
c16_t *ch0r = (c16_t *)dl_ch_estimates_ext[rtx * n_rx + aarx];
c16_t *ch0c = (c16_t *)dl_ch_estimates_ext[ctx * n_rx + aarx];
nr_conjch0_mult_ch1(ch0r,
ch0c,
(int32_t *)conjH_H_elements[aarx][ctx][rtx], // sic
conjH_H_elements[aarx][ctx][rtx], // sic
nb_rb_0,
shift);
if (aarx != 0)
@@ -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
+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
mult_complex_vector_real_scalar((int16_t *)mod_ptrs, beta_ptrs * AMP, (int16_t *)mod_ptrs_amp, 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,
+18 -36
View File
@@ -305,7 +305,6 @@ extern "C" {
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,14 +316,14 @@ This function performs componentwise multiplication and accumulation of a comple
The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$
*/
static inline 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 c16_t alpha, c16_t *y, const 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]);
const simd_q15_t alpha_r_128 = set1_int16(alpha.r);
const simd_q15_t alpha_i_128 = set1_int16(alpha.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]);
@@ -335,37 +334,18 @@ The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$
}
}
// Same with correct types
static inline void multaddRealVectorComplexScalar(const c16_t *in, const c16_t alpha, c16_t *out, uint32_t N)
{
// do 8 multiplications at a time
simd_q15_t *x_128 = (simd_q15_t *)in, *y_128 = (simd_q15_t *)out;
// 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++) {
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)));
}
}
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));
@@ -451,7 +431,7 @@ This function performs componentwise multiplication and accumulation of a real s
The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$
*/
static inline void multadd_complex_vector_real_scalar(int16_t *x, int16_t alpha, int16_t *y, 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);
@@ -462,11 +442,12 @@ static inline void multadd_complex_vector_real_scalar(int16_t *x, int16_t alpha,
}
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;
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(int16_t *x, int16_t alpha, int16_t *y, uint32_t N)
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;
@@ -478,7 +459,8 @@ static inline void mult_complex_vector_real_scalar(int16_t *x, int16_t alpha, in
}
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;
y[offset + n].r = (x[offset + n].r * alpha) >> 16;
y[offset + n].i = (x[offset + n].i * alpha) >> 16;
}
}
@@ -499,7 +481,7 @@ static inline void mult_complex_vector_real_scalar(int16_t *x, int16_t alpha, in
@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
*/
static inline void mult_cpx_conj_vector(const c16_t *x1, const c16_t *x2, c16_t *y, uint32_t N, int output_shift)
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;
@@ -524,8 +506,8 @@ static inline void mult_cpx_conj_vector(const c16_t *x1, const c16_t *x2, c16_t
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 uint32_t N,
const int output_shift)
{
const simde__m128i *x1_128 = (simde__m128i *)x1;
const simde__m128i *x2_128 = (simde__m128i *)x2;
@@ -538,7 +520,7 @@ static inline void mult_cpx_vector(const c16_t *x1, // Q15
}
}
static inline void multadd_cpx_vector(const c16_t *x1, const c16_t *x2, c16_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;
@@ -877,7 +859,7 @@ This function performs componentwise subsctraction of complex vectors
The function implemented is : \f$\mathbf{y} = \alpha + \mathbf{x}\f$
*/
static inline int32_t sub_cpx_vector16(c16_t *x, c16_t *y, c16_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;
+1 -1
View File
@@ -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;i<NUMBER_OF_SCH_STATS_MAX;i++)
+46 -44
View File
@@ -710,55 +710,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);