multiple ssb detection via pbch dmrs (selection of best ssb only, working in pbchsim for SNR>=0)
This commit is contained in:
@@ -32,6 +32,169 @@
|
||||
//#define DEBUG_PDCCH
|
||||
|
||||
|
||||
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned char symbol,
|
||||
NR_UE_SSB *current_ssb)
|
||||
{
|
||||
int pilot[200] __attribute__((aligned(16)));
|
||||
unsigned char aarx;
|
||||
unsigned short k;
|
||||
unsigned int pilot_cnt;
|
||||
int16_t ch[2],*pil,*rxF;
|
||||
int symbol_offset;
|
||||
int dmrss;
|
||||
|
||||
uint8_t nushift;
|
||||
uint8_t ssb_index=current_ssb->i_ssb;
|
||||
uint8_t n_hf=current_ssb->n_hf;
|
||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
|
||||
|
||||
nushift = ue->frame_parms.Nid_cell%4;
|
||||
ue->frame_parms.nushift = nushift;
|
||||
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
|
||||
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
|
||||
|
||||
if (ue->is_synchronized ==0 ) dmrss = symbol-1;
|
||||
else dmrss = symbol-5;
|
||||
|
||||
AssertFatal((symbol > 0 && symbol < 4 && ue->is_synchronized == 0) ||
|
||||
(symbol > 4 && symbol < 8 && ue->is_synchronized == 1),
|
||||
"symbol %d is illegal for PBCH DM-RS (is_synchronized %d)\n",
|
||||
symbol,ue->is_synchronized);
|
||||
|
||||
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
|
||||
|
||||
|
||||
k = nushift;
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ue->frame_parms.ofdm_symbol_size,
|
||||
ue->frame_parms.Ncp,Ns,k, symbol);
|
||||
#endif
|
||||
|
||||
// generate pilot
|
||||
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
|
||||
|
||||
int re_offset = ssb_offset;
|
||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
pil = (int16_t *)&pilot[0];
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
|
||||
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
|
||||
printf("rxF addr %p\n", rxF);
|
||||
#endif
|
||||
//if ((ue->frame_parms.N_RB_DL&1)==0) {
|
||||
|
||||
// Treat first 2 pilots specially (left edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
current_ssb->c_re +=ch[0];
|
||||
current_ssb->c_im +=ch[1];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
current_ssb->c_re +=ch[0];
|
||||
current_ssb->c_im +=ch[1];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
current_ssb->c_re +=ch[0];
|
||||
current_ssb->c_im +=ch[1];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) {
|
||||
|
||||
// if (pilot_cnt == 30)
|
||||
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
|
||||
|
||||
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
|
||||
if (dmrss == 1 && pilot_cnt == 12) {
|
||||
pilot_cnt=48;
|
||||
re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
}
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
current_ssb->c_re +=ch[0];
|
||||
current_ssb->c_im +=ch[1];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
current_ssb->c_re +=ch[0];
|
||||
current_ssb->c_im +=ch[1];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
pil+=2;
|
||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
current_ssb->c_re +=ch[0];
|
||||
current_ssb->c_im +=ch[1];
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||
|
||||
}
|
||||
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
|
||||
@@ -50,6 +50,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned short coreset_start_subcarrier,
|
||||
unsigned short nb_rb_coreset);
|
||||
|
||||
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned char symbol,
|
||||
NR_UE_SSB *current_ssb);
|
||||
|
||||
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
unsigned char Ns,
|
||||
|
||||
@@ -58,6 +58,11 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, int pbch_initial_symbol, runmode_t mod
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
|
||||
int ret =-1;
|
||||
uint8_t best_ssb =0;
|
||||
uint8_t n_hf =0;
|
||||
uint32_t best_metric =0;
|
||||
|
||||
NR_UE_SSB *current_ssb = malloc(sizeof(NR_UE_SSB));
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
|
||||
@@ -70,30 +75,53 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, int pbch_initial_symbol, runmode_t mod
|
||||
// loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection
|
||||
for (int hf = 0; hf < N_hf; hf++) {
|
||||
for (int l = 0; l < N_L ; l++) {
|
||||
if (ret !=0) {
|
||||
|
||||
// initialization of structure parameters
|
||||
current_ssb->n_hf = hf;
|
||||
current_ssb->i_ssb = l;
|
||||
current_ssb->c_re = 0;
|
||||
current_ssb->c_im = 0;
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||
nr_pbch_channel_estimation(ue,0,0,i,i-pbch_initial_symbol,l,hf);
|
||||
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
|
||||
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||
nr_pbch_dmrs_correlation(ue,0,0,i,current_ssb);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
|
||||
ret = nr_rx_pbch(ue,
|
||||
&ue->proc.proc_rxtx[0],
|
||||
ue->pbch_vars[0],
|
||||
frame_parms,
|
||||
0,
|
||||
l,
|
||||
SISO,
|
||||
ue->high_speed_flag);
|
||||
|
||||
|
||||
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im+current_ssb->c_re;
|
||||
|
||||
if(current_ssb->metric > best_metric) { // if metric of current structure is higher than the best one
|
||||
best_metric = current_ssb->metric;
|
||||
best_ssb = l;
|
||||
n_hf = hf;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
// computing channel estimation for selected best ssb
|
||||
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||
nr_pbch_channel_estimation(ue,0,0,i,i-pbch_initial_symbol,best_ssb,n_hf);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
|
||||
ret = nr_rx_pbch(ue,
|
||||
&ue->proc.proc_rxtx[0],
|
||||
ue->pbch_vars[0],
|
||||
frame_parms,
|
||||
0,
|
||||
best_ssb,
|
||||
SISO,
|
||||
ue->high_speed_flag);
|
||||
|
||||
if (ret==0) {
|
||||
|
||||
frame_parms->nb_antenna_ports_eNB = 1; //pbch_tx_ant;
|
||||
@@ -116,6 +144,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, int pbch_initial_symbol, runmode_t mod
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
|
||||
@@ -950,6 +950,15 @@ typedef struct {
|
||||
int16_t *prach;
|
||||
} NR_UE_PRACH;
|
||||
|
||||
// structure used for multiple SSB detection
|
||||
typedef struct NR_UE_SSB {
|
||||
uint8_t i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8)
|
||||
uint8_t n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64
|
||||
uint32_t metric; // metric to order SSB hypothesis
|
||||
uint32_t c_re;
|
||||
uint32_t c_im;
|
||||
} NR_UE_SSB;
|
||||
|
||||
/*typedef enum {
|
||||
/// do not detect any DCIs in the current subframe
|
||||
NO_DCI = 0x0,
|
||||
|
||||
Reference in New Issue
Block a user