The nr_srs_channel_estimation function is split into the nr_srs_ls_channel_estimation and nr_srs_channel_interpolation functions to allow the use of a common delay

Define CIRCULAR_INC
This commit is contained in:
rmagueta
2026-03-19 10:07:07 +00:00
parent 0db8ddac08
commit 4f31a4eb89
5 changed files with 231 additions and 172 deletions
+1 -1
View File
@@ -195,7 +195,7 @@ static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, g
e->ul_freq_estimate_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 2048, -10, 80);
l = new_framelog(h, database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", "subframe", "chest_t");
l = new_framelog(h, database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", "subframe", "chest_f");
framelog_set_update_only_at_sf9(l, 0);
v = new_view_xy(2048, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE);
logger_add_view(l, v);
+4
View File
@@ -366,6 +366,10 @@ void nr_deconstruct_5g_s_tmsi(const uint64_t fiveg_s_tmsi, uint16_t *amf_set_id,
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b)))
/* Macro used to perform a circular increment. This implementation is computationally more efficient than using the remainder of the
* integer division, and improves code readability when compared to repetitive if... else statements. */
#define CIRCULAR_INC(val, inc, size) (((val) + (inc) >= (size)) ? ((val) + (inc) - (size)) : ((val) + (inc)))
static const char *const duplex_mode_txt[] = {"FDD", "TDD"};
#ifdef __cplusplus
@@ -765,30 +765,23 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
} // Antenna loop
}
int nr_srs_channel_estimation(int ant,
int p_index,
uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t *srs_generated_signal,
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint32_t *signal_power,
uint32_t *noise_power,
int16_t *noise_power_per_rb,
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE])
int nr_srs_ls_channel_estimation(int ant,
int p_index,
uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t *srs_generated_signal,
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
delay_t *delay)
{
#ifdef SRS_DEBUG
LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__);
#endif
const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
const uint64_t first_subcarrier = (first_carrier_offset - (ofdm_symbol_size >> 1)) + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
const uint8_t N_ap = 1 << srs_pdu->num_ant_ports;
const uint8_t K_TC = 2 << srs_pdu->comb_size;
@@ -799,11 +792,7 @@ int nr_srs_channel_estimation(int ant,
fd_cdm = 2;
}
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS];
c16_t srs_estimated_channel_freq_avg[ofdm_symbol_size];
memset(srs_ls_estimated_channel, 0, ofdm_symbol_size * N_symb_SRS * sizeof(c16_t));
memset(srs_estimated_channel_freq_avg, 0, ofdm_symbol_size * sizeof(c16_t));
delay_t delay = {0};
for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++) {
uint16_t srs_symbol_offset = srs_symb * ofdm_symbol_size;
@@ -813,12 +802,7 @@ int nr_srs_channel_estimation(int ant,
LOG_I(NR_PHY, "============================== SRS symbol index %d ===========================\n", srs_symb);
#endif
// Channel estimation based on least square method
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb];
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
uint16_t subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb], 0, ofdm_symbol_size);
c16_t ls_estimated = {0};
for (int k = 0; k < M_sc_b_SRS; k++) {
@@ -835,10 +819,7 @@ int nr_srs_channel_estimation(int ant,
ls_estimated = c16maddConjShift(generated_srs, received_srs, ls_estimated, nr_srs_info->srs_generated_signal_bits);
// Subcarrier increment
subcarrier_cdm += K_TC;
if (subcarrier_cdm >= ofdm_symbol_size) {
subcarrier_cdm = subcarrier_cdm - ofdm_symbol_size;
}
subcarrier_cdm = CIRCULAR_INC(subcarrier_cdm, K_TC, ofdm_symbol_size);
}
}
@@ -867,17 +848,116 @@ int nr_srs_channel_estimation(int ant,
#endif
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
subcarrier = CIRCULAR_INC(subcarrier, K_TC, ofdm_symbol_size);
} // for (int k = 0; k < M_sc_b_SRS; k++)
// Delay estimation
c16_t ch_estimates_time[ofdm_symbol_size] __attribute__((aligned(32)));
nr_est_delay(ofdm_symbol_size, srs_ls_estimated_channel, ch_estimates_time, &delay);
if (srs_symb == 0) {
c16_t ch_estimates_time[ofdm_symbol_size] __attribute__((aligned(32)));
nr_est_delay(ofdm_symbol_size, srs_ls_estimated_channel, ch_estimates_time, delay);
}
} // for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++)
// Interpolation of LS estimates
return 0;
}
void nr_srs_noise_power_estimation(uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
uint32_t signal_power,
const c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
uint32_t *noise_power,
int16_t *noise_power_per_rb)
{
const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index);
int tot_subcarriers = m_SRS_b * NR_NB_SC_PER_RB;
uint16_t subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[0][0], 0, ofdm_symbol_size);
if (subcarrier + tot_subcarriers < ofdm_symbol_size) {
*noise_power = signal_energy_nodc(&srs_received_noise[subcarrier], tot_subcarriers) / tot_subcarriers;
} else {
int size1 = ofdm_symbol_size - subcarrier;
int size2 = tot_subcarriers - size1;
uint64_t noise_power_p1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
uint64_t noise_power_p2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
*noise_power = (noise_power_p1 + noise_power_p2) / tot_subcarriers;
}
// Compute SNR per RB on symbol 0
subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[0][0], 0, ofdm_symbol_size);
for (int rb = 0; rb < m_SRS_b; rb++) {
if (subcarrier + NR_NB_SC_PER_RB < ofdm_symbol_size) {
noise_power_per_rb[rb] += signal_energy_nodc(&srs_received_noise[subcarrier], NR_NB_SC_PER_RB);
} else {
int size1 = ofdm_symbol_size - subcarrier;
int size2 = NR_NB_SC_PER_RB - size1;
uint32_t noise_power_per_rb1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
uint32_t noise_power_per_rb2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
noise_power_per_rb[rb] += (noise_power_per_rb1 + noise_power_per_rb2) / NR_NB_SC_PER_RB;
}
noise_power_per_rb[rb] = max(noise_power_per_rb[rb], 1);
subcarrier = CIRCULAR_INC(subcarrier, NR_NB_SC_PER_RB, ofdm_symbol_size);
#ifdef SRS_DEBUG
LOG_I(NR_PHY,
"[RB %3i] noise_power_per_rb = %i, SNR_per_rb = %i dB\n",
rb,
noise_power_per_rb[rb],
dB_fixed(signal_power) - dB_fixed(noise_power_per_rb[rb]));
#endif
}
#ifdef SRS_DEBUG
int32_t signal_power_dB = dB_fixed(signal_power);
int32_t noise_power_dB = dB_fixed(*noise_power);
LOG_I(NR_PHY,
"signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n",
signal_power_dB,
noise_power_dB,
signal_power_dB - noise_power_dB);
#endif
}
int nr_srs_channel_interpolation(int ant,
int p_index,
uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
int est_delay,
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint32_t *signal_power,
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE])
{
#ifdef SRS_DEBUG
LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__);
#endif
const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
const uint64_t first_subcarrier = (first_carrier_offset - (ofdm_symbol_size >> 1)) + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
const uint8_t K_TC = 2 << srs_pdu->comb_size;
const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index);
const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB / K_TC;
c16_t srs_estimated_channel_freq_avg[ofdm_symbol_size];
memset(srs_estimated_channel_freq_avg, 0, ofdm_symbol_size * sizeof(c16_t));
for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++) {
uint16_t srs_symbol_offset = srs_symb * ofdm_symbol_size;
#ifdef SRS_DEBUG
LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
LOG_I(NR_PHY, "============================== SRS symbol index %d ===========================\n", srs_symb);
#endif
// Additional 4 in the array size is needed to maintain 16 byte memory alignment required for AVX2 instructions in channel
// interpolation
@@ -891,18 +971,15 @@ int nr_srs_channel_estimation(int ant,
uint16_t subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
c16_t *srs_estimated_channel16 = &srs_est[subcarrier_abs];
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb];
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
uint16_t subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb], 0, ofdm_symbol_size);
int delay_idx = get_delay_idx(delay.est_delay, MAX_DELAY_COMP);
int delay_idx = get_delay_idx(est_delay, MAX_DELAY_COMP);
const c16_t *srs_delay_table = delay_table[delay_idx];
for (int k = 0; k < M_sc_b_SRS; k++) {
// Apply delay
ls_estimated = c16mulShift(srs_ls_estimated_channel[srs_symbol_offset + subcarrier], srs_delay_table[subcarrier], 8);
c16_t ls_estimated = c16mulShift(srs_ls_estimated_channel[srs_symbol_offset + subcarrier], srs_delay_table[subcarrier], 8);
// Channel interpolation
if (srs_pdu->comb_size == 0) {
@@ -935,34 +1012,21 @@ int nr_srs_channel_estimation(int ant,
}
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
subcarrier = CIRCULAR_INC(subcarrier, K_TC, ofdm_symbol_size);
subcarrier_abs += K_TC;
} // for (int k = 0; k < M_sc_b_SRS; k++)
// Revert delay
int inv_delay_idx = get_delay_idx(-delay.est_delay, MAX_DELAY_COMP);
int inv_delay_idx = get_delay_idx(-est_delay, MAX_DELAY_COMP);
const c16_t *srs_inv_delay_table = delay_table[inv_delay_idx];
subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][0], 0, ofdm_symbol_size);
for (int k = 0; k < K_TC * M_sc_b_SRS; k++) {
srs_est[subcarrier_abs] = c16mulShift(srs_est[subcarrier_abs], srs_inv_delay_table[subcarrier], 8);
// Subcarrier increment
subcarrier++;
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
subcarrier = CIRCULAR_INC(subcarrier, 1, ofdm_symbol_size);
subcarrier_abs++;
if (subcarrier_abs >= ofdm_symbol_size) {
subcarrier_abs -= ofdm_symbol_size;
}
}
memcpy(&srs_estimated_channel_freq[srs_symbol_offset], &srs_est[mem_offset], ofdm_symbol_size * sizeof(c16_t));
@@ -975,11 +1039,7 @@ int nr_srs_channel_estimation(int ant,
ofdm_symbol_size);
#ifdef SRS_DEBUG
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb];
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
subcarrier = CIRCULAR_INC(subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb], 0, ofdm_symbol_size);
subcarrier_abs = first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb];
for (int k = 0; k < K_TC * M_sc_b_SRS; k++) {
@@ -1007,10 +1067,7 @@ int nr_srs_channel_estimation(int ant,
srs_received_noise[srs_symbol_offset + subcarrier].i);
// Subcarrier increment
subcarrier++;
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
subcarrier = CIRCULAR_INC(subcarrier, 1, ofdm_symbol_size);
subcarrier_abs++;
}
#endif
@@ -1047,61 +1104,5 @@ int nr_srs_channel_estimation(int ant,
return -1;
}
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
if (p_index == 0) {
if (subcarrier + tot_subcarriers < ofdm_symbol_size) {
*noise_power = signal_energy_nodc(&srs_received_noise[subcarrier], tot_subcarriers) / tot_subcarriers;
} else {
int size1 = ofdm_symbol_size - subcarrier;
int size2 = tot_subcarriers - size1;
uint64_t noise_power_p1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
uint64_t noise_power_p2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
*noise_power = (noise_power_p1 + noise_power_p2) / tot_subcarriers;
}
}
// Compute SNR per RB for port 0 and symbol 0
if (p_index == 0) {
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
for (int rb = 0; rb < m_SRS_b; rb++) {
if (subcarrier >= ofdm_symbol_size) {
subcarrier -= ofdm_symbol_size;
}
if (subcarrier + NR_NB_SC_PER_RB < ofdm_symbol_size) {
noise_power_per_rb[rb] += signal_energy_nodc(&srs_received_noise[subcarrier], NR_NB_SC_PER_RB);
} else {
int size1 = ofdm_symbol_size - subcarrier;
int size2 = NR_NB_SC_PER_RB - size1;
uint32_t noise_power_per_rb1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1;
uint32_t noise_power_per_rb2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2;
noise_power_per_rb[rb] += (noise_power_per_rb1 + noise_power_per_rb2) / NR_NB_SC_PER_RB;
}
noise_power_per_rb[rb] = max(noise_power_per_rb[rb], 1);
subcarrier += NR_NB_SC_PER_RB;
#ifdef SRS_DEBUG
LOG_I(NR_PHY,
"[RB %3i] noise_power_per_rb = %i, SNR_per_rb = %i dB\n",
rb,
noise_power_per_rb[rb],
dB_fixed(*signal_power) - dB_fixed(noise_power_per_rb[rb]));
#endif
}
}
#ifdef SRS_DEBUG
int32_t signal_power_dB = dB_fixed(*signal_power);
int32_t noise_power_dB = dB_fixed(*noise_power);
LOG_I(NR_PHY,
"signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n",
signal_power_dB,
noise_power_dB,
signal_power_dB - noise_power_dB);
#endif
return 0;
}
+37 -17
View File
@@ -75,23 +75,43 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
unsigned char symbol,
uint32_t nb_re_pusch);
int nr_srs_channel_estimation(int ant,
int p_index,
uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t *srs_generated_signal,
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint32_t *signal_power,
uint32_t *noise_power,
int16_t *noise_power_per_rb,
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE]);
int nr_srs_ls_channel_estimation(int ant,
int p_index,
uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t *srs_generated_signal,
c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
delay_t *delay);
int nr_srs_channel_interpolation(int ant,
int p_index,
uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS],
int est_delay,
c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint32_t *signal_power,
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE]);
void nr_srs_noise_power_estimation(uint16_t ofdm_symbol_size,
uint16_t first_carrier_offset,
uint8_t N_symb_SRS,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
uint32_t signal_power,
const c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
uint32_t *noise_power,
int16_t *noise_power_per_rb);
void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF_comp,
+59 -25
View File
@@ -880,33 +880,49 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
stop_meas(&gNB->get_srs_signal_stats);
uint32_t signal_power_avg = 0;
uint32_t noise_power_avg = 0;
int16_t noise_power_per_rb[srs_pdu->bwp_size];
memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t));
c16_t srs_ls_estimated_channel[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS];
if (*srs_est >= 0) {
start_meas(&gNB->srs_channel_estimation_stats);
delay_t delay = {0};
for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) {
for (int p_ind = 0; p_ind < N_ap; p_ind++) {
delay_t delay_aux = {0};
nr_srs_ls_channel_estimation(ant_rx_ind,
p_ind,
ofdm_symbol_size,
frame_parms->first_carrier_offset,
N_symb_SRS,
srs_pdu,
nr_srs_info,
nr_srs_info->srs_generated_signal[p_ind],
srs_received_signal[ant_rx_ind],
srs_ls_estimated_channel[ant_rx_ind][p_ind],
&delay_aux);
if (delay_aux.delay_max_val > delay.delay_max_val)
delay = delay_aux;
}
}
for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) {
uint32_t noise_power = 0;
for (int p_ind = 0; p_ind < N_ap; p_ind++) {
uint32_t signal_power = 0;
nr_srs_channel_estimation(ant_rx_ind,
p_ind,
ofdm_symbol_size,
frame_parms->first_carrier_offset,
N_symb_SRS,
srs_pdu,
nr_srs_info,
nr_srs_info->srs_generated_signal[p_ind],
srs_received_signal[ant_rx_ind],
srs_received_noise[ant_rx_ind],
srs_estimated_channel_freq[ant_rx_ind][p_ind],
srs_estimated_channel_time[ant_rx_ind][p_ind],
srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
&signal_power,
&noise_power,
noise_power_per_rb,
frame_parms->delay_table);
nr_srs_channel_interpolation(ant_rx_ind,
p_ind,
ofdm_symbol_size,
frame_parms->first_carrier_offset,
N_symb_SRS,
srs_pdu,
nr_srs_info,
srs_ls_estimated_channel[ant_rx_ind][p_ind],
delay.est_delay,
srs_received_noise[ant_rx_ind],
srs_estimated_channel_freq[ant_rx_ind][p_ind],
srs_estimated_channel_time[ant_rx_ind][p_ind],
srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
&signal_power,
frame_parms->delay_table);
signal_power_avg += signal_power;
@@ -914,7 +930,7 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(slot_rx),
T_INT(0),
T_INT(ant_rx_ind),
T_INT(p_ind),
T_BUFFER(srs_estimated_channel_freq[ant_rx_ind][p_ind], N_symb_SRS * ofdm_symbol_size * sizeof(c16_t)));
@@ -923,17 +939,35 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(slot_rx),
T_INT(0),
T_INT(ant_rx_ind),
T_INT(p_ind),
T_BUFFER(srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size * sizeof(c16_t)));
}
noise_power_avg += noise_power;
}
signal_power_avg /= (nb_antennas_rx * N_ap);
noise_power_avg /= nb_antennas_rx;
signal_power_avg = max(signal_power_avg, 1);
uint32_t noise_power_avg = 0;
int16_t noise_power_per_rb[srs_pdu->bwp_size];
memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t));
for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) {
uint32_t noise_power_per_ant = 0;
nr_srs_noise_power_estimation(ofdm_symbol_size,
frame_parms->first_carrier_offset,
N_symb_SRS,
srs_pdu,
nr_srs_info,
signal_power_avg,
srs_received_noise[ant_rx_ind],
&noise_power_per_ant,
noise_power_per_rb);
noise_power_avg += noise_power_per_ant;
}
noise_power_avg /= nb_antennas_rx;
gNB->srs->snr = dB_fixed(signal_power_avg) - dB_fixed(max(noise_power_avg, 1));
const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index);