Compare commits

...

2 Commits

4 changed files with 43 additions and 6 deletions

View File

@@ -138,6 +138,9 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
AssertFatal(ret_loader == 0, "error loading LDPC library\n");
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
fp->delay_table = calloc(2 * MAX_DELAY_COMP + 1, sizeof(*fp->delay_table));
fp->delay_table128 = calloc(2 * MAX_DELAY_COMP + 1, sizeof(*fp->delay_table128));
AssertFatal(fp->delay_table && fp->delay_table128, "Failed to allocate delay tables\n");
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
init_delay_table(128, MAX_DELAY_COMP, 128, fp->delay_table128);
@@ -283,6 +286,9 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_nrLDPC_coding_interface(&gNB->nrLDPC_coding_interface);
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
free_and_zero(fp->delay_table);
free_and_zero(fp->delay_table128);
}
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,

View File

@@ -336,6 +336,11 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero(ue->prs_vars[idx]);
}
free(ue->frame_parms.delay_table);
ue->frame_parms.delay_table = NULL;
free(ue->frame_parms.delay_table128);
ue->frame_parms.delay_table128 = NULL;
sl_ue_free(ue);
}
@@ -489,6 +494,9 @@ void clean_UE_harq(PHY_VARS_NR_UE *UE)
void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
frame_parms->delay_table = calloc(2 * MAX_DELAY_COMP + 1, sizeof(*frame_parms->delay_table));
frame_parms->delay_table128 = calloc(2 * MAX_DELAY_COMP + 1, sizeof(*frame_parms->delay_table128));
AssertFatal(frame_parms->delay_table && frame_parms->delay_table128, "Failed to allocate delay tables\n");
init_delay_table(frame_parms->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, frame_parms->delay_table);
crcTableInit();
init_byte2m128i();

View File

@@ -80,7 +80,7 @@
#define MAX_NUM_NR_SRS_AP 4
#define MAX_DELAY_COMP 20
#define MAX_DELAY_COMP 160
#define PBCH_MAX_RE_PER_SYMBOL (20 * 12)
@@ -239,10 +239,10 @@ struct NR_DL_FRAME_PARMS {
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// Table used to apply the delay compensation in DL/UL
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE];
/// Table used to apply the delay compensation in PUCCH2
c16_t delay_table128[2 * MAX_DELAY_COMP + 1][128];
/// Table used to apply the delay compensation in DL/UL (dynamically allocated)
c16_t (*delay_table)[NR_MAX_OFDM_SYMBOL_SIZE];
/// Table used to apply the delay compensation in PUCCH2 (dynamically allocated)
c16_t (*delay_table128)[128];
/// Power used by SSB in order to estimate signal strength and path loss
int ss_PBCH_BlockPower;

View File

@@ -384,7 +384,30 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates
// estimated delay, and causing the delay compensation to worsen the result instead of improving it. After analyzing several
// peaks, and doing many tests, a PEAK_DETECT_THRESHOLD = 15 is an adequate value, to apply delay compensation only when there is
// clearly a peak
delay->est_delay = mean_val > 0 && max_val / mean_val > PEAK_DETECT_THRESHOLD ? max_pos - sync_pos : 0;
if (mean_val == 0 || max_val / mean_val <= PEAK_DETECT_THRESHOLD) {
delay->est_delay = 0;
return;
}
// In multipath channels, the strongest tap may be a late reflection rather than the
// first arrival. Aligning to a late tap shifts the FFT window so early paths fall
// before the CP, worsening ISI. Instead, find the first significant tap (-6 dB
// relative to the peak in power) which keeps the most multipath energy inside the CP.
// TODO: could scan from max_pos - scan_range to max_pos instead of -scan_range to
// +scan_range since the first path is always <= peak delay
const int threshold = max_val >> 2;
const int scan_range = MAX_DELAY_COMP < ofdm_symbol_size / 2 ? MAX_DELAY_COMP : ofdm_symbol_size / 2 - 1;
int first_sig_delay = max_pos;
for (int d = -scan_range; d <= scan_range; d++) {
int idx = d < 0 ? d + ofdm_symbol_size : d;
int power = c16amp2(ch_estimates_time[idx]) >> 1;
if (power > threshold) {
first_sig_delay = d;
break;
}
}
delay->est_delay = first_sig_delay - sync_pos;
}
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb)