Commit afde7f6c authored by francescomani's avatar francescomani

improvements in precoding initialization at MAC

parent 8f858af8
......@@ -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;
......
......@@ -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);
......
......@@ -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,
......
......@@ -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;
}
}
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment