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, void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp, c16_t **rxdataF_comp,
int32_t **ul_ch_mag, c16_t **ul_ch_mag,
int32_t **ul_ch_magb, c16_t **ul_ch_magb,
uint8_t symbol, uint8_t symbol,
uint16_t Msc_RS, uint16_t Msc_RS,
uint8_t Qm) 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; int8_t uespec_nushift, uespec_poffset=0, pil_offset=0;
uint8_t pilot0,pilot1,pilot2,pilot3; uint8_t pilot0,pilot1,pilot2,pilot3;
short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev; int16_t *fl = NULL, *fm = NULL, *fr = NULL, *fl_dc = NULL, *fm_dc = NULL, *fr_dc = NULL, *f1, *f2l = NULL, *f2r = NULL;
short *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; int **rxdataF;
int32_t **dl_bf_ch_estimates;
int uespec_pilot[300]; int uespec_pilot[300];
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; 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; 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; 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 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++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
c16_t *rxF = (c16_t *)&rxdataF[aarx][pil_offset + frame_parms->first_carrier_offset + symbol * frame_parms->ofdm_symbol_size];
rxF = (short *)&rxdataF[aarx][pil_offset + frame_parms->first_carrier_offset + symbol*frame_parms->ofdm_symbol_size]; c16_t *pil = (c16_t *)uespec_pilot;
pil = (short *)uespec_pilot; c16_t *dl_bf_ch = &dl_bf_ch_estimates[aarx][ch_offset];
dl_bf_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset];
memset(dl_bf_ch,0,4*(frame_parms->ofdm_symbol_size)); memset(dl_bf_ch,0,4*(frame_parms->ofdm_symbol_size));
//memset(dl_bf_ch,0,2*(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) { if (phy_vars_ue->high_speed_flag==0) {
// multiply previous channel estimate by ch_est_alpha // multiply previous channel estimate by ch_est_alpha
if (frame_parms->Ncp==0){ 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, 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); frame_parms->ofdm_symbol_size);
} else { } 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 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 // For second half of RBs skip DC carrier
if (rb==(frame_parms->N_RB_DL>>1)) { 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 (rb_alloc_ind==1) {
if (uespec_pilots==1) { if (uespec_pilots==1) {
if (beamforming_mode==7) { if (beamforming_mode==7) {
if (frame_parms->Ncp==0) { if (frame_parms->Ncp==0) {
multadd_real_vector_complex_scalar(fl, c16mulShift(*pil, rxF[0], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fm, c16mulShift(*pil, rxF[4], 15), dl_bf_ch, 16);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(fr, c16mulShift(*pil, rxF[8], 15), dl_bf_ch, 16);
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);
} else { } 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"); 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); exit(-1);
@@ -243,8 +232,8 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
} }
} }
rxF+=24; rxF += 12;
dl_bf_ch+=24; dl_bf_ch += 12;
} }
} else { // Odd number of RBs } else { // Odd number of RBs
for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { 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 (frame_parms->Ncp==0) {
if (skip_half==1) { if (skip_half==1) {
if (pil_offset<2) { if (pil_offset<2) {
multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
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;
} else { } else {
multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
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;
} }
} else if (skip_half==2) { } else if (skip_half==2) {
if (pil_offset<2) { if (pil_offset<2) {
multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[8], 15), 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(f1,ch,dl_bf_ch,16);
pil+=2;
} else { } else {
multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16);
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;
} }
} else { } else {
multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16);
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;
} }
} else { } 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"); 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"); LOG_E(PHY,"lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):transmission mode not supported.\n");
} }
} }
} }
rxF += 12;
rxF+=24; dl_bf_ch += 12;
dl_bf_ch+=24;
} // first half loop } // first half loop
// Do middle RB (around DC) // 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); //printf("DC rb %d (%p)\n",rb,rxF);
if (rb_alloc_ind==1) { if (rb_alloc_ind==1) {
if (pil_offset<2) { if (pil_offset<2) {
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fl_dc, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(fm_dc, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
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); rxF = (c16_t *)&rxdataF[aarx][symbol * (frame_parms->ofdm_symbol_size)];
ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15); multadd_real_vector_complex_scalar(fr_dc, c16mulShift(*pil++, rxF[3], 15), dl_bf_ch, 16);
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;;
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;;
} else { } else {
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fl_dc, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
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)]; 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);
ch[0] = (short)(((int)pil[0]*rxF[2] - (int)pil[1]*rxF[3])>>15); multadd_real_vector_complex_scalar(fr_dc, c16mulShift(*pil++, rxF[5], 15), dl_bf_ch, 16);
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;;
} }
} // rballoc==1 } // rballoc==1
else { 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; rxF += 7 + pil_offset;
dl_bf_ch+=24; dl_bf_ch += 12;
rb++; rb++;
for (; rb<frame_parms->N_RB_DL; 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 (frame_parms->Ncp==0) {
if (skip_half==1) { if (skip_half==1) {
if (pil_offset<2) { if (pil_offset<2) {
multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
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;
} else { } else {
multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
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;
} }
} else if (skip_half==2) { } else if (skip_half==2) {
if (pil_offset<2) { if (pil_offset<2) {
multadd_real_vector_complex_scalar(f1, c16mulShift(*pil++, rxF[8], 15), 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(f1,ch,dl_bf_ch,16);
pil+=2;
} else { } else {
multadd_real_vector_complex_scalar(f2l, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15); multadd_real_vector_complex_scalar(f2r, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16);
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;
} }
} else { } else {
multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_bf_ch, 16);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, rxF[4], 15), dl_bf_ch, 16);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[8], 15), dl_bf_ch, 16);
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;
} }
} else { } 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"); 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; rxF += 12;
dl_bf_ch+=24; dl_bf_ch += 12;
} // second half of RBs } // second half of RBs
} // odd number of RBs } // odd number of RBs
// Temporal Interpolation // Temporal Interpolation
if (phy_vars_ue->perfect_ce == 0) { if (phy_vars_ue->perfect_ce == 0) {
dl_bf_ch = &dl_bf_ch_estimates[aarx][ch_offset];
dl_bf_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset];
#ifdef DEBUG_BF_CH #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]); printf("[dlsch_bf_ch_est.c]:symbol %d, dl_bf_ch (%d,%d)\n",symbol,dl_bf_ch[0],dl_bf_ch[1]);
#endif #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) { if (phy_vars_ue->high_speed_flag == 0) {
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
32767 - phy_vars_ue->ch_est_alpha, 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); 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)); //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 } else { // high_speed_flag == 1
@@ -670,48 +518,48 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
if (symbol == pilot0) { if (symbol == pilot0) {
// printf("Interpolating %d->0\n",4-phy_vars_ue->lte_frame_parms.Ncp); // 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][(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 #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]); 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 #endif
// pilot spacing 5 symbols (1/5,2/5,3/5,4/5 combination) // pilot spacing 5 symbols (1/5,2/5,3/5,4/5 combination)
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
26214, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
6554, 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); frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
19661, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
13107, 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); frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
13107, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
19661, 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); frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
6554, 6554,
dl_bf_ch - (2 * (frame_parms->ofdm_symbol_size)), dl_bf_ch - frame_parms->ofdm_symbol_size,
frame_parms->ofdm_symbol_size); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
26214, 26214,
dl_bf_ch - (2 * (frame_parms->ofdm_symbol_size)), dl_bf_ch - frame_parms->ofdm_symbol_size,
frame_parms->ofdm_symbol_size); frame_parms->ofdm_symbol_size);
} else if (symbol == pilot1) { } 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 #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]); 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 #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) // pilot spacing 3 symbols (1/3,2/3 combination)
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
21845, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
10923, 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); frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
10923, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
21845, 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); frame_parms->ofdm_symbol_size);
} else if (symbol == pilot2) { } 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 #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]); 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 #endif
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
21845, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
10923, 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); frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
10923, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
21845, 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); frame_parms->ofdm_symbol_size);
} else { // symbol == pilot3 } else { // symbol == pilot3
// printf("Interpolating 0->%d\n",4-phy_vars_ue->lte_frame_parms.Ncp); // 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) // pilot spacing 3 symbols (1/3,2/3 combination)
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
21845, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
10923, 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); frame_parms->ofdm_symbol_size);
mult_complex_vector_real_scalar(dl_bf_ch_prev, mult_complex_vector_real_scalar(dl_bf_ch_prev,
10923, 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); frame_parms->ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_bf_ch, multadd_complex_vector_real_scalar(dl_bf_ch,
21845, 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); frame_parms->ofdm_symbol_size);
} }
@@ -790,12 +638,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
} }
} }
} }
} //aarx } // 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
return(0); return(0);
} }
@@ -39,7 +39,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
unsigned char nu,aarx; unsigned char nu,aarx;
unsigned short k; unsigned short k;
unsigned int rb,pilot_cnt; 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; int ch_offset,symbol_offset;
// unsigned int n; // unsigned int n;
// int i; // int i;
@@ -177,16 +177,16 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
p); p);
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[p][0]; c16_t *pil = (c16_t *)&pilot[p][0];
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+k+ue->frame_parms.first_carrier_offset))]; c16_t *rxF = (c16_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 *dl_ch = (c16_t *)&dl_ch_estimates[(p << 1) + aarx][ch_offset];
// if (eNb_id==0) // 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 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, 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); ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH #ifdef DEBUG_CH
@@ -196,352 +196,97 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
if ((ue->frame_parms.N_RB_DL==6) || if ((ue->frame_parms.N_RB_DL==6) ||
(ue->frame_parms.N_RB_DL==50) || (ue->frame_parms.N_RB_DL==50) ||
(ue->frame_parms.N_RB_DL==100)) { (ue->frame_parms.N_RB_DL==100)) {
//First half of pilots // First half of pilots
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
#ifdef DEBUG_CH dl_ch += 4;
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]); multadd_real_vector_complex_scalar(f2l2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
#endif rxF += 6;
multadd_real_vector_complex_scalar(fl, dl_ch += 8;
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;
for (pilot_cnt=2; pilot_cnt<((ue->frame_parms.N_RB_DL)-1); pilot_cnt+=2) { 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 multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); //Im rxF += 6;
#ifdef DEBUG_CH dl_ch += 4;
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]); multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
#endif rxF += 6;
multadd_real_vector_complex_scalar(f, dl_ch += 8;
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;
} }
// printf("Second half\n");
// Second half of RBs // Second half of RBs
k = (nu + nushift)%6; k = (nu + nushift)%6;
rxF = (c16_t *)&rxdataF[aarx][symbol_offset + 1 + k];
if (k > 6) for (pilot_cnt = 0; pilot_cnt < ((ue->frame_parms.N_RB_DL) - 3); pilot_cnt += 2) {
k -=6; multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
rxF += 6;
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; dl_ch += 4;
#ifdef DEBUG_CH multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
printf("second half k %d\n",k); rxF += 6;
#endif dl_ch += 8;
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;
} }
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); for (pilot_cnt = 2; pilot_cnt < 24; pilot_cnt += 2) {
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
#ifdef DEBUG_CH rxF += 6;
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]); dl_ch += 4;
#endif multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
multadd_real_vector_complex_scalar(fr, rxF += 6;
ch, dl_ch += 8;
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;
} }
multadd_real_vector_complex_scalar(f_dc, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); dl_ch += 4;
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");
// Second half of RBs // Second half of RBs
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; rxF = (c16_t *)&rxdataF[aarx][symbol_offset + 1 + k];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(f2_dc, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
#ifdef DEBUG_CH dl_ch += 8;
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]); for (pilot_cnt = 0; pilot_cnt < 22; pilot_cnt += 2) {
// ch[0] = 1024; multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
// ch[1] = -128; rxF += 6;
#endif dl_ch += 4;
multadd_real_vector_complex_scalar(f2_dc, multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch, rxF += 6;
dl_ch, dl_ch += 8;
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;
} }
multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); rxF += 6;
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); dl_ch += 4;
#ifdef DEBUG_CH multadd_real_vector_complex_scalar(f2r2, c16mulShift(*pil, rxF[0], 15), dl_ch, 24);
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]); } else if (ue->frame_parms.N_RB_DL == 15) {
// ch[0] = 1024; for (rb = 0; rb < 28; rb += 4) {
// ch[1] = -128; multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
#endif rxF += 6;
multadd_real_vector_complex_scalar(fr, dl_ch += 4;
ch, multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
dl_ch, rxF += 6;
24); dl_ch += 8;
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(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); dl_ch += 4;
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");
//Second half of RBs //Second half of RBs
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))]; rxF = (c16_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); multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
multadd_real_vector_complex_scalar(f2, dl_ch += 8;
ch,
dl_ch,
24);
pil+=2;
rxF+=12;
dl_ch+=16;
for (rb=0; rb<28; rb+=4) { for (rb = 0; rb < 28; rb += 4) {
//printf("aarx=%d\n",aarx); multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
//printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]); rxF += 6;
//printf("rx[%d][%d] -> (%d,%d)\n",p, dl_ch += 4;
// ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p), multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, rxF[0], 15), dl_ch, 24);
// rxF[0], rxF += 6;
// rxF[1]); 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(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;
} }
} else { } else {
LOG_E(PHY,"channel estimation not implemented for ue->frame_parms.N_RB_DL = %d\n",ue->frame_parms.N_RB_DL); 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) { if (ue->perfect_ce == 0) {
// Temporal Interpolation // Temporal Interpolation
// printf("ch_offset %d\n",ch_offset); // 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) { 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 } else { // high_speed_flag == 1
if (symbol == 0) { if (symbol == 0) {
// printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp); // 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)]; // 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)) { if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12)) {
//LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns); //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)]; 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 + (2 * (symb_sz)), 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 + (2 * (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) << 1)), 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) << 1)), symb_sz); multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + 2 * symb_sz, symb_sz);
} }
interpolateS11S12 = 1; interpolateS11S12 = 1;
} // this is 1/3,2/3 combination for pilots spaced by 3 symbols } // this is 1/3,2/3 combination for pilots spaced by 3 symbols
else if (symbol == pilot1) { 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); //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) 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; previous_subframe = ((Ns>>1) - 1 )%9;
if((subframe_select(&ue->frame_parms,previous_subframe) == SF_UL)) { 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); 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 + (2 * (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) << 1)), 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) << 1)), 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 * 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 * 2 * (symb_sz)), symb_sz); multadd_complex_vector_real_scalar(dl_ch, 32440, dl_ch_prev + 3 * symb_sz, symb_sz);
} else { } else {
mult_complex_vector_real_scalar(dl_ch_prev, 24576, dl_ch_prev + (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 + (2 * (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) << 1)), 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) << 1)), 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 * 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 * 2 * (symb_sz)), symb_sz); multadd_complex_vector_real_scalar(dl_ch, 24576, dl_ch_prev + 3 * symb_sz, symb_sz);
} }
} else { } else {
mult_complex_vector_real_scalar(dl_ch_prev, 328, dl_ch_prev + (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, 21845, dl_ch_prev + (2 * (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) << 1), 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) << 1)), 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) } // pilot spacing 3 symbols (1/3,2/3 combination)
} else if (symbol == pilot2) { } else if (symbol == pilot2) {
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p << 1) + aarx][pilot1 * (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 + (2 * (symb_sz)), 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 + (2 * (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) << 1)), 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) << 1)), symb_sz); multadd_complex_vector_real_scalar(dl_ch, 21845, dl_ch_prev + 2 * symb_sz, symb_sz);
} else { // symbol == pilot3 } else { // symbol == pilot3
// printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp); // 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) 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); 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 + (2 * (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) << 1)), 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) << 1)), 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 * 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 * 2 * (symb_sz)), symb_sz); multadd_complex_vector_real_scalar(dl_ch, 24576, dl_ch_prev + 3 * symb_sz, symb_sz);
} else { } else {
mult_complex_vector_real_scalar(dl_ch_prev, 10923, dl_ch_prev + (2 * (symb_sz)), 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 + (2 * (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) << 1), 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) << 1)), 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) } // pilot spacing 3 symbols (1/3,2/3 combination)
if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) { if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) {
//LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns); //LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns);
interpolateS11S12 = 0; interpolateS11S12 = 0;
//LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol); //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_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_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 // 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]; 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))); int pilot[600] __attribute__((aligned(16)));
unsigned char aarx,aa; unsigned char aarx,aa;
unsigned int rb; 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; int ch_offset,symbol_offset;
// unsigned int n; // unsigned int n;
// int i; // int i;
@@ -684,37 +684,37 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
if (l==6) { if (l==6) {
ch = (short *)&dl_ch_estimates[aarx][ch_offset]; ch = (short *)&dl_ch_estimates[aarx][ch_offset];
// printf("Interpolating ch 2,6 => %d\n",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)]; ch0 = (short *)&dl_ch_estimates[aarx][0 * (symb_sz)];
memcpy(ch0, ch_prev, 4 * symb_sz); memcpy(ch0, ch_prev, 4 * symb_sz);
ch1 = (short *)&dl_ch_estimates[aarx][1 * (symb_sz)]; ch1 = (short *)&dl_ch_estimates[aarx][1 * (symb_sz)];
memcpy(ch1, ch_prev, 4 * symb_sz); memcpy(ch1, ch_prev, 4 * symb_sz);
// 3/4 ch2 + 1/4 ch6 => ch3 // 3/4 ch2 + 1/4 ch6 => ch3
mult_complex_vector_real_scalar(ch_prev, 24576, 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(ch, 8192, ch_prev + (2 * (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 // 1/2 ch2 + 1/2 ch6 => ch4
mult_complex_vector_real_scalar(ch_prev, 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(ch, 16384, ch_prev + (4 * (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 // 1/4 ch2 + 3/4 ch6 => ch5
mult_complex_vector_real_scalar(ch_prev, 8192, 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(ch, 24576, ch_prev + (6 * ((symb_sz))), symb_sz); multadd_complex_vector_real_scalar((c16_t *)ch, 24576, ch_prev + 3 * symb_sz, symb_sz);
} }
if (l==10) { if (l==10) {
ch = (short *)&dl_ch_estimates[aarx][ch_offset]; 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 // 3/4 ch6 + 1/4 ch10 => ch7
mult_complex_vector_real_scalar(ch_prev, 24576, 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(ch, 8192, ch_prev + (2 * (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 // 1/2 ch6 + 1/2 ch10 => ch8
mult_complex_vector_real_scalar(ch_prev, 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(ch, 16384, ch_prev + (4 * (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 // 1/4 ch6 + 3/4 ch10 => ch9
mult_complex_vector_real_scalar(ch_prev, 8192, 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(ch, 24576, ch_prev + (6 * ((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 // 5/4 ch10 - 1/4 ch6 => ch11
// 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)]; ch11 = (short *)&dl_ch_estimates[aarx][11 * (symb_sz)];
memcpy(ch11, ch_prev, 4 * 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 subframe) {
int pilot_khz_1dot25[2*2*600] __attribute__((aligned(16))); int pilot_khz_1dot25[2*2*600] __attribute__((aligned(16)));
unsigned char aarx,aa; unsigned char aarx,aa;
//unsigned int rb; // unsigned int rb;
int16_t ch[2];
short *pil,*rxF,*dl_ch/*,*ch0,*ch1,*ch11,*chp,*ch_prev*/;
int ch_offset,symbol_offset; int ch_offset,symbol_offset;
int pilot_cnt; int pilot_cnt;
int16_t *f,*f2,*fl,*f2l2,*fr,*f2r2/*,*f2_dc,*f_dc*/; int16_t *f, *f2, *fl, *f2l2, *fr, *f2r2 /*,*f2_dc,*f_dc*/;
unsigned int k;
// unsigned int n; // unsigned int n;
// int i; // int i;
int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0]; 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++) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
// generate pilot // generate pilot
lte_dl_mbsfn_khz_1dot25_rx(ue, lte_dl_mbsfn_khz_1dot25_rx(ue, pilot_khz_1dot25, subframe);
&pilot_khz_1dot25[0], c16_t *pil = (c16_t *)pilot_khz_1dot25;
subframe); c16_t *dl_ch = (c16_t *)&dl_ch_estimates[aarx][ch_offset];
pil = (short *)&pilot_khz_1dot25[0]; memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size_khz_1dot25);
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));
if( (subframe&0x1) == 0) { unsigned int k = (subframe & 0x1) == 0 ? 0 : 3;
rxF+=0; c16_t *rxF = (c16_t *)&rxdataF[aarx][ue->frame_parms.first_carrier_offset_khz_1dot25 + k];
k=0;
} else {
rxF+=6;//2*3;
k=3;
}
if(1/*ue->frame_parms.N_RB_DL==25*/) { 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); multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
multadd_real_vector_complex_scalar(fl, dl_ch += 4;
ch, multadd_real_vector_complex_scalar(f2l2, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
dl_ch, rxF += 6;
24); dl_ch += 8;
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;
for(pilot_cnt=2; pilot_cnt<ue->frame_parms.N_RB_DL*12-1/*299*/; pilot_cnt+=2) { 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); multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
multadd_real_vector_complex_scalar(f, dl_ch += 4;
ch, multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
dl_ch, rxF += 6;
24); dl_ch += 8;
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;
} }
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) { 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); multadd_real_vector_complex_scalar(f, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
multadd_real_vector_complex_scalar(f, dl_ch += 4;
ch, multadd_real_vector_complex_scalar(f2, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
dl_ch, rxF += 6;
24); dl_ch += 8;
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;
} }
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 24);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 6;
multadd_real_vector_complex_scalar(fr, dl_ch += 4;
ch, multadd_real_vector_complex_scalar(f2r2, c16mulShift(*pil, *rxF, 15), dl_ch, 24);
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);
} }
} }
+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 \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. \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, int lte_sync_time(c16_t **rxdata, LTE_DL_FRAME_PARMS *frame_parms, int *eNB_id);
LTE_DL_FRAME_PARMS *frame_parms,
int *eNB_id);
/*! /*!
\brief This function performs the coarse frequency and PSS synchronization. \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); unsigned char eNB_id);
int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
L1_rxtx_proc_t *proc, L1_rxtx_proc_t *proc,
LTE_eNB_ULSCH_t * ulsch, LTE_eNB_ULSCH_t *ulsch,
int32_t **ul_ch_estimates, c16_t **ul_ch_estimates,
int32_t **ul_ch_estimates_time, c16_t **ul_ch_estimates_time,
int32_t **rxdataF_ext, c16_t **rxdataF_ext,
module_id_t UE_id, module_id_t UE_id,
uint8_t l, uint8_t l,
uint8_t Ns); uint8_t Ns);
int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **ul_ch_estimates, c16_t **ul_ch_estimates,
int32_t **ul_ch_estimates_time, c16_t **ul_ch_estimates_time,
int32_t **rxdataF_ext, c16_t **rxdataF_ext,
int N_rb_alloc, int N_rb_alloc,
int frame_rx, int frame_rx,
int subframe_rx, int subframe_rx,
@@ -217,9 +215,7 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
int interpolate, int interpolate,
uint16_t rnti); uint16_t rnti);
int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, c16_t *ul_ch_estimates, uint16_t nb_rb);
int32_t *ul_ch_estimates,
uint16_t nb_rb);
int lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, int lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
LTE_eNB_COMMON *eNB_common_vars, 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, unsigned char number_of_cards,
short coef); short coef);
int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms, int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms, c16_t **ul_ch_estimates_time);
int32_t **ul_ch_estimates_time);
void lte_eNB_I0_measurements(PHY_VARS_eNB *phy_vars_eNB, void lte_eNB_I0_measurements(PHY_VARS_eNB *phy_vars_eNB,
int subframe, int subframe,
@@ -252,11 +247,10 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *phy_vars_eNBy,
module_id_t UE_id, module_id_t UE_id,
unsigned char init_averaging); unsigned char init_averaging);
void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms, void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp, c16_t **rxdataF_comp,
int **ul_ch_mag, c16_t **ul_ch_mag,
int **ul_ch_mag_b, c16_t **ul_ch_mag_b,
unsigned char symbol, unsigned char symbol,
unsigned short Msc_RS, unsigned short Msc_RS,
unsigned char Qm); unsigned char Qm);
+4 -6
View File
@@ -114,7 +114,7 @@ void lte_sync_time_free(void) {
#define SHIFT 17 #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 // perform a time domain correlation using the oversampled sync sequence
unsigned int n, ar, s, peak_pos, peak_val, sync_source; 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]; //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 (int i = 0; i < sizeofArray(primary_synch_time); i++)
for (ar = 0; ar < frame_parms->nb_antennas_rx; ar++) { 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 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], (c16_t *)&(rxdata[ar][n + length]), 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].r += result.r;
sync_out[i].i += result.i; sync_out[i].i += result.i;
sync_out2[i].r += result2.r; 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 // 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++) for (int ar=0; ar<ru->nb_rx; ar++)
memcpy((void *)&ru->common.rxdata[ar][2*length], memcpy(ru->common.rxdata[ar] + 2 * length, ru->common.rxdata[ar], frame_parms->ofdm_symbol_size);
(void *)&ru->common.rxdata[ar][0],
frame_parms->ofdm_symbol_size);
int32_t maxlev0=0; int32_t maxlev0=0;
int maxpos0=0; int maxpos0=0;
@@ -27,6 +27,7 @@
#include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h"
#include "lte_estimation.h" #include "lte_estimation.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_vars.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)) // round(exp(sqrt(-1)*(pi/2)*[0:1:N-1]/N)*pow2(15))
static const int16_t ru_90[2 * 128] = { static const int16_t ru_90[2 * 128] = {
@@ -68,13 +69,14 @@ static const int16_t ru_90c[2 * 128] = {
int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
L1_rxtx_proc_t *proc, L1_rxtx_proc_t *proc,
LTE_eNB_ULSCH_t * ulsch, LTE_eNB_ULSCH_t *ulsch,
int32_t **ul_ch_estimates, c16_t **ul_ch_estimates,
int32_t **ul_ch_estimates_time, c16_t **ul_ch_estimates_time,
int32_t **rxdataF_ext, c16_t **rxdataF_ext,
module_id_t UE_id, module_id_t UE_id,
unsigned char l, unsigned char l,
unsigned char Ns) { unsigned char Ns)
{
AssertFatal(ul_ch_estimates != NULL, "ul_ch_estimates is null "); AssertFatal(ul_ch_estimates != NULL, "ul_ch_estimates is null ");
AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n"); AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n");
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
@@ -82,14 +84,11 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t harq_pid; uint8_t harq_pid;
int16_t delta_phase = 0; int16_t delta_phase = 0;
const int16_t *ru1 = ru_90;
const int16_t *ru2 = ru_90;
int16_t current_phase1,current_phase2; int16_t current_phase1,current_phase2;
uint16_t aa,Msc_RS,Msc_RS_idx; uint16_t aa,Msc_RS,Msc_RS_idx;
uint16_t *Msc_idx_ptr; uint16_t *Msc_idx_ptr;
int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp; int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
int32_t *ul_ch1=NULL, *ul_ch2=NULL; c16_t *ul_ch1 = NULL, *ul_ch2 = NULL;
int16_t ul_ch_estimates_re,ul_ch_estimates_im;
//uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB; //uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t cyclic_shift; 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 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)]; uint32_t v=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[Ns+(subframe<<1)];
int symbol_offset,i; int symbol_offset,i;
//debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift); // 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};
simde__m128i *rxdataF128, *ul_ref128, *ul_ch128; 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; if (ulsch->ue_type > 0) harq_pid = 0;
else { 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; 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; Msc_RS = N_rb_alloc*12;
cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
ulsch->harq_processes[harq_pid]->n_DMRS2 + ulsch->harq_processes[harq_pid]->n_DMRS2 +
@@ -154,16 +151,8 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
#endif #endif
for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) { for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
ul_ch_estimates_re = ((int16_t *) ul_ch_estimates[aa])[i<<1]; c16_t alpha = (c16_t){alphaTBL_re[alpha_ind], alphaTBL_im[alpha_ind]};
ul_ch_estimates_im = ((int16_t *) ul_ch_estimates[aa])[(i<<1)+1]; ul_ch_estimates[aa][i] = c16MulConjShift(alpha, ul_ch_estimates[aa][i], 15);
// ((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);
alpha_ind+=cyclic_shift; alpha_ind+=cyclic_shift;
if (alpha_ind>11) 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)); memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
for(i=0; i<Msc_RS; i++) 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; int len;
switch(frame_parms->N_RB_DL) { switch(frame_parms->N_RB_DL) {
case 6: 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); current_phase2 = (delta_phase/7)*(k-pilot_pos2);
// msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2); // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2);
// set the right quadrant // set the right quadrant
(current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c); c16_t *ru1 = (c16_t *)(current_phase1 > 0 ? ru_90 : ru_90c);
(current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c); c16_t *ru2 = (c16_t *)(current_phase2 > 0 ? ru_90 : ru_90c);
// take absolute value and clip // take absolute value and clip
current_phase1 = cmin(abs(current_phase1),127); current_phase1 = cmin(abs(current_phase1),127);
current_phase2 = cmin(abs(current_phase2),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]);
// rotate channel estimates by estimated phase // rotate channel estimates by estimated phase
rotate_cpx_vector((c16_t *) ul_ch1, rotate_cpx_vector(ul_ch1, &ru1[current_phase1], &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS, 15);
(c16_t *) &ru1[2*current_phase1], rotate_cpx_vector(ul_ch2, &ru2[current_phase2], tmp_estimates, Msc_RS, 15);
(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);
// Combine the two rotated estimates // 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, 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); Msc_RS);
multadd_complex_vector_real_scalar((int16_t *)&tmp_estimates[0], multadd_complex_vector_real_scalar(tmp_estimates, SCALE, &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS);
SCALE,
(int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k],
Msc_RS);
/* /*
if ((k<pilot_pos1) || ((k>pilot_pos2))) { 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 lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **ul_ch_estimates, c16_t **ul_ch_estimates,
int32_t **ul_ch_estimates_time, c16_t **ul_ch_estimates_time,
int32_t **rxdataF_ext, c16_t **rxdataF_ext,
int N_rb_alloc, int N_rb_alloc,
int frame_rx, int frame_rx,
int subframe_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, uint32_t cyclic_shift,
unsigned char l, unsigned char l,
int interpolate, int interpolate,
uint16_t rnti) { uint16_t rnti)
{
int16_t delta_phase = 0; int16_t delta_phase = 0;
const int16_t *ru1 = ru_90;
const int16_t *ru2 = ru_90;
int16_t current_phase1,current_phase2; int16_t current_phase1,current_phase2;
uint16_t aa,Msc_RS,Msc_RS_idx; uint16_t aa,Msc_RS,Msc_RS_idx;
uint16_t *Msc_idx_ptr; uint16_t *Msc_idx_ptr;
int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp; int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
int32_t *ul_ch1=NULL, *ul_ch2=NULL; c16_t *ul_ch1 = NULL, *ul_ch2 = NULL;
int16_t ul_ch_estimates_re,ul_ch_estimates_im;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint32_t alpha_ind; 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; int symbol_offset,i;
//debug_msg("lte_ul_channel_estimation_RRU: cyclic shift %d\n",cyclicShift); // 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};
simde__m128i *rxdataF128, *ul_ref128, *ul_ch128; 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", 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); l,pilot_pos1,pilot_pos2);
Msc_RS = N_rb_alloc*12; Msc_RS = N_rb_alloc*12;
@@ -388,16 +361,8 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
#endif #endif
for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) { for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
ul_ch_estimates_re = ((int16_t *) ul_ch_estimates[aa])[i<<1]; c16_t alpha = (c16_t){alphaTBL_re[alpha_ind], alphaTBL_im[alpha_ind]};
ul_ch_estimates_im = ((int16_t *) ul_ch_estimates[aa])[(i<<1)+1]; ul_ch_estimates[aa][i] = c16MulConjShift(alpha, ul_ch_estimates[aa][i], 15);
// ((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);
alpha_ind+=cyclic_shift; alpha_ind+=cyclic_shift;
if (alpha_ind>11) 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)); memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
for(i=0; i<Msc_RS; i++) 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; int len;
switch(frame_parms->N_RB_DL) { switch(frame_parms->N_RB_DL) {
case 6: 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); current_phase2 = (delta_phase/7)*(k-pilot_pos2);
// msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2); // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2);
// set the right quadrant // set the right quadrant
(current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c); c16_t *ru1 = (c16_t *)(current_phase1 > 0 ? ru_90 : ru_90c);
(current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c); c16_t *ru2 = (c16_t *)(current_phase2 > 0 ? ru_90 : ru_90c);
// take absolute value and clip // take absolute value and clip
current_phase1 = cmin(abs(current_phase1),127); current_phase1 = cmin(abs(current_phase1),127);
current_phase2 = cmin(abs(current_phase2),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]);
// rotate channel estimates by estimated phase // rotate channel estimates by estimated phase
rotate_cpx_vector((c16_t *) ul_ch1, rotate_cpx_vector(ul_ch1, &ru1[current_phase1], &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS, 15);
(c16_t *) &ru1[2*current_phase1], rotate_cpx_vector(ul_ch2, &ru2[current_phase2], tmp_estimates, Msc_RS, 15);
(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);
// Combine the two rotated estimates // 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, 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); Msc_RS);
multadd_complex_vector_real_scalar((int16_t *)&tmp_estimates[0], multadd_complex_vector_real_scalar(tmp_estimates, SCALE, &ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k], Msc_RS);
SCALE,
(int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * k],
Msc_RS);
} }
} //for(k=... } //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++) { for (k=0; k<frame_parms->symbols_per_tti>>1; k++) {
if (k==pilot_pos1) k++; if (k==pilot_pos1) k++;
memcpy((void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*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], (void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * pilot_pos1],
frame_parms->N_RB_UL*12*sizeof(int)); frame_parms->N_RB_UL * 12 * sizeof(int));
} else if (interpolate == 0 && l == pilot_pos2) { } else if (interpolate == 0 && l == pilot_pos2) {
for (k=0; k<frame_parms->symbols_per_tti>>1; k++) { for (k=0; k<frame_parms->symbols_per_tti>>1; k++) {
if (k==pilot_pos2) 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))], 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], (void *)&ul_ch_estimates[aa][frame_parms->N_RB_UL * 12 * pilot_pos2],
frame_parms->N_RB_UL*12*sizeof(int)); frame_parms->N_RB_UL * 12 * sizeof(int));
} }
delta_phase = lte_ul_freq_offset_estimation(frame_parms, 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); 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; int a_idx = 64;
uint8_t conj_flag = 0; 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),
l/(frame_parms->symbols_per_tti/2), l/(frame_parms->symbols_per_tti/2),
frame_parms); frame_parms);
lte_ul_channel_estimation(&eNB->frame_parms,proc, lte_ul_channel_estimation(&eNB->frame_parms,
eNB->ulsch[UE_id], proc,
eNB->pusch_vars[UE_id]->drs_ch_estimates, eNB->ulsch[UE_id],
eNB->pusch_vars[UE_id]->drs_ch_estimates_time, (c16_t **)eNB->pusch_vars[UE_id]->drs_ch_estimates,
eNB->pusch_vars[UE_id]->rxdataF_ext, (c16_t **)eNB->pusch_vars[UE_id]->drs_ch_estimates_time,
(c16_t **)eNB->pusch_vars[UE_id]->rxdataF_ext,
UE_id, 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; 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 ((eNB->measurements.n0_power_dB[0]+3)<pusch_vars->ulsch_power[0])
if (23<pusch_vars->ulsch_power[0]) { if (23<pusch_vars->ulsch_power[0]) {
freq_equalization(frame_parms, freq_equalization(frame_parms,
pusch_vars->rxdataF_comp, (c16_t **)pusch_vars->rxdataF_comp,
pusch_vars->ul_ch_mag, (c16_t **)pusch_vars->ul_ch_mag,
pusch_vars->ul_ch_magb, (c16_t **)pusch_vars->ul_ch_magb,
l, l,
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb * 12,
Qm); Qm);
} }
} }
@@ -202,23 +202,21 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t mod_order_0, uint16_t mod_order_0,
uint32_t rb_alloc) uint32_t rb_alloc)
{ {
c16_t rho_amp_x0[frame_parms->N_RB_DL * 12];
int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; c16_t rho_rho_amp_x0[frame_parms->N_RB_DL * 12];
int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
uint16_t amp_tmp; uint16_t amp_tmp;
uint16_t *llr16=(uint16_t*)dlsch_llr; uint16_t *llr16=(uint16_t*)dlsch_llr;
int i, len, nsymb; int i, len, nsymb;
uint8_t symbol, symbol_mod; uint8_t symbol, symbol_mod;
int len_acc=0; int len_acc = 0;
uint16_t *sic_data;
uint16_t pbch_pss_sss_adjust; uint16_t pbch_pss_sss_adjust;
nsymb = (frame_parms->Ncp==0) ? 14:12; nsymb = (frame_parms->Ncp==0) ? 14:12;
for (symbol=num_pdcch_symbols; symbol<nsymb; symbol++) { 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)]); uint16_t *rxF = (uint16_t *)&rxdataF_comp[0][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)]); c16_t *rho_1 = (c16_t *)&rho_i[0][symbol * frame_parms->N_RB_DL * 12];
sic_data = (uint16_t*)&sic_buffer[0][((int16_t)len_acc)]; c16_t *sic_data = (c16_t *)&sic_buffer[0][len_acc];
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; 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 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, amp_tmp,
(int16_t *)rho_amp_x0, // this is in Q13 rho_amp_x0, // this is in Q13
len); len);
mult_cpx_vector((c16_t *)rho_1, // Q15 mult_cpx_vector(rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13 rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0, rho_rho_amp_x0,
len, len,
13); 13);
@@ -271,10 +269,10 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
#endif #endif
sub_cpx_vector16((c16_t *)rxF, sub_cpx_vector16((c16_t *)rxF,
(c16_t *)rho_rho_amp_x0, rho_rho_amp_x0,
//(int16_t *)clean_x1, //(int16_t *)clean_x1,
(c16_t *)rxF, (c16_t *)rxF,
len*2); len * 2);
#ifdef DEBUG_LLR_SIC #ifdef DEBUG_LLR_SIC
LOG_M("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); 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, uint16_t mod_order_0,
uint32_t rb_alloc) uint32_t rb_alloc)
{ {
int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; c16_t rho_amp_x0[frame_parms->N_RB_DL * 12];
int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; c16_t rho_rho_amp_x0[frame_parms->N_RB_DL * 12];
uint16_t amp_tmp; uint16_t amp_tmp;
uint32_t *llr32=(uint32_t*)dlsch_llr; uint32_t *llr32=(uint32_t*)dlsch_llr;
int i, len, nsymb; int i, len, nsymb;
uint8_t symbol, symbol_mod; uint8_t symbol, symbol_mod;
int len_acc=0; int len_acc = 0;
uint16_t *sic_data;
uint16_t pbch_pss_sss_adjust; uint16_t pbch_pss_sss_adjust;
unsigned char len_mod4=0; unsigned char len_mod4=0;
simde__m128i llr128[2]; 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; nsymb = (frame_parms->Ncp==0) ? 14:12;
for (symbol=num_pdcch_symbols; symbol<nsymb; symbol++) { 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)]); uint16_t *rxF = (uint16_t *)&rxdataF_comp[0][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)]); c16_t *rho_1 = (c16_t *)&rho_i[0][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_mag = (simde__m128i *)&dl_ch_mag[0][symbol * frame_parms->N_RB_DL * 12];
sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]); c16_t *sic_data = (c16_t *)&sic_buffer[0][len_acc];
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; 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; len_acc+=len;
mult_complex_vector_real_scalar((int16_t *)sic_data, mult_complex_vector_real_scalar(sic_data,
amp_tmp, amp_tmp,
(int16_t *)rho_amp_x0, // this is in Q13 rho_amp_x0, // this is in Q13
len); len);
mult_cpx_vector((c16_t *)rho_1, // Q15 mult_cpx_vector(rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13 rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0, rho_rho_amp_x0,
len, len,
13); 13);
sub_cpx_vector16((c16_t *)rxF, sub_cpx_vector16((c16_t *)rxF,
(c16_t *)rho_rho_amp_x0, rho_rho_amp_x0,
//(int16_t *)clean_x1, //(int16_t *)clean_x1,
(c16_t *)rxF, (c16_t *)rxF,
len*2); len * 2);
len_mod4 = len&3; len_mod4 = len&3;
len>>=2; // length in quad words (4 REs) 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, uint16_t mod_order_0,
uint32_t rb_alloc) uint32_t rb_alloc)
{ {
int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; c16_t rho_amp_x0[frame_parms->N_RB_DL * 12];
int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; c16_t rho_rho_amp_x0[frame_parms->N_RB_DL * 12];
uint16_t amp_tmp; uint16_t amp_tmp;
uint16_t *llr32=(uint16_t*)dlsch_llr; uint16_t *llr32=(uint16_t*)dlsch_llr;
int i, len, nsymb, len2; int i, len, nsymb, len2;
uint8_t symbol, symbol_mod; uint8_t symbol, symbol_mod;
int len_acc=0; int len_acc = 0;
uint16_t *sic_data;
uint16_t pbch_pss_sss_adjust; uint16_t pbch_pss_sss_adjust;
unsigned char len_mod4=0; unsigned char len_mod4=0;
uint16_t *llr2; 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; nsymb = (frame_parms->Ncp==0) ? 14:12;
for (symbol=num_pdcch_symbols; symbol<nsymb; symbol++) { 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)]); uint16_t *rxF = (uint16_t *)(&rxdataF_comp[0][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)]); c16_t *rho_1 = (c16_t *)(&rho_i[0][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_mag = (simde__m128i *)(&dl_ch_mag[0][symbol * frame_parms->N_RB_DL * 12]);
ch_magb = (simde__m128i*)(&dl_ch_magb[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); ch_magb = (simde__m128i *)(&dl_ch_magb[0][symbol * frame_parms->N_RB_DL * 12]);
sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]); c16_t *sic_data = (c16_t *)(&sic_buffer[0][len_acc]);
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; 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; len_acc+=len;
mult_complex_vector_real_scalar((int16_t *)sic_data, mult_complex_vector_real_scalar(sic_data,
amp_tmp, amp_tmp,
(int16_t *)rho_amp_x0, // this is in Q13 rho_amp_x0, // this is in Q13
len); len);
mult_cpx_vector((c16_t *)rho_1, // Q15 mult_cpx_vector(rho_1, // Q15
(c16_t *)rho_amp_x0, // Q13 rho_amp_x0, // Q13
(c16_t *)rho_rho_amp_x0, rho_rho_amp_x0,
len, len,
13); 13);
sub_cpx_vector16((c16_t *)rxF, sub_cpx_vector16((c16_t *)rxF,
(c16_t *)rho_rho_amp_x0, rho_rho_amp_x0,
//(int16_t *)clean_x1, //(int16_t *)clean_x1,
(c16_t *)rxF, (c16_t *)rxF,
len*2); len * 2);
llr2 = llr32; llr2 = llr32;
llr32 += (len*6); llr32 += (len*6);
+1 -3
View File
@@ -297,9 +297,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) {
exit(-1); exit(-1);
*/ */
sync_pos = lte_sync_time(ue->common_vars.rxdata, sync_pos = lte_sync_time((c16_t **)ue->common_vars.rxdata, frame_parms, (int *)&ue->common_vars.eNb_id);
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); // 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) if (sync_pos >= frame_parms->nb_prefix_samples)
@@ -253,7 +253,7 @@ static void nr_pusch_antenna_processing(void *arg)
pil++; pil++;
c16_t ch = c16addShift(ch0, ch1, 1); c16_t ch = c16addShift(ch0, ch1, 1);
*max_ch = max(abs(ch.r), abs(ch.i)); *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 + 4] = ch;
ul_ls_est[n + 5] = ch; ul_ls_est[n + 5] = ch;
noise_amp2 += c16amp2(c16sub(ch0, 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() // Zero Forcing Rx function: nr_det_HhH()
static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a static void nr_ulsch_det_HhH(c16_t *after_mf_00, // a
int32_t *after_mf_01,//b c16_t *after_mf_01, // b
int32_t *after_mf_10,//c c16_t *after_mf_10, // c
int32_t *after_mf_11,//d c16_t *after_mf_11, // d
uint32_t *det_fin,//1/ad-bc uint32_t *det_fin, // 1/ad-bc
unsigned short nb_rb, unsigned short nb_rb,
unsigned char symbol, unsigned char symbol,
int32_t shift) 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 *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; 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. // TODO: This function is just a wrapper, can be removed.
static void nr_ulsch_conjch0_mult_ch1(int *ch0, 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)
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0)
{ {
//This function is used to compute multiplications in H_hermitian * H matrix //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, 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, static void nr_ulsch_construct_HhH_elements(c16_t *conjch00_ch00,
int *conjch01_ch01, c16_t *conjch01_ch01,
int *conjch11_ch11, c16_t *conjch11_ch11,
int *conjch10_ch10,// c16_t *conjch10_ch10, //
int *conjch20_ch20, c16_t *conjch20_ch20,
int *conjch21_ch21, c16_t *conjch21_ch21,
int *conjch30_ch30, c16_t *conjch30_ch30,
int *conjch31_ch31, c16_t *conjch31_ch31,
int *conjch00_ch01,//00_01 c16_t *conjch00_ch01, // 00_01
int *conjch01_ch00,//01_00 c16_t *conjch01_ch00, // 01_00
int *conjch10_ch11,//10_11 c16_t *conjch10_ch11, // 10_11
int *conjch11_ch10,//11_10 c16_t *conjch11_ch10, // 11_10
int *conjch20_ch21, c16_t *conjch20_ch21,
int *conjch21_ch20, c16_t *conjch21_ch20,
int *conjch30_ch31, c16_t *conjch30_ch31,
int *conjch31_ch30, c16_t *conjch31_ch30,
int32_t *after_mf_00, c16_t *after_mf_00,
int32_t *after_mf_01, c16_t *after_mf_01,
int32_t *after_mf_10, c16_t *after_mf_10,
int32_t *after_mf_11, c16_t *after_mf_11,
unsigned short nb_rb, unsigned short nb_rb,
unsigned char symbol) 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_mag,
int **ul_ch_magb, int **ul_ch_magb,
int **ul_ch_magc, 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 short nb_rb,
unsigned char n_rx, unsigned char n_rx,
unsigned char mod_order, unsigned char mod_order,
int shift, int shift,
unsigned char symbol, unsigned char symbol,
int length, int length,
uint32_t noise_var, uint32_t noise_var)
uint32_t buffer_length)
{ {
int *ch00, *ch01, *ch10, *ch11; c16_t *ch00, *ch01, *ch10, *ch11;
int *ch20, *ch30, *ch21, *ch31; c16_t *ch20, *ch30, *ch21, *ch31;
uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); 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 /* we need at least alignment to 16 bytes, let's put 32 to be sure
* (maybe not necessary but doesn't hurt) * (maybe not necessary but doesn't hurt)
*/ */
int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32))); c16_t conjch00_ch01[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32))); c16_t conjch01_ch00[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32))); c16_t conjch10_ch11[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32))); c16_t conjch11_ch10[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32))); c16_t conjch00_ch00[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32))); c16_t conjch01_ch01[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32))); c16_t conjch10_ch10[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32))); c16_t conjch11_ch11[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32))); c16_t conjch20_ch20[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32))); c16_t conjch21_ch21[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32))); c16_t conjch30_ch30[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32))); c16_t conjch31_ch31[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32))); c16_t conjch20_ch21[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32))); c16_t conjch30_ch31[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32))); c16_t conjch21_ch20[12 * nb_rb] __attribute__((aligned(32)));
int32_t conjch31_ch30[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))); c16_t af_mf_00[12 * nb_rb] __attribute__((aligned(32)));
int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32))); c16_t af_mf_01[12 * nb_rb] __attribute__((aligned(32)));
int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32))); c16_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_11[12 * nb_rb] __attribute__((aligned(32)));
uint32_t determ_fin[12*nb_rb] __attribute__((aligned(32))); uint32_t determ_fin[12*nb_rb] __attribute__((aligned(32)));
switch (n_rx) { switch (n_rx) {
case 2:// case 2://
ch00 = &((int *)ul_ch_estimates_ext)[0 * buffer_length]; ch00 = ul_ch_estimates_ext[0][0];
ch01 = &((int *)ul_ch_estimates_ext)[2 * buffer_length]; ch01 = ul_ch_estimates_ext[1][0];
ch10 = &((int *)ul_ch_estimates_ext)[1 * buffer_length]; ch10 = ul_ch_estimates_ext[0][1];
ch11 = &((int *)ul_ch_estimates_ext)[3 * buffer_length]; ch11 = ul_ch_estimates_ext[1][1];
ch20 = NULL; ch20 = NULL;
ch21 = NULL; ch21 = NULL;
ch30 = NULL; ch30 = NULL;
@@ -585,14 +583,14 @@ static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
break; break;
case 4:// case 4://
ch00 = &((int *)ul_ch_estimates_ext)[0 * buffer_length]; ch00 = ul_ch_estimates_ext[0][0];
ch01 = &((int *)ul_ch_estimates_ext)[4 * buffer_length]; ch01 = ul_ch_estimates_ext[1][0];
ch10 = &((int *)ul_ch_estimates_ext)[1 * buffer_length]; ch10 = ul_ch_estimates_ext[0][1];
ch11 = &((int *)ul_ch_estimates_ext)[5 * buffer_length]; ch11 = ul_ch_estimates_ext[1][1];
ch20 = &((int *)ul_ch_estimates_ext)[2 * buffer_length]; ch20 = ul_ch_estimates_ext[2][0];
ch21 = &((int *)ul_ch_estimates_ext)[6 * buffer_length]; ch21 = ul_ch_estimates_ext[2][1];
ch30 = &((int *)ul_ch_estimates_ext)[3 * buffer_length]; ch30 = ul_ch_estimates_ext[3][0];
ch31 = &((int *)ul_ch_estimates_ext)[7 * buffer_length]; ch31 = ul_ch_estimates_ext[3][1];
break; break;
default: default:
@@ -1031,15 +1029,17 @@ static void inner_rx(PHY_VARS_gNB *gNB,
(int **)rxF_ch_maga, (int **)rxF_ch_maga,
(int **)rxF_ch_magb, (int **)rxF_ch_magb,
(int **)rxF_ch_magc, (int **)rxF_ch_magc,
(int **)chFext, nb_layer,
nb_rx_ant,
buffer_length,
chFext,
rel15_ul->rb_size, rel15_ul->rb_size,
frame_parms->nb_antennas_rx, frame_parms->nb_antennas_rx,
rel15_ul->qam_mod_order, rel15_ul->qam_mod_order,
pusch_vars->log2_maxh, pusch_vars->log2_maxh,
symbol, symbol,
pusch_vars->ul_valid_re_per_slot[symbol], pusch_vars->ul_valid_re_per_slot[symbol],
nvar, nvar);
buffer_length);
} }
} }
if (nb_layer != 2 || rel15_ul->qam_mod_order > 6) if (nb_layer != 2 || rel15_ul->qam_mod_order > 6)
+12 -16
View File
@@ -20,16 +20,15 @@
*/ */
#ifndef __FILT16A_H__ #ifndef __FILT16A_H__
#define __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 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] = static const short filt16a_m0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, -12288, 0, 0, 0, 0};
{{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}; 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 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] = static const short filt16a_m1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0};
{{-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}; 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 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] = static const short filt16a_m2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0};
{{-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_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 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] = static const short filt16a_m3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0};
{{-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}; 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 = int slot_prs =
(proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame; (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]; c16_t mod_prs[NR_MAX_PRS_LENGTH];
const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr; const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
int16_t ch[2] = {0}, noiseFig[2] = {0};
int16_t k_prime = 0, k = 0; int16_t k_prime = 0, k = 0;
int32_t ch_pwr = 0, snr = 0, rsrp = 0, mean_val = 0, prs_toa = 0; int32_t ch_pwr = 0, snr = 0, rsrp = 0, mean_val = 0, prs_toa = 0;
double ch_pwr_dbm = 0.0f; double ch_pwr_dbm = 0.0f;
#ifdef DEBUG_PRS_CHEST #ifdef DEBUG_PRS_CHEST
char filename[64] = {0}, varname[64] = {0}; char filename[64] = {0}, varname[64] = {0};
#endif #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 scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15);
int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB; 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; int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset;
@@ -149,8 +147,8 @@ 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; k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset;
// Channel estimation and interpolation // Channel estimation and interpolation
pil = (int16_t *)mod_prs; c16_t *pil = (c16_t *)mod_prs;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k]; c16_t *rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
if(prs_cfg->CombSize == 2) if(prs_cfg->CombSize == 2)
{ {
@@ -181,101 +179,79 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
} }
//Start pilot //Start pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); c16_t ch = c16MulConjShift(*pil, *rxF, 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);
multadd_real_vector_complex_scalar(fl,
ch,
ch_tmp,
8);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig));
#ifdef DEBUG_PRS_PRINTS #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]); 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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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 //Middle pilots
for(int pIdx = 1; pIdx < num_pilots-1; pIdx+=2) for (int pIdx = 1; pIdx < num_pilots - 1; pIdx += 2) {
{ c16_t ch = c16MulConjShift(*pil, *rxF, 15);
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); multadd_real_vector_complex_scalar(pIdx == 1 ? fml : fm, ch, ch_tmp, 8);
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);
}
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig));
#ifdef DEBUG_PRS_PRINTS #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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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];
ch = c16MulConjShift(*pil, *rxF, 15);
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); multadd_real_vector_complex_scalar(pIdx == (num_pilots - 3) ? fmr : fmm, ch, ch_tmp, 8);
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);
}
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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];
ch_tmp +=8; ch_tmp += 4;
} }
//End pilot //End pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); ch = c16MulConjShift(*pil, *rxF, 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);
multadd_real_vector_complex_scalar(fr,
ch,
ch_tmp,
8);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0] * pil[0] - (int32_t)ch[1] * pil[1]) >> 15); noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1] * pil[0] + (int32_t)ch[0] * pil[1]) >> 15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10 * log10(squaredMod(*((c16_t *)rxF)) - squaredMod(*((c16_t *)noiseFig))) - 10 * log10(squaredMod(*((c16_t *)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n",
rxAnt, rxAnt,
@@ -295,39 +271,39 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
// Choose the interpolation filters // Choose the interpolation filters
switch (k_prime) { switch (k_prime) {
case 0: case 0:
fl = (short int *)filt16a_l0; fl = filt16a_l0;
fml = filt16a_mm0; fml = filt16a_mm0;
fmm = filt16a_mm0; fmm = filt16a_mm0;
fmr = (short int *)filt16a_m0; fmr = filt16a_m0;
fm = (short int *)filt16a_m0; fm = filt16a_m0;
fr = (short int *)filt16a_r0; fr = filt16a_r0;
break; break;
case 1: case 1:
fl = (short int *)filt16a_l1; fl = filt16a_l1;
fml = filt16a_ml1; fml = filt16a_ml1;
fmm = filt16a_mm1; fmm = filt16a_mm1;
fmr = filt16a_mr1; fmr = filt16a_mr1;
fm = (short int *)filt16a_m1; fm = filt16a_m1;
fr = (short int *)filt16a_r1; fr = filt16a_r1;
break; break;
case 2: case 2:
fl = (short int *)filt16a_l2; fl = filt16a_l2;
fml = filt16a_ml2; fml = filt16a_ml2;
fmm = filt16a_mm2; fmm = filt16a_mm2;
fmr = filt16a_mr2; fmr = filt16a_mr2;
fm = (short int *)filt16a_m2; fm = filt16a_m2;
fr = (short int *)filt16a_r2; fr = filt16a_r2;
break; break;
case 3: case 3:
fl = (short int *)filt16a_l3; fl = filt16a_l3;
fml = filt16a_ml3; fml = filt16a_ml3;
fmm = filt16a_mm3; fmm = filt16a_mm3;
fmr = filt16a_mm3; fmr = filt16a_mm3;
fm = (short int *)filt16a_m3; fm = filt16a_m3;
fr = (short int *)filt16a_r3; fr = filt16a_r3;
break; break;
default: default:
@@ -337,101 +313,89 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
} }
//Start pilot //Start pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); c16_t ch = c16MulConjShift(*pil, *rxF, 15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fl, multadd_real_vector_complex_scalar(fl,
ch, ch,
ch_tmp, ch_tmp,
16); 16);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #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]); 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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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];
ch = c16MulConjShift(*pil, *rxF, 15);
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(fml, multadd_real_vector_complex_scalar(fml,
ch, ch,
ch_tmp, ch_tmp,
16); 16);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #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]); 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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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];
ch_tmp +=8; ch_tmp += 4;
//Middle pilots //Middle pilots
for(int pIdx = 2; pIdx < num_pilots-2; pIdx++) 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); c16_t ch = c16MulConjShift(*pil, *rxF, 15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fmm, multadd_real_vector_complex_scalar(fmm,
ch, ch,
ch_tmp, ch_tmp,
16); 16);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); c16_t noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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];
ch_tmp +=8; ch_tmp += 4;
} }
//End pilot //End pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15); ch = c16MulConjShift(*pil, *rxF, 15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fmr, multadd_real_vector_complex_scalar(fmr,
ch, ch,
ch_tmp, ch_tmp,
16); 16);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #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]); 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 #endif
pil +=2; pil++;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; 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];
ch = c16MulConjShift(*pil, *rxF, 15);
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, multadd_real_vector_complex_scalar(fr,
ch, ch,
ch_tmp, ch_tmp,
16); 16);
// SNR & RSRP estimation // SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF)); rsrp += squaredMod(*rxF);
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15); noiseFig = c16sub(*rxF, c16mulShift(ch, *pil, 15));
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15); snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS #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]); 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 #endif
@@ -446,7 +410,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
prs_meas[rxAnt]->rsrp = rsrp / (float)num_pilots; prs_meas[rxAnt]->rsrp = rsrp / (float)num_pilots;
//reset channel pointer //reset channel pointer
ch_tmp = (int16_t*)ch_tmp_buf; ch_tmp = (c16_t *)ch_tmp_buf;
} // for rxAnt } // for rxAnt
} //for l } //for l
@@ -696,31 +660,31 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
k, k,
symbol); symbol);
const c16_t *fl, *fm, *fr; const int16_t *fl, *fm, *fr;
switch (k) { switch (k) {
case 0: case 0:
fl = filt16a_l0; fl = (int16_t *)filt16a_l0;
fm = filt16a_m0; fm = (int16_t *)filt16a_m0;
fr = filt16a_r0; fr = (int16_t *)filt16a_r0;
break; break;
case 1: case 1:
fl = filt16a_l1; fl = (int16_t *)filt16a_l1;
fm = filt16a_m1; fm = (int16_t *)filt16a_m1;
fr = filt16a_r1; fr = (int16_t *)filt16a_r1;
break; break;
case 2: case 2:
fl = filt16a_l2; fl = (int16_t *)filt16a_l2;
fm = filt16a_m2; fm = (int16_t *)filt16a_m2;
fr = filt16a_r2; fr = (int16_t *)filt16a_r2;
break; break;
case 3: case 3:
fl = filt16a_l3; fl = (int16_t *)filt16a_l3;
fm = filt16a_m3; fm = (int16_t *)filt16a_m3;
fr = filt16a_r3; fr = (int16_t *)filt16a_r3;
break; break;
default: default:
@@ -748,21 +712,21 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
c16_t ch; c16_t ch;
ch = c16mulShift(*pil, rxF[re_offset], 15); 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); 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++; pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15); 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); 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++; pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15); 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); 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++; pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
dl_ch += 12; dl_ch += 12;
@@ -786,7 +750,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
ch.i, ch.i,
pil->r, pil->r,
pil->i); pil->i);
multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); multadd_real_vector_complex_scalar(fl, ch, dl_ch, 16);
pil++; pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size; 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, ch.i,
pil->r, pil->r,
pil->i); pil->i);
multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); multadd_real_vector_complex_scalar(fm, ch, dl_ch, 16);
pil++; pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15); ch = c16mulShift(*pil, rxF[re_offset], 15);
@@ -811,7 +775,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
ch.i, ch.i,
pil->r, pil->r,
pil->i); pil->i);
multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); multadd_real_vector_complex_scalar(fr, ch, dl_ch, 16);
pil++; pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
dl_ch += 12; dl_ch += 12;
@@ -843,7 +807,6 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned char aarx; unsigned char aarx;
unsigned short k; unsigned short k;
unsigned int pilot_cnt; unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch;
int ch_offset,symbol_offset; int ch_offset,symbol_offset;
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; 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) if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
dmrs_ref = BWPStart; dmrs_ref = BWPStart;
// generate pilot // 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 // 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); 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++) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
k = coreset_start_subcarrier; k = coreset_start_subcarrier;
pil = (int16_t *)&pilot[dmrs_ref*3]; c16_t *pil = &pilot[dmrs_ref * 3];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; c16_t *rxF = &rxdataF[aarx][symbol_offset + k + 1];
dl_ch = (int16_t *)&pdcch_dl_ch_estimates[aarx][ch_offset]; 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 #ifdef DEBUG_PDCCH
printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[dmrs_ref*3], ue->frame_parms.N_RB_DL); 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 CH_INTERP
// if ((ue->frame_parms.N_RB_DL&1)==0) { // if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF += 4;
#ifdef DEBUG_PDCCH k += 2;
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;
if (k >= ue->frame_parms.ofdm_symbol_size) { if (k >= ue->frame_parms.ofdm_symbol_size) {
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); multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); dl_ch += 12;
#ifdef DEBUG_PDCCH k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
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]); rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 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;
for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt += 3) { 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) { multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
k -= ue->frame_parms.ofdm_symbol_size; k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; 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;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
#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;
} }
#else //ELSE CH_INTERP #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++) { 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 #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]); printf("pilot[%u] = (%d, %d)\trxF[%d] = (%d, %d)\n", pilot_cnt, pil[0], pil[1], k+1, rxF[0], rxF[1]);
#endif #endif
ch_sum[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); c16_t ch = c16mulShift(*pil++, *rxF, 15);
ch_sum[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); ch_sum.r += ch.r;
pil += 2; ch_sum.i += ch.i;
rxF += 8; k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
k += 4; rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
if (pilot_cnt % 3 == 2) { if (pilot_cnt % 3 == 2) {
ch[0] = ch_sum[0] / 3; ch.r = ch_sum.r / 3;
ch[1] = ch_sum[1] / 3; ch.i = ch_sum.i / 3;
multadd_real_vector_complex_scalar(filt16a_1, ch, dl_ch, 16); multadd_real_vector_complex_scalar(filt16a_1, ch, dl_ch, 16);
#ifdef DEBUG_PDCCH #ifdef DEBUG_PDCCH
for (int m =0; m<12; m++) for (int m =0; m<12; m++)
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
#endif #endif
dl_ch += 24; dl_ch += 12;
ch_sum[0] = 0; ch_sum = (c32_t){0};
ch_sum[1] = 0;
} }
} }
#endif //END CH_INTERP #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); return sum_x2 / size - (sum_x / size) * (sum_x / size);
} }
static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp, static int nr_csi_rs_channel_estimation(
const UE_nr_rxtx_proc_t *proc, const NR_DL_FRAME_PARMS *fp,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, const UE_nr_rxtx_proc_t *proc,
const nr_csi_info_t *nr_csi_info, const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const int32_t **csi_rs_generated_signal, const nr_csi_info_t *nr_csi_info,
const int32_t csi_rs_received_signal[][fp->samples_per_slot_wCP], const int32_t **csi_rs_generated_signal,
const csi_mapping_parms_t *csi_mapping, const int32_t csi_rs_received_signal[][fp->samples_per_slot_wCP],
const int CDM_group_size, const csi_mapping_parms_t *csi_mapping,
uint8_t mem_offset, const int CDM_group_size,
int32_t csi_rs_ls_estimated_channel[][csi_mapping->ports][fp->ofdm_symbol_size], uint8_t mem_offset,
int32_t csi_rs_estimated_channel_freq[][csi_mapping->ports][fp->ofdm_symbol_size + FILTER_MARGIN], c16_t csi_rs_ls_estimated_channel[][csi_mapping->ports][fp->ofdm_symbol_size],
int16_t *log2_re, c16_t csi_rs_estimated_channel_freq[][csi_mapping->ports][fp->ofdm_symbol_size + FILTER_MARGIN],
int16_t *log2_maxh, int16_t *log2_re,
uint32_t *noise_power) int16_t *log2_maxh,
uint32_t *noise_power)
{ {
const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP; const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP;
*noise_power = 0; *noise_power = 0;
@@ -288,7 +289,7 @@ static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp,
/// LS channel estimation /// LS channel estimation
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { 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++) { 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; 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 *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 *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 tmp = c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits);
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);
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions // 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. // 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_channel[ant_rx][port_tx][kinit].r += tmp.r;
csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im; 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; 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 *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 *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) | ", printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ",
port_tx+3000, ant_rx, port_tx+3000, ant_rx,
tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i, 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 /// Channel interpolation
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { 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++) { 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 = (fp->first_carrier_offset + rb * NR_NB_SC_PER_RB) % fp->ofdm_symbol_size;
uint16_t k_offset = k + mem_offset; uint16_t k_offset = k + mem_offset;
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { 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]; c16_t csi_rs_ls_estimated_channel16 = 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_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 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); 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) || } 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 (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 } 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 = (fp->first_carrier_offset + rb*NR_NB_SC_PER_RB) % fp->ofdm_symbol_size;
uint16_t k_offset = k + mem_offset; uint16_t k_offset = k + mem_offset;
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { 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_ls_estimated_channel16 = &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_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_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); 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)); 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; (k + fp->ofdm_symbol_size - fp->first_carrier_offset)/NR_NB_SC_PER_RB;
LOG_I(NR_PHY, "(k = %4d) |\t", k); LOG_I(NR_PHY, "(k = %4d) |\t", k);
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) { 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_ls_estimated_channel16 = &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_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) | ", printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
port_tx+3000, ant_rx, port_tx+3000, ant_rx,
csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i, 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 nr_csi_info_t *nr_csi_info,
const uint8_t N_ports, const uint8_t N_ports,
uint8_t mem_offset, 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, const int16_t log2_maxh,
uint8_t *rank_indicator) { uint8_t *rank_indicator)
{
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
const int16_t cond_dB_threshold = 5; const int16_t cond_dB_threshold = 5;
int count = 0; 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 | * | 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[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_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))); 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 nr_csi_info_t *nr_csi_info,
const uint8_t N_ports, const uint8_t N_ports,
uint8_t mem_offset, 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 uint32_t interference_plus_noise_power,
const uint8_t rank_indicator, const uint8_t rank_indicator,
const int16_t log2_re, const int16_t log2_re,
uint8_t *i1, uint8_t *i1,
uint8_t *i2, uint8_t *i2,
uint32_t *precoded_sinr_dB) { uint32_t *precoded_sinr_dB)
{
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; 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'. // 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) { if(rank_indicator == 0 || rank_indicator == 1) {
c64_t sum[4] = {0};
int32_t sum_re[4] = {0}; c64_t sum2[4] = {0};
int32_t sum_im[4] = {0}; int64_t tested_precoded_sinr[4] = {0};
int32_t sum2_re[4] = {0};
int32_t sum2_im[4] = {0};
int32_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++) { 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 = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
uint16_t k_offset = k + mem_offset; uint16_t k_offset = k + mem_offset;
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { 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]; const c16_t p0 = 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 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) // 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[0].r += (p0.r + p1.r);
sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i); sum[0].i += (p0.i + 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[0].r += (sum[0].r * sum[0].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; 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) // 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[1].r += (p0.r - p1.i);
sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r); sum[1].i += (p0.i + 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[1].r += (sum[1].r * sum[1].r) >> 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; 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) // 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[2].r += (p0.r - p1.r);
sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i); sum[2].i += (p0.i - 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[2].r += (sum[2].r * sum[2].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; 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) // 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[3].r += (p0.r + p1.i);
sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r); sum[3].i += (p0.i - 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[3].r += (sum[3].r * sum[3].r) >> 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; 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 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. // we performed this above.
for(int p = 0; p<4; p++) { for(int p = 0; p<4; p++) {
int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re); int64_t power_re = sum2[p].r - (sum[p].r >> log2_re) * (sum[p].r >> log2_re);
int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>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)/(int32_t)interference_plus_noise_power; tested_precoded_sinr[p] = (power_re + power_im) / interference_plus_noise_power;
} }
if(rank_indicator == 0) { 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); 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]; c16_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_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 // (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 // 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. // TODO: This function is just a wrapper, can be removed.
void nr_conjch0_mult_ch1(int *ch0, void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0)
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0)
{ {
//This function is used to compute multiplications in H_hermitian * H matrix //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 rtx = 0; rtx < nl; rtx++) {//row
for (int ctx = 0; ctx < nl; ctx++) {//column for (int ctx = 0; ctx < nl; ctx++) {//column
for (int aarx = 0; aarx < n_rx; aarx++) { for (int aarx = 0; aarx < n_rx; aarx++) {
int *ch0r = (int *)dl_ch_estimates_ext[rtx * n_rx + aarx]; c16_t *ch0r = (c16_t *)dl_ch_estimates_ext[rtx * n_rx + aarx];
int *ch0c = (int *)dl_ch_estimates_ext[ctx * n_rx + aarx]; c16_t *ch0c = (c16_t *)dl_ch_estimates_ext[ctx * n_rx + aarx];
nr_conjch0_mult_ch1(ch0r, nr_conjch0_mult_ch1(ch0r,
ch0c, ch0c,
(int32_t *)conjH_H_elements[aarx][ctx][rtx], // sic conjH_H_elements[aarx][ctx][rtx], // sic
nb_rb_0, nb_rb_0,
shift); shift);
if (aarx != 0) if (aarx != 0)
@@ -59,11 +59,7 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
uint16_t *llr_deint, uint16_t *llr_deint,
uint16_t nb_rb_pdsch); uint16_t nb_rb_pdsch);
void nr_conjch0_mult_ch1(int *ch0, void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0);
int *ch1,
int32_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. /** \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 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))); 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); 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 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, map_current_symbol(p,
dmrs_symbol, dmrs_symbol,
+18 -36
View File
@@ -305,7 +305,6 @@ extern "C" {
x128++; x128++;
} }
} }
//cmult_sv.h
/*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N) /*!\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. 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$ 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 // do 8 multiplications at a time
simd_q15_t *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y; simd_q15_t *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y;
// printf("alpha = %d,%d\n",alpha[0],alpha[1]); // 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_r_128 = set1_int16(alpha.r);
const simd_q15_t alpha_i_128 = set1_int16(alpha[1]); const simd_q15_t alpha_i_128 = set1_int16(alpha.i);
for (uint32_t i = 0; i < N >> 3; i++) { for (uint32_t i = 0; i < N >> 3; i++) {
const simd_q15_t yr = mulhi_s1_int16(alpha_r_128, x_128[i]); const simd_q15_t 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 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, 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) c16_t *y)
{ {
// do 8 multiplications at a time // do 8 multiplications at a time
const simd_q15_t alpha_r_128 = set1_int16(alpha->r); 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_i_128 = set1_int16(alpha.i);
const simd_q15_t *x_128 = (const simd_q15_t *)x; 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 yr = mulhi_s1_int16(alpha_r_128, *x_128);
const simd_q15_t yi = mulhi_s1_int16(alpha_i_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); 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_unpacklo_epi16(yr, yi));
y_128 = simde_mm_adds_epi16(y_128, simde_mm_unpackhi_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$ 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; simd_q15_t alpha_128, *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y;
alpha_128 = set1_int16(alpha); 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++) { for (uint32_t n = 0; n < num_adds; n++) {
const uint32_t offset = num_simd_adds * 4; 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; 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++) { for (uint32_t n = 0; n < num_adds; n++) {
const uint32_t offset = num_simd_adds * 4; 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 N - the size f the vectors (this function does N cpx mpy. WARNING: N%4==0;
@param output_shift - shift to be applied to generate output @param 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 *x1_128 = (simde__m128i *)x1;
const simde__m128i *x2_128 = (simde__m128i *)x2; 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 static inline void mult_cpx_vector(const c16_t *x1, // Q15
const c16_t *x2, // Q13 const c16_t *x2, // Q13
c16_t *y, c16_t *y,
uint32_t N, const uint32_t N,
int output_shift) const int output_shift)
{ {
const simde__m128i *x1_128 = (simde__m128i *)x1; const simde__m128i *x1_128 = (simde__m128i *)x1;
const simde__m128i *x2_128 = (simde__m128i *)x2; 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 *x1_128 = (simde__m128i *)x1;
const simde__m128i *x2_128 = (simde__m128i *)x2; 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$ 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 *x_128 = (simde__m128i *)x;
simde__m128i *y_128 = (simde__m128i *)y; 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); pdu->rx_indication_rel8.length);
// estimate timing advance for MAC // 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; timing_advance_update = sync_pos;
for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++) for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++)
+45 -43
View File
@@ -711,54 +711,56 @@ void ru_fep_full_2thread(RU_t *ru,
3/(fp->symbols_per_tti/2),// Ns = slot number 3/(fp->symbols_per_tti/2),// Ns = slot number
fp); fp);
lte_ul_channel_estimation_RRU(fp, lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates, (c16_t **)calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time, (c16_t **)calibration->drs_ch_estimates_time,
calibration->rxdataF_ext, (c16_t **)calibration->rxdataF_ext,
fp->N_RB_DL, //N_rb_alloc, fp->N_RB_DL, // N_rb_alloc,
proc->frame_rx, proc->frame_rx,
proc->tti_rx,//proc->subframe_rx, proc->tti_rx, // proc->subframe_rx,
0,//u = 0..29 0, // u = 0..29
0,//v = 0,1 0, // v = 0,1
/*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0, /*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/ 0,
3,//l, 3, // l,
0,//interpolate, 0, // interpolate,
0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/); 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); 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 (ru->state == RU_CHECK_SYNC) {
if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) { 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); // LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check);
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); 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) { if (ru->wait_check == 20) {
ru->state = RU_RUN; ru->state = RU_RUN;
ru->wait_check = 0; ru->wait_check = 0;
// Send RRU_sync_ok // Send RRU_sync_ok
rru_config_msg.type = 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 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"); 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); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice, &rru_config_msg, rru_config_msg.len) != -1),
/* "Failed to send msg to RAU %d\n",
//LOG_I(PHY,"~~~~~~~~~ RU_RUN\n"); ru->idx);
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_I(PHY,"~~~~~~~~~ RU_RUN\n");
//LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1); LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1);
LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1); LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1);
exit(-1);*/ //LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,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); LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);
exit(-1); exit(-1);*/
} }
} else { } else if (ru->state == RU_RUN) {
AssertFatal(1==0,"Should not get here\n"); // 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); stop_meas(&ru->ofdm_demod_stats);