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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user