From 26fd99ff61cc69f454e69adbfbb5a09c64f0db54 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 4 Oct 2024 11:01:51 +0200 Subject: [PATCH] terminal independent common functions in nr_generate_csi_rs --- openair1/PHY/NR_TRANSPORT/nr_csi_rs.c | 171 ++++-------------- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 5 + .../PHY/nr_phy_common/inc/nr_phy_common.h | 29 +++ .../PHY/nr_phy_common/src/nr_phy_common.c | 160 ++++++++++++++++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 + 5 files changed, 237 insertions(+), 132 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c index cf5ead64a2..50c1b73d01 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c @@ -48,31 +48,32 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss); #endif - int dataF_offset = slot * frame_parms->samples_per_slot_wCP; - //*8(max allocation per RB)*2(QPSK)) - int csi_rs_length = frame_parms->N_RB_DL << 4; - int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); - uint32_t beta = amp; - // setting the frequency density from its index - double rho = 0; - switch (csi_params->freq_density) { - case 0: - rho = 0.5; - break; - case 1: - rho = 0.5; - break; - case 2: - rho = 1; - break; - case 3: - rho = 3; - break; - default: - AssertFatal(false, "Invalid frequency density index for CSI\n"); - } + double rho = get_csi_rho(csi_params->freq_density); + int csi_length = get_csi_modulation_length(rho, + csi_params->freq_density, + phy_csi_parms->kprime, + csi_params->start_rb, + csi_params->nr_of_rbs); +#ifdef NR_CSIRS_DEBUG + printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length); +#endif + + //*8(max allocation per RB)*2(QPSK)) + int16_t mod_csi[frame_parms->symbols_per_slot][(frame_parms->N_RB_DL << 4) >> 1] __attribute__((aligned(16))); + get_modulated_csi_symbols(frame_parms->symbols_per_slot, + slot, + frame_parms->N_RB_DL, + csi_length, + mod_csi, + phy_csi_parms->lprime, + csi_params->symb_l0, + csi_params->symb_l1, + csi_params->row, + csi_params->scramb_id); + + uint32_t beta = get_csi_beta_amplitude(amp, csi_params->power_control_offset_ss); double alpha = 0; if (phy_csi_parms->ports == 1) alpha = rho; @@ -86,114 +87,20 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, // CDM group size from CDM type index int gs = get_cdm_group_size(csi_params->cdm_type); - int kprime = phy_csi_parms->kprime; - int csi_length; - if (rho < 1) { - if (csi_params->freq_density == 0) { - csi_length = (((csi_params->start_rb + csi_params->nr_of_rbs) >> 1) << kprime) << 1; - } else { - csi_length = ((((csi_params->start_rb + csi_params->nr_of_rbs) >> 1) << kprime) + 1) << 1; - } - } else { - csi_length = (((uint16_t) rho * (csi_params->start_rb + csi_params->nr_of_rbs)) << kprime) << 1; - } + int dataF_offset = slot * frame_parms->samples_per_slot_wCP; -#ifdef NR_CSIRS_DEBUG - printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length); -#endif - - if (csi_params->csi_type == 2) // ZP-CSI - return; - - // assuming amp is the amplitude of SSB channels - switch (csi_params->power_control_offset_ss) { - case 0: - beta = (amp * ONE_OVER_SQRT2_Q15) >> 15; - break; - case 1: - beta = amp; - break; - case 2: - beta = (amp * ONE_OVER_SQRT2_Q15) >> 14; - break; - case 3: - beta = amp << 1; - break; - default: - AssertFatal(false, "Invalid SS power offset density index for CSI\n"); - } - - for (int lp = 0; lp <= phy_csi_parms->lprime; lp++) { - int symb = csi_params->symb_l0; - const uint32_t *gold = - nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id); - nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); - uint8_t row = csi_params->row; - if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) { - const uint32_t *gold = - nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id); - nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); - } - if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) { - symb = csi_params->symb_l1; - const uint32_t *gold = - nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id); - nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); - if ((row == 13) || (row == 16)) { - const uint32_t *gold = - nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id); - nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); - } - } - } - - uint16_t start_sc = frame_parms->first_carrier_offset; - // resource mapping according to 38.211 7.4.1.5.3 - for (int n = csi_params->start_rb; n < (csi_params->start_rb + csi_params->nr_of_rbs); n++) { - if ((csi_params->freq_density > 1) || (csi_params->freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB - for (int ji = 0; ji < phy_csi_parms->size; ji++) { // loop over CDM groups - for (int s = 0 ; s < gs; s++) { // loop over each CDM group size - int p = s + phy_csi_parms->j[ji] * gs; // port index - for (int kp = 0; kp <= kprime; kp++) { // loop over frequency resource elements within a group - // frequency index of current resource element - int k = (start_sc + (n * NR_NB_SC_PER_RB) + phy_csi_parms->koverline[ji] + kp) % (frame_parms->ofdm_symbol_size); - // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 - int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1); - int na = n * alpha; - int kpn = (rho * phy_csi_parms->koverline[ji]) / NR_NB_SC_PER_RB; - int mprime = na + kp + kpn; // sequence index - for (int lp = 0; lp <= phy_csi_parms->lprime; lp++) { // loop over frequency resource elements within a group - int l = lp + phy_csi_parms->loverline[ji]; - // wt according to tables 7.4.5.3-2 to 7.4.5.3-5 - int wt; - if (s < 2) - wt = 1; - else if (s < 4) - wt = -2 * (lp % 2) + 1; - else if (s < 6) - wt = -2 * (lp / 2) + 1; - else { - if ((lp == 0) || (lp == 3)) - wt = 1; - else - wt = -1; - } - int index = ((l * frame_parms->ofdm_symbol_size + k) << 1) + (2 * dataF_offset); - ((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15; - ((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15; -#ifdef NR_CSIRS_DEBUG - printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n", - l, - k, - mprime, - p + 3000, - ((int16_t*)dataF[p])[index], - ((int16_t*)dataF[p])[index + 1]); -#endif - } - } - } - } - } - } + csi_rs_resource_mapping(dataF, + frame_parms->N_RB_DL << 4, + mod_csi, + frame_parms->ofdm_symbol_size, + dataF_offset, + frame_parms->first_carrier_offset, + phy_csi_parms, + csi_params->start_rb, + csi_params->nr_of_rbs, + alpha, + beta, + rho, + gs, + csi_params->freq_density); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 28e2c6b421..3250cf5f31 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -869,6 +869,11 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, return; } + if(csirs_config_pdu->csi_type == 2) { + LOG_E(NR_PHY, "Handling of ZP CSI-RS not handled yet at PHY\n"); + return; + } + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP]; int16_t log2_re = 0; diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index 2731470618..e0bc2aaa15 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -23,6 +23,8 @@ #define __NR_PHY_COMMON__H__ #include "PHY/impl_defs_top.h" #include "PHY/TOOLS/tools_defs.h" +#include "PHY/NR_REFSIG/nr_refsig_common.h" +#include "PHY/MODULATION/nr_modulation.h" typedef struct { int size; @@ -33,8 +35,35 @@ typedef struct { int koverline[16]; int loverline[16]; } csi_mapping_parms_t; +void get_modulated_csi_symbols(int symbols_per_slot, + int slot, + int N_RB_DL, + int mod_length, + int16_t mod_csi[][(N_RB_DL << 4) >> 1], + int lprime, + int l0, + int l1, + int row, + int scramb_id); +void csi_rs_resource_mapping(int32_t **dataF, + int csi_rs_length, + int16_t mod_csi[][csi_rs_length >> 1], + int ofdm_symbol_size, + int dataF_offset, + int start_sc, + const csi_mapping_parms_t *mapping_parms, + int start_rb, + int nb_rbs, + double alpha, + int beta, + double rho, + int gs, + int freq_density); csi_mapping_parms_t get_csi_mapping_parms(int row, int b, int l0, int l1); int get_cdm_group_size(int cdm_type); +double get_csi_rho(int freq_density); +uint32_t get_csi_beta_amplitude(const int16_t amp, int power_control_offset_ss); +int get_csi_modulation_length(double rho, int freq_density, int kprime, int start_rb, int nb_rbs); void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re); void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re); void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re); diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index 88e941c49f..aaf93444cd 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -354,6 +354,166 @@ void nr_256qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int simde_mm_empty(); } +void csi_rs_resource_mapping(int32_t **dataF, + int csi_rs_length, + int16_t mod_csi[][csi_rs_length >> 1], + int ofdm_symbol_size, + int dataF_offset, + int start_sc, + const csi_mapping_parms_t *mapping_parms, + int start_rb, + int nb_rbs, + double alpha, + int beta, + double rho, + int gs, + int freq_density) +{ + // resource mapping according to 38.211 7.4.1.5.3 + for (int n = start_rb; n < (start_rb + nb_rbs); n++) { + if ((freq_density > 1) || (freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB + for (int ji = 0; ji < mapping_parms->size; ji++) { // loop over CDM groups + for (int s = 0 ; s < gs; s++) { // loop over each CDM group size + int p = s + mapping_parms->j[ji] * gs; // port index + for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group + // frequency index of current resource element + int k = (start_sc + (n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp) % (ofdm_symbol_size); + // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 + int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1); + int na = n * alpha; + int kpn = (rho * mapping_parms->koverline[ji]) / NR_NB_SC_PER_RB; + int mprime = na + kp + kpn; // sequence index + for (int lp = 0; lp <= mapping_parms->lprime; lp++) { // loop over frequency resource elements within a group + int l = lp + mapping_parms->loverline[ji]; + // wt according to tables 7.4.5.3-2 to 7.4.5.3-5 + int wt; + if (s < 2) + wt = 1; + else if (s < 4) + wt = -2 * (lp % 2) + 1; + else if (s < 6) + wt = -2 * (lp / 2) + 1; + else { + if ((lp == 0) || (lp == 3)) + wt = 1; + else + wt = -1; + } + int index = ((l * ofdm_symbol_size + k) << 1) + (2 * dataF_offset); + ((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15; + ((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15; + LOG_D(PHY, + "l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n", + l, + k, + mprime, + p + 3000, + ((int16_t*)dataF[p])[index], + ((int16_t*)dataF[p])[index + 1]); + } + } + } + } + } + } +} + +void get_modulated_csi_symbols(int symbols_per_slot, + int slot, + int N_RB_DL, + int mod_length, + int16_t mod_csi[][(N_RB_DL << 4) >> 1], + int lprime, + int l0, + int l1, + int row, + int scramb_id) +{ + for (int lp = 0; lp <= lprime; lp++) { + int symb = l0; + const uint32_t *gold = + nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + lp, scramb_id); + nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); + if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) { + const uint32_t *gold = + nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + 1, scramb_id); + nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); + } + if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) { + symb = l1; + const uint32_t *gold = + nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + lp, scramb_id); + nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); + if ((row == 13) || (row == 16)) { + const uint32_t *gold = + nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + 1, scramb_id); + nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); + } + } + } +} + +uint32_t get_csi_beta_amplitude(const int16_t amp, int power_control_offset_ss) +{ + uint32_t beta = amp; + // assuming amp is the amplitude of SSB channels + switch (power_control_offset_ss) { + case 0: + beta = (amp * ONE_OVER_SQRT2_Q15) >> 15; + break; + case 1: + beta = amp; + break; + case 2: + beta = (amp * ONE_OVER_SQRT2_Q15) >> 14; + break; + case 3: + beta = amp << 1; + break; + default: + AssertFatal(false, "Invalid SS power offset density index for CSI\n"); + } + return beta; +} + +int get_csi_modulation_length(double rho, int freq_density, int kprime, int start_rb, int nr_rbs) +{ + int csi_length = 0; + if (rho < 1) { + if (freq_density == 0) { + csi_length = (((start_rb + nr_rbs) >> 1) << kprime) << 1; + } else { + csi_length = ((((start_rb + nr_rbs) >> 1) << kprime) + 1) << 1; + } + } else { + csi_length = (((uint16_t) rho * (start_rb + nr_rbs)) << kprime) << 1; + } + return csi_length; +} + +double get_csi_rho(int freq_density) +{ + // setting the frequency density from its index + double rho = 0; + switch (freq_density) { + case 0: + rho = 0.5; + break; + case 1: + rho = 0.5; + break; + case 2: + rho = 1; + break; + case 3: + rho = 3; + break; + default: + AssertFatal(false, "Invalid frequency density index for CSI\n"); + } + return rho; +} + int get_cdm_group_size(int cdm_type) { // CDM group size from CDM type index diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e6d2e3bdce..f713c3b1af 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -220,6 +220,10 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, if (csirs->active == 1) { LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; + if (csi_params->csi_type == 2) { // ZP-CSI + csirs->active = 0; + return; + } csi_mapping_parms_t mapping_parms = get_csi_mapping_parms(csi_params->row, csi_params->freq_domain, csi_params->symb_l0,