mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 21:20:30 +00:00
Compare commits
6 Commits
develop
...
SRS_improv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7789339cfb | ||
|
|
8e00cf0532 | ||
|
|
422b10cdac | ||
|
|
f877d51db6 | ||
|
|
32cfe3cc8b | ||
|
|
74e56c0cde |
@@ -143,6 +143,10 @@ ID = GNB_PHY_UL_TIME_CHANNEL_ESTIMATE
|
||||
DESC = gNodeB channel estimation in the time domain
|
||||
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
|
||||
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t
|
||||
ID = GNB_PHY_UL_SNR_ESTIMATE
|
||||
DESC = gNodeB SNR estimation based on SRS
|
||||
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
|
||||
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,snr
|
||||
ID = GNB_PHY_PRACH_INPUT_SIGNAL
|
||||
DESC = gNodeB input data in the time domain for slots with PRACH detection
|
||||
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
|
||||
|
||||
@@ -19,6 +19,7 @@ typedef struct {
|
||||
widget *pucch_pusch_iq_plot;
|
||||
widget *ul_freq_estimate_ue_xy_plot;
|
||||
widget *ul_time_estimate_ue_xy_plot;
|
||||
widget *ul_snr_estimate_ue_xy_plot;
|
||||
widget *current_ue_label;
|
||||
widget *current_ue_button;
|
||||
widget *prev_ue_button;
|
||||
@@ -26,6 +27,7 @@ typedef struct {
|
||||
logger *pucch_pusch_iq_logger;
|
||||
logger *ul_freq_estimate_ue_logger;
|
||||
logger *ul_time_estimate_ue_logger;
|
||||
logger *ul_snr_ue_logger;
|
||||
} gnb_gui;
|
||||
|
||||
typedef struct {
|
||||
@@ -98,6 +100,9 @@ static void set_current_ue(gui *g, gnb_data *e, int ue)
|
||||
|
||||
sprintf(s, "UL channel estimation in time domain [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->ul_time_estimate_ue_xy_plot, s);
|
||||
|
||||
sprintf(s, "UL SNR per RB based on SRS [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->ul_snr_estimate_ue_xy_plot, s);
|
||||
}
|
||||
|
||||
void reset_ue_ids(void)
|
||||
@@ -146,12 +151,13 @@ static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, g
|
||||
logger *l;
|
||||
view *v;
|
||||
|
||||
main_window = new_toplevel_window(g, 1500, 230, "gNB tracer");
|
||||
main_window = new_toplevel_window(g, 1500, 460, "gNB tracer");
|
||||
top_container = new_container(g, VERTICAL);
|
||||
widget_add_child(g, main_window, top_container, -1);
|
||||
|
||||
line = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, top_container, line, -1);
|
||||
|
||||
logo = new_image(g, openair_logo_png, openair_logo_png_len);
|
||||
|
||||
/* logo + prev/next UE buttons */
|
||||
@@ -206,6 +212,21 @@ static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, g
|
||||
logger_add_view(l, v);
|
||||
e->ul_time_estimate_ue_logger = l;
|
||||
|
||||
line = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, top_container, line, -1);
|
||||
|
||||
/* UL SNR based on SRS */
|
||||
w = new_xy_plot(g, 1280, 200, "", 190);
|
||||
e->ul_snr_estimate_ue_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, 0, 273, -10, 65);
|
||||
l = new_framelog(h, database, "GNB_PHY_UL_SNR_ESTIMATE", "subframe", "snr");
|
||||
framelog_set_update_only_at_sf9(l, 0);
|
||||
framelog_set_type_buffer_db(l);
|
||||
v = new_view_xy(273, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE);
|
||||
logger_add_view(l, v);
|
||||
e->ul_snr_ue_logger = l;
|
||||
|
||||
set_current_ue(g, ed, ed->ue);
|
||||
register_notifier(g, "click", e->current_ue_button, click, ed);
|
||||
register_notifier(g, "click", e->prev_ue_button, click, ed);
|
||||
@@ -251,6 +272,7 @@ int main(int n, char **v)
|
||||
on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1);
|
||||
on_off(database, "GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE", is_on, 1);
|
||||
on_off(database, "GNB_PHY_UL_TIME_CHANNEL_ESTIMATE", is_on, 1);
|
||||
on_off(database, "GNB_PHY_UL_SNR_ESTIMATE", is_on, 1);
|
||||
|
||||
gnb_data.ue = 0;
|
||||
gnb_data.e = ⪚
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef enum {
|
||||
FRAMELOG_BUFFER,
|
||||
FRAMELOG_BUFFER_dB,
|
||||
} framelog_buffer_type_t;
|
||||
|
||||
struct framelog {
|
||||
struct logger common;
|
||||
void *database;
|
||||
@@ -22,6 +27,7 @@ struct framelog {
|
||||
int skip_current; /* internal data for the skip mechanism */
|
||||
int skip_on; /* internal data for the skip mechanism */
|
||||
int update_only_at_sf9;
|
||||
framelog_buffer_type_t type;
|
||||
};
|
||||
|
||||
static void _event(void *p, event e)
|
||||
@@ -52,7 +58,10 @@ static void _event(void *p, event e)
|
||||
}
|
||||
if (l->skip_on) return;
|
||||
|
||||
nsamples = bsize / (2*sizeof(int16_t));
|
||||
if (l->type == FRAMELOG_BUFFER)
|
||||
nsamples = bsize / (2 * sizeof(int16_t));
|
||||
else
|
||||
nsamples = bsize / sizeof(int16_t);
|
||||
|
||||
if (l->blength != nsamples * 10) {
|
||||
l->blength = nsamples * 10;
|
||||
@@ -71,10 +80,15 @@ static void _event(void *p, event e)
|
||||
}
|
||||
|
||||
/* TODO: compute the LOGs in the plotter (too much useless computations) */
|
||||
for (i = 0; i < nsamples; i++) {
|
||||
int I = ((int16_t *)buffer)[i*2];
|
||||
int Q = ((int16_t *)buffer)[i*2+1];
|
||||
l->buffer[subframe * nsamples + i] = 10*log10(1.0+(float)(I*I+Q*Q));
|
||||
if (l->type == FRAMELOG_BUFFER_dB) {
|
||||
for (i = 0; i < nsamples; i++)
|
||||
l->buffer[subframe * nsamples + i] = ((int16_t *)buffer)[i];
|
||||
} else {
|
||||
for (i = 0; i < nsamples; i++) {
|
||||
int I = ((int16_t *)buffer)[i * 2];
|
||||
int Q = ((int16_t *)buffer)[i * 2 + 1];
|
||||
l->buffer[subframe * nsamples + i] = 10 * log10(1.0 + (float)(I * I + Q * Q));
|
||||
}
|
||||
}
|
||||
|
||||
if (l->update_only_at_sf9 == 0 || subframe == 9)
|
||||
@@ -132,6 +146,8 @@ logger *new_framelog(event_handler *h, void *database,
|
||||
abort();
|
||||
}
|
||||
|
||||
ret->type = FRAMELOG_BUFFER;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -153,3 +169,9 @@ void framelog_set_update_only_at_sf9(logger *_this, int update_only_at_sf9)
|
||||
struct framelog *l = _this;
|
||||
l->update_only_at_sf9 = update_only_at_sf9;
|
||||
}
|
||||
|
||||
void framelog_set_type_buffer_db(logger *_this)
|
||||
{
|
||||
struct framelog *l = _this;
|
||||
l->type = FRAMELOG_BUFFER_dB;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ logger *new_iqdotlog(void *event_handler, void *database,
|
||||
|
||||
void framelog_set_skip(logger *_this, int skip_delay);
|
||||
void framelog_set_update_only_at_sf9(logger *_this, int update_only_at_sf9);
|
||||
void framelog_set_type_buffer_db(logger *_this);
|
||||
|
||||
void textlog_dump_buffer(logger *_this, int dump_buffer);
|
||||
void textlog_raw_time(logger *_this, int raw_time);
|
||||
|
||||
@@ -36,49 +36,74 @@
|
||||
|
||||
#define I0_SKIP_DC 1
|
||||
|
||||
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size])
|
||||
void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
|
||||
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
uint8_t ant,
|
||||
uint8_t N_ap,
|
||||
uint32_t samples_per_frame,
|
||||
uint16_t *timing_advance_offset,
|
||||
int16_t *timing_advance_offset_nsec)
|
||||
{
|
||||
int timing_advance = 0;
|
||||
int max_val = 0;
|
||||
|
||||
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
|
||||
int temp = 0;
|
||||
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r;
|
||||
int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i;
|
||||
temp += (Re*Re/2) + (Im*Im/2);
|
||||
int64_t mean_val = 0;
|
||||
int64_t max_val = 0;
|
||||
int32_t max_idx = 0;
|
||||
int16_t ofdm_oversample_symbol_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size;
|
||||
for (int k = 0; k < ofdm_oversample_symbol_size; k++) {
|
||||
int64_t abs_val = 0;
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
abs_val += squaredMod(srs_estimated_channel_time[p_index][k]);
|
||||
}
|
||||
if (temp > max_val) {
|
||||
timing_advance = i;
|
||||
max_val = temp;
|
||||
mean_val += abs_val;
|
||||
if (abs_val > max_val) {
|
||||
max_val = abs_val;
|
||||
max_idx = k;
|
||||
}
|
||||
}
|
||||
max_val = max_val / N_ap;
|
||||
mean_val = mean_val / (N_ap * ofdm_oversample_symbol_size);
|
||||
|
||||
if (timing_advance > frame_parms->ofdm_symbol_size/2) {
|
||||
timing_advance = timing_advance - frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
if (max_idx > ofdm_oversample_symbol_size >> 1)
|
||||
max_idx = max_idx - ofdm_oversample_symbol_size;
|
||||
|
||||
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
|
||||
const uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 7;
|
||||
// Check for detection threshold
|
||||
if ((mean_val != 0) && (max_val / mean_val > 100)) {
|
||||
int timing_advance = max_idx / NR_SRS_IDFT_OVERSAMP_FACTOR;
|
||||
|
||||
// do some integer rounding to improve TA accuracy
|
||||
int sync_pos_rounded;
|
||||
if (timing_advance > 0) {
|
||||
sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1;
|
||||
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
|
||||
const uint16_t bw_scaling = ofdm_symbol_size >> 7;
|
||||
|
||||
// do some integer rounding to improve TA accuracy
|
||||
int sync_pos_rounded;
|
||||
if (timing_advance > 0) {
|
||||
sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1;
|
||||
} else {
|
||||
sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1;
|
||||
}
|
||||
|
||||
*timing_advance_offset = sync_pos_rounded / bw_scaling;
|
||||
|
||||
// put timing advance command in 0..63 range
|
||||
*timing_advance_offset += 31;
|
||||
|
||||
if (*timing_advance_offset < 0)
|
||||
*timing_advance_offset = 0;
|
||||
if (*timing_advance_offset > 63)
|
||||
*timing_advance_offset = 63;
|
||||
|
||||
*timing_advance_offset_nsec = (max_idx * 1e9) / (NR_SRS_IDFT_OVERSAMP_FACTOR * samples_per_frame * 100);
|
||||
} else {
|
||||
sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1;
|
||||
*timing_advance_offset = 0xFFFF;
|
||||
*timing_advance_offset_nsec = 0x8000;
|
||||
}
|
||||
|
||||
int timing_advance_update = sync_pos_rounded / bw_scaling;
|
||||
|
||||
// put timing advance command in 0..63 range
|
||||
timing_advance_update += 31;
|
||||
|
||||
if (timing_advance_update < 0) timing_advance_update = 0;
|
||||
if (timing_advance_update > 63) timing_advance_update = 63;
|
||||
|
||||
return timing_advance_update;
|
||||
LOG_D(PHY,
|
||||
"SRS estimatd ToA [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)\n",
|
||||
ant,
|
||||
*timing_advance_offset,
|
||||
*timing_advance_offset_nsec,
|
||||
max_val,
|
||||
mean_val,
|
||||
max_idx);
|
||||
}
|
||||
|
||||
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
|
||||
|
||||
@@ -770,27 +770,28 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
} // Antenna loop
|
||||
}
|
||||
|
||||
int nr_srs_channel_estimation(
|
||||
const PHY_VARS_gNB *gNB,
|
||||
const int frame,
|
||||
const int slot,
|
||||
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[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
int8_t *snr_per_rb,
|
||||
int8_t *snr)
|
||||
int nr_srs_channel_estimation(const int ant,
|
||||
const int p_index,
|
||||
const uint16_t ofdm_symbol_size,
|
||||
const uint16_t first_carrier_offset,
|
||||
const 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[ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[ofdm_symbol_size],
|
||||
uint32_t *signal_power,
|
||||
uint32_t *noise_power,
|
||||
int16_t *noise_power_per_rb)
|
||||
{
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
const uint64_t subcarrier_offset = first_carrier_offset + 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;
|
||||
@@ -801,271 +802,243 @@ int nr_srs_channel_estimation(
|
||||
fd_cdm = 2;
|
||||
}
|
||||
|
||||
c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)];
|
||||
uint32_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||
|
||||
const uint32_t arr_len = frame_parms->nb_antennas_rx * N_ap * M_sc_b_SRS;
|
||||
|
||||
c16_t ch[arr_len];
|
||||
memset(ch, 0, arr_len * sizeof(c16_t));
|
||||
|
||||
c16_t noise[arr_len];
|
||||
memset(noise, 0, arr_len * sizeof(c16_t));
|
||||
|
||||
uint8_t mem_offset = ((16 - ((intptr_t)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF)
|
||||
c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS];
|
||||
uint8_t mem_offset = ((16 - ((intptr_t)&srs_estimated_channel_freq[subcarrier_offset + nr_srs_info->k_0_p[p_index][0]])) & 0xF)
|
||||
>> 2; // >> 2 <=> /sizeof(int32_t)
|
||||
|
||||
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
|
||||
// The End of OFDM symbol corresponds to the position of last 16384 in the filter
|
||||
// The c16multaddVectRealComplex applies the remaining 8 zeros of filter, therefore, to avoid a buffer overflow,
|
||||
// we added 8 in the array size
|
||||
c16_t srs_est[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset + 8] __attribute__((aligned(32)));
|
||||
c16_t srs_est[ofdm_symbol_size * N_symb_SRS + mem_offset + 8] __attribute__((aligned(32)));
|
||||
c16_t ls_estimated = {0};
|
||||
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
memset(srs_ls_estimated_channel, 0, frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) * sizeof(c16_t));
|
||||
memset(srs_est, 0, (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset) * sizeof(c16_t));
|
||||
memset(srs_ls_estimated_channel, 0, ofdm_symbol_size * N_symb_SRS * sizeof(c16_t));
|
||||
memset(srs_est, 0, (ofdm_symbol_size * N_symb_SRS + mem_offset) * sizeof(c16_t));
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
|
||||
LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
|
||||
#endif
|
||||
|
||||
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier > frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
|
||||
c16_t *srs_estimated_channel16 = &srs_est[subcarrier + mem_offset];
|
||||
c16_t *srs_estimated_channel16 = &srs_est[subcarrier + mem_offset];
|
||||
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
if (k % fd_cdm == 0) {
|
||||
ls_estimated = (c16_t){0, 0};
|
||||
uint16_t subcarrier_cdm = subcarrier;
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
if (k % fd_cdm == 0) {
|
||||
ls_estimated = (c16_t){0, 0};
|
||||
uint16_t subcarrier_cdm = subcarrier;
|
||||
|
||||
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
|
||||
int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r;
|
||||
int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i;
|
||||
|
||||
int16_t received_real = srs_received_signal[ant][subcarrier_cdm].r;
|
||||
int16_t received_imag = srs_received_signal[ant][subcarrier_cdm].i;
|
||||
|
||||
// We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and
|
||||
// generated_imag. So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16
|
||||
// bits.
|
||||
ls_estimated.r += (int16_t)(((int32_t)generated_real * received_real + (int32_t)generated_imag * received_imag)
|
||||
>> nr_srs_info->srs_generated_signal_bits);
|
||||
ls_estimated.i += (int16_t)(((int32_t)generated_real * received_imag - (int32_t)generated_imag * received_real)
|
||||
>> nr_srs_info->srs_generated_signal_bits);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier_cdm += K_TC;
|
||||
if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier_cdm = subcarrier_cdm - frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srs_ls_estimated_channel[subcarrier] = ls_estimated;
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
int subcarrier_log = subcarrier - subcarrier_offset;
|
||||
if (subcarrier_log < 0) {
|
||||
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
if (subcarrier_log % 12 == 0) {
|
||||
LOG_I(NR_PHY, "------------------------------------ %d ------------------------------------\n", subcarrier_log / 12);
|
||||
LOG_I(NR_PHY, "\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n");
|
||||
}
|
||||
LOG_I(NR_PHY,
|
||||
"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
|
||||
subcarrier_log,
|
||||
srs_generated_signal[p_index][subcarrier].r,
|
||||
srs_generated_signal[p_index][subcarrier].i,
|
||||
srs_received_signal[ant][subcarrier].r,
|
||||
srs_received_signal[ant][subcarrier].i,
|
||||
ls_estimated.r,
|
||||
ls_estimated.i);
|
||||
#endif
|
||||
|
||||
const uint16_t sc_offset = subcarrier + mem_offset;
|
||||
|
||||
// Channel interpolation
|
||||
if (srs_pdu->comb_size == 0) {
|
||||
if (k == 0) { // First subcarrier case
|
||||
// filt8_start is {12288,8192,4096,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt8_start, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
// filt8_start is {12288,8192,4096,0,0,0,0,0}
|
||||
srs_estimated_channel16 = &srs_est[subcarrier];
|
||||
const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2;
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size
|
||||
|| k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases
|
||||
// filt8_end is {4096,8192,12288,16384,0,0,0,0}
|
||||
const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2;
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (k % 2 == 1) { // 1st middle case
|
||||
// filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0}
|
||||
c16multaddVectRealComplex(filt8_middle2, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (k % 2 == 0) { // 2nd middle case
|
||||
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
|
||||
c16multaddVectRealComplex(filt8_middle4, &ls_estimated, srs_estimated_channel16, 8);
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
}
|
||||
} else {
|
||||
if (k == 0) { // First subcarrier case
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if (subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size
|
||||
|| k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases
|
||||
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_end, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else { // Middle case
|
||||
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_middle4, &ls_estimated, srs_estimated_channel16, 16);
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
}
|
||||
}
|
||||
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
|
||||
c16_t generated_srs = srs_generated_signal[subcarrier_cdm];
|
||||
c16_t received_srs = srs_received_signal[subcarrier_cdm];
|
||||
// We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the real and imaginary parts of
|
||||
// generated_srs. So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16
|
||||
// bits.
|
||||
ls_estimated = c16maddConjShift(generated_srs, received_srs, ls_estimated, nr_srs_info->srs_generated_signal_bits);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier += K_TC;
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier = subcarrier - frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
memcpy(srs_estimated_channel_freq[ant][p_index],
|
||||
&srs_est[mem_offset],
|
||||
(frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)) * sizeof(c16_t));
|
||||
|
||||
// Compute noise
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier > frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
uint16_t base_idx = ant * N_ap * M_sc_b_SRS + p_index * M_sc_b_SRS;
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
ch[base_idx + k] = srs_estimated_channel_freq[ant][p_index][subcarrier];
|
||||
noise[base_idx + k].r = abs(srs_ls_estimated_channel[subcarrier].r - ch[base_idx + k].r);
|
||||
noise[base_idx + k].i = abs(srs_ls_estimated_channel[subcarrier].i - ch[base_idx + k].i);
|
||||
subcarrier += K_TC;
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier = subcarrier - frame_parms->ofdm_symbol_size;
|
||||
subcarrier_cdm += K_TC;
|
||||
if (subcarrier_cdm >= ofdm_symbol_size) {
|
||||
subcarrier_cdm = subcarrier_cdm - ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srs_ls_estimated_channel[subcarrier] = ls_estimated;
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier > frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
for (int k = 0; k < K_TC * M_sc_b_SRS; k++) {
|
||||
int subcarrier_log = subcarrier - subcarrier_offset;
|
||||
if (subcarrier_log < 0) {
|
||||
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
if (subcarrier_log % 12 == 0) {
|
||||
LOG_I(NR_PHY, "------------------------------------- %d -------------------------------------\n", subcarrier_log / 12);
|
||||
LOG_I(NR_PHY, "\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n");
|
||||
}
|
||||
|
||||
LOG_I(NR_PHY,
|
||||
"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
|
||||
subcarrier_log,
|
||||
srs_ls_estimated_channel[subcarrier].r,
|
||||
srs_ls_estimated_channel[subcarrier].i,
|
||||
srs_estimated_channel_freq[ant][p_index][subcarrier].r,
|
||||
srs_estimated_channel_freq[ant][p_index][subcarrier].i,
|
||||
noise[base_idx + (k / K_TC)].r,
|
||||
noise[base_idx + (k / K_TC)].i);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier++;
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier = subcarrier - frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
int subcarrier_log = subcarrier - subcarrier_offset;
|
||||
if (subcarrier_log < 0) {
|
||||
subcarrier_log = subcarrier_log + ofdm_symbol_size;
|
||||
}
|
||||
if (subcarrier_log % 12 == 0) {
|
||||
LOG_I(NR_PHY, "------------------------------------ %d ------------------------------------\n", subcarrier_log / 12);
|
||||
LOG_I(NR_PHY, "\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n");
|
||||
}
|
||||
LOG_I(NR_PHY,
|
||||
"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
|
||||
subcarrier_log,
|
||||
srs_generated_signal[subcarrier].r,
|
||||
srs_generated_signal[subcarrier].i,
|
||||
srs_received_signal[subcarrier].r,
|
||||
srs_received_signal[subcarrier].i,
|
||||
ls_estimated.r,
|
||||
ls_estimated.i);
|
||||
#endif
|
||||
|
||||
// Convert to time domain
|
||||
freq2time(gNB->frame_parms.ofdm_symbol_size,
|
||||
(int16_t *)srs_estimated_channel_freq[ant][p_index],
|
||||
(int16_t *)srs_estimated_channel_time[ant][p_index]);
|
||||
const uint16_t sc_offset = subcarrier + mem_offset;
|
||||
|
||||
memcpy(srs_estimated_channel_time_shifted[ant][p_index],
|
||||
&srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1],
|
||||
(gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(c16_t));
|
||||
// Channel interpolation
|
||||
if (srs_pdu->comb_size == 0) {
|
||||
if (k == 0) { // First subcarrier case
|
||||
// filt8_start is {12288,8192,4096,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt8_start, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
// filt8_start is {12288,8192,4096,0,0,0,0,0}
|
||||
srs_estimated_channel16 = &srs_est[subcarrier];
|
||||
const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2;
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if ((subcarrier + K_TC) >= ofdm_symbol_size || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases
|
||||
// filt8_end is {4096,8192,12288,16384,0,0,0,0}
|
||||
const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2;
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (k % 2 == 1) { // 1st middle case
|
||||
// filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0}
|
||||
c16multaddVectRealComplex(filt8_middle2, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (k % 2 == 0) { // 2nd middle case
|
||||
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
|
||||
c16multaddVectRealComplex(filt8_middle4, &ls_estimated, srs_estimated_channel16, 8);
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
}
|
||||
} else {
|
||||
if (k == 0) { // First subcarrier case
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if (subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if ((subcarrier + K_TC) >= ofdm_symbol_size || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases
|
||||
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_end, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else { // Middle case
|
||||
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_middle4, &ls_estimated, srs_estimated_channel16, 16);
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1],
|
||||
srs_estimated_channel_time[ant][p_index],
|
||||
(gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(c16_t));
|
||||
// Subcarrier increment
|
||||
subcarrier += K_TC;
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier = subcarrier - ofdm_symbol_size;
|
||||
}
|
||||
|
||||
} // for (int p_index = 0; p_index < N_ap; p_index++)
|
||||
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
// Compute signal power
|
||||
uint32_t signal_power = max(signal_energy_nodc(ch, arr_len), 1);
|
||||
memcpy(srs_estimated_channel_freq, &srs_est[mem_offset], (ofdm_symbol_size * N_symb_SRS) * sizeof(c16_t));
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "signal_power = %u\n", signal_power);
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
|
||||
for (int k = 0; k < K_TC * M_sc_b_SRS; k++) {
|
||||
int subcarrier_log = subcarrier - subcarrier_offset;
|
||||
if (subcarrier_log < 0) {
|
||||
subcarrier_log = subcarrier_log + ofdm_symbol_size;
|
||||
}
|
||||
|
||||
if (subcarrier_log % 12 == 0) {
|
||||
LOG_I(NR_PHY, "------------------------------------- %d -------------------------------------\n", subcarrier_log / 12);
|
||||
LOG_I(NR_PHY, "\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n");
|
||||
}
|
||||
|
||||
LOG_I(NR_PHY,
|
||||
"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
|
||||
subcarrier_log,
|
||||
srs_ls_estimated_channel[subcarrier].r,
|
||||
srs_ls_estimated_channel[subcarrier].i,
|
||||
srs_estimated_channel_freq[subcarrier].r,
|
||||
srs_estimated_channel_freq[subcarrier].i,
|
||||
srs_received_noise[subcarrier].r,
|
||||
srs_received_noise[subcarrier].i);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier++;
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier = subcarrier - ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (signal_power == 0) {
|
||||
// Convert to time domain
|
||||
int16_t ofdm_symbol_size_half = ofdm_symbol_size >> 1;
|
||||
int16_t ofdm_oversample_symbol_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size;
|
||||
int16_t ofdm_oversample_symbol_size_half = ofdm_oversample_symbol_size >> 1;
|
||||
int16_t start_offset = ofdm_oversample_symbol_size - ofdm_symbol_size_half;
|
||||
|
||||
c16_t chF_interpol[ofdm_oversample_symbol_size] __attribute__((aligned(32)));
|
||||
memset(chF_interpol, 0, sizeof(chF_interpol));
|
||||
|
||||
// Place SRS channel estimates in FFT shifted format for oversampling
|
||||
memcpy(&chF_interpol[0], &srs_estimated_channel_freq[0], ofdm_symbol_size_half * sizeof(c16_t));
|
||||
memcpy(&chF_interpol[start_offset], &srs_estimated_channel_freq[ofdm_symbol_size_half], ofdm_symbol_size_half * sizeof(c16_t));
|
||||
|
||||
// Convert to time domain oversampled
|
||||
freq2time(ofdm_oversample_symbol_size, (int16_t *)chF_interpol, (int16_t *)srs_estimated_channel_time);
|
||||
|
||||
// Do FFT shift
|
||||
memcpy(srs_estimated_channel_time_shifted,
|
||||
&srs_estimated_channel_time[ofdm_oversample_symbol_size_half],
|
||||
ofdm_oversample_symbol_size_half * sizeof(c16_t));
|
||||
|
||||
memcpy(&srs_estimated_channel_time_shifted[ofdm_oversample_symbol_size_half],
|
||||
srs_estimated_channel_time,
|
||||
ofdm_oversample_symbol_size_half * sizeof(c16_t));
|
||||
|
||||
// Compute wideband SNR
|
||||
int tot_subcarriers = m_SRS_b * NR_NB_SC_PER_RB;
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
if (subcarrier >= ofdm_symbol_size) {
|
||||
subcarrier -= ofdm_symbol_size;
|
||||
}
|
||||
if (subcarrier + tot_subcarriers < ofdm_symbol_size) {
|
||||
*signal_power = signal_energy_nodc(&srs_estimated_channel_freq[subcarrier], tot_subcarriers) / tot_subcarriers;
|
||||
if (p_index == 0) {
|
||||
*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 signal_power_p1 = signal_energy_nodc(&srs_estimated_channel_freq[subcarrier], size1) * size1;
|
||||
uint64_t signal_power_p2 = signal_energy_nodc(&srs_estimated_channel_freq[0], size2) * size2;
|
||||
*signal_power = (signal_power_p1 + signal_power_p2) / tot_subcarriers;
|
||||
if (p_index == 0) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
*signal_power = max(*signal_power, 1);
|
||||
if (*signal_power == 0) {
|
||||
LOG_W(NR_PHY, "Received SRS signal power is 0\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compute noise power
|
||||
const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3;
|
||||
const uint8_t n_noise_est = frame_parms->nb_antennas_rx * N_ap * srs_symbols_per_rb;
|
||||
uint64_t sum_re = 0;
|
||||
uint64_t sum_re2 = 0;
|
||||
uint64_t sum_im = 0;
|
||||
uint64_t sum_im2 = 0;
|
||||
|
||||
for (int rb = 0; rb < m_SRS_b; rb++) {
|
||||
sum_re = 0;
|
||||
sum_re2 = 0;
|
||||
sum_im = 0;
|
||||
sum_im2 = 0;
|
||||
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
uint16_t base_idx = ant * N_ap * M_sc_b_SRS + p_index * M_sc_b_SRS + rb * srs_symbols_per_rb;
|
||||
for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) {
|
||||
sum_re = sum_re + noise[base_idx + srs_symb].r;
|
||||
sum_re2 = sum_re2 + noise[base_idx + srs_symb].r * noise[base_idx + srs_symb].r;
|
||||
sum_im = sum_im + noise[base_idx + srs_symb].i;
|
||||
sum_im2 = sum_im2 + noise[base_idx + srs_symb].i * noise[base_idx + srs_symb].i;
|
||||
} // for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++)
|
||||
} // for (int p_index = 0; p_index < N_ap; p_index++)
|
||||
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
|
||||
|
||||
noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) + sum_im2 / n_noise_est
|
||||
- (sum_im / n_noise_est) * (sum_im / n_noise_est),
|
||||
1);
|
||||
snr_per_rb[rb] = dB_fixed(signal_power) - dB_fixed(noise_power_per_rb[rb]);
|
||||
// Compute SNR per RB for port 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, "noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]);
|
||||
LOG_I(NR_PHY, "[RB %3i] noise_power_per_rb = %i, snr_per_rb = %i dB\n", rb, noise_power_per_rb, snr_per_rb[rb]);
|
||||
#endif
|
||||
|
||||
} // for (int rb = 0; rb < m_SRS_b; rb++)
|
||||
|
||||
const uint32_t noise_power = max(signal_energy_nodc(noise, arr_len), 1);
|
||||
|
||||
*snr = dB_fixed(signal_power) - dB_fixed(noise_power);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "noise_power = %u, SNR = %i dB\n", noise_power, *snr);
|
||||
LOG_I(NR_PHY, "signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n", dB_fixed(signal_power), dB_fixed(noise_power), *snr);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -65,8 +65,13 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB,
|
||||
unsigned char symbol,
|
||||
uint8_t nrOfLayers);
|
||||
|
||||
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
|
||||
void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
|
||||
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
|
||||
uint8_t ant,
|
||||
uint8_t N_ap,
|
||||
uint32_t samples_per_frame,
|
||||
uint16_t *timing_advance_offset,
|
||||
int16_t *timing_advance_offset_nsec);
|
||||
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -76,20 +81,22 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pusch);
|
||||
|
||||
int nr_srs_channel_estimation(
|
||||
const PHY_VARS_gNB *gNB,
|
||||
const int frame,
|
||||
const int slot,
|
||||
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[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
int8_t *snr_per_rb,
|
||||
int8_t *snr);
|
||||
int nr_srs_channel_estimation(const int ant,
|
||||
const int p_index,
|
||||
const uint16_t ofdm_symbol_size,
|
||||
const uint16_t first_carrier_offset,
|
||||
const 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[ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[ofdm_symbol_size],
|
||||
uint32_t *signal_power,
|
||||
uint32_t *noise_power,
|
||||
int16_t *noise_power_per_rb);
|
||||
|
||||
void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *rxdataF_comp,
|
||||
|
||||
@@ -242,7 +242,8 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
slot_t slot,
|
||||
nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
nr_srs_info_t *nr_srs_info,
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]);
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]);
|
||||
|
||||
void init_prach_list(PHY_VARS_gNB *gNB);
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
|
||||
@@ -80,59 +80,67 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
slot_t slot,
|
||||
nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
nr_srs_info_t *nr_srs_info,
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)])
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)])
|
||||
{
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
|
||||
const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot
|
||||
const uint8_t l0 = srs_pdu->time_start_position; // starting symbol in this slot
|
||||
const uint8_t l0 = srs_pdu->time_start_position; // starting symbol in this slot
|
||||
const uint64_t symbol_offset = (n_symbols + l0) * frame_parms->ofdm_symbol_size;
|
||||
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
|
||||
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
|
||||
const uint8_t N_ap = 1<<srs_pdu->num_ant_ports;
|
||||
const uint8_t N_ap = 1 << srs_pdu->num_ant_ports;
|
||||
const uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols;
|
||||
const uint8_t K_TC = 2 << srs_pdu->comb_size;
|
||||
const uint16_t M_sc_b_SRS = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index) * NR_NB_SC_PER_RB / K_TC;
|
||||
|
||||
c16_t *rx_signal;
|
||||
bool no_srs_signal = true;
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
|
||||
memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size * sizeof(c16_t));
|
||||
rx_signal = &rxdataF[ant][symbol_offset];
|
||||
memset(srs_received_noise[ant], 0, frame_parms->ofdm_symbol_size * sizeof(c16_t));
|
||||
c16_t *rx_signal = &rxdataF[ant][symbol_offset];
|
||||
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,"===== UE port %d --> gNB Rx antenna %i =====\n", p_index, ant);
|
||||
LOG_I(NR_PHY, "===== UE port %d --> gNB Rx antenna %i =====\n", p_index, ant);
|
||||
#endif
|
||||
|
||||
for (int l_line = 0; l_line < N_symb_SRS; l_line++) {
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,":::::::: OFDM symbol %d ::::::::\n", l0+l_line);
|
||||
LOG_I(NR_PHY, ":::::::: OFDM symbol %d ::::::::\n", l0 + l_line);
|
||||
#endif
|
||||
|
||||
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][l_line];
|
||||
if (subcarrier>frame_parms->ofdm_symbol_size) {
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
uint16_t l_line_offset = l_line*frame_parms->ofdm_symbol_size;
|
||||
uint16_t l_line_offset = l_line * frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
|
||||
srs_received_signal[ant][l_line_offset+subcarrier] = rx_signal[l_line_offset+subcarrier];
|
||||
|
||||
// Subcarriers with SRS symbols
|
||||
srs_received_signal[ant][l_line_offset + subcarrier] = rx_signal[l_line_offset + subcarrier];
|
||||
if (rx_signal[l_line_offset + subcarrier].r || rx_signal[l_line_offset + subcarrier].i) {
|
||||
no_srs_signal = false;
|
||||
}
|
||||
|
||||
// Subcarriers without SRS symbols and only noise
|
||||
srs_received_noise[ant][l_line_offset + subcarrier] = rx_signal[l_line_offset + subcarrier + 1];
|
||||
for (int n = 1; n < K_TC; n++) {
|
||||
uint16_t subcarrier_n = subcarrier + n;
|
||||
if (subcarrier_n >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier_n -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
srs_received_noise[ant][l_line_offset + subcarrier_n] = rx_signal[l_line_offset + subcarrier_n];
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
int subcarrier_log = subcarrier-subcarrier_offset;
|
||||
if(subcarrier_log < 0) {
|
||||
int subcarrier_log = subcarrier - subcarrier_offset;
|
||||
if (subcarrier_log < 0) {
|
||||
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
if(subcarrier_log%12 == 0) {
|
||||
LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12);
|
||||
if (subcarrier_log % 12 == 0) {
|
||||
LOG_I(NR_PHY, "------------ %d ------------\n", subcarrier_log / 12);
|
||||
}
|
||||
LOG_I(NR_PHY,
|
||||
"(%i) \t%i\t%i\n",
|
||||
@@ -144,7 +152,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
// Subcarrier increment
|
||||
subcarrier += K_TC;
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
@@ -366,10 +366,10 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
|
||||
#endif
|
||||
|
||||
uint16_t subcarrier = subcarrier_offset + k_0_p;
|
||||
if (subcarrier>frame_parms->ofdm_symbol_size) {
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
uint16_t l_line_offset = l_line*frame_parms->ofdm_symbol_size;
|
||||
uint16_t l_line_offset = l_line * frame_parms->ofdm_symbol_size;
|
||||
|
||||
// For each port, and for each OFDM symbol, here it is computed and mapped an SRS sequence with M_sc_b_SRS symbols
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
@@ -399,7 +399,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
|
||||
// Subcarrier increment
|
||||
subcarrier += K_TC;
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
@@ -219,6 +219,7 @@ extern "C" {
|
||||
{
|
||||
return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)};
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline c16_t c16MulConjShift(const c16_t a, const c16_t b, const int Shift)
|
||||
{
|
||||
return (c16_t) {
|
||||
@@ -234,6 +235,14 @@ extern "C" {
|
||||
};
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline c16_t c16maddConjShift(const c16_t a, const c16_t b, c16_t c, const int Shift)
|
||||
{
|
||||
return (c16_t) {
|
||||
.r = (int16_t)(((a.r * b.r + a.i * b.i ) >> Shift) + c.r),
|
||||
.i = (int16_t)(((a.r * b.i - a.i * b.r ) >> Shift) + c.i)
|
||||
};
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline c32_t c32x16mulShift(const c16_t a, const c16_t b, const int Shift) {
|
||||
return (c32_t) {
|
||||
.r = (a.r * b.r - a.i * b.i) >> Shift,
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#define MAX_NUM_RU_PER_gNB 8
|
||||
#define MAX_PUCCH0_NID 8
|
||||
#define NR_SRS_IDFT_OVERSAMP_FACTOR 2
|
||||
|
||||
typedef struct {
|
||||
int nb_id;
|
||||
|
||||
@@ -711,7 +711,7 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint32
|
||||
int fill_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *reported_symbol,
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const int N_RB_UL,
|
||||
const int8_t *snr_per_rb,
|
||||
const int16_t *snr_per_rb,
|
||||
const int srs_est) {
|
||||
reported_symbol->num_prgs = srs_pdu->beamforming.num_prgs;
|
||||
for (int prg_idx = 0; prg_idx < reported_symbol->num_prgs; prg_idx++) {
|
||||
@@ -1007,14 +1007,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
|
||||
uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols;
|
||||
c16_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size * N_symb_SRS];
|
||||
c16_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports]
|
||||
[frame_parms->ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32)));
|
||||
c16_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size]
|
||||
uint8_t N_ap = 1 << srs_pdu->num_ant_ports;
|
||||
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
||||
uint16_t ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
c16_t srs_received_signal[nb_antennas_rx][ofdm_symbol_size * N_symb_SRS];
|
||||
c16_t srs_received_noise[nb_antennas_rx][ofdm_symbol_size * N_symb_SRS];
|
||||
c16_t srs_estimated_channel_freq[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32)));
|
||||
c16_t srs_estimated_channel_time[nb_antennas_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size]
|
||||
__attribute__((aligned(32)));
|
||||
c16_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports]
|
||||
[frame_parms->ofdm_symbol_size];
|
||||
int8_t snr_per_rb[srs_pdu->bwp_size];
|
||||
c16_t srs_estimated_channel_time_shifted[nb_antennas_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size];
|
||||
|
||||
start_meas(&gNB->generate_srs_stats);
|
||||
if (check_srs_pdu(srs_pdu, &gNB->nr_srs_info[i]->srs_pdu) == 0) {
|
||||
@@ -1023,24 +1024,65 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
stop_meas(&gNB->generate_srs_stats);
|
||||
c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb];
|
||||
start_meas(&gNB->get_srs_signal_stats);
|
||||
int srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
|
||||
int srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal, srs_received_noise);
|
||||
stop_meas(&gNB->get_srs_signal_stats);
|
||||
|
||||
uint32_t signal_power[nb_antennas_rx][N_ap];
|
||||
uint32_t noise_power[nb_antennas_rx];
|
||||
uint32_t signal_power_avg = 0;
|
||||
uint32_t noise_power_avg = 0;
|
||||
int16_t snr_per_rb[srs_pdu->bwp_size];
|
||||
int16_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||
memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t));
|
||||
uint16_t timing_advance_offset[nb_antennas_rx];
|
||||
int16_t timing_advance_offset_nsec[nb_antennas_rx];
|
||||
|
||||
if (srs_est >= 0) {
|
||||
start_meas(&gNB->srs_channel_estimation_stats);
|
||||
nr_srs_channel_estimation(gNB,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
srs_pdu,
|
||||
gNB->nr_srs_info[i],
|
||||
(const c16_t**)gNB->nr_srs_info[i]->srs_generated_signal,
|
||||
srs_received_signal,
|
||||
srs_estimated_channel_freq,
|
||||
srs_estimated_channel_time,
|
||||
srs_estimated_channel_time_shifted,
|
||||
snr_per_rb,
|
||||
&gNB->srs->snr);
|
||||
for (int ant_ind = 0; ant_ind < nb_antennas_rx; ant_ind++) {
|
||||
for (int p_ind = 0; p_ind < N_ap; p_ind++) {
|
||||
nr_srs_channel_estimation(ant_ind,
|
||||
p_ind,
|
||||
ofdm_symbol_size,
|
||||
frame_parms->first_carrier_offset,
|
||||
N_symb_SRS,
|
||||
srs_pdu,
|
||||
gNB->nr_srs_info[i],
|
||||
(const c16_t *)gNB->nr_srs_info[i]->srs_generated_signal[p_ind],
|
||||
srs_received_signal[ant_ind],
|
||||
srs_received_noise[ant_ind],
|
||||
srs_estimated_channel_freq[ant_ind][p_ind],
|
||||
srs_estimated_channel_time[ant_ind][p_ind],
|
||||
srs_estimated_channel_time_shifted[ant_ind][p_ind],
|
||||
&signal_power[ant_ind][p_ind],
|
||||
&noise_power[ant_ind],
|
||||
noise_power_per_rb);
|
||||
signal_power_avg += signal_power[ant_ind][p_ind];
|
||||
}
|
||||
noise_power_avg += noise_power[ant_ind];
|
||||
}
|
||||
signal_power_avg /= (nb_antennas_rx * N_ap);
|
||||
noise_power_avg /= nb_antennas_rx;
|
||||
signal_power_avg = max(signal_power_avg, 1);
|
||||
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);
|
||||
for (int rb = 0; rb < m_SRS_b; rb++) {
|
||||
snr_per_rb[rb] = dB_fixed(signal_power_avg) - dB_fixed(max(noise_power_per_rb[rb] / nb_antennas_rx, 1));
|
||||
}
|
||||
stop_meas(&gNB->srs_channel_estimation_stats);
|
||||
|
||||
start_meas(&gNB->srs_timing_advance_stats);
|
||||
for (int ant_ind = 0; ant_ind < nb_antennas_rx; ant_ind++) {
|
||||
nr_est_srs_timing_advance_offset(ofdm_symbol_size,
|
||||
srs_estimated_channel_time[ant_ind],
|
||||
ant_ind,
|
||||
N_ap,
|
||||
frame_parms->samples_per_frame,
|
||||
&timing_advance_offset[ant_ind],
|
||||
&timing_advance_offset_nsec[ant_ind]);
|
||||
}
|
||||
stop_meas(&gNB->srs_timing_advance_stats);
|
||||
}
|
||||
|
||||
if ((gNB->srs->snr * 10) < gNB->srs_thres) {
|
||||
@@ -1053,7 +1095,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(0),
|
||||
T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
|
||||
T_BUFFER(srs_estimated_channel_freq[0][0], ofdm_symbol_size * sizeof(int32_t)));
|
||||
|
||||
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE,
|
||||
T_INT(0),
|
||||
@@ -1061,7 +1103,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(0),
|
||||
T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
|
||||
T_BUFFER(srs_estimated_channel_time_shifted[0][0], NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size * sizeof(int32_t)));
|
||||
|
||||
T(T_GNB_PHY_UL_SNR_ESTIMATE,
|
||||
T_INT(0),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(0),
|
||||
T_BUFFER(snr_per_rb, srs_pdu->bwp_size * sizeof(int16_t)));
|
||||
|
||||
UL_INFO->srs_ind.sfn = frame_rx;
|
||||
UL_INFO->srs_ind.slot = slot_rx;
|
||||
@@ -1071,10 +1121,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
nfapi_nr_srs_indication_pdu_t *srs_indication = UL_INFO->srs_pdu_list + UL_INFO->srs_ind.number_of_pdus++;
|
||||
srs_indication->handle = srs_pdu->handle;
|
||||
srs_indication->rnti = srs_pdu->rnti;
|
||||
start_meas(&gNB->srs_timing_advance_stats);
|
||||
srs_indication->timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF;
|
||||
stop_meas(&gNB->srs_timing_advance_stats);
|
||||
srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? (int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) : 0xFFFF;
|
||||
// TODO currently we fill timing_advance_offset and timing_advance_offset_nsec for antenna 0. Need to extend it for other
|
||||
// antennas
|
||||
srs_indication->timing_advance_offset = srs_est >= 0 ? timing_advance_offset[0] : 0xFFFF;
|
||||
srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? timing_advance_offset_nsec[0] : 0x8000;
|
||||
switch (srs_pdu->srs_parameters_v4.usage) {
|
||||
case 0:
|
||||
LOG_W(NR_PHY, "SRS report was not requested by MAC\n");
|
||||
@@ -1116,9 +1166,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
start_meas(&gNB->srs_beam_report_stats);
|
||||
nfapi_nr_srs_beamforming_report_t nr_srs_bf_report;
|
||||
nr_srs_bf_report.prg_size = srs_pdu->beamforming.prg_size;
|
||||
nr_srs_bf_report.num_symbols = 1 << srs_pdu->num_symbols;
|
||||
nr_srs_bf_report.num_symbols = N_symb_SRS;
|
||||
nr_srs_bf_report.wide_band_snr = srs_est >= 0 ? (gNB->srs->snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid
|
||||
nr_srs_bf_report.num_reported_symbols = 1 << srs_pdu->num_symbols;
|
||||
nr_srs_bf_report.num_reported_symbols = N_symb_SRS;
|
||||
AssertFatal(nr_srs_bf_report.num_reported_symbols == 1,
|
||||
"nr_srs_bf_report.num_reported_symbols %i not handled yet!\n",
|
||||
nr_srs_bf_report.num_reported_symbols);
|
||||
@@ -1148,7 +1198,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
start_meas(&gNB->srs_iq_matrix_stats);
|
||||
nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_channel_iq_matrix;
|
||||
nr_srs_channel_iq_matrix.normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation;
|
||||
nr_srs_channel_iq_matrix.num_gnb_antenna_elements = gNB->frame_parms.nb_antennas_rx;
|
||||
nr_srs_channel_iq_matrix.num_gnb_antenna_elements = nb_antennas_rx;
|
||||
nr_srs_channel_iq_matrix.num_ue_srs_ports = srs_pdu->srs_parameters_v4.num_total_ue_antennas;
|
||||
nr_srs_channel_iq_matrix.prg_size = srs_pdu->srs_parameters_v4.prg_size;
|
||||
nr_srs_channel_iq_matrix.num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size;
|
||||
|
||||
Reference in New Issue
Block a user