From 14cceed229c16f82fadd382f1bc256c9c3aee134 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 30 Mar 2026 11:56:13 +0100 Subject: [PATCH] Fix incorrect SRS subcarrier mapping in fill_srs_channel_matrix The previous implementation of fill_srs_channel_matrix assumed an incorrect SRS subcarrier mapping, leading to wrong indexing of the estimated channel in frequency domain --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 65 ++++++++++------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index de72db32db..63f5aa8c87 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -712,56 +712,50 @@ static int fill_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *reported_sym return 0; } -static int fill_srs_channel_matrix( - nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_channel_iq_matrix, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const uint8_t normalized_iq_representation, - const uint16_t num_gnb_antenna_elements, - const uint16_t num_ue_srs_ports, - const uint16_t prg_size, - const uint16_t num_prgs, - const NR_DL_FRAME_PARMS *frame_parms, - const c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] - [frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)]) +static int fill_srs_channel_matrix(nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_channel_iq_matrix, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const NR_DL_FRAME_PARMS *frame_parms, + const c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)]) { + const uint16_t num_gnb_antenna_elements = frame_parms->nb_antennas_rx; + const uint16_t num_ue_srs_ports = srs_pdu->srs_parameters_v4.num_total_ue_antennas; + const uint8_t normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation; + const uint16_t prg_size = srs_pdu->srs_parameters_v4.prg_size; + const uint16_t num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size; + const uint64_t first_subcarrier = + (frame_parms->first_carrier_offset - (frame_parms->ofdm_symbol_size >> 1)) + srs_pdu->bwp_start * NR_NB_SC_PER_RB; + const uint16_t step = prg_size * NR_NB_SC_PER_RB; + nr_srs_channel_iq_matrix->normalized_iq_representation = normalized_iq_representation; nr_srs_channel_iq_matrix->num_gnb_antenna_elements = num_gnb_antenna_elements; nr_srs_channel_iq_matrix->num_ue_srs_ports = num_ue_srs_ports; nr_srs_channel_iq_matrix->prg_size = prg_size; nr_srs_channel_iq_matrix->num_prgs = num_prgs; + uint8_t *channel_matrix = nr_srs_channel_iq_matrix->channel_matrix; - const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; - const uint16_t step = prg_size*NR_NB_SC_PER_RB; + c16_t *channel_matrix16 = (c16_t *)channel_matrix; + c8_t *channel_matrix8 = (c8_t *)channel_matrix; - c16_t *channel_matrix16 = (c16_t*)channel_matrix; - c8_t *channel_matrix8 = (c8_t*)channel_matrix; + for (int uI = 0; uI < num_ue_srs_ports; uI++) { + for (int gI = 0; gI < num_gnb_antenna_elements; gI++) { - for(int uI = 0; uI < num_ue_srs_ports; uI++) { - for(int gI = 0; gI < num_gnb_antenna_elements; gI++) { + // channel_matrix8 or channel_matrix16 will only be populated for the symbol 0 + uint16_t subcarrier_abs = first_subcarrier + nr_srs_info->k_0_p[uI][0]; - uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[uI][0]; - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } - - for(int pI = 0; pI < num_prgs; pI++) { - const c16_t *srs_estimated_channel16 = srs_estimated_channel_freq[gI][uI] + subcarrier; - uint16_t index = uI*num_gnb_antenna_elements*num_prgs + gI*num_prgs + pI; + for (int pI = 0; pI < num_prgs; pI++) { + const c16_t *srs_estimated_channel16 = srs_estimated_channel_freq[gI][uI] + subcarrier_abs; + uint16_t index = uI * num_gnb_antenna_elements * num_prgs + gI * num_prgs + pI; if (normalized_iq_representation == 0) { - channel_matrix8[index].r = (int8_t)(srs_estimated_channel16->r>>8); - channel_matrix8[index].i = (int8_t)(srs_estimated_channel16->i>>8); + channel_matrix8[index].r = (int8_t)(srs_estimated_channel16->r >> 8); + channel_matrix8[index].i = (int8_t)(srs_estimated_channel16->i >> 8); } else { channel_matrix16[index].r = srs_estimated_channel16->r; channel_matrix16[index].i = srs_estimated_channel16->i; } - // Subcarrier increment - subcarrier += step; - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } + subcarrier_abs += step; } } } @@ -1312,11 +1306,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N fill_srs_channel_matrix(&nr_srs_channel_iq_matrix, srs_pdu, gNB->nr_srs_info[i], - srs_pdu->srs_parameters_v4.iq_representation, - nb_antennas_rx, - srs_pdu->srs_parameters_v4.num_total_ue_antennas, - srs_pdu->srs_parameters_v4.prg_size, - srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size, frame_parms, srs_estimated_channel_freq);