Commit ebf00db7 authored by Francesco Mani's avatar Francesco Mani

multiple ssb detection via pbch dmrs (selection of best ssb only, working in pbchsim for SNR>=0)

parent d1027421
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment