Compare commits

...

4 Commits

5 changed files with 147 additions and 43 deletions

View File

@@ -138,11 +138,11 @@ ID = GNB_PHY_UL_PAYLOAD_RX_BITS
ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE
DESC = gNodeB channel estimation in the frequency domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_f
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
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_t
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
@@ -151,6 +151,10 @@ ID = GNB_PHY_DL_OUTPUT_SIGNAL
DESC = gNodeB output data in the freq domain for slots
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,frame : int,slot : int,antenna : buffer,txdata
ID = GNB_PHY_UL_SRS_TOA_NS
DESC = gNB ToA estimate from SRS (in ns)
GROUP = ALL:PHY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : buffer,toa_ns
#MAC logs
ID = ENB_MAC_UE_DL_SDU

View File

@@ -36,18 +36,17 @@
#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])
int nr_est_timing_advance_srs(uint16_t ofdm_symbol_size,
uint8_t N_ap_srs,
const c16_t srs_estimated_channel_time[][N_ap_srs][ofdm_symbol_size])
{
int timing_advance = 0;
int max_val = 0;
int64_t 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);
for (int i = 0; i < ofdm_symbol_size; i++) {
int64_t temp = 0;
for (int aa = 0; aa < N_ap_srs; aa++) {
temp += squaredMod(srs_estimated_channel_time[0][aa][i]); // computing for the first receive antenna
}
if (temp > max_val) {
timing_advance = i;
@@ -55,12 +54,12 @@ int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
}
}
if (timing_advance > frame_parms->ofdm_symbol_size/2) {
timing_advance = timing_advance - frame_parms->ofdm_symbol_size;
if (timing_advance > ofdm_symbol_size / 2) {
timing_advance = timing_advance - ofdm_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;
const uint16_t bw_scaling = ofdm_symbol_size >> 7;
// do some integer rounding to improve TA accuracy
int sync_pos_rounded;

View File

@@ -42,6 +42,75 @@
#define NO_INTERP 1
#define dBc(x, y) (dB_fixed(((int32_t)(x)) * (x) + ((int32_t)(y)) * (y)))
#define NR_SRS_IDFT_OVERSAMP_FACTOR 8
/* Generic function to find the peak of channel estimation buffer */
int16_t nr_est_toa_ns_srs(uint16_t ofdm_symbol_size,
uint8_t N_arx,
uint8_t N_ap,
uint32_t samples_per_frame,
c16_t srs_estimated_channel_freq[N_arx][N_ap][ofdm_symbol_size],
int16_t *srs_toa_ns)
{
c16_t chT_interpol[N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size] __attribute__((aligned(32)));
int ofdm_size_half = ofdm_symbol_size >> 1;
int16_t start_offset = (NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size) - ofdm_size_half;
for (int arx_index = 0; arx_index < N_arx; arx_index++) {
for (int ap_index = 0; ap_index < N_ap; ap_index++) {
c16_t chF_interpol[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_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[arx_index][ap_index][0], ofdm_size_half * sizeof(c16_t));
memcpy(&chF_interpol[start_offset],
&srs_estimated_channel_freq[arx_index][ap_index][ofdm_size_half],
ofdm_size_half * sizeof(c16_t));
// Convert to time domain oversampled
freq2time(ofdm_symbol_size * NR_SRS_IDFT_OVERSAMP_FACTOR, (int16_t *)chF_interpol, (int16_t *)chT_interpol[ap_index]);
}
int64_t mean_val = 0;
int64_t max_val = 0;
int32_t max_idx = 0;
for (int k = 0; k < NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size; k++) {
int64_t abs_val = 0;
for (int p_index = 0; p_index < N_ap; p_index++) {
abs_val += squaredMod(chT_interpol[p_index][k]);
}
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 * NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size);
if (max_idx > NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_size_half)
max_idx = max_idx - NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size;
// Check for detection threshold
if ((mean_val != 0) && (max_val / mean_val > 100)) {
srs_toa_ns[arx_index] = (max_idx * 1e9) / (NR_SRS_IDFT_OVERSAMP_FACTOR * samples_per_frame * 100);
} else {
srs_toa_ns[arx_index] = 0x8000;
}
LOG_D(PHY,
"SRS estimatd ToA [RX ant %d]: %d ns (max_val %ld, mean_val %ld, max_idx %d)\n",
arx_index,
srs_toa_ns[arx_index],
max_val,
mean_val,
max_idx);
} // Antenna loop
// TODO currently we are reporting ns for single antenna
return srs_toa_ns[0];
}
typedef struct puschAntennaProc_s {
unsigned char Ns;
@@ -1015,7 +1084,7 @@ int nr_srs_channel_estimation(
uint32_t signal_power = max(signal_energy_nodc(ch, arr_len), 1);
#ifdef SRS_DEBUG
LOG_I(NR_PHY, "signal_power = %u\n", signal_power);
LOG_I(NR_PHY, "signal_power = %d dB\n", dB_fixed(signal_power));
#endif
if (signal_power == 0) {

View File

@@ -65,8 +65,16 @@ 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]);
int nr_est_timing_advance_srs(uint16_t ofdm_symbol_size,
uint8_t N_ap,
const c16_t srs_estimated_channel_time[][N_ap][ofdm_symbol_size]);
int16_t nr_est_toa_ns_srs(uint16_t ofdm_symbol_size,
uint8_t N_arx,
uint8_t N_ap,
uint32_t samples_per_frame,
c16_t srs_estimated_channel_freq[N_arx][N_ap][ofdm_symbol_size],
int16_t *srs_toa_ns);
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,

View File

@@ -1007,13 +1007,13 @@ 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]
__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];
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_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][ofdm_symbol_size] __attribute__((aligned(32)));
c16_t srs_estimated_channel_time_shifted[nb_antennas_rx][N_ap][ofdm_symbol_size];
int8_t snr_per_rb[srs_pdu->bwp_size];
start_meas(&gNB->generate_srs_stats);
@@ -1047,21 +1047,27 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
srs_est = -1;
}
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE,
T_INT(0),
T_INT(srs_pdu->rnti),
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)));
for (int ant_rx = 0; ant_rx < nb_antennas_rx; ant_rx++) {
for (int p_index = 0; p_index < N_ap; p_index++) {
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE,
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(slot_rx),
T_INT(ant_rx),
T_INT(p_index),
T_BUFFER(srs_estimated_channel_freq[ant_rx][p_index], ofdm_symbol_size * sizeof(c16_t)));
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE,
T_INT(0),
T_INT(srs_pdu->rnti),
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(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE,
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(slot_rx),
T_INT(ant_rx),
T_INT(p_index),
T_BUFFER(srs_estimated_channel_time_shifted[ant_rx][p_index], ofdm_symbol_size * sizeof(c16_t)));
}
}
UL_INFO->srs_ind.sfn = frame_rx;
UL_INFO->srs_ind.slot = slot_rx;
@@ -1071,10 +1077,28 @@ 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;
int16_t srs_toa_ns[nb_antennas_rx];
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;
srs_indication->timing_advance_offset =
srs_est >= 0 ? nr_est_timing_advance_srs(ofdm_symbol_size, N_ap, srs_estimated_channel_time) : 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;
srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? nr_est_toa_ns_srs(ofdm_symbol_size,
nb_antennas_rx,
N_ap,
frame_parms->samples_per_frame,
srs_estimated_channel_freq,
srs_toa_ns)
: 0x8000;
T(T_GNB_PHY_UL_SRS_TOA_NS,
T_INT(gNB->Mod_id),
T_INT(srs_pdu->rnti),
T_INT(frame_rx),
T_INT(slot_rx),
T_BUFFER(srs_toa_ns, nb_antennas_rx * sizeof(int16_t)));
switch (srs_pdu->srs_parameters_v4.usage) {
case 0:
LOG_W(NR_PHY, "SRS report was not requested by MAC\n");
@@ -1116,9 +1140,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 +1172,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;