From afde7f6c51e43806b637c2867ab13f0acff8cfa2 Mon Sep 17 00:00:00 2001 From: francescomani <email@francescomani.it> Date: Mon, 25 Mar 2024 13:09:31 +0100 Subject: [PATCH] improvements in precoding initialization at MAC --- common/utils/nr/nr_common.c | 12 -- common/utils/nr/nr_common.h | 1 - openair2/LAYER2/NR_MAC_gNB/config.c | 107 +++++++++++------- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 19 +--- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 5 files changed, 75 insertions(+), 65 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 4006fbb8580..e61fe01c8be 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -827,18 +827,6 @@ void get_samplerate_and_bw(int mu, } } -void get_K1_K2(int N1, int N2, int *K1, int *K2) -{ - // num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214 - if(N2 == N1 || N1 == 2) - *K1 = 2; - else if (N2 == 1) - *K1 = 5; - else - *K1 = 3; - *K2 = N2 > 1 ? 2 : 1; -} - // from start symbol index and nb or symbols to symbol occupation bitmap in a slot uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) { return ((1<<nrOfSymbols)-1)<<startSymbolIndex; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index a18b1cecc9a..8456ec48a27 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -188,7 +188,6 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports); uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols); int get_nb_periods_per_frame(uint8_t tdd_period); long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS); -void get_K1_K2(int N1, int N2, int *K1, int *K2); bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type); int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index); int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 5b7b24b9dd2..95b5c6cbecd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -67,6 +67,36 @@ c16_t convert_precoder_weight(double complex c_in) return (c16_t) {.r = (short)cr, .i = (short)ci}; } +void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers) +{ + // num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214 + switch (layers) { + case 1: + *K1 = 1; + *K2 = 1; + break; + case 2: + *K2 = N2 == 1 ? 1 : 2; + if(N2 == N1 || N1 == 2) + *K1 = 2; + else if (N2 == 1) + *K1 = 4; + else + *K1 = 3; + break; + case 3: + case 4: + *K2 = N2 == 1 ? 1 : 2; + if (N1 == 6) + *K1 = 5; + else + *K1 = N1; + break; + default: + AssertFatal(false, "Number of layers %d not supported\n", layers); + } +} + nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPorts_t antenna_ports) { int num_antenna_ports = antenna_ports.N1 * antenna_ports.N2 * antenna_ports.XP; @@ -88,16 +118,20 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort int O2 = N2 > 1 ? 4 : 1; //Vertical beam oversampling (1 or 4) int O1 = num_antenna_ports > 2 ? 4 : 1; //Horizontal beam oversampling (1 or 4) - int K1, K2; - get_K1_K2(N1, N2, &K1, &K2); - int max_mimo_layers = (num_antenna_ports < NR_MAX_NB_LAYERS) ? num_antenna_ports : NR_MAX_NB_LAYERS; AssertFatal(max_mimo_layers <= 4, "Max number of layers supported is 4\n"); + AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); + + int K1[max_mimo_layers]; + memset(K1, 0, sizeof(K1)); + int K2[max_mimo_layers]; + memset(K2, 0, sizeof(K2)); - gNB->precoding_matrix_size[0] = N1 * O1 * N2 * O2 * 4; - nfapi_nr_pm_list_t mat = {.num_pm_idx = gNB->precoding_matrix_size[0]}; - for (int i = 1; i < max_mimo_layers; i++) { - gNB->precoding_matrix_size[i] = 2 * N1 * O1 * N2 * O2 * K1 * K2; + nfapi_nr_pm_list_t mat = {.num_pm_idx = 0}; + for (int i = 0; i < max_mimo_layers; i++) { + get_K1_K2(N1, N2, &K1[i], &K2[i], i + 1); + int i2_size = i == 0 ? 4 : 2; + gNB->precoding_matrix_size[i] = i2_size * N1 * O1 * N2 * O2 * K1[i] * K2[i]; mat.num_pm_idx += gNB->precoding_matrix_size[i]; } @@ -106,10 +140,10 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort mat.pmi_pdu = pmi_pdu; // Generation of codebook Type1 with codebookMode 1 (num_antenna_ports < 16) - AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); + // Generate DFT vertical beams // ll: index of a vertical beams vector (represented by i1_1 in TS 38.214) - const int max_l = N1 * O1 + (K1 - 1) * O1; + const int max_l = N1 * O1 + 4 * O1; // max k1 is 4*O1 double complex v[max_l][N1]; for (int ll = 0; ll < max_l; ll++) { // i1_1 for (int nn = 0; nn < N1; nn++) { @@ -119,7 +153,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort } // Generate DFT Horizontal beams // mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214) - const int max_m = N2 * O2 + (K2 - 1) * O2; + const int max_m = N2 * O2 + O2; // max k2 is O2 double complex u[max_m][N2]; for (int mm = 0; mm < max_m; mm++) { // i1_2 for (int nn = 0; nn < N2; nn++) { @@ -158,12 +192,12 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort double complex res_code; // Table 5.2.2.2.1-5: - int pmiq = 0; + int pmiq = -1; // Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 for (int nn = 0; nn < 4; nn++) { - pmiq = ll * N2 * O2 * 4 + mm * 4 + nn; + pmiq++; pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix pmi_pdu[pmiq].numLayers = 1; pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; @@ -175,7 +209,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", + "1 Layer Precoding Matrix[pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, len, creal(res_code), @@ -191,7 +225,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", + "1 Layer Precoding Matrix[pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, len, creal(res_code), @@ -208,12 +242,11 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort // Table 5.2.2.2.1-6: // Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS // Compute the code book size for generating 2 layers out of Tx antenna ports - // pmi=1,...,pmi_size, we construct - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { + for (int k2 = 0; k2 < K2[1]; k2++) { + for (int k1 = 0; k1 < K1[1]; k1++) { + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 for (int nn = 0; nn < 2; nn++) { // i_2 pmiq++; pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix @@ -238,7 +271,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + "2 Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, i_rows, j_col, @@ -254,7 +287,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + "2 Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, i_rows, j_col, @@ -272,15 +305,13 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort if (max_mimo_layers < 3) return mat; - // Table 5.2.2.2.1-7: // Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - // pmi=1,...,pmi_size are computed as follows - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { + for (int k2 = 0; k2 < K2[2]; k2++) { + for (int k1 = 0; k1 < K1[2]; k1++) { + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 for (int nn = 0; nn < 2; nn++) { // i_2 pmiq++; pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix @@ -310,7 +341,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + "3 Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, i_rows, j_col, @@ -326,7 +357,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + "3 Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, i_rows, j_col, @@ -344,14 +375,12 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort if (max_mimo_layers < 4) return mat; - // Table 5.2.2.2.1-8: // Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { + for (int k2 = 0; k2 < K2[3]; k2++) { + for (int k1 = 0; k1 < K1[3]; k1++) { + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 for (int nn = 0; nn < 2; nn++) { // i_2 pmiq++; pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix @@ -386,7 +415,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + "4 Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, i_rows, j_col, @@ -402,7 +431,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort weights->precoder_weight_Re = precoder_weight.r; weights->precoder_weight_Im = precoder_weight.i; LOG_D(PHY, - "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + "4 Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", pmiq, i_rows, j_col, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e01c0861d0d..3d7179d04cf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -223,21 +223,14 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac, int k1, k2; get_k1_k2_indices(layers, N1, N2, i13, &k1, &k2); // get indices k1 and k2 for PHY matrix (not actual k1 and k2 values) const int O2 = N2 == 1 ? 1 : 4; + int O1 = 4; //Horizontal beam oversampling = 4 for more than 2 antenna ports int max_i2 = 0; int lay_index = 0; - if (layers == 1) { - max_i2 = 4; - // computing precoding matrix index according to rule set in allocation function init_codebook_gNB - lay_index = i2 + (i12 * max_i2) + (i11 * max_i2 * N2 * O2); - } - else { - max_i2 = 2; - // num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214 - int K1, K2; - get_K1_K2(N1, N2, &K1, &K2); - // computing precoding matrix index according to rule set in allocation function init_codebook_gNB - lay_index = i2 + (k2 * max_i2) + (k1 * max_i2 * K2) + (i12 * max_i2 * K2 * K1) + (i11 * max_i2 * K2 * K1 * N2 * O2); - } + max_i2 = layers == 1 ? 4 : 2; + int K1, K2; + get_K1_K2(N1, N2, &K1, &K2, layers); + // computing precoding matrix index according to rule set in allocation function init_codebook_gNB + lay_index = i2 + (i11 * max_i2) + (i12 * max_i2 * N1 * O1) + (k1 * max_i2 * N1 * O1 * N2 * O2) + (k2 * max_i2 * N1 * O1 * N2 * O2 * K1); return 1 + prev_layers_size + lay_index; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 62289989427..6e38f491f64 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -36,6 +36,7 @@ #include "common/ngran_types.h" void set_cset_offset(uint16_t); +void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers); void mac_top_init_gNB(ngran_node_t node_type, NR_ServingCellConfigCommon_t *scc, -- GitLab