Merge remote-tracking branch 'develop' into NR_RA_cleanup

This commit is contained in:
Thomas Schlichter
2021-01-29 18:52:37 +01:00
242 changed files with 2761 additions and 12549 deletions
+11
View File
@@ -43,6 +43,8 @@
#include "SCHED_NR/fapi_nr_l1.h"
#include "nfapi_nr_interface.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
/*
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
extern openair0_config_t openair0_cfg[MAX_CARDS];
@@ -181,6 +183,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
}
/* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */
generate_lowpapr_typ1_refsig_sequences(SHRT_MAX);
nr_init_csi_rs(gNB, 0); // TODO scramblingID currently hardcoded to 0, to be taken from higher layer parameter scramblingID when implemented
/// Transport init necessary for NR synchro
@@ -375,6 +381,11 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
/*
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL;
*/
free_gnb_lowpapr_sequences();
}
/*
void install_schedule_handlers(IF_Module_t *if_inst)
@@ -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,
@@ -30,6 +30,9 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
//#define DEBUG_CH
//#define DEBUG_PUSCH
@@ -119,15 +122,36 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
break;
}
//------------------generate DMRS------------------//
if (pusch_pdu->transform_precoding==1) // if transform precoding is disabled
if (pusch_pdu->transform_precoding == transform_precoder_disabled)
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
else
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
else { // if transform precoding or SC-FDMA is enabled in Uplink
// NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible
uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2));
uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number;
uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
int16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index];
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated");
LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index);
nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
#ifdef DEBUG_PUSCH
printf ("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v);
LOG_M("gNb_DMRS_SEQ.m","gNb_DMRS_SEQ", dmrs_seq,6*nb_rb_pusch,1,1);
#endif
}
//------------------------------------------------//
#ifdef DEBUG_PUSCH
for (int i=0;i<(6*nb_rb_pusch);i++)
printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]);
+48
View File
@@ -247,3 +247,51 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin
output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1];
}
}
int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned int Ns,
int16_t *dmrs_seq,
int32_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
uint32_t re_offset,
uint8_t dmrs_type)
{
int8_t w, nb_dmrs;
int k;
int dmrs_offset = re_offset/((dmrs_type==pusch_dmrs_type1)?2:3);
if (dmrs_type != pusch_dmrs_type1)
LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type);
if ((p>=1000) && (p<1008)) {
if (gNB->frame_parms.Ncp == NORMAL) {
nb_dmrs = NR_NB_SC_PER_RB/2; // for DMRS TYPE 1 - 6 DMRS REs present per RB
for (int i=dmrs_offset; i<dmrs_offset+(nb_pusch_rb*nb_dmrs); i++) {
k = i-dmrs_offset;
w = (wf1[p-1000][i&1])*(wt1[p-1000][lp]);
((int16_t*)output)[2*k] = w*dmrs_seq[2*i];
((int16_t*)output)[(2*k)+1] = -(w*dmrs_seq[(2*i)+1]);// conjugate
#ifdef DEBUG_PUSCH
printf("NR_DMRS_RX: nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d nb_dmrs %d\n", dmrs_type, p, nb_pusch_rb, nb_dmrs);
printf("NR_DMRS_RX: wf[%d] = %d wt[%d]= %d\n", i&1, wf1[p-1000][i&1], lp, wt1[p-1000][lp]);
printf("NR_DMRS_RX: i %d dmrs_offset %d k %d pusch dmrsseq[i<<1] %d, dmrsseq[(i<<1)+1] %d pilots[k<<1] %d pilots[(k<<1)+1] %d\n", i, dmrs_offset, k,
dmrs_seq[i<<1], dmrs_seq[(i<<1)+1], ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]);
#endif
}
} else {
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
}
} else {
LOG_E(PHY,"Illegal p %d PUSCH DMRS port\n",p);
}
return(0);
}
+14
View File
@@ -59,4 +59,18 @@ extern __m64 byte2m64_re[256];
extern __m64 byte2m64_im[256];
extern __m128i byte2m128i[256];
int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned int Ns,
int16_t *dmrs_seq,
int32_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
uint32_t re_offset,
uint8_t dmrs_type);
#endif
+109 -20
View File
@@ -108,6 +108,39 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC,
return rv_overbar;
}
/*******************************************************************
*
* NAME : get_index_for_dmrs_lowpapr_seq
*
* PARAMETERS : num_dmrs_res - Total number of DMRS RES possible in allocated RBs
*
*
* RETURN : returns index of array dmrs_ul_allocated_res
*
* DESCRIPTION : finds the index which in turn is used to index into dmrs low papr sequences
*
*********************************************************************/
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) {
int16_t index = -1;
if (num_dmrs_res >= dmrs_ul_allocated_res[(MAX_INDEX_DMRS_UL_ALLOCATED_REs-1)])
index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1;
else
index = (num_dmrs_res/6) -1;
for (;index >= 0; index--) {
if (dmrs_ul_allocated_res[index] == num_dmrs_res)
break;
}
LOG_D(PHY, "num_dmrs_res: %d INDEX RETURNED: %d", num_dmrs_res, index);
return index;
}
/*******************************************************************
*
* NAME : base_sequence_36_or_larger
@@ -126,13 +159,19 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC,
int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
unsigned int u,
unsigned int v,
unsigned int scaling)
unsigned int scaling, unsigned int if_dmrs_seq)
{
int16_t *rv_overbar;
unsigned int N_ZC;
unsigned int N_ZC, M_ZC;
double q_overbar, x;
unsigned int q,m,n;
unsigned int M_ZC = ul_allocated_re[Msc_RS];
if (if_dmrs_seq)
M_ZC = dmrs_ul_allocated_res[Msc_RS];
else
M_ZC = ul_allocated_re[Msc_RS];
rv_overbar = malloc16(IQ_SIZE*M_ZC);
if (rv_overbar == NULL) {
@@ -140,7 +179,11 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
assert(0);
}
N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
if (if_dmrs_seq)
N_ZC = dmrs_ref_ul_primes[Msc_RS];
else
N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
q_overbar = N_ZC * (u+1)/(double)31;
@@ -159,19 +202,24 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
return rv_overbar;
}
/*******************************************************************
*
* NAME : generate_ul_srs_sequences
*
* PARAMETERS : scaling to apply
*
* RETURN : none
*
* DESCRIPTION : uplink reference signal sequences generation
* which are Low-PAPR base sequences
* see TS 38.211 5.2.2 Low-PAPR sequence generation
*
*********************************************************************/
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling)
{
unsigned int u,Msc_RS;
unsigned int v = 0; // sequence hopping and group hopping are not supported yet
for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
for (u=0; u < U_GROUP_NUMBER; u++) {
gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
}
}
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
for (u=0; u < U_GROUP_NUMBER; u++) {
gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1);
}
}
}
void generate_ul_reference_signal_sequences(unsigned int scaling)
{
@@ -184,10 +232,13 @@ void generate_ul_reference_signal_sequences(unsigned int scaling)
#endif
for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
v = 0;
v = 0;
for (u=0; u < U_GROUP_NUMBER; u++) {
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
#if 0
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
@@ -198,10 +249,19 @@ void generate_ul_reference_signal_sequences(unsigned int scaling)
}
}
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
v = 0; // neither group hopping or sequnce hopping is supported for PUSCH DMRS hence v = 0
for (u=0; u < U_GROUP_NUMBER; u++) {
dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1);
}
}
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < SRS_SB_CONF; Msc_RS++) {
for (u=0; u < U_GROUP_NUMBER; u++) {
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling);
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 0);
#if 0
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
@@ -212,8 +272,11 @@ void generate_ul_reference_signal_sequences(unsigned int scaling)
}
}
}
}
/*******************************************************************
*
* NAME : free_ul_reference_signal_sequences
@@ -233,7 +296,33 @@ void free_ul_reference_signal_sequences(void)
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
if (rv_ul_ref_sig[u][v][Msc_RS])
free16(rv_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*ul_allocated_re[Msc_RS]);
if ((v==0) && (Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs))
if (dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS])
free16(dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]);
}
}
}
}
/*******************************************************************
*
* NAME : free_gnb_lowpapr_sequences
*
* PARAMETERS : none
*
* RETURN : none
*
* DESCRIPTION : free of uplink reference signal sequences
*
*********************************************************************/
void free_gnb_lowpapr_sequences(void)
{
unsigned int u,v,Msc_RS;
for (Msc_RS=0; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
v=0;
for (u=0; u < U_GROUP_NUMBER; u++) {
if (gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS])
free16(gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]);
}
}
}
+74 -1
View File
@@ -38,6 +38,10 @@
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#ifdef DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H
#define EXTERN
#define INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
@@ -255,7 +259,10 @@ const char phi_M_ZC_24[24*U_GROUP_NUMBER]
;
/************** FUNCTION ******************************************/
int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling);
int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq);
int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
/*!
\brief This function generate the sounding reference symbol (SRS) for the uplink.
@@ -265,6 +272,72 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned
void generate_ul_reference_signal_sequences(unsigned int scaling);
void free_ul_reference_signal_sequences(void);
// Supported for 100Mhz configuration - which has max 273 RBs
#define MAX_INDEX_DMRS_UL_ALLOCATED_REs 53
const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
/* Number of possible DMRS REs based on PRBs allocated for PUSCH. Array has values until 273 RBs (100Mhz BW)
Number of PUSCH RBs allocated should be able to be expressed as 2topowerofn*3topowerofn*5tothepowerofn
According to 3GPP spec 38.211 section 6.3.1.4
Table used in calculating DMRS low papr type1 sequence for transform precoding */
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/*RBs 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, */
6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96,
/*RBs 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, */
108, 120, 144, 150, 162, 180, 192, 216, 240, 270, 288, 300,
/*RBs 54, 60, 64, 72 75, 80, 81, 90, 96, 100, (Bw 40Mhz) */
324, 360, 384, 432, 450, 480, 486, 540, 576, 600,
/*RBs 108, 120 125 128 135 144 150 160 162 180 192 200 */
648, 720, 750, 768, 810, 864, 900, 960, 972, 1080, 1152, 1200,
/*RBs 216 225 240 243 250 256 270 supported until 100Mhz */
1296, 1350, 1440, 1458, 1500, 1536, 1620
}
#endif
;
/* Table of largest prime number N_ZC < possible DMRS REs M_ZC, this array has values until 100Mhz
According to 3GPP spec 38.211 section 5.2.2.1
Table used in calculating DMRS low papr type1 sequence for transform precoding */
const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/*DMRS REs 6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96, */
5, 11, 17, 23, 29, 31, 47, 53, 59, 71, 89, 89,
/*DMRS REs 108, 120, 144, 150, 162, 180, 192, 216, 240, 270, 288, 300, */
107, 113, 139, 149, 157, 179, 191, 211, 239, 269, 283, 293,
/*DMRS REs 324, 360, 384, 432, 450, 480, 486, 540, 576, 600, */
317, 359, 383, 431, 449, 479, 479, 523, 571, 599,
/*DMRS REs 648, 720, 750, 768, 810, 864, 900, 960, 972, 1080, 1152, 1200, */
647, 719, 743, 761, 809, 863, 887, 953, 971, 1069, 1151, 1193,
/*DMRS REs 1296, 1350, 1440, 1458, 1500, 1536 1620 supported until 100Mhz */
1291, 1327, 1439, 1453, 1499, 1531, 1619
}
#endif
;
/// PUSCH DMRS for transform precoding
int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res);
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling);
void free_gnb_lowpapr_sequences(void);
#undef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
#undef EXTERN
@@ -212,7 +212,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
\param z Pointer to input in frequnecy domain, and it is also the output in time domain
\param Msc_PUSCH number of allocated data subcarriers
*/
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH);
void nr_idft(int32_t *z, uint32_t Msc_PUSCH);
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@param rxdataF_comp Compensated channel output
@@ -12,7 +12,7 @@
//#define DEBUG_RB_EXT
//#define DEBUG_CH_MAG
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
@@ -38,7 +38,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
}
for (i=0,ip=0; i<Msc_PUSCH; i++, ip+=4) {
((uint32_t*)idft_in0)[ip+0] = z[i];
((int32_t*)idft_in0)[ip+0] = z[i];
}
@@ -203,7 +203,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
z[i] = ((uint32_t*)idft_out0)[ip];
z[i] = ((int32_t*)idft_out0)[ip];
}
// conjugate output
@@ -1118,6 +1118,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
}
LOG_D(PHY,"dmrs_symbol: nb_re_pusch %d\n",nb_re_pusch);
gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
} else {
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
}
@@ -1219,9 +1220,21 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
symbol,
rel15_ul->rb_size);
stop_meas(&gNB->ulsch_mrc_stats);
#ifdef NR_SC_FDMA
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
if (rel15_ul->transform_precoding == transform_precoder_enabled) {
#ifdef __AVX2__
// For odd number of resource blocks need byte alignment to multiple of 8
int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
#else
int nb_re_pusch2 = nb_re_pusch;
#endif
// perform IDFT operation on the compensated rxdata if transform precoding is enabled
nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch);
LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d\n", symbol, nb_re_pusch);
}
//----------------------------------------------------------
@@ -1245,32 +1258,33 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
/* Subtract total PTRS RE's in the symbol from PUSCH RE's */
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
}
/*---------------------------------------------------------------------------------------------------- */
/*-------------------- LLRs computation -------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------*/
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
{
#ifdef __AVX2__
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
#else
int off = 0;
#endif
uint32_t rxdataF_ext_offset = 0;
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
start_meas(&gNB->ulsch_llr_stats);
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
&gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
rel15_ul->rb_size,
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
i,
rel15_ul->qam_mod_order);
stop_meas(&gNB->ulsch_llr_stats);
rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
}// symbol loop
}// last symbol check
}
/*---------------------------------------------------------------------------------------------------- */
/*-------------------- LLRs computation -------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------*/
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1)) {
#ifdef __AVX2__
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
#else
int off = 0;
#endif
uint32_t rxdataF_ext_offset = 0;
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
start_meas(&gNB->ulsch_llr_stats);
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
&gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
rel15_ul->rb_size,
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
i,
rel15_ul->qam_mod_order);
stop_meas(&gNB->ulsch_llr_stats);
rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
}// symbol loop
}// last symbol check
return (0);
}
@@ -181,9 +181,9 @@ typedef struct {
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
int32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
uint32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
int32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/*
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
uint8_t q[MAX_CQI_PAYLOAD];
+96 -24
View File
@@ -46,9 +46,11 @@
#include "executables/softmodem-common.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
//#define DEBUG_SCFDMA
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
//#define DEBUG_PUSCH_MAPPING
//#define DEBUG_MAC_PDU
//#define DEBUG_DFT_IDFT
//extern int32_t uplink_counter;
@@ -153,6 +155,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned int G = nr_get_G(nb_rb, number_of_symbols,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
///////////
@@ -184,8 +188,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
(int16_t *)ulsch_ue->d_mod);
// pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid);
///////////
////////////////////////////////////////////////////////////////////////
@@ -243,26 +246,72 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
l_prime[0] = 0; // single symbol ap 0
#ifdef NR_SC_FDMA
uint32_t nb_re_pusch, nb_re_dmrs_per_rb;
uint32_t y_offset = 0;
uint16_t index;
uint8_t u = 0, v = 0;
int16_t *dmrs_seq = NULL;
for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
if (pusch_pdu->transform_precoding == transform_precoder_enabled) {
if((ul_dmrs_symb_pos >> l) & 0x01)
nb_re_dmrs_per_rb = nb_dmrs_re_per_rb;
else
nb_re_dmrs_per_rb = 0;
uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB;
uint32_t y_offset = 0;
uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2);
nb_re_pusch = nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb);
// Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol
index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol);
u = pusch_pdu->dfts_ofdm.low_papr_group_number;
v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index];
nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated");
LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index);
for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
if((ul_dmrs_symb_pos >> l) & 0x01)
/* In the symbol with DMRS no data would be transmitted CDM groups is 2*/
continue;
nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
y_offset = y_offset + nb_re_pusch;
LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n", l, nb_re_pusch, y_offset);
#ifdef DEBUG_PUSCH_MAPPING
printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n",
y_offset, nb_re_pusch, l, nb_rb);
#endif
}
#ifdef DEBUG_DFT_IDFT
int32_t debug_symbols[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
int offset = 0;
printf("NR_ULSCH_UE: available_bits: %d, mod_order: %d", available_bits,mod_order);
for (int ll = 0; ll < (available_bits/mod_order); ll++) {
debug_symbols[ll] = ulsch_ue->y[ll];
}
printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols);
for (int ll = 0; ll < (number_of_symbols-number_dmrs_symbols); ll++) {
nr_idft(&debug_symbols[offset], nb_re_pusch);
offset = offset + nb_re_pusch;
}
LOG_M("preDFT_all_symbols.m","UE_preDFT", tx_layers[0],number_of_symbols*nb_re_pusch,1,1);
LOG_M("postDFT_all_symbols.m","UE_postDFT", ulsch_ue->y,number_of_symbols*nb_re_pusch,1,1);
LOG_M("DEBUG_IDFT_SYMBOLS.m","UE_Debug_IDFT", debug_symbols,number_of_symbols*nb_re_pusch,1,1);
LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1);
#endif
y_offset = y_offset + nb_re_pusch;
}
#else
memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t));
#endif
else
memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t));
///////////
////////////////////////////////////////////////////////////////////////
@@ -279,6 +328,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t k_prime = 0;
uint16_t m = 0;
#ifdef DEBUG_PUSCH_MAPPING
printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u);
#endif
// DMRS params for this ap
get_Wt(Wt, ap, dmrs_type);
get_Wf(Wf, ap, dmrs_type);
@@ -295,18 +351,25 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if ((ul_dmrs_symb_pos >> l) & 0x01) {
is_dmrs_sym = 1;
if (pusch_pdu->transform_precoding == 1){ // if transform precoding is disabled
if (pusch_pdu->transform_precoding == transform_precoder_disabled){
if (dmrs_type == pusch_dmrs_type1)
dmrs_idx = start_rb*6;
else
dmrs_idx = start_rb*4;
// Perform this on gold sequence, not required when SC FDMA operation is done,
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
} else {
dmrs_idx = 0;
}
}
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
AssertFatal(pusch_pdu->transform_precoding == transform_precoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
is_ptrs_sym = 1;
@@ -338,8 +401,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if (is_dmrs == 1) {
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
if (pusch_pdu->transform_precoding == transform_precoder_enabled) {
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
} else {
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
}
#ifdef DEBUG_PUSCH_MAPPING
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
+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_ */
+2 -2
View File
@@ -112,7 +112,7 @@ static inline void cmac_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
{
__m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
cmac_tmp = _mm256_sign_epi16(b,*(__m256i*)reflip);
cmac_tmp_re32 = _mm256_madd_epi16(a,cmac_tmp);
@@ -129,7 +129,7 @@ static inline void cmacc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
{
__m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
cmac_tmp_re32 = _mm256_madd_epi16(a,b);
+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;
-5
View File
@@ -42,11 +42,6 @@
#define nr_subframe_t lte_subframe_t
#define nr_slot_t lte_subframe_t
// [hna] This enables SC-FDMA transmission in Uplink. If disabled, then OFDMA is used in UPLINK.
#ifndef NR_SC_FDMA
// #define NR_SC_FDMA
#endif
#define MAX_NUM_SUBCARRIER_SPACING 5
#define NR_MAX_NB_RB 275
+5 -3
View File
@@ -601,9 +601,11 @@ typedef enum{
ul_rgb_config1 = 1,
ul_rgb_config2 = 2
} ul_rgb_Size_t;
typedef enum {
transformPrecoder_enabled = 1,
transformPrecoder_disabled = 2
/* Aligned values of this enum to other tranform precoder enums
* eg: as defined in fapi_nr_ue_interface.h for transform_precoder_t*/
typedef enum {
transformPrecoder_enabled = 0,
transformPrecoder_disabled = 1
} transformPrecoder_t;
typedef enum {
codebookSubset_fullyAndPartialAndNonCoherent = 1,