Merge remote-tracking branch 'origin/nr_ue_improve_time_and_freq_sync' into integration_2022_wk44
This commit is contained in:
+2
-2
@@ -798,10 +798,10 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
|
||||
|
||||
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
|
||||
int samples_shift = -(UE->rx_offset>>1);
|
||||
UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame
|
||||
UE->max_pos_fil = 0; // reset IIR filter when sample shift is applied
|
||||
if (samples_shift != 0) {
|
||||
LOG_I(NR_PHY,"Adjusting frame in time by %i samples\n", samples_shift);
|
||||
UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame
|
||||
UE->max_pos_fil += samples_shift << 15; // reset IIR filter when sample shift is applied
|
||||
}
|
||||
return samples_shift;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#define DEBUG_PHY
|
||||
//#define DEBUG_PHY
|
||||
|
||||
// Adjust location synchronization point to account for drift
|
||||
// The adjustment is performed once per frame based on the
|
||||
@@ -75,14 +75,14 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
// filter position to reduce jitter
|
||||
if (clear == 1)
|
||||
ue->max_pos_fil = max_pos;
|
||||
ue->max_pos_fil = max_pos << 15;
|
||||
else
|
||||
ue->max_pos_fil = ((ue->max_pos_fil * coef) + (max_pos * ncoef)) >> 15;
|
||||
ue->max_pos_fil = ((ue->max_pos_fil * coef) >> 15) + (max_pos * ncoef);
|
||||
|
||||
// do not filter to have proactive timing adjustment
|
||||
//ue->max_pos_fil = max_pos;
|
||||
//ue->max_pos_fil = max_pos << 15;
|
||||
|
||||
int diff = ue->max_pos_fil - sync_pos;
|
||||
int diff = (ue->max_pos_fil >> 15) - sync_pos;
|
||||
|
||||
if (frame_parms->freq_range==nr_FR2)
|
||||
sync_offset = 2;
|
||||
@@ -118,7 +118,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PHY
|
||||
LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
|
||||
LOG_I(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
|
||||
subframe,
|
||||
diff,
|
||||
ue->rx_offset,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/nr_mod_table.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
@@ -39,7 +40,26 @@
|
||||
//#define DEBUG_PBCH
|
||||
//#define DEBUG_PRS_CHEST // To enable PRS Matlab dumps
|
||||
//#define DEBUG_PRS_PRINTS // To enable PRS channel estimation debug logs
|
||||
extern short nr_qpsk_mod_table[8];
|
||||
|
||||
#define CH_INTERP 0
|
||||
#define NO_INTERP 1
|
||||
|
||||
/* Generic function to find the peak of channel estimation buffer */
|
||||
void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val)
|
||||
{
|
||||
int32_t max_val = 0, max_idx = 0, abs_val = 0;
|
||||
for(int k = 0; k < buf_len; k++)
|
||||
{
|
||||
abs_val = squaredMod(((c16_t*)buffer)[k]);
|
||||
if(abs_val > max_val)
|
||||
{
|
||||
max_val = abs_val;
|
||||
max_idx = k;
|
||||
}
|
||||
}
|
||||
*peak_val = max_val;
|
||||
*peak_idx = max_idx;
|
||||
}
|
||||
|
||||
int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
uint8_t rsc_id,
|
||||
@@ -545,29 +565,6 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define CH_INTERP 0
|
||||
#define NO_INTERP 1
|
||||
|
||||
/* Generic function to find the peak of channel estimation buffer */
|
||||
void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val)
|
||||
{
|
||||
int32_t max_val = 0, max_idx = 0, abs_val = 0;
|
||||
for(int k = 0; k < buf_len; k++)
|
||||
{
|
||||
abs_val = squaredMod(((c16_t*)buffer)[k]);
|
||||
if(abs_val > max_val)
|
||||
{
|
||||
max_val = abs_val;
|
||||
max_idx = k;
|
||||
}
|
||||
}
|
||||
*peak_val = max_val;
|
||||
*peak_idx = max_idx;
|
||||
}
|
||||
|
||||
#define CH_INTERP 0
|
||||
#define NO_INTERP 1
|
||||
|
||||
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t gNB_id,
|
||||
@@ -990,7 +987,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
if (dmrss == 2)
|
||||
UEscopeCopy(ue, pbchDlChEstimateTime, (void*)dl_ch_estimates_time, sizeof(struct complex16), ue->frame_parms.nb_antennas_rx, idftsizeidx);
|
||||
UEscopeCopy(ue, pbchDlChEstimateTime, (void*)dl_ch_estimates_time, sizeof(struct complex16), ue->frame_parms.nb_antennas_rx, ue->frame_parms.ofdm_symbol_size);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1223,6 +1220,10 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
ch[0] = ch_sum[0] / 3;
|
||||
ch[1] = ch_sum[1] / 3;
|
||||
multadd_real_vector_complex_scalar(filt16a_1, ch, dl_ch, 16);
|
||||
#ifdef DEBUG_PDCCH
|
||||
for (int m =0; m<12; m++)
|
||||
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
|
||||
#endif
|
||||
dl_ch += 24;
|
||||
ch_sum[0] = 0;
|
||||
ch_sum[1] = 0;
|
||||
|
||||
@@ -682,18 +682,22 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
int32_t avgs;
|
||||
int32_t avgP[4];
|
||||
int n_rb,rb_offset;
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
|
||||
|
||||
// Pointers to extracted PDCCH symbols in frequency-domain.
|
||||
int32_t rx_size = 4*273*12;
|
||||
__attribute__ ((aligned(32))) int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size];
|
||||
int32_t rx_size = 4*n_rb*12;
|
||||
__attribute__ ((aligned(32))) int32_t rxdataF_ext[frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t rxdataF_comp[frame_parms->nb_antennas_rx][rx_size];
|
||||
__attribute__ ((aligned(32))) int32_t pdcch_dl_ch_estimates_ext[frame_parms->nb_antennas_rx][rx_size];
|
||||
|
||||
memset(rxdataF_comp, 0, sizeof(rxdataF_comp));
|
||||
|
||||
// Pointer to llrs, 4-bit resolution.
|
||||
int32_t llr_size = 2*4*100*12;
|
||||
int32_t llr_size = 2*4*n_rb*9;
|
||||
int16_t llr[llr_size];
|
||||
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
|
||||
memset(llr, 0, sizeof(llr));
|
||||
|
||||
LOG_D(PHY,"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
|
||||
rel15->coreset.frequency_domain_resource[0],n_rb,rb_offset);
|
||||
for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) {
|
||||
|
||||
@@ -51,7 +51,7 @@ extern openair0_config_t openair0_cfg[];
|
||||
int cnt=0;
|
||||
|
||||
#define DEBUG_INITIAL_SYNCH
|
||||
|
||||
#define DUMP_PBCH_CH_ESTIMATES 0
|
||||
|
||||
// create a new node of SSB structure
|
||||
NR_UE_SSB* create_ssb_node(uint8_t i, uint8_t h) {
|
||||
@@ -168,6 +168,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
|
||||
phy_pdcch_config,
|
||||
&result);
|
||||
|
||||
if (DUMP_PBCH_CH_ESTIMATES && (ret == 0)) {
|
||||
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1);
|
||||
write_output("pbch_ch_estimates_time.m", "pbch_ch_estimates_time", dl_ch_estimates_time, frame_parms->nb_antennas_rx*frame_parms->ofdm_symbol_size, 1, 1);
|
||||
}
|
||||
|
||||
temp_ptr=temp_ptr->next_ssb;
|
||||
}
|
||||
|
||||
@@ -246,52 +251,51 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE);
|
||||
if (sync_pos < fp->nb_prefix_samples)
|
||||
continue;
|
||||
|
||||
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;
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation){
|
||||
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
|
||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
||||
if (ue->ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) < fp->samples_per_frame) {
|
||||
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation){
|
||||
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
|
||||
|
||||
// start for offset correction
|
||||
int start = sa ? is*fp->samples_per_frame : is*fp->samples_per_frame + ue->ssb_offset;
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
// loop over samples
|
||||
int end = sa ? n_frames*fp->samples_per_frame-1 : start + NR_N_SYMBOLS_SSB*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
// start for offset correction
|
||||
int start = is*fp->samples_per_frame;
|
||||
|
||||
for(int n=start; n<end; n++){
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
|
||||
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
|
||||
// loop over samples
|
||||
int end = start + fp->samples_per_frame;
|
||||
|
||||
for(int n=start; n<end; n++){
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
|
||||
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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))) {
|
||||
|
||||
/* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
|
||||
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
|
||||
/* symbol number are from beginning of SS/PBCH blocks as below: */
|
||||
/* Signal PSS PBCH SSS PBCH */
|
||||
/* symbol number 0 1 2 3 */
|
||||
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
/* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
|
||||
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
|
||||
/* symbol number are from beginning of SS/PBCH blocks as below: */
|
||||
/* Signal PSS PBCH SSS PBCH */
|
||||
/* symbol number 0 1 2 3 */
|
||||
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
|
||||
/* 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_init_sync(ue,
|
||||
@@ -317,10 +321,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
// start for offset correction
|
||||
int start = sa ? is*fp->samples_per_frame : is*fp->samples_per_frame + ue->ssb_offset;
|
||||
int start = is*fp->samples_per_frame;
|
||||
|
||||
// loop over samples
|
||||
int end = sa ? n_frames*fp->samples_per_frame-1 : start + NR_N_SYMBOLS_SSB*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
int end = start + fp->samples_per_frame;
|
||||
|
||||
for(int n=start; n<end; n++){
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
|
||||
@@ -1561,9 +1561,9 @@ int main(int argc, char **argv)
|
||||
for (int r = 1; r < max_rounds; r++)
|
||||
printf(",%d/%d", n_errors[r], round_trials[r]);
|
||||
printf(") (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u",
|
||||
n_false_positive, n_trials, errors_scrambling[0], available_bits * n_trials);
|
||||
n_false_positive, n_trials, errors_scrambling[0], available_bits * round_trials[0]);
|
||||
for (int r = 1; r < max_rounds; r++)
|
||||
printf(",%u/%u", errors_scrambling[r], available_bits * n_trials);
|
||||
printf(",%u/%u", errors_scrambling[r], available_bits * round_trials[r]);
|
||||
printf(")\n");
|
||||
printf("\n");
|
||||
|
||||
|
||||
@@ -181,7 +181,6 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
thread_pool_size = 8;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
@@ -179,7 +179,6 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
thread_pool_size = 8;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
@@ -235,7 +235,6 @@ L1s = (
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
thread_pool_size = 4;
|
||||
# pucch0_dtx_threshold = 150;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -239,7 +239,6 @@ L1s = (
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
thread_pool_size = 8;
|
||||
# pucch0_dtx_threshold = 150;
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user