Fixed several bugs in UE initial sync procedures
Now UE gets sync all time in rfsimulator. Yet to be tested with hardware.
This commit is contained in:
@@ -204,6 +204,181 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("slot_fep: done\n");
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
unsigned char aa;
|
||||
unsigned int nb_prefix_samples;
|
||||
unsigned int nb_prefix_samples0;
|
||||
unsigned int abs_symbol;
|
||||
if (ue->is_synchronized) {
|
||||
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
|
||||
}
|
||||
else {
|
||||
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
}
|
||||
//unsigned int subframe_offset;//,subframe_offset_F;
|
||||
unsigned int slot_offset;
|
||||
//int i;
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
||||
unsigned int rx_offset;
|
||||
|
||||
|
||||
void (*dft)(int16_t *,int16_t *, int);
|
||||
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
|
||||
|
||||
switch (frame_parms->ofdm_symbol_size) {
|
||||
case 128:
|
||||
dft = dft128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
dft = dft256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
dft = dft512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
dft = dft1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
dft = dft1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
dft = dft2048;
|
||||
break;
|
||||
|
||||
case 3072:
|
||||
dft = dft3072;
|
||||
break;
|
||||
|
||||
case 4096:
|
||||
dft = dft4096;
|
||||
break;
|
||||
|
||||
case 8192:
|
||||
dft = dft8192;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unsupported ofdm symbol size \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (no_prefix) {
|
||||
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
|
||||
} else {
|
||||
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
}
|
||||
|
||||
/*if (l<0 || l>=7-frame_parms->Ncp) {
|
||||
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
|
||||
return(-1);
|
||||
}*/
|
||||
|
||||
if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
|
||||
printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
rx_offset = sample_offset + slot_offset - SOFFSET;
|
||||
// Align with 256 bit
|
||||
// rx_offset = rx_offset&0xfffffff8;
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
/*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
|
||||
ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
|
||||
#endif
|
||||
|
||||
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
|
||||
|
||||
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
|
||||
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
|
||||
|
||||
rx_offset += frame_parms->ofdm_symbol_size * symbol;
|
||||
|
||||
if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
|
||||
|
||||
rx_offset += nb_prefix_samples;
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
|
||||
(short*) &common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft((int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
||||
rx_offset += nb_prefix_samples0;
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
|
||||
(void *) &common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft((int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
|
||||
dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
}
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("slot_fep: done\n");
|
||||
#endif
|
||||
|
||||
@@ -255,7 +255,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
|
||||
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
|
||||
|
||||
int start = ue->ssb_offset; // start for offset correction is at ssb_offset (pss time position)
|
||||
int start = is*fp->samples_per_frame+ue->ssb_offset; // start for offset correction is at ssb_offset (pss time position)
|
||||
int end = start + 4*(fp->ofdm_symbol_size + fp->nb_prefix_samples); // loop over samples in 4 symbols (ssb size), including prefix
|
||||
|
||||
for(int n=start; n<end; n++){
|
||||
@@ -281,10 +281,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
|
||||
for(int i=0; i<4;i++)
|
||||
nr_slot_fep(ue,
|
||||
nr_slot_fep_init_sync(ue,
|
||||
i,
|
||||
0,
|
||||
ue->ssb_offset,
|
||||
is*fp->samples_per_frame+ue->ssb_offset,
|
||||
0);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
|
||||
@@ -880,7 +880,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||
|
||||
/* perform correlation of rx data and pss sequence ie it is a dot product */
|
||||
result = dot_product64((short*)primary_synchro_time_nr[pss_index],
|
||||
(short*) &(rxdata[ar][n])+(is*frame_parms->samples_per_frame),
|
||||
(short*) &(rxdata[ar][n+is*frame_parms->samples_per_frame]),
|
||||
frame_parms->ofdm_symbol_size,
|
||||
shift);
|
||||
pss_corr_ue[pss_index][n] += abs64(result);
|
||||
@@ -914,13 +914,13 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||
int64_t result1,result2;
|
||||
// Computing cross-correlation at peak on half the symbol size for first half of data
|
||||
result1 = dot_product64((short*)primary_synchro_time_nr[pss_source],
|
||||
(short*) &(rxdata[0][peak_position])+(is*frame_parms->samples_per_frame),
|
||||
(short*) &(rxdata[0][peak_position+is*frame_parms->samples_per_frame]),
|
||||
frame_parms->ofdm_symbol_size>>1,
|
||||
shift);
|
||||
// Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
|
||||
// as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
|
||||
result2 = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size),
|
||||
(short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)),
|
||||
(short*) &(rxdata[0][peak_position+frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)]),
|
||||
frame_parms->ofdm_symbol_size>>1,
|
||||
shift);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user