Commit 9574efbf authored by Florian Kaltenberger's avatar Florian Kaltenberger
Browse files

Merge remote-tracking branch 'origin/nr_ssb_periodicity' into integration-nr-2019-w21

parents 4cd3d635 acc88008
......@@ -169,6 +169,7 @@ static void UE_synch(void *arg) {
int freq_offset=0;
UE->is_synchronized = 0;
if (UE->UE_scan == 0) {
get_band(downlink_frequency[CC_id][0], &UE->frame_parms.eutra_band, &uplink_frequency_offset[CC_id][0], &UE->frame_parms.frame_type);
LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n",
......@@ -239,7 +240,7 @@ static void UE_synch(void *arg) {
case pbch:
LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
if (nr_initial_sync( &syncD->proc, UE, UE->mode ) == 0) {
if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) {
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot;
LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
......@@ -348,7 +349,7 @@ static void UE_synch(void *arg) {
}
}
void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
// Process Rx data for one sub-frame
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
//clean previous FAPI MESSAGE
......@@ -376,9 +377,9 @@ void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
uint64_t a=rdtsc();
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode, UE_mac->phy_config.config_req.pbch_config);
LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
// printf(">>> nr_ue_pdcch_procedures ended\n");
//printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
}
......@@ -413,7 +414,7 @@ void UE_processing(void *arg) {
processingData_t *rxtxD=(processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
processSubframeRX(UE, proc);
processSlotRX(UE, proc);
//printf(">>> mac ended\n");
// Prepare the future Tx data
#if 0
......@@ -447,7 +448,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for(int x=0; x<10; x++) {
for(int x=0; x<20; x++) { // two frames for initial sync
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe;
......@@ -613,6 +614,7 @@ void *UE_thread(void *arg) {
continue;
}
absolute_slot++;
// whatever means thread_idx
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
......
......@@ -393,7 +393,7 @@ static void get_options(void) {
uint32_t online_log_messages;
uint32_t glog_level, glog_verbosity;
uint32_t start_telnetsrv=0;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
......
......@@ -150,7 +150,7 @@
/* command line parameters common to eNodeB and UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC { \
#define CMDLINE_PARAMS_DESC_UE { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
......
......@@ -398,6 +398,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20);
gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value;
gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value;
gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value;
if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
gNB_config->subframe_config.duplex_mode.value = TDD;
......
......@@ -715,14 +715,13 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
// init RX buffers
common_vars->rxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
}
for (i=0; i<fp->nb_antennas_rx; i++) {
common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_subframe*10+2048)*sizeof(int32_t) );
common_vars->rxdata[i] = (int32_t*) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) );
}
......@@ -905,6 +904,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->decode_MIB = 1;
ue->decode_SIB = 1;
ue->ssb_periodicity = 5; // initialization of ssb periodicity to 5ms according to TS38.213 section 4.1
init_prach_tables(839);
......
......@@ -117,8 +117,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
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));
......@@ -135,13 +133,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
if (symbol==0) {
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],
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_length_samples],
(void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples],
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);
......@@ -150,19 +148,20 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
start_meas(&ue->rx_dft_stats);
#endif
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(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 += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol;// +
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol;
// + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
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],
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);
......@@ -170,13 +169,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
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_length_samples],
(void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
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) % frame_length_samples],
dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(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
......@@ -192,6 +191,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
#endif
}
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
#endif
......
......@@ -134,10 +134,11 @@ void free_context_synchro_nr(void);
void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
void free_context_pss_nr(void);
int set_pss_nr(int ofdm_symbol_size);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change);
int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
int fo_flag,
int is,
int *eNB_id,
int *f_off);
......
......@@ -65,7 +65,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
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,
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], eNB_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,Ns,k, symbol);
#endif
......@@ -324,6 +324,9 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
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);
#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
......@@ -441,8 +444,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
k = coreset_start_subcarrier;
#ifdef DEBUG_PDCCH
printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k, symbol);
printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,Ns,k, symbol);
#endif
fl = filt16a_l1;
......@@ -638,6 +641,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch)
{
int pilot[1320] __attribute__((aligned(16)));
unsigned char aarx;
unsigned short k;
......@@ -665,8 +669,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
int re_offset = k;
#ifdef DEBUG_CH
printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k, symbol);
printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,Ns,k, symbol);
#endif
switch (nushift) {
......
......@@ -201,13 +201,14 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
char duplex_string[2][4] = {"FDD","TDD"};
char prefix_string[2][9] = {"NORMAL","EXTENDED"};
int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode)
int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int n_frames)
{
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
int32_t metric_tdd_ncp=0;
uint8_t phase_tdd_ncp;
double im, re;
int is;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1;
......@@ -222,10 +223,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode)
nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,fp->N_RB_DL,n_ssb_crb,0);
LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
/*
write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
exit(-1);
*/
/* Initial synchronisation
*
......@@ -244,17 +242,18 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode)
if (1){ // (cnt>100)
cnt =0;
// initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame
// only one frame is used for symulation tools
for(is=0; is<n_frames;is++) {
/* process pss search on received buffer */
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE);
if (sync_pos >= fp->nb_prefix_samples)
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
else
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;
//write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id);
LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset);
......@@ -278,7 +277,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode)
}
}
/* check that SSS/PBCH block is continuous inside the received buffer */
if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) {
......@@ -333,16 +331,20 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode)
ue->common_vars.freq_offset );
*/
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n",
fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret);
#endif
}
else {
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos);
#endif
}
if (ret == 0) break;
}
}
else {
ret = -1;
......@@ -370,6 +372,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode)
#endif
//#endif
ue->is_synchronized_on_frame = is; // to notify on which of the two frames sync was successful
if (ue->UE_scan_carrier == 0) {
#if UE_AUTOTEST_TRACE
......
......@@ -417,6 +417,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
uint8_t i_ssb,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag) {
int Ns = proc->nr_tti_rx;
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
int max_h=0;
int symbol;
......@@ -443,19 +445,21 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
int symbol_offset=1;
if (ue->is_synchronized > 0)
symbol_offset=ue->symbol_offset;
symbol_offset=(ue->symbol_offset)%(frame_parms->symbols_per_slot);
else
symbol_offset=0;
#ifdef DEBUG_PBCH
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF);
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF);
write_output("rxdataF0_pbch.m","rxF0pbch",
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
#endif
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
for (symbol=1; symbol<4; symbol++) {
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF,
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF,
nr_ue_pbch_vars->dl_ch_estimates,
nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext,
......
......@@ -1480,7 +1480,9 @@ void generate_RIV_tables(void);
@param mode current running mode
*/
int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
PHY_VARS_NR_UE *phy_vars_ue,
runmode_t mode,
int n_frames);
/*!
......
......@@ -402,7 +402,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
assert(0);
}
size = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int64_t)*frame_parms_ue->samples_per_subframe;
size = sizeof(int64_t)*(frame_parms_ue->samples_per_frame + (2*ofdm_symbol_size));
q = (int64_t*)malloc16(size);
if (q != NULL) {
pss_corr_ue[i] = q;
......@@ -611,7 +611,7 @@ void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_ch
void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **rxdata)
{
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int samples_for_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
int samples_for_frame = 2*frame_parms->samples_per_frame;
AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti);
......@@ -658,7 +658,7 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r
*
*********************************************************************/
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
{
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int synchro_position;
......@@ -667,9 +667,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
#ifdef DBG_PSS_NR
int samples_for_frame = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1);
LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1);
#endif
......@@ -678,7 +676,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) {
rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+8192)*sizeof(int32_t));
rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_frame+8192)*sizeof(int32_t));
}
#ifdef SYNCHRO_DECIMAT
......@@ -693,7 +691,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
#ifdef DBG_PSS_NR
LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1);
LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame,1,1);
#endif
......@@ -708,6 +706,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
synchro_position = pss_search_time_nr(rxdata,
frame_parms,
fo_flag,
is,
(int *)&PHY_vars_UE->common_vars.eNb_id,
(int *)&PHY_vars_UE->common_vars.freq_offset);
......@@ -746,6 +745,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
return synchro_position;
}
static inline int abs32(int x)
{
return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
......@@ -820,6 +820,7 @@ static inline double angle64(int64_t x)
int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
int fo_flag,
int is,
int *eNB_id,
int *f_off)
{
......@@ -829,13 +830,17 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
int64_t avg[NUMBER_PSS_SEQUENCE];
double ffo_est=0;
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
// performing the correlation on a frame length plus one symbol for the first of the two frame
// to take into account the possibility of PSS in between the two frames
unsigned int length;
if (is==0)
length = frame_parms->samples_per_frame + (2*frame_parms->ofdm_symbol_size);
else
length = frame_parms->samples_per_frame;
AssertFatal(length>0,"illegal length %d\n",length);
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
peak_value = 0;
peak_position = 0;
pss_source = 0;
......@@ -871,7 +876,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]),
(short*) &(rxdata[ar][n])+(is*frame_parms->samples_per_frame),
frame_parms->ofdm_symbol_size,
shift);
pss_corr_ue[pss_index][n] += abs64(result);
......@@ -905,13 +910,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]),
(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),
(short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)),
frame_parms->ofdm_symbol_size>>1,
shift);
......@@ -950,6 +955,9 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6);
LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6);
LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6);
if (is)
LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1);
else
LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1);
} else {
debug_cnt++;
......
......@@ -292,7 +292,7 @@ typedef struct {
/// \brief Holds the received data in time domain.
/// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[
/// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[
int32_t **rxdata;
NR_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX];
......@@ -880,8 +880,10 @@ typedef struct {
int UE_scan_carrier;
/// \brief Indicator that UE should enable estimation and compensation of frequency offset
int UE_fo_compensation;
/// \brief Indicator that UE is synchronized to an eNB
/// \brief Indicator that UE is synchronized to a gNB
int is_synchronized;
/// \brief Indicates on which frame is synchronized in a two frame synchronization
int is_synchronized_on_frame;
/// Data structure for UE process scheduling
UE_nr_proc_t proc;
/// Flag to indicate the UE shouldn't do timing correction at all
......@@ -1038,6 +1040,7 @@ typedef struct {
// uint8_t prach_timer;
uint8_t decode_SIB;
uint8_t decode_MIB;
uint8_t ssb_periodicity;
/// temporary offset during cell search prior to MIB decoding
int ssb_offset;
uint16_t symbol_offset; // offset in terms of symbols for detected ssb in sync
......
......@@ -93,10 +93,18 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
int ssb_start_symbol, rel_slot;
n_hf = cfg->sch_config.half_frame_index.value;
// if SSB periodicity is 5ms, they are transmitted in both half frames
if ( cfg->sch_config.ssb_periodicity.value == 5) {
if (slot<10)
n_hf=0;
else
n_hf=1;
}
// to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be
rel_slot = (n_hf)? (slot-10) : slot;
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
if(rel_slot<10 && rel_slot>=0) {
......@@ -114,7 +122,10 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp);
if (fp->Lmax == 4)
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp);
else
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp);
nr_generate_pbch(&gNB->pbch,
pbch_pdu,
......@@ -137,6 +148,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id;
uint8_t ssb_frame_periodicity; // every how many frames SSB are generated
if (cfg->sch_config.ssb_periodicity.value < 20)
ssb_frame_periodicity = 1;
else
ssb_frame_periodicity = (cfg->sch_config.ssb_periodicity.value)/10 ; // 10ms is the frame length
if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return;