Commit 0f55139d authored by Khodr Saaifan's avatar Khodr Saaifan Committed by Thomas Schlichter

Extend nr_dlsch demoulation to support multiple Rx antennas with MRC

parent b962cc94
...@@ -642,14 +642,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ...@@ -642,14 +642,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->pdsch_vars[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); ue->pdsch_vars[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][eNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); ue->pdsch_vars[th_id][eNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) ); ue->pdsch_vars[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
ue->pdsch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); ue->pdsch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
} }
for (int i=0; i<fp->nb_antennas_rx; i++) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
}
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
...@@ -662,6 +657,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ...@@ -662,6 +657,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
ue->pdsch_vars[th_id][eNB_id]->rho[idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
} }
} }
......
...@@ -145,7 +145,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -145,7 +145,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
PHY_NR_MEASUREMENTS *measurements = &ue->measurements; PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
NR_UE_DLSCH_t **dlsch; NR_UE_DLSCH_t **dlsch;
int avg[4]; int avg[16];
// int avg_0[2]; // int avg_0[2];
// int avg_1[2]; // int avg_1[2];
...@@ -396,6 +396,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -396,6 +396,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
frame_parms, frame_parms,
n_tx,
n_rx,
dlsch, dlsch,
symbol, symbol,
pilots, pilots,
...@@ -416,63 +418,46 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -416,63 +418,46 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#endif #endif
if (first_symbol_flag==1) { if (first_symbol_flag==1) {
if (beamforming_mode==0){ if (beamforming_mode==0){
if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) { nr_dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
nr_dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
frame_parms, frame_parms,
n_tx,
avg, avg,
symbol, symbol,
len, len,
nb_rb); nb_rb);
avgs = 0; avgs = 0;
for (aatx=0;aatx<frame_parms->nb_antenna_ports_gNB;aatx++) for (aatx=0;aatx<n_tx;aatx++)
for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) for (aarx=0;aarx<n_rx;aarx++) {
avgs = cmax(avgs,avg[(aatx<<1)+aarx]); //LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
avgs = cmax(avgs,avg[(aatx*frame_parms->nb_antennas_rx)+aarx]);
pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
} median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) }
{ pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+3;
nr_dlsch_channel_level_median(pdsch_vars[eNB_id]->dl_ch_estimates_ext, //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[eNB_id]->log2_maxh);
median,
n_tx, if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
n_rx, nr_dlsch_channel_level_median(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
2*len,// subcarriers Re Im median,
0); n_tx,
n_rx,
for (aatx = 0; aatx < n_tx; ++aatx) len,
{ symbol*nb_rb*12);
for (aarx = 0; aarx < n_rx; ++aarx)
{ for (aatx = 0; aatx < n_tx; aatx++) {
avgs = cmax(avgs, median[aatx*n_rx + aarx]); for (aarx = 0; aarx < n_rx; aarx++) {
} avgs = cmax(avgs, median[aatx*n_rx + aarx]);
} }
}
pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; // this might need to be tuned pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;}
}
} }
//#ifdef UE_DEBUG_TRACE
LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
frame%1024,nr_slot_rx, pdsch_vars[eNB_id]->log2_maxh, frame%1024,nr_slot_rx, pdsch_vars[eNB_id]->log2_maxh,
pdsch_vars[eNB_id]->log2_maxh0, pdsch_vars[eNB_id]->log2_maxh0,
pdsch_vars[eNB_id]->log2_maxh1, pdsch_vars[eNB_id]->log2_maxh1,
avg[0],avgs); avg[0],avgs);
//LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
//#endif
//wait until pdcch is decoded
//proc->channel_level = 1;
} }
/*
uint32_t wait = 0;
while(proc->channel_level == 0)
{
usleep(1);
wait++;
}
*/
#if T_TRACER #if T_TRACER
if (type == PDSCH) if (type == PDSCH)
{ {
...@@ -504,6 +489,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -504,6 +489,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
pdsch_vars[eNB_id]->rxdataF_comp0, pdsch_vars[eNB_id]->rxdataF_comp0,
(aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
frame_parms, frame_parms,
n_tx,
symbol, symbol,
pilots, pilots,
first_symbol_flag, first_symbol_flag,
...@@ -514,48 +500,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -514,48 +500,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
/*if (symbol == 5) { /*if (symbol == 5) {
write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
} */ } */
/*if ((rx_type==rx_IC_single_stream) &&
(eNB_id_i<ue->n_connected_eNB)) {
nr_dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
pdsch_vars[eNB_id_i]->dl_ch_mag0,
pdsch_vars[eNB_id_i]->dl_ch_magb0,
pdsch_vars[eNB_id_i]->rxdataF_comp0,
(aatx>1) ? pdsch_vars[eNB_id_i]->rho : NULL,
frame_parms,
symbol,
first_symbol_flag,
i_mod,
nb_rb,
pdsch_vars[eNB_id]->log2_maxh,
measurements); // log2_maxh+I0_shift
#ifdef DEBUG_PHY
if (symbol == 5) {
write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
}
#endif
dlsch_dual_stream_correlation(frame_parms,
symbol,
nb_rb,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->log2_maxh);
}*/
} }
else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){
nr_dlsch_channel_compensation_core(pdsch_vars[eNB_id]->rxdataF_ext, nr_dlsch_channel_compensation_core(pdsch_vars[eNB_id]->rxdataF_ext,
pdsch_vars[eNB_id]->dl_ch_estimates_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id]->dl_ch_mag0, pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0, pdsch_vars[eNB_id]->dl_ch_magb0,
pdsch_vars[eNB_id]->rxdataF_comp0, //rxdataF_comp pdsch_vars[eNB_id]->rxdataF_comp0, //rxdataF_comp
NULL, NULL,
n_tx, n_tx,
n_rx, n_rx,
dlsch0_harq->Qm, dlsch0_harq->Qm,
pdsch_vars[eNB_id]->log2_maxh, pdsch_vars[eNB_id]->log2_maxh,
2*len, // subcarriers Re Im 2*len, // subcarriers Re Im
...@@ -592,8 +547,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -592,8 +547,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
} */ } */
}
}
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
...@@ -608,9 +562,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -608,9 +562,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
#endif #endif
if (frame_parms->nb_antennas_rx > 1) { if (frame_parms->nb_antennas_rx > 1) {
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0, nr_dlsch_detection_mrc(pdsch_vars[eNB_id]->rxdataF_comp0,
(n_tx>1) ? pdsch_vars[eNB_id]->rho : NULL,
pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0,
n_tx,
n_rx,
symbol,
nb_rb);
} else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){
nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0,
NULL, NULL,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->dl_ch_rho2_ext,
...@@ -628,7 +591,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -628,7 +591,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
} */ } */
} }
} }
//printf("start compute LLR\n"); //printf("start compute LLR\n");
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round];
...@@ -819,8 +781,9 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, ...@@ -819,8 +781,9 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
int **rxdataF_comp, int **rxdataF_comp,
int **rho, int **rho,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t nb_aatx,
unsigned char symbol, unsigned char symbol,
uint8_t pilots, uint8_t pilots,
uint8_t first_symbol_flag, uint8_t first_symbol_flag,
unsigned char mod_order, unsigned char mod_order,
unsigned short nb_rb, unsigned short nb_rb,
...@@ -830,266 +793,286 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, ...@@ -830,266 +793,286 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
#if defined(__i386) || defined(__x86_64) #if defined(__i386) || defined(__x86_64)
unsigned short rb; unsigned short rb;
unsigned char aatx,aarx; unsigned char aatx,aarx;
__m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128; __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
QAM_amp128b = _mm_setzero_si128(); QAM_amp128b = _mm_setzero_si128();
for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) { for (aatx=0; aatx<nb_aatx; aatx++) {
if (mod_order == 4) { if (mod_order == 4) {
QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10)
QAM_amp128b = _mm_setzero_si128(); QAM_amp128b = _mm_setzero_si128();
QAM_amp128r = _mm_setzero_si128(); } else if (mod_order == 6) {
} else if (mod_order == 6) { QAM_amp128 = _mm_set1_epi16(QAM64_n1); //
QAM_amp128 = _mm_set1_epi16(QAM64_n1); // QAM_amp128b = _mm_set1_epi16(QAM64_n2);
QAM_amp128b = _mm_set1_epi16(QAM64_n2); }
QAM_amp128r = _mm_setzero_si128();
} else if (mod_order == 8) { // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
QAM_amp128 = _mm_set1_epi16(QAM256_n1);
QAM_amp128b = _mm_set1_epi16(QAM256_n2); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
QAM_amp128r = _mm_set1_epi16(QAM256_n3);
} dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
// printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12]; for (rb=0; rb<nb_rb; rb++) {
dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12]; if (mod_order>2) {
dl_ch_mag128r = (__m128i *)&dl_ch_magr[(aatx<<1)+aarx][symbol*nb_rb*12]; // get channel amplitude if not QPSK
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12]; mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]);
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
for (rb=0; rb<nb_rb; rb++) { mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]);
if (mod_order>2) { mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// get channel amplitude if not QPSK
mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]);
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); // store channel magnitude here in a new field of dlsch
mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); dl_ch_mag128b[0] = dl_ch_mag128[0];
dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128);
mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
//print_ints("Re(ch):",(int16_t*)&mmtmpD0);
// store channel magnitude here in a new field of dlsch //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
//print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128b[1] = dl_ch_mag128[1];
dl_ch_mag128r[0] = dl_ch_mag128[0]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128);
dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
//print_ints("Re(ch):",(int16_t*)&mmtmpD0); if (pilots==0) {
//print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);
//print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
dl_ch_mag128b[1] = dl_ch_mag128[1];
dl_ch_mag128r[1] = dl_ch_mag128[1]; dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); dl_ch_mag128b[2] = dl_ch_mag128[2];
dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
if (pilots==0) { dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); }
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
dl_ch_mag128b[2] = dl_ch_mag128[2];
dl_ch_mag128r[2] = dl_ch_mag128[2]; dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); if (pilots==0) {
} dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); }
dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); }
// multiply by conjugated channel
dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); // print_ints("re",&mmtmpD0);
dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); // print_ints("im",&mmtmpD1);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
if (pilots==0) { // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); // print_ints("re(shift)",&mmtmpD0);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); // print_ints("im(shift)",&mmtmpD1);
dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
} mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
} // print_ints("c0",&mmtmpD2);
// print_ints("c1",&mmtmpD3);
// multiply by conjugated channel rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpD0); /*if (rb==0) {
printf("arx%d atx%d rb_index %d SC 0 symbol%d\n",aarx,aatx,rb,symbol);//
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit) printf("rx_F_re: %d rx_F_im: %d \n",((int16_t*)&rxdataF128[0])[0],((int16_t*)&rxdataF128[0])[1]);
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); printf("ch_re = %d ch_im = %d \n",((int16_t*)&dl_ch128[0])[0],((int16_t*)&dl_ch128[0])[1]);//
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); printf("rx_Fcomp_re: %d rx_Fcomp_im: %d \n",((int16_t*)&rxdataF_comp128[0])[0],((int16_t*)&rxdataF_comp128[0])[1]);
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); }*/
// print_ints("im",&mmtmpD1); // multiply by conjugated channel
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
// print_ints("re(shift)",&mmtmpD0); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
// print_ints("im(shift)",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// print_ints("c0",&mmtmpD2); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// print_ints("c1",&mmtmpD3); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// print_shorts("rx:",rxdataF128);
// print_shorts("ch:",dl_ch128); rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// print_shorts("pack:",rxdataF_comp128); // print_shorts("rx:",rxdataF128+1);
// print_shorts("ch:",dl_ch128+1);
// multiply by conjugated channel // print_shorts("pack:",rxdataF_comp128+1);
mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit) if (pilots==0) {
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); // multiply by conjugated channel
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// print_shorts("rx:",rxdataF128+1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// print_shorts("ch:",dl_ch128+1);
// print_shorts("pack:",rxdataF_comp128+1); rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// print_shorts("rx:",rxdataF128+2);
if (pilots==0) { // print_shorts("ch:",dl_ch128+2);
// multiply by conjugated channel // print_shorts("pack:",rxdataF_comp128+2);
mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit) dl_ch128+=3;
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); dl_ch_mag128+=3;
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); dl_ch_mag128b+=3;
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); rxdataF128+=3;
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); rxdataF_comp128+=3;
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); dl_ch128+=2;
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); dl_ch_mag128+=2;
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); dl_ch_mag128b+=2;
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); rxdataF128+=2;
rxdataF_comp128+=2;
rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); }
// print_shorts("rx:",rxdataF128+2); }
// print_shorts("ch:",dl_ch128+2); }
// print_shorts("pack:",rxdataF_comp128+2); }
dl_ch128+=3;
dl_ch_mag128+=3;
dl_ch_mag128b+=3;
dl_ch_mag128r+=3;
rxdataF128+=3;
rxdataF_comp128+=3;
} else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
dl_ch128+=2;
dl_ch_mag128+=2;
dl_ch_mag128b+=2;
dl_ch_mag128r+=2;
rxdataF128+=2;
rxdataF_comp128+=2;
}
}
}
}
if (rho) {
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
for (rb=0; rb<nb_rb; rb++) {
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
// print_ints("re",&mmtmpD0);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpD1);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// print_ints("re(shift)",&mmtmpD0);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// print_ints("im(shift)",&mmtmpD1);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// print_ints("c0",&mmtmpD2);
// print_ints("c1",&mmtmpD3);
rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
//print_shorts("rx:",dl_ch128_2);
//print_shorts("ch:",dl_ch128);
//print_shorts("pack:",rho128);
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
//print_shorts("rx:",dl_ch128_2+1);
//print_shorts("ch:",dl_ch128+1);
//print_shorts("pack:",rho128+1);
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[2]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
//print_shorts("rx:",dl_ch128_2+2);
//print_shorts("ch:",dl_ch128+2);
//print_shorts("pack:",rho128+2);
dl_ch128+=3;
dl_ch128_2+=3;
rho128+=3;
}
if (first_symbol_flag==1) { if (rho) {
measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); //rho[aatx*n_rx+0] = Cov(H_0,0,H*_0,aatx), aatx=0,...n_tx-1
} //rho[aatx*n_rx+1] = Cov(H_1,1,H*_1,aatx), aatx=0,...n_tx-1
} //rho[aatx*n_rx+aarx] = Cov(H_aarx,arrx,H*_aarx,aatx), aatx=0,...n_tx-1
}
int avg_rho_re[nb_aatx][frame_parms->nb_antennas_rx];
int avg_rho_im[nb_aatx][frame_parms->nb_antennas_rx];
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*nb_rb*12];//H_{aarx,0}
for (aatx=1; aatx<nb_aatx; aatx++) {
avg_rho_re[aatx][aarx] = 0;
avg_rho_im[aatx][aarx] = 0;
rho128 = (__m128i *)&rho[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];//(aatx*frame_parms->nb_antennas_rx)+
dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
for (rb=0; rb<nb_rb; rb++) {
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
// print_ints("re",&mmtmpD0);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpD1);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// print_ints("re(shift)",&mmtmpD0);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// print_ints("im(shift)",&mmtmpD1);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// print_ints("c0",&mmtmpD2);
// print_ints("c1",&mmtmpD3);
rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
//print_shorts("rx:",dl_ch128_2);
//print_shorts("ch:",dl_ch128);
//print_shorts("pack:",rho128);
avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[0])[0]+
((int16_t*)&rho128[0])[2] +
((int16_t*)&rho128[0])[4] +
((int16_t*)&rho128[0])[6])/16;
avg_rho_im[aatx][aarx] +=(((int16_t*)&rho128[0])[1]+
((int16_t*)&rho128[0])[3] +
((int16_t*)&rho128[0])[5] +
((int16_t*)&rho128[0])[7])/16;
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
//print_shorts("rx:",dl_ch128_2+1);
//print_shorts("ch:",dl_ch128+1);
//print_shorts("pack:",rho128+1);
// multiply by conjugated channel
avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[1])[0]+
((int16_t*)&rho128[1])[2] +
((int16_t*)&rho128[1])[4] +
((int16_t*)&rho128[1])[6])/16;
avg_rho_im[aatx][aarx] +=(((int16_t*)&rho128[1])[1]+
((int16_t*)&rho128[1])[3] +
((int16_t*)&rho128[1])[5] +
((int16_t*)&rho128[1])[7])/16;
mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[2]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
//print_shorts("rx:",dl_ch128_2+2);
//print_shorts("ch:",dl_ch128+2);
//print_shorts("pack:",rho128+2);
avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[2])[0]+
((int16_t*)&rho128[2])[2] +
((int16_t*)&rho128[2])[4] +
((int16_t*)&rho128[2])[6])/16;
avg_rho_im[aatx][aarx] +=(((int16_t*)&rho128[2])[1]+
((int16_t*)&rho128[2])[3] +
((int16_t*)&rho128[2])[5] +
((int16_t*)&rho128[2])[7])/16;
dl_ch128+=3;
dl_ch128_2+=3;
rho128+=3;
}
if (first_symbol_flag==1) {
//measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12);
avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12);
avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12);
printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]);
}
}
}
}
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
#elif defined(__arm__) #elif defined(__arm__)
...@@ -1499,6 +1482,8 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, ...@@ -1499,6 +1482,8 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
uint8_t n_rx,
NR_UE_DLSCH_t **dlsch_ue, NR_UE_DLSCH_t **dlsch_ue,
uint8_t symbol, uint8_t symbol,
uint8_t pilots, uint8_t pilots,
...@@ -1523,10 +1508,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, ...@@ -1523,10 +1508,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) { for (aatx=0; aatx<n_tx; aatx++) {
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<n_rx; aarx++) {
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*n_rx)+aarx][symbol*nb_rb*12];
for (rb=0;rb<nb_rb_0;rb++) { for (rb=0;rb<nb_rb_0;rb++) {
...@@ -1557,6 +1542,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, ...@@ -1557,6 +1542,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
//compute average channel_level on each (TX,RX) antenna pair //compute average channel_level on each (TX,RX) antenna pair
void nr_dlsch_channel_level(int **dl_ch_estimates_ext, void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
int32_t *avg, int32_t *avg,
uint8_t symbol, uint8_t symbol,
uint32_t len, uint32_t len,
...@@ -1565,42 +1551,41 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, ...@@ -1565,42 +1551,41 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
#if defined(__x86_64__)||defined(__i386__) #if defined(__x86_64__)||defined(__i386__)
short rb; short rb;
unsigned char aatx,aarx; unsigned char aatx,aarx;
__m128i *dl_ch128, avg128D; __m128i *dl_ch128, avg128D;
//nb_rb*nre = y * 2^x //nb_rb*nre = y * 2^x
int16_t x = factor2(len); int16_t x = factor2(len);
//x = (x>4) ? 4 : x; //x = (x>4) ? 4 : x;
int16_t y = (len)>>x; int16_t y = (len)>>x;
//printf("len = %d = %d * 2^(%d)\n",len,y,x); //printf("len = %d = %d * 2^(%d)\n",len,y,x);
AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__);
for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) for (aatx=0; aatx<n_tx; aatx++)
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level //clear average level
avg128D = _mm_setzero_si128(); avg128D = _mm_setzero_si128();
// 5 is always a symbol with no pilots for both normal and extended prefix
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
for (rb=0;rb<nb_rb;rb++) { for (rb=0;rb<nb_rb;rb++) {
avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
dl_ch128+=3; dl_ch128+=3;
} }
avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] + avg[(aatx*frame_parms->nb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] +
((int32_t*)&avg128D)[1] + ((int32_t*)&avg128D)[1] +
((int32_t*)&avg128D)[2] + ((int32_t*)&avg128D)[2] +
((int32_t*)&avg128D)[3])/y; ((int32_t*)&avg128D)[3])/y;
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
} }
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
#elif defined(__arm__) #elif defined(__arm__)
...@@ -1671,48 +1656,48 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -1671,48 +1656,48 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
#if defined(__x86_64__)||defined(__i386__) #if defined(__x86_64__)||defined(__i386__)
short ii; short ii;
int aatx,aarx; int aatx,aarx;
int length2; int length2;
int max = 0, min=0; int max = 0, min=0;
int norm_pack; int norm_pack;
__m128i *dl_ch128, norm128D; __m128i *dl_ch128, norm128D;
for (aatx=0; aatx<n_tx; aatx++){ for (aatx=0; aatx<n_tx; aatx++){
for (aarx=0; aarx<n_rx; aarx++) { for (aarx=0; aarx<n_rx; aarx++) {
max = 0; max = median[aatx*n_rx + aarx];//initialize the med point for max
min = 0; min = median[aatx*n_rx + aarx];//initialize the med point for min
norm128D = _mm_setzero_si128(); norm128D = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][start_point]; dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point];
length2 = length>>2; length2 = length>>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop
for (ii=0;ii<length2;ii++) { for (ii=0;ii<length2;ii++) {
norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 1); norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 2);//[|H_0|²/4 |H_1|²/4 |H_2|²/4 |H_3|²/4]
//print_ints("norm128D",&norm128D[0]); //print_ints("norm128D",&norm128D[0]);
norm_pack = ((int32_t*)&norm128D)[0] + norm_pack = ((int32_t*)&norm128D)[0] +
((int32_t*)&norm128D)[1] + ((int32_t*)&norm128D)[1] +
((int32_t*)&norm128D)[2] + ((int32_t*)&norm128D)[2] +
((int32_t*)&norm128D)[3]; ((int32_t*)&norm128D)[3];// compute the sum
if (norm_pack > max) if (norm_pack > max)
max = norm_pack; max = norm_pack;//store values more than max
if (norm_pack < min) if (norm_pack < min)
min = norm_pack; min = norm_pack;//store values less than min
dl_ch128+=1; dl_ch128+=1;
} }
median[aatx*n_rx + aarx] = (max+min)>>1; median[aatx*n_rx + aarx] = (max+min)>>1;
// printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); //printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min);
} }
} }
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
#elif defined(__arm__) #elif defined(__arm__)
...@@ -2235,6 +2220,59 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, ...@@ -2235,6 +2220,59 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
return(nb_rb_pdsch); return(nb_rb_pdsch);
} }
void nr_dlsch_detection_mrc(int **rxdataF_comp,
int **rho,
int **dl_ch_mag,
int **dl_ch_magb,
short n_tx,
short n_rx,
unsigned char symbol,
unsigned short nb_rb) {
#if defined(__x86_64__)||defined(__i386__)
unsigned char aatx, aarx;
int i;
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b;
if (n_rx>1) {
for (aatx=0; aatx<n_tx; aatx++) {
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[(aatx*n_rx)][symbol*nb_rb*12];
for (aarx=1; aarx<n_rx; aarx++) {
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx*n_rx)+aarx][symbol*nb_rb*12];// aarx=1,..., n_rx-1
dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[(aatx*n_rx)+aarx][symbol*nb_rb*12];
dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[(aatx*n_rx)+aarx][symbol*nb_rb*12];
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) {
rxdataF_comp128_0[i] = _mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
dl_ch_mag128_0[i] = _mm_adds_epi16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
dl_ch_mag128_0b[i] = _mm_adds_epi16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
/*if (i==0) {
printf("atx%d symbol%d\n",aatx,symbol);
printf("mrc comp0 re: %d mrc comp0 im: %d \n",((int16_t*)&rxdataF_comp128_0[0])[0],((int16_t*)&rxdataF_comp128_0[0])[1]);
printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
}*/
}
}
}
if (rho) {
/*rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
for (i=0; i<nb_rb*3; i++) {
// print_shorts("mrc rho0:",&rho128_0[i]);
// print_shorts("mrc rho1:",&rho128_1[i]);
rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
}*/
}
_mm_empty();
_m_empty();
}
#endif
}
static void nr_dlsch_layer_demapping(int16_t **llr_cw, static void nr_dlsch_layer_demapping(int16_t **llr_cw,
uint8_t Nl, uint8_t Nl,
......
...@@ -805,6 +805,7 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext, ...@@ -805,6 +805,7 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
int32_t **rxdataF_comp, int32_t **rxdataF_comp,
int32_t **rho, int32_t **rho,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t nb_aatx,
uint8_t symbol, uint8_t symbol,
uint8_t start_symbol, uint8_t start_symbol,
uint8_t first_symbol_flag, uint8_t first_symbol_flag,
...@@ -889,6 +890,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -889,6 +890,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
int length, int length,
int start_point); int start_point);
void nr_dlsch_detection_mrc(int **rxdataF_comp,
int **rho,
int **dl_ch_mag,
int **dl_ch_magb,
short n_tx,
short n_rx,
unsigned char symbol,
unsigned short nb_rb);
void nr_dlsch_detection_mrc_core(int **rxdataF_comp, void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
int **rxdataF_comp_i, int **rxdataF_comp_i,
int **rho, int **rho,
...@@ -962,6 +972,7 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms, ...@@ -962,6 +972,7 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
*/ */
void nr_dlsch_channel_level(int **dl_ch_estimates_ext, void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
int32_t *avg, int32_t *avg,
uint8_t symbol, uint8_t symbol,
uint32_t len, uint32_t len,
...@@ -993,6 +1004,8 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext, ...@@ -993,6 +1004,8 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
uint8_t n_rx,
NR_UE_DLSCH_t **dlsch_ue, NR_UE_DLSCH_t **dlsch_ue,
uint8_t symbol, uint8_t symbol,
uint8_t start_symbol, uint8_t start_symbol,
......
...@@ -234,7 +234,7 @@ typedef struct { ...@@ -234,7 +234,7 @@ typedef struct {
//! estimated rssi (dBm) //! estimated rssi (dBm)
short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX];
//! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][4][4];
//! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2];
...@@ -379,8 +379,8 @@ typedef struct { ...@@ -379,8 +379,8 @@ typedef struct {
int32_t **dl_ch_magb1[8][8]; int32_t **dl_ch_magb1[8][8];
/// \brief Magnitude of Downlink Channel, first layer (256QAM level). /// \brief Magnitude of Downlink Channel, first layer (256QAM level).
int32_t **dl_ch_magr0; int32_t **dl_ch_magr0;
/// \brief Cross-correlation of two eNB signals. /// \brief Cross-correlation Matrix of the gNB Tx channel signals.
/// - first index: rx antenna [0..nb_antennas_rx[ /// - first index: aatx*n_rx+aarx for all aatx=[0..n_tx[ and aarx=[0..nb_rx[
/// - second index: symbol [0..] /// - second index: symbol [0..]
int32_t **rho; int32_t **rho;
/// never used... always send dl_ch_rho_ext instead... /// never used... always send dl_ch_rho_ext instead...
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment