Adding 16x IDFT interpolation for PRS peak estimation
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
//#define DEBUG_CH
|
||||
//#define DEBUG_PRS_CHEST
|
||||
//#define DEBUG_PRS_PRINTS
|
||||
#define IDFT_INTERPOL_FACTOR 1
|
||||
extern short nr_qpsk_mod_table[8];
|
||||
int k_prime_table[4][12] = {
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1},
|
||||
@@ -62,12 +63,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
prs_meas_t **prs_meas = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas;
|
||||
int32_t **prs_chestF = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_ch_estimates;
|
||||
int32_t **prs_chestT = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_ch_estimates_time;
|
||||
int slot_prs;
|
||||
if(rep_num > 0)
|
||||
slot_prs = (proc->nr_slot_rx - prs_cfg->PRSResourceTimeGap)%frame_params->slots_per_frame;
|
||||
else
|
||||
slot_prs = proc->nr_slot_rx;
|
||||
|
||||
int slot_prs = (proc->nr_slot_rx - rep_num*prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame)%frame_params->slots_per_frame;
|
||||
uint32_t **nr_gold_prs = ue->nr_gold_prs[gNB_id][rsc_id][slot_prs];
|
||||
|
||||
uint8_t rxAnt = 0, idx = 0;
|
||||
@@ -76,13 +72,18 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
int16_t k_prime = 0, k = 0, re_offset = 0, first_half = 0, second_half = 0;
|
||||
int16_t *ch_tmp = (int16_t *)malloc16_clear(frame_params->ofdm_symbol_size*sizeof(int32_t));
|
||||
AssertFatal((ch_tmp != NULL), "[%s] channel estimate buffer initialization failed!!", __FUNCTION__);
|
||||
int16_t *chF_interpol = (int16_t *)malloc16_clear(IDFT_INTERPOL_FACTOR*frame_params->ofdm_symbol_size*sizeof(int32_t));
|
||||
AssertFatal((chF_interpol != NULL), "[%s] channel estimate buffer initialization failed!!", __FUNCTION__);
|
||||
int16_t *chT_interpol = (int16_t *)malloc16_clear(IDFT_INTERPOL_FACTOR*frame_params->ofdm_symbol_size*sizeof(int32_t));
|
||||
AssertFatal((chT_interpol != NULL), "[%s] channel estimate buffer initialization failed!!", __FUNCTION__);
|
||||
int32_t ch_pwr = 0, snr = 0;
|
||||
#ifdef DEBUG_PRS_CHEST
|
||||
char filename[64] = {0}, varname[64] = {0};
|
||||
#endif
|
||||
int16_t *ch_init = ch_tmp;
|
||||
int16_t *ch_init = ch_tmp;
|
||||
int16_t scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15);
|
||||
int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB;
|
||||
int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB;
|
||||
int16_t start_offset = (IDFT_INTERPOL_FACTOR-1)*frame_params->ofdm_symbol_size>>1;
|
||||
|
||||
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++)
|
||||
{
|
||||
@@ -434,9 +435,12 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
if(second_half > 0)
|
||||
memcpy((int16_t *)&prs_chestF[rxAnt][0], &ch_tmp[(first_half<<1)], second_half*sizeof(int32_t));
|
||||
|
||||
memcpy((int16_t *)&chF_interpol[start_offset+re_offset], &ch_tmp[0], first_half*sizeof(int32_t));
|
||||
memcpy((int16_t *)&chF_interpol[start_offset], &ch_tmp[(first_half<<1)], second_half*sizeof(int32_t));
|
||||
|
||||
// Time domain IMPULSE response
|
||||
idft_size_idx_t idftsizeidx;
|
||||
switch (frame_params->ofdm_symbol_size) {
|
||||
switch (IDFT_INTERPOL_FACTOR*frame_params->ofdm_symbol_size) {
|
||||
case 128:
|
||||
idftsizeidx = IDFT_128;
|
||||
break;
|
||||
@@ -473,18 +477,46 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
idftsizeidx = IDFT_4096;
|
||||
break;
|
||||
|
||||
case 8192:
|
||||
idftsizeidx = IDFT_8192;
|
||||
break;
|
||||
|
||||
case 12288:
|
||||
idftsizeidx = IDFT_12288;
|
||||
break;
|
||||
|
||||
case 16384:
|
||||
idftsizeidx = IDFT_16384;
|
||||
break;
|
||||
|
||||
case 24576:
|
||||
idftsizeidx = IDFT_24576;
|
||||
break;
|
||||
|
||||
case 32768:
|
||||
idftsizeidx = IDFT_32768;
|
||||
break;
|
||||
|
||||
case 49152:
|
||||
idftsizeidx = IDFT_49152;
|
||||
break;
|
||||
|
||||
case 65536:
|
||||
idftsizeidx = IDFT_65536;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_I(PHY, "%s: unsupported ofdm symbol size \n", __FUNCTION__);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
idft(idftsizeidx,
|
||||
(int16_t *)&prs_chestF[rxAnt][0],
|
||||
(int16_t *)&ch_tmp[0],1);
|
||||
(int16_t *)&chF_interpol[0],
|
||||
(int16_t *)&chT_interpol[0],1);
|
||||
|
||||
// rearrange impulse response
|
||||
memcpy((int16_t *)&prs_chestT[rxAnt][0], &ch_tmp[frame_params->ofdm_symbol_size], (frame_params->ofdm_symbol_size>>1)*sizeof(int32_t));
|
||||
memcpy((int16_t *)&prs_chestT[rxAnt][(frame_params->ofdm_symbol_size>>1)], &ch_tmp[0], (frame_params->ofdm_symbol_size>>1)*sizeof(int32_t));
|
||||
memcpy((int16_t *)&prs_chestT[rxAnt][0], &chT_interpol[IDFT_INTERPOL_FACTOR*frame_params->ofdm_symbol_size], (frame_params->ofdm_symbol_size>>1)*sizeof(int32_t));
|
||||
memcpy((int16_t *)&prs_chestT[rxAnt][(frame_params->ofdm_symbol_size>>1)], &chT_interpol[start_offset], (frame_params->ofdm_symbol_size>>1)*sizeof(int32_t));
|
||||
|
||||
// peak estimator
|
||||
peak_estimator(&prs_chestT[rxAnt][0],
|
||||
@@ -530,6 +562,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
}
|
||||
|
||||
free(ch_tmp);
|
||||
free(chF_interpol);
|
||||
free(chT_interpol);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -5363,7 +5363,7 @@ void idft8192(int16_t *x,int16_t *y,unsigned char scale)
|
||||
|
||||
#endif
|
||||
|
||||
int16_t tw16384[3*2*4096];
|
||||
int16_t tw16384[3*2*4096] __attribute__((aligned(32)));
|
||||
|
||||
#ifndef __AVX2__
|
||||
void dft16384(int16_t *x,int16_t *y,unsigned char scale)
|
||||
@@ -7013,6 +7013,122 @@ void idft49152(int16_t *input, int16_t *output,uint8_t scale) {
|
||||
_m_empty();
|
||||
}
|
||||
|
||||
int16_t tw65536[3*2*4096] __attribute__((aligned(32)));
|
||||
|
||||
#ifndef __AVX2__
|
||||
void idft65536(int16_t *x,int16_t *y,unsigned char scale)
|
||||
{
|
||||
|
||||
simd_q15_t xtmp[16384],ytmp[16384],*tw65536_128p=(simd_q15_t *)tw65536,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
|
||||
simd_q15_t *ytmpp = &ytmp[0];
|
||||
int i,j;
|
||||
|
||||
for (i=0,j=0; i<16384; i+=4,j++) {
|
||||
transpose16_ooff(x128+i,xtmp+j,4096);
|
||||
}
|
||||
|
||||
|
||||
idft16384((int16_t*)(xtmp),(int16_t*)(ytmp),1);
|
||||
idft16384((int16_t*)(xtmp+4096),(int16_t*)(ytmp+4096),1);
|
||||
idft16384((int16_t*)(xtmp+8192),(int16_t*)(ytmp+8192),1);
|
||||
idft16384((int16_t*)(xtmp+12288),(int16_t*)(ytmp+12288),1);
|
||||
|
||||
for (i=0; i<4096; i++) {
|
||||
ibfly4(ytmpp,ytmpp+4096,ytmpp+8192,ytmpp+12288,
|
||||
y128p,y128p+4096,y128p+8192,y128p+12288,
|
||||
tw65536_128p,tw63536_128p+4096,tw65536_128p+8192);
|
||||
tw65536_128p++;
|
||||
y128p++;
|
||||
ytmpp++;
|
||||
}
|
||||
|
||||
if (scale>0) {
|
||||
|
||||
for (i=0; i<1024; i++) {
|
||||
y128[0] = shiftright_int16(y128[0],scale);
|
||||
y128[1] = shiftright_int16(y128[1],scale);
|
||||
y128[2] = shiftright_int16(y128[2],scale);
|
||||
y128[3] = shiftright_int16(y128[3],scale);
|
||||
y128[4] = shiftright_int16(y128[4],scale);
|
||||
y128[5] = shiftright_int16(y128[5],scale);
|
||||
y128[6] = shiftright_int16(y128[6],scale);
|
||||
y128[7] = shiftright_int16(y128[7],scale);
|
||||
y128[8] = shiftright_int16(y128[8],scale);
|
||||
y128[9] = shiftright_int16(y128[9],scale);
|
||||
y128[10] = shiftright_int16(y128[10],scale);
|
||||
y128[11] = shiftright_int16(y128[11],scale);
|
||||
y128[12] = shiftright_int16(y128[12],scale);
|
||||
y128[13] = shiftright_int16(y128[13],scale);
|
||||
y128[14] = shiftright_int16(y128[14],scale);
|
||||
y128[15] = shiftright_int16(y128[15],scale);
|
||||
|
||||
y128+=16;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
}
|
||||
|
||||
#else // __AVX2__
|
||||
void idft65536(int16_t *x,int16_t *y,unsigned char scale)
|
||||
{
|
||||
|
||||
simd256_q15_t xtmp[8192],ytmp[8192],*tw65536_256p=(simd256_q15_t *)tw65536,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
|
||||
simd256_q15_t *ytmpp = &ytmp[0];
|
||||
int i,j;
|
||||
|
||||
for (i=0,j=0; i<8192; i+=4,j++) {
|
||||
transpose16_ooff_simd256(x256+i,xtmp+j,2048);
|
||||
}
|
||||
|
||||
|
||||
idft16384((int16_t*)(xtmp),(int16_t*)(ytmp),1);
|
||||
idft16384((int16_t*)(xtmp+2048),(int16_t*)(ytmp+2048),1);
|
||||
idft16384((int16_t*)(xtmp+4096),(int16_t*)(ytmp+4096),1);
|
||||
idft16384((int16_t*)(xtmp+6144),(int16_t*)(ytmp+6144),1);
|
||||
|
||||
for (i=0; i<2048; i++) {
|
||||
ibfly4_256(ytmpp,ytmpp+2048,ytmpp+4096,ytmpp+6144,
|
||||
y256p,y256p+2048,y256p+4096,y256p+6144,
|
||||
tw65536_256p,tw65536_256p+4096,tw65536_256p+8192);
|
||||
tw65536_256p++;
|
||||
y256p++;
|
||||
ytmpp++;
|
||||
}
|
||||
|
||||
if (scale>0) {
|
||||
|
||||
for (i=0; i<512; i++) {
|
||||
y256[0] = shiftright_int16_simd256(y256[0],scale);
|
||||
y256[1] = shiftright_int16_simd256(y256[1],scale);
|
||||
y256[2] = shiftright_int16_simd256(y256[2],scale);
|
||||
y256[3] = shiftright_int16_simd256(y256[3],scale);
|
||||
y256[4] = shiftright_int16_simd256(y256[4],scale);
|
||||
y256[5] = shiftright_int16_simd256(y256[5],scale);
|
||||
y256[6] = shiftright_int16_simd256(y256[6],scale);
|
||||
y256[7] = shiftright_int16_simd256(y256[7],scale);
|
||||
y256[8] = shiftright_int16_simd256(y256[8],scale);
|
||||
y256[9] = shiftright_int16_simd256(y256[9],scale);
|
||||
y256[10] = shiftright_int16_simd256(y256[10],scale);
|
||||
y256[11] = shiftright_int16_simd256(y256[11],scale);
|
||||
y256[12] = shiftright_int16_simd256(y256[12],scale);
|
||||
y256[13] = shiftright_int16_simd256(y256[13],scale);
|
||||
y256[14] = shiftright_int16_simd256(y256[14],scale);
|
||||
y256[15] = shiftright_int16_simd256(y256[15],scale);
|
||||
|
||||
y256+=16;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
}
|
||||
|
||||
#endif //__AVX2__
|
||||
|
||||
int16_t twa73728[49152] __attribute__((aligned(32)));
|
||||
int16_t twb73728[49152] __attribute__((aligned(32)));
|
||||
// 24576 x 3
|
||||
@@ -10708,6 +10824,7 @@ int dfts_autoinit(void)
|
||||
init_rad2(8192,tw8192);
|
||||
init_rad4(16384,tw16384);
|
||||
init_rad2(32768,tw32768);
|
||||
init_rad4(65536,tw65536);
|
||||
|
||||
init_rad3(768,twa768,twb768);
|
||||
init_rad3(1536,twa1536,twb1536);
|
||||
|
||||
@@ -275,10 +275,13 @@ This function performs optimized fixed-point radix-2 FFT/IFFT.
|
||||
SZ_DEF(8192) \
|
||||
SZ_DEF(9216) \
|
||||
SZ_DEF(12288) \
|
||||
SZ_DEF(16384) \
|
||||
SZ_DEF(18432) \
|
||||
SZ_DEF(24576) \
|
||||
SZ_DEF(32768) \
|
||||
SZ_DEF(36864) \
|
||||
SZ_DEF(49152) \
|
||||
SZ_DEF(65536) \
|
||||
SZ_DEF(73728) \
|
||||
SZ_DEF(98304)
|
||||
|
||||
|
||||
@@ -149,11 +149,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
{
|
||||
if( (((frame*fp->slots_per_frame + slot) - (gNB->prs_vars.prs_cfg[rsc_id].PRSResourceSetPeriod[1] + gNB->prs_vars.prs_cfg[rsc_id].PRSResourceOffset)+gNB->prs_vars.prs_cfg[rsc_id].PRSResourceSetPeriod[0])%gNB->prs_vars.prs_cfg[rsc_id].PRSResourceSetPeriod[0]) == i*gNB->prs_vars.prs_cfg[rsc_id].PRSResourceTimeGap )
|
||||
{
|
||||
if (i > 0)
|
||||
slot_prs = (slot - gNB->prs_vars.prs_cfg[rsc_id].PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame;
|
||||
else
|
||||
slot_prs = slot;
|
||||
|
||||
slot_prs = (slot - i*gNB->prs_vars.prs_cfg[rsc_id].PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame;
|
||||
LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id);
|
||||
nr_generate_prs(gNB->nr_gold_prs[rsc_id][slot_prs],&gNB->common_vars.txdataF[0][txdataF_offset], AMP, &gNB->prs_vars.prs_cfg[rsc_id], cfg, fp);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user