free5GRAN  V1.0
Time and frequency synchronization

Time domain synchronization:

Time domain synchronization is based on PSS and SSS correlation. Those two physical signals are part of Synchronization Signal Block (SSB), which also comprises PBCH and PBCH DMRS. PSS and SSS are generated based on N_ID_2 and N_ID_1. Time domain synchronization consists in cross correlating all possible PSS sequences with received frame. Highest correlation peak gives N_ID_2 and the time where input signal contains PSS, which provides PSS position in received frame and thus time synchronization. SSS sequences are then correlated with received signal to deduce N_ID_1 and receiver can compute Physical Cell ID, written N_ID_CELL:

N_ID_CELL = 3 . N_ID_1 + N_ID_2

In the current implementation, PSS synchronization is done in src/phy/phy.cpp line 111:

free5GRAN::phy::synchronization::search_pss(n_id_2,synchronisation_index,peak_value, common_cp_length, buff, fft_size);

And SSS correlation is done after having isolated the corresponding part of the signal:

free5GRAN::phy::synchronization::get_sss(n_id_1, peak_value_sss, sss_signal, fft_size, n_id_2);

In the current version, cell time-wise synchronization is done twice. In a first step, the receiver tries to search if a cell exists, and scan the frequency with the lowest possible bandwidth. In a second step, receiver increases its bandwidth and re-synchronizes with the cell. While resynchronizing, receiver first downsample the signal so the PSS search is much quicker:

vector<complex<float>> pss_signal_downsampled(48 * symbol_duration_downsampled);
for (int i = 0; i < 48 * symbol_duration_downsampled; i ++){
pss_signal_downsampled[i] = pss_signal[downsampling_factor * i];
}

Frequency domain synchronization:

Fine frequency synchronization has to be performed to mitigate Doppler effects. First, SSB symbols cyclic prefixes are correlated with corresponding symbols part. Phase offset on each symbol is derived as being the phase of the previous correlation. Finally, global phase offset is computed as being the mean of symbols phase offsets, and frequency correction is computed.

In the current implementation, this is done in src/phy/phy.cpp line 346:

free5GRAN::phy::signal_processing::compute_fine_frequency_offset(ssb_signal, symbol_duration, fft_size, common_cp_length, scs, freq_offset, free5GRAN::NUM_SYMBOLS_SSB);