Merge remote-tracking branch 'origin/lte_uplink_improvement' into integration_2021_wk04_b

This commit is contained in:
hardy
2021-01-29 07:41:47 +01:00
30 changed files with 1084 additions and 252 deletions
@@ -786,33 +786,38 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms,
Ravg[0]=0;
Ravg[1]=0;
int16_t iv, rv, phase_idx = 0;
__m128i avg128U1, avg128U2, R[3], mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3;
__m128i R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
__m128 avg128U1, avg128U2;
// round(tan((pi/4)*[1:1:N]/N)*pow2(15))
int16_t alpha[128] = {201, 402, 603, 804, 1006, 1207, 1408, 1610, 1811, 2013, 2215, 2417, 2619, 2822, 3024, 3227, 3431, 3634, 3838, 4042, 4246, 4450, 4655, 4861, 5066, 5272, 5479, 5686, 5893, 6101, 6309, 6518, 6727, 6937, 7147, 7358, 7570, 7782, 7995, 8208, 8422, 8637, 8852, 9068, 9285, 9503, 9721, 9940, 10160, 10381, 10603, 10825, 11049, 11273, 11498, 11725, 11952, 12180, 12410, 12640, 12872, 13104, 13338, 13573, 13809, 14046, 14285, 14525, 14766, 15009, 15253, 15498, 15745, 15993, 16243, 16494, 16747, 17001, 17257, 17515, 17774, 18035, 18298, 18563, 18829, 19098, 19368, 19640, 19915, 20191, 20470, 20750, 21033, 21318, 21605, 21895, 22187, 22481, 22778, 23078, 23380, 23685, 23992, 24302, 24615, 24931, 25250, 25572, 25897, 26226, 26557, 26892, 27230, 27572, 27917, 28266, 28618, 28975, 29335, 29699, 30067, 30440, 30817, 31198, 31583, 31973, 32368, 32767};
// compute log2_maxh (output_shift)
avg128U1 = _mm_setzero_si128();
avg128U2 = _mm_setzero_si128();
avg128U1 = _mm_setzero_ps();
avg128U2 = _mm_setzero_ps();
for (rb=0; rb<nb_rb; rb++) {
avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[0],ul_ch1[0]));
avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[1],ul_ch1[1]));
avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[2],ul_ch1[2]));
avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[0],ul_ch2[0]));
avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[1],ul_ch2[1]));
avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[2],ul_ch2[2]));
avg128U1 = _mm_add_ps(avg128U1,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch1[0],ul_ch1[0])));
avg128U1 = _mm_add_ps(avg128U1,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch1[1],ul_ch1[1])));
avg128U1 = _mm_add_ps(avg128U1,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch1[2],ul_ch1[2])));
avg128U2 = _mm_add_ps(avg128U2,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch2[0],ul_ch2[0])));
avg128U2 = _mm_add_ps(avg128U2,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch2[1],ul_ch2[1])));
avg128U2 = _mm_add_ps(avg128U2,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch2[2],ul_ch2[2])));
ul_ch1+=3;
ul_ch2+=3;
}
avg[0] = (((int *)&avg128U1)[0] +
((int *)&avg128U1)[1] +
((int *)&avg128U1)[2] +
((int *)&avg128U1)[3])/(nb_rb*12);
avg[1] = (((int *)&avg128U2)[0] +
((int *)&avg128U2)[1] +
((int *)&avg128U2)[2] +
((int *)&avg128U2)[3])/(nb_rb*12);
avg[0] = (int)( (((float*)&avg128U1)[0] +
((float*)&avg128U1)[1] +
((float*)&avg128U1)[2] +
((float*)&avg128U1)[3])/(float)(nb_rb*12) );
avg[1] = (int)( (((float*)&avg128U2)[0] +
((float*)&avg128U2)[1] +
((float*)&avg128U2)[2] +
((float*)&avg128U2)[3])/(float)(nb_rb*12) );
// msg("avg0 = %d, avg1 = %d\n",avg[0],avg[1]);
avg[0] = cmax(avg[0],avg[1]);
avg[1] = log2_approx(avg[0]);
+2
View File
@@ -2071,6 +2071,8 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
ulsch->harq_processes[harq_pid]->round++;
ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3;
ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
ulsch->harq_processes[harq_pid]->Or1 = 0;
ulsch->harq_processes[harq_pid]->Or2 = 0;
}
ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
+8 -3
View File
@@ -716,6 +716,7 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
uint8_t NSF_PHICH = 4;
uint8_t pusch_subframe=-1;
uint8_t i;
uint8_t harq_pid = 0;
int subframe = proc->subframe_tx;
phich_config_t *phich;
@@ -748,16 +749,20 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
nseq_PHICH = ((phich->first_rb/Ngroup_PHICH) +
phich->n_DMRS)%(2*NSF_PHICH);
harq_pid = subframe2harq_pid(frame_parms,phich_frame2_pusch_frame(frame_parms,proc->frame_tx,subframe),pusch_subframe);
if (harq_pid == 255) {
LOG_E(PHY,"FATAL ERROR: illegal harq_pid, returning\n");
return;
}
LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, AMP %d ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d)\n",
eNB->Mod_id,subframe2harq_pid(frame_parms,
phich_frame2_pusch_frame(frame_parms,proc->frame_tx,subframe),pusch_subframe),proc->frame_tx,
eNB->Mod_id,harq_pid,proc->frame_tx,
subframe,amp,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,
phich->hi,
phich->first_rb);
T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe),
T_INT(-1 /* TODO: rnti */),
T_INT(subframe2harq_pid(frame_parms,phich_frame2_pusch_frame(frame_parms,proc->frame_tx,subframe),pusch_subframe)),
T_INT(harq_pid),
T_INT(Ngroup_PHICH), T_INT(NSF_PHICH),
T_INT(ngroup_PHICH), T_INT(nseq_PHICH),
T_INT(phich->hi),
+28
View File
@@ -102,6 +102,34 @@ unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char su
return(subframe&7);
switch (frame_parms->tdd_config) {
case 1:
if (subframe == 6) {
return(0);
} else if (subframe==9){
return(1);
} else if (subframe==1){
return(2);
} else if (subframe==4){
return(3);
} else {
LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n",
subframe,frame_parms->tdd_config);
return(0);
}
break;
case 2:
if (subframe == 3) {
return(1);
} else if (subframe==8){
return(0);
} else {
LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n",
subframe,frame_parms->tdd_config);
return(0);
}
break;
case 3:
if ( (subframe == 8) || (subframe == 9) ) {
return(subframe-8);
+1 -1
View File
@@ -626,7 +626,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
for (i=0; i<NCS2; i++) {
lev = (int32_t)prach_ifft[(preamble_shift2+i)];
avg_en += lev;
levdB = dB_fixed_times10(lev);
levdB = dB_fixed_x10(lev);
if (levdB>*max_preamble_energy) {
*max_preamble_energy = levdB;
+150 -7
View File
@@ -721,6 +721,137 @@ int16_t pucchfmt3_Decode( int16_t b[48],
}
}
uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB,
int frame,
uint8_t subframe,
uint8_t shortened_format
)
//-----------------------------------------------------------------------------
{
LTE_eNB_COMMON *common_vars = &eNB->common_vars;
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
uint32_t u,v,n,aa;
uint32_t z[12*14];
int16_t *zptr;
int16_t rxcomp[NB_ANTENNAS_RX][2*12*14];
uint8_t ns,N_UL_symb,nsymb,n_cs_base;
uint16_t i,j,re_offset;
uint8_t m,l;
uint8_t n_cs,alpha_ind;
int16_t tmp_re,tmp_im,W_re=0,W_im=0;
int16_t W4_nouse[4]={32767,32767,-32768,-32768};
int32_t n0_IQ[2];
double interference_power;
int16_t *rxptr;
uint32_t symbol_offset;
uint32_t u0 = (frame_parms->pucch_config_common.grouphop[subframe<<1]) % 30;
uint32_t u1 = (frame_parms->pucch_config_common.grouphop[1+(subframe<<1)]) % 30;
uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
int calc_cnt;
zptr = (int16_t *)z;
N_UL_symb = (frame_parms->Ncp==NORMAL) ? 7 : 6;
interference_power=0.0;
calc_cnt=0;
// loop over 2 slots
for (n_cs_base=0; n_cs_base<12; n_cs_base++) {
zptr = (int16_t *)z;
for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) {
//loop over symbols in slot
for (l=0; l<N_UL_symb; l++) {
n_cs = eNB->ncs_cell[ns][l]+n_cs_base;
if(((l>1)&&(l<N_UL_symb-2)) || ((ns==(1+(subframe<<1))) && (shortened_format==1)) ){
zptr+=24;
continue;
}
if (l<2) { // data
W_re=W4_nouse[l];
W_im=0;
} else if ((l>=N_UL_symb-2)) { // data
W_re=W4_nouse[l-N_UL_symb+4];
W_im=0;
}
alpha_ind=0;
// compute output sequence
for (n=0; n<12; n++) {
// this is r_uv^alpha(n)
tmp_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
tmp_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);
// this is S(ns)*w_noc(m)*r_uv^alpha(n)
zptr[n<<1] = (tmp_re*W_re - tmp_im*W_im)>>15;
zptr[1+(n<<1)] = -(tmp_re*W_im + tmp_im*W_re)>>15;
alpha_ind = (alpha_ind + n_cs)%12;
} // n
zptr+=24;
} // l
} // ns
m = 1;
nsymb = N_UL_symb<<1;
zptr = (int16_t*)z;
// Do detection
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
n0_IQ[0]=0;
n0_IQ[1]=0;
for (j=0,l=0; l<nsymb; l++) {
if((((l%N_UL_symb)>1)&&((l%N_UL_symb)<N_UL_symb-2)) || ((nsymb>=N_UL_symb) && (shortened_format==1)) ){
j+=24;
continue;
}
if ((l<(nsymb>>1)) && ((m&1) == 0))
re_offset = (m*6) + frame_parms->first_carrier_offset;
else if ((l<(nsymb>>1)) && ((m&1) == 1))
re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12;
else if ((m&1) == 0)
re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12;
else
re_offset = ((m-1)*6) + frame_parms->first_carrier_offset;
if (re_offset > frame_parms->ofdm_symbol_size)
re_offset -= (frame_parms->ofdm_symbol_size);
symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*l;
rxptr = (int16_t *)&common_vars->rxdataF[aa][symbol_offset];
for (i=0; i<12; i++,j+=2,re_offset++) {
if (re_offset==frame_parms->ofdm_symbol_size)
re_offset = 0;
rxcomp[aa][j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15) - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15);
rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15);
n0_IQ[0]+=rxcomp[aa][j];
n0_IQ[1]+=rxcomp[aa][1+j];
} //re
calc_cnt++;
} // symbol
n0_IQ[0]/=12;
n0_IQ[1]/=12;
interference_power+= (double)(n0_IQ[0]*n0_IQ[0]+n0_IQ[1]*n0_IQ[1]);
} // antenna
}
interference_power /= calc_cnt;
eNB->measurements.n0_pucch_dB = dB_fixed_x10((int)interference_power)/10;
LOG_D(PHY,"estimate pucch noise %lf %d %d\n",interference_power,calc_cnt,eNB->measurements.n0_pucch_dB);
return 0;
}
/* PUCCH format3 << */
uint32_t rx_pucch(PHY_VARS_eNB *eNB,
@@ -740,7 +871,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
static int first_call = 1;
LTE_eNB_COMMON *common_vars = &eNB->common_vars;
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
int8_t sigma2_dB = max(eNB->measurements.n0_subband_power_tot_dB[0], eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]);
int8_t sigma2_dB = eNB->measurements.n0_pucch_dB;
uint32_t u,v,n,aa;
uint32_t z[12*14];
int16_t *zptr;
@@ -765,8 +897,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
uint8_t deltaPUCCH_Shift = frame_parms->pucch_config_common.deltaPUCCH_Shift;
uint8_t NRB2 = frame_parms->pucch_config_common.nRB_CQI;
uint8_t Ncs1_div_deltaPUCCH_Shift = frame_parms->pucch_config_common.nCS_AN;
uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30;
uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30;
uint32_t u0 = (frame_parms->pucch_config_common.grouphop[subframe<<1]) % 30;
uint32_t u1 = (frame_parms->pucch_config_common.grouphop[1+(subframe<<1)]) % 30;
uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
int chL;
@@ -1141,8 +1274,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
}
// this is total energy received, summed over data and reference
stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
if (fmt==pucch_format1a){
stat += ((((stat_re*stat_re)) + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
}else{
stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
}
// now second slot
stat_re=0;
stat_im=0;
@@ -1170,8 +1308,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
#ifdef DEBUG_PUCCH_RX
printf("aa%d re %d : phase %d : stat %d\n",aa,re,phase,stat);
#endif
stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
if (fmt==pucch_format1a){
stat += ((((stat_re*stat_re)) + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
}else{
stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
}
} //re
} // aa
+5 -1
View File
@@ -621,7 +621,11 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t frame,
uint8_t Ns);
uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB,
int frame,
uint8_t subframe,
uint8_t shortened_format
);
uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
PUCCH_FMT_t fmt,
+36 -11
View File
@@ -755,6 +755,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
__m128i *ul_ch128,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128;
uint8_t aarx;//,symbol_mod;
__m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
#elif defined(__arm__)
int16x4_t *ul_ch128,*rxdataF128;
int16x8_t *ul_ch_mag128,*ul_ch_mag128b,*rxdataF_comp128;
@@ -762,6 +763,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
int32x4_t mmtmpU0,mmtmpU1,mmtmpU0b,mmtmpU1b;
int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -872,6 +874,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
rxdataF_comp128[0] = _mm_add_epi16(rxdataF_comp128[0],(*(__m128i *)&jitter[0]));
rxdataF_comp128[1] = _mm_add_epi16(rxdataF_comp128[1],(*(__m128i *)&jitter[0]));
rxdataF_comp128[2] = _mm_add_epi16(rxdataF_comp128[2],(*(__m128i *)&jitter[0]));
ul_ch128+=3;
ul_ch_mag128+=3;
ul_ch_mag128b+=3;
@@ -918,9 +921,10 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
mmtmpU1 = vqshlq_s32(mmtmpU1,-output_shift128);
rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
// Add a jitter to compensate for the saturation in "packs" resulting in a bias on the DC after IDFT
rxdataF_comp128[0] = vqaddq_s16(rxdataF_comp128[0],(*(int16x8_t *)&jitter[0]));
rxdataF_comp128[1] = vqaddq_s16(rxdataF_comp128[1],(*(int16x8_t *)&jitter[0]));
rxdataF_comp128[2] = vqaddq_s16(rxdataF_comp128[2],(*(int16x8_t *)&jitter[0]));
rxdataF_comp128[0] = vqaddq_s16(rxdataF_comp128[0],(*(int16x8_t*)&jitter[0]));
rxdataF_comp128[1] = vqaddq_s16(rxdataF_comp128[1],(*(int16x8_t*)&jitter[0]));
rxdataF_comp128[2] = vqaddq_s16(rxdataF_comp128[2],(*(int16x8_t*)&jitter[0]));
ul_ch128+=6;
ul_ch_mag128+=3;
ul_ch_mag128b+=3;
@@ -1031,6 +1035,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
AssertFatal(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb > 0,
"PUSCH (%d/%x) nb_rb=0!\n", harq_pid,ulsch[UE_id]->rnti);
for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active); l++) {
if(LOG_DEBUGFLAG(DEBUG_ULSCH)) {
LOG_I(PHY,"rx_ulsch : symbol %d (first_rb %d,nb_rb %d), rxdataF %p, rxdataF_ext %p\n",l,
@@ -1064,18 +1069,38 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
if (deltaMCS==1) {
// Note we're using TBS instead of sumKr, since didn't run segmentation yet!
MPR_times_100Ks = 500*ulsch[UE_id]->harq_processes[harq_pid]->TBS/(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*4*ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch);
AssertFatal(MPR_times_100Ks < 750 && MPR_times_100Ks >= 0,"Impossible value for MPR_times_100Ks %d (TBS %d,Nre %d)\n",
MPR_times_100Ks,ulsch[UE_id]->harq_processes[harq_pid]->TBS,
(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*4*ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch));
if (MPR_times_100Ks > 0) correction_factor = ulsch_power_LUT[MPR_times_100Ks];
if ((MPR_times_100Ks > 0)&&(MPR_times_100Ks < 750)){
correction_factor = ulsch_power_LUT[MPR_times_100Ks];
}else{
correction_factor = 1;
}
}
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)/correction_factor;
LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid,
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_times10(pusch_vars->ulsch_power[i]));
//symbol 3
int symbol_offset = frame_parms->N_RB_UL*12*(3 - frame_parms->Ncp);
pusch_vars->ulsch_interference_power[i] = interference_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12);
pusch_vars->ulsch_power[i] = signal_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12);
//symbol 3+7
symbol_offset = frame_parms->N_RB_UL*12*((3 - frame_parms->Ncp)+(7-frame_parms->Ncp));
pusch_vars->ulsch_interference_power[i] += interference_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12);
pusch_vars->ulsch_power[i] += signal_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12);
pusch_vars->ulsch_interference_power[i] = pusch_vars->ulsch_interference_power[i]/correction_factor;
pusch_vars->ulsch_power[i] = pusch_vars->ulsch_power[i]/correction_factor;
if(pusch_vars->ulsch_power[i]>0x20000000){
pusch_vars->ulsch_power[i] = 0x20000000;
pusch_vars->ulsch_interference_power[i] = 1;
}else{
pusch_vars->ulsch_power[i] -= pusch_vars->ulsch_interference_power[i];
if(pusch_vars->ulsch_power[i]<1) pusch_vars->ulsch_power[i] = 1;
if(pusch_vars->ulsch_interference_power[i]<1)pusch_vars->ulsch_interference_power[i] = 1;
}
LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_x10(pusch_vars->ulsch_power[i]));
}
ulsch_channel_level(pusch_vars->drs_ch_estimates,
+315
View File
@@ -540,6 +540,289 @@ int16_t dB_table_times10[256] = {
240,
240
};
uint32_t bit_seach_mask[32] = {
0x80000000, 0x40000000, 0x20000000, 0x10000000,
0x08000000, 0x04000000, 0x02000000, 0x01000000,
0x00800000, 0x00400000, 0x00200000, 0x00100000,
0x00080000, 0x00040000, 0x00020000, 0x00010000,
0x00008000, 0x00004000, 0x00002000, 0x00001000,
0x00000800, 0x00000400, 0x00000200, 0x00000100,
0x00000080, 0x00000040, 0x00000020, 0x00000010,
0x00000008, 0x00000004, 0x00000002, 0x00000001
};
uint32_t bit_seach_res[32] = {
31, 30, 29, 28,
27, 26, 25, 24,
23, 22, 21, 20,
19, 18, 17, 16,
15, 14, 13, 12,
11, 10, 9, 8,
7, 6, 5, 4,
3, 2, 1, 0
};
uint32_t dB_fix_x10_tbl[128] = {
0 ,
0 ,
1 ,
1 ,
1 ,
2 ,
2 ,
2 ,
3 ,
3 ,
3 ,
4 ,
4 ,
4 ,
5 ,
5 ,
5 ,
5 ,
6 ,
6 ,
6 ,
7 ,
7 ,
7 ,
7 ,
8 ,
8 ,
8 ,
9 ,
9 ,
9 ,
9 ,
10 ,
10 ,
10 ,
10 ,
11 ,
11 ,
11 ,
12 ,
12 ,
12 ,
12 ,
13 ,
13 ,
13 ,
13 ,
14 ,
14 ,
14 ,
14 ,
15 ,
15 ,
15 ,
15 ,
16 ,
16 ,
16 ,
16 ,
16 ,
17 ,
17 ,
17 ,
17 ,
18 ,
18 ,
18 ,
18 ,
19 ,
19 ,
19 ,
19 ,
19 ,
20 ,
20 ,
20 ,
20 ,
20 ,
21 ,
21 ,
21 ,
21 ,
22 ,
22 ,
22 ,
22 ,
22 ,
23 ,
23 ,
23 ,
23 ,
23 ,
24 ,
24 ,
24 ,
24 ,
24 ,
24 ,
25 ,
25 ,
25 ,
25 ,
25 ,
26 ,
26 ,
26 ,
26 ,
26 ,
27 ,
27 ,
27 ,
27 ,
27 ,
27 ,
28 ,
28 ,
28 ,
28 ,
28 ,
29 ,
29 ,
29 ,
29 ,
29 ,
29 ,
30 ,
30 ,
30
};
uint32_t dB_fix_x10_tbl_low[128] = {
0 ,
0 ,
30 ,
48 ,
60 ,
70 ,
78 ,
85 ,
90 ,
95 ,
100 ,
104 ,
108 ,
111 ,
115 ,
118 ,
120 ,
123 ,
126 ,
128 ,
130 ,
132 ,
134 ,
136 ,
138 ,
140 ,
141 ,
143 ,
145 ,
146 ,
148 ,
149 ,
151 ,
152 ,
153 ,
154 ,
156 ,
157 ,
158 ,
159 ,
160 ,
161 ,
162 ,
163 ,
164 ,
165 ,
166 ,
167 ,
168 ,
169 ,
170 ,
171 ,
172 ,
172 ,
173 ,
174 ,
175 ,
176 ,
176 ,
177 ,
178 ,
179 ,
179 ,
180 ,
181 ,
181 ,
182 ,
183 ,
183 ,
184 ,
185 ,
185 ,
186 ,
186 ,
187 ,
188 ,
188 ,
189 ,
189 ,
190 ,
190 ,
191 ,
191 ,
192 ,
192 ,
193 ,
193 ,
194 ,
194 ,
195 ,
195 ,
196 ,
196 ,
197 ,
197 ,
198 ,
198 ,
199 ,
199 ,
200 ,
200 ,
200 ,
201 ,
201 ,
202 ,
202 ,
203 ,
203 ,
203 ,
204 ,
204 ,
205 ,
205 ,
205 ,
206 ,
206 ,
206 ,
207 ,
207 ,
208 ,
208 ,
208 ,
209 ,
209 ,
209 ,
210 ,
210 ,
210
};
/*
int8_t dB_fixed(int x) {
@@ -571,6 +854,38 @@ int8_t dB_fixed(int x) {
}
*/
int16_t dB_fixed_x10(uint32_t x) {
int16_t dB_power = 0;
//for new algorithm
uint32_t cnt;
uint32_t Exponent;
uint32_t Mantissa;
uint32_t shift_right;
uint32_t tbl_resolution = 7;
uint32_t tbl_addr_mask;
if (x < 128){ //OAI alogrithm
dB_power = dB_fix_x10_tbl_low[x];
}
else { //new algorithm
tbl_addr_mask = 0x0000007Fu; // (1 << tbl_resolution) - 1;//i.e. 0x0000007F
Mantissa = 0;
Exponent = 0;
for (cnt = 0; cnt < 32; cnt++) {
if ((bit_seach_mask[cnt] & x) != 0) {
Exponent = bit_seach_res[cnt];
Mantissa = x & (~bit_seach_mask[cnt]);
break;
}
}
shift_right = Exponent - tbl_resolution;
Mantissa = (Mantissa >> shift_right) & tbl_addr_mask;
dB_power = dB_fix_x10_tbl[Mantissa] + Exponent * 30u;
}
return dB_power;
}
int16_t dB_fixed_times10(uint32_t x)
{
int16_t dB_power=0;
+1
View File
@@ -30,5 +30,6 @@
#define DB_ROUTINES_H_
int16_t dB_fixed_times10(uint32_t x);
int16_t dB_fixed_x10(uint32_t x);
#endif /* DB_ROUTINES_H_ */
+106 -89
View File
@@ -29,6 +29,7 @@
#define shift 4
//#define shift_DC 0
#define SHRT_MIN -32768
#if defined(__x86_64__) || defined(__i386__)
#ifdef LOCALIZATION
@@ -67,52 +68,39 @@ int32_t subcarrier_energy(int32_t *input,uint32_t length, int32_t *subcarrier_en
}
#endif
//-----------------------------------------------------------------
// Average Power calculation with DC removing
//-----------------------------------------------------------------
int32_t signal_energy(int32_t *input,uint32_t length)
{
uint32_t i;
int32_t temp;
__m128i in, in_clp, i16_min, coe1;
__m128 num0, num1, num2, num3, recp1;
int32_t i;
int32_t temp,temp2;
register __m64 mm0,mm1,mm2,mm3;
__m64 *in = (__m64 *)input;
//init
num0 = _mm_setzero_ps();
num1 = _mm_setzero_ps();
i16_min = _mm_set1_epi16(SHRT_MIN);
coe1 = _mm_set1_epi16(1);
recp1 = _mm_rcp_ps(_mm_cvtepi32_ps(_mm_set1_epi32(length)));
mm0 = _mm_setzero_si64();//pxor(mm0,mm0);
mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
for (i=0; i<length>>1; i++) {
mm1 = in[i];
mm2 = mm1;
mm1 = _m_pmaddwd(mm1,mm1);
mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes
// mm2 = _m_psrawi(mm2,shift_DC);
mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes
//Acc
for (i = 0; i < (length >> 2); i++) {
in = _mm_loadu_si128((__m128i *)input);
in_clp = _mm_subs_epi16(in, _mm_cmpeq_epi16(in, i16_min));//if in=SHRT_MIN in+1, else in
num0 = _mm_add_ps(num0, _mm_cvtepi32_ps(_mm_madd_epi16(in_clp, in_clp)));
num1 = _mm_add_ps(num1, _mm_cvtepi32_ps(_mm_madd_epi16(in, coe1)));//DC
input += 4;
}
//Ave
num2 = _mm_dp_ps(num0, recp1, 0xFF);//AC power
num3 = _mm_dp_ps(num1, recp1, 0xFF);//DC
num3 = _mm_mul_ps(num3, num3); //DC power
//remove DC
temp = _mm_cvtsi128_si32(_mm_cvttps_epi32(_mm_sub_ps(num2, num3)));
mm1 = mm0;
mm0 = _m_psrlqi(mm0,32);
mm0 = _m_paddd(mm0,mm1);
temp = _m_to_int(mm0);
temp/=length;
temp<<=shift; // this is the average of x^2
// now remove the DC component
mm2 = _m_psrlqi(mm3,32);
mm2 = _m_paddw(mm2,mm3);
mm2 = _m_pmaddwd(mm2,mm2);
temp2 = _m_to_int(mm2);
temp2/=(length*length);
// temp2<<=(2*shift_DC);
temp -= temp2;
_mm_empty();
_m_empty();
return((temp>0)?temp:1);
return temp;
}
int32_t signal_energy_amp_shift(int32_t *input,uint32_t length)
@@ -163,61 +151,27 @@ int32_t signal_energy_amp_shift(int32_t *input,uint32_t length)
int32_t signal_energy_nodc(int32_t *input,uint32_t length)
{
int32_t i;
int32_t temp;
register __m64 mm0,mm1;//,mm2,mm3;
__m64 *in = (__m64 *)input;
#ifdef MAIN
int16_t *printb;
#endif
mm0 = _mm_setzero_si64();//_pxor(mm0,mm0);
// mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
for (i=0; i<length>>1; i++) {
mm1 = in[i];
mm1 = _m_pmaddwd(mm1,mm1);// SIMD complex multiplication
mm1 = _m_psradi(mm1,shift);
mm0 = _m_paddd(mm0,mm1);
// temp2 = mm0;
// printf("%d %d\n",((int *)&in[i])[0],((int *)&in[i])[1]);
// printb = (int16_t *)&mm2;
// printf("mm2 %d : %d %d %d %d\n",i,printb[0],printb[1],printb[2],printb[3]);
__m128i in;
__m128 mm0;
//init
mm0 = _mm_setzero_ps();
//Acc
for (i=0; i<(length>>2); i++) {
in = _mm_loadu_si128((__m128i *)input);
mm0 = _mm_add_ps(mm0,_mm_cvtepi32_ps(_mm_madd_epi16(in,in)));
input += 4;
}
//Ave
temp = (int)((((float*)&mm0)[0] +
((float*)&mm0)[1] +
((float*)&mm0)[2] +
((float*)&mm0)[3])/(float)length);
/*
#ifdef MAIN
printb = (int16_t *)&mm3;
printf("%d %d %d %d\n",printb[0],printb[1],printb[2],printb[3]);
#endif
*/
mm1 = mm0;
mm0 = _m_psrlqi(mm0,32);
mm0 = _m_paddd(mm0,mm1);
temp = _m_to_int(mm0);
temp/=length;
temp<<=shift; // this is the average of x^2
#ifdef MAIN
printf("E x^2 = %d\n",temp);
#endif
_mm_empty();
_m_empty();
return((temp>0)?temp:1);
return temp;
}
#elif defined(__arm__)
@@ -364,3 +318,66 @@ main(int argc,char **argv)
}
#endif
#define SHRT_MIN -32768
int32_t signal_power(int32_t *input, uint32_t length)
{
uint32_t i;
int32_t temp;
__m128i in, in_clp, i16_min;
__m128 num0, num1;
__m128 recp1;
//init
num0 = _mm_setzero_ps();
i16_min = _mm_set1_epi16(SHRT_MIN);
recp1 = _mm_rcp_ps(_mm_cvtepi32_ps(_mm_set1_epi32(length)));
//Acc
for (i = 0; i < (length >> 2); i++) {
in = _mm_loadu_si128((__m128i *)input);
in_clp = _mm_subs_epi16(in, _mm_cmpeq_epi16(in, i16_min));//if in=SHRT_MIN in+1, else in
num0 = _mm_add_ps(num0, _mm_cvtepi32_ps(_mm_madd_epi16(in_clp, in_clp)));
input += 4;
}
//Ave
num1 = _mm_dp_ps(num0, recp1, 0xFF);
temp = _mm_cvtsi128_si32(_mm_cvttps_epi32(num1));
return temp;
}
int32_t interference_power(int32_t *input, uint32_t length)
{
uint32_t i;
int32_t temp;
__m128i in, in_clp, i16_min;
__m128i num0, num1, num2, num3;
__m128 num4, num5, num6;
__m128 recp1;
//init
i16_min = _mm_set1_epi16(SHRT_MIN);
num5 = _mm_setzero_ps();
recp1 = _mm_rcp_ps(_mm_cvtepi32_ps(_mm_set1_epi32(length>>2)));// 1/n, n= length/4
//Acc
for (i = 0; i < (length >> 2); i++) {
in = _mm_loadu_si128((__m128i *)input);
in_clp = _mm_subs_epi16(in, _mm_cmpeq_epi16(in, i16_min)); //if in=SHRT_MIN, in+1, else in
num0 = _mm_cvtepi16_epi32(in_clp); //lower 2 complex [0], [1]
num1 = _mm_cvtepi16_epi32(_mm_shuffle_epi32(in_clp, 0x4E)); //upper 2 complex [2], [3]
num2 = _mm_srai_epi32(_mm_add_epi32(num0, num1), 0x01); //average A=complex( [0] + [2] ) / 2, B=complex( [1] + [3] ) / 2
num3 = _mm_sub_epi32(num2, _mm_shuffle_epi32(num2, 0x4E)); //complexA-complexB, B-A
num4 = _mm_dp_ps(_mm_cvtepi32_ps(num3), _mm_cvtepi32_ps(num3), 0x3F);//C = num3 lower complex power, C, C, C
num5 = _mm_add_ps(num5, num4); //Acc Cn, Cn, Cn, Cn,
input += 4;
}
//Interference ve
num6 = _mm_mul_ps(num5, recp1); //Cn / n
temp = _mm_cvtsi128_si32(_mm_cvttps_epi32(num6));
return temp;
}
+4
View File
@@ -431,6 +431,9 @@ int32_t subcarrier_energy(int32_t *,uint32_t, int32_t* subcarrier_energy, uint16
*/
int32_t signal_energy_nodc(int32_t *,uint32_t);
int32_t signal_power(int32_t *,uint32_t);
int32_t interference_power(int32_t *,uint32_t);
/*!\fn double signal_energy_fp(double *s_re[2], double *s_im[2],uint32_t, uint32_t,uint32_t);
\brief Computes the signal energy per subcarrier
*/
@@ -469,6 +472,7 @@ uint8_t dB_fixed64(uint64_t x);
int8_t dB_fixed2(uint32_t x,uint32_t y);
int16_t dB_fixed_times10(uint32_t x);
int16_t dB_fixed_x10(uint32_t x);
int32_t phy_phase_compensation_top(uint32_t pilot_type,
uint32_t initial_pilot,
+5
View File
@@ -166,6 +166,8 @@ typedef struct {
int32_t **ul_ch_magb;
/// measured RX power based on DRS
int ulsch_power[2];
/// measured Interference power based on DRS
int ulsch_interference_power[2];
/// \brief llr values.
/// - first index: ? [0..1179743] (hard coded)
int16_t *llr;
@@ -419,6 +421,8 @@ typedef struct {
int subband_cqi_tot_dB[NUMBER_OF_UE_MAX][100];
/// PRACH background noise level
int prach_I0;
/// PUCCH background noise level
int n0_pucch_dB;
} PHY_MEASUREMENTS_eNB;
@@ -667,6 +671,7 @@ typedef struct PHY_VARS_eNB_s {
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
uint8_t *FS6bufferZone;
int32_t pusch_signal_threshold;
} PHY_VARS_eNB;