Commit 3e0efbde authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/nr_ue_improve_time_and_freq_sync' into integration_2022_wk44

parents 00106a7e 5063957a
......@@ -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;
}
);
......
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