diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 750bdd8287..ca9d735fca 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -723,6 +723,18 @@ 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<rbSize = g_rbSize; sched_pdsch->mcs = g_mcsIndex; sched_pdsch->nrOfLayers = g_nrOfLayers; + sched_pdsch->pm_index = g_pmi; /* the following might override the table that is mandated by RRC * configuration */ current_BWP->mcsTableIdx = g_mcsTableIdx; @@ -235,8 +236,39 @@ nrUE_params_t *get_nrUE_params(void) { return &nrUE_params; } -void do_nothing(void *args) { + +void validate_input_pmi(rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts, int nrOfLayers, int pmi) +{ + if (pmi == 0) + return; + + int num_antenna_ports = pdsch_AntennaPorts.N1 * pdsch_AntennaPorts.N2 * pdsch_AntennaPorts.XP; + int N1 = pdsch_AntennaPorts.N1; + int N2 = pdsch_AntennaPorts.N2; + int O1 = N1 > 1 ? 4 : 1; + int O2 = N2 > 1 ? 4 : 1; + int K1, K2; + if (num_antenna_ports > 2) + get_K1_K2(N1, N2, &K1, &K2); + else { + K1 = 1; K2 = 1; + } + int num_pmi = 1; // pmi = 0 is the identity matrix + switch (nrOfLayers) { + case 1 : + num_pmi += N1 * O1 * N2 * O2 * 4; + AssertFatal(pmi < num_pmi, "Input PMI index %d exceeds the limit of configured matrices %d for %d layers\n", pmi, num_pmi, nrOfLayers); + return; + case 2 : + num_pmi += N1 * O1 * N2 * O2 * K1 * K2 * 2; + AssertFatal(pmi < num_pmi, "Input PMI index %d exceeds the limit of conigured matrices %d for %d layers\n", pmi, num_pmi, nrOfLayers); + break; + default : + AssertFatal(false, "Precoding with more than 2 nrOfLayers not yet supported\n"); + } } + + int NB_UE_INST = 1; int main(int argc, char **argv) @@ -327,7 +359,7 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt(argc, argv, "f:hA:pf:g:i:n:s:S:t:v:x:y:z:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y")) != -1) { + while ((c = getopt(argc, argv, "f:hA:p:f:g:i:n:s:S:t:v:x:y:z:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y")) != -1) { switch (c) { case 'f': scg_fd = fopen(optarg,"r"); @@ -404,35 +436,19 @@ int main(int argc, char **argv) printf("Setting SNR1 to %f\n",snr1); break; - /* - case 't': - Td= atof(optarg); - break; - */ - /*case 'p': - extended_prefix_flag=1; - break;*/ - - /* - case 'r': - ricean_factor = pow(10,-.1*atof(optarg)); - if (ricean_factor>1) { - printf("Ricean factor must be between 0 and 1\n"); - exit(-1); - } - break; - */ case 'x': - g_nrOfLayers=atoi(optarg); + g_nrOfLayers = atoi(optarg); - if ((g_nrOfLayers==0) || - (g_nrOfLayers>4)) { - printf("Unsupported nr Of Layers %d\n",g_nrOfLayers); + if ((g_nrOfLayers == 0) || (g_nrOfLayers > 4)) { + printf("Unsupported nr Of Layers %d\n", g_nrOfLayers); exit(-1); } - break; + case 'p': + g_pmi = atoi(optarg); + break; + case 'v': num_rounds = atoi(optarg); @@ -559,6 +575,7 @@ int main(int argc, char **argv) printf("-y Number of TX antennas used in gNB\n"); printf("-z Number of RX antennas used in UE\n"); printf("-x Num of layer for PDSCH\n"); + printf("-p Precoding matrix index\n"); printf("-i Change channel estimation technique. Arguments list: Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}\n"); //printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n"); printf("-R N_RB_DL\n"); @@ -688,6 +705,8 @@ int main(int argc, char **argv) gNB->ap_N2 = pdsch_AntennaPorts.N2; gNB->ap_XP = pdsch_AntennaPorts.XP; + validate_input_pmi(pdsch_AntennaPorts, g_nrOfLayers, g_pmi); + NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t)); prepare_sim_uecap(UE_Capability_nr,scc,mu, N_RB_DL,g_mcsTableIdx);