Commit 779362dc authored by hardy's avatar hardy
Browse files

Merge remote-tracking branch 'origin/NR_CSI_reporting' into integration_2020_wk44

parents b0797c08 1a1ee59d
......@@ -1593,6 +1593,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
......
......@@ -1260,7 +1260,7 @@ typedef struct
typedef struct
{
uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535
uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255
} nfapi_nr_ul_tti_request_number_of_ue_t;
......@@ -1541,7 +1541,7 @@ typedef struct
}nfapi_nr_uci_pucch_pdu_format_2_3_4_t;
typedef enum {
NFAPI_NR_UCI_PDCCH_PDU_TYPE = 0,
NFAPI_NR_UCI_PUSCH_PDU_TYPE = 0,
NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE = 1,
NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE = 2,
} nfapi_nr_uci_pdu_type_e;
......
......@@ -260,7 +260,7 @@ crc6 (unsigned char * inptr, int bitlen)
}
if (resbit > 0)
crc = (crc << resbit) ^ (crc8Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
crc = (crc << resbit) ^ (crc6Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
return crc;
}
......
......@@ -181,9 +181,27 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
LOG_D(PHY,"Initializing PUSCH DMRS Gold sequence with (%x,%x)\n",Nid_pusch[0],Nid_pusch[1]);
nr_gold_pusch(gNB, &Nid_pusch[0]);
//CSI RS init
gNB->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
AssertFatal(csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
for (int slot=0; slot<fp->slots_per_frame; slot++) {
csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
AssertFatal(csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
csi_rs[slot][symb] = (uint32_t *)malloc16(NR_MAX_CSI_RS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
}
}
nr_init_csi_rs(gNB, 0); // TODO scramblingID currently hardcoded to 0, to be taken from higher layer parameter scramblingID when implemented
/// Transport init necessary for NR synchro
init_nr_transport(gNB);
gNB->first_run_I0_measurements = 1;
common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*));
......
......@@ -65,7 +65,7 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1)) + (Nid<<1);
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1));
for (uint32_t n=0; n<NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD; n++) {
pdcch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
......@@ -130,3 +130,26 @@ void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid) {
}
}
}
void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid)
{
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
uint32_t x1, x2;
uint8_t reset;
for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<10) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
for (uint32_t n=0; n<NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD; n++) {
csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
}
}
}
......@@ -38,6 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
*/
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid);
void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid);
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/MODULATION/nr_modulation.h"
//#define NR_CSIRS_DEBUG
int nr_generate_csi_rs(uint32_t **gold_csi_rs,
int32_t** txdataF,
int16_t amp,
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params)
{
int16_t mod_csi[frame_parms.symbols_per_slot][NR_MAX_CSI_RS_LENGTH>>1];
uint16_t b = csi_params.freq_domain;
uint16_t n, csi_bw, csi_start, p, k, l, mprime, na, kpn, csi_length;
uint8_t size, ports, kprime, lprime, i, gs;
uint8_t j[16], k_n[6], koverline[16], loverline[16];
int found = 0;
int wf, wt, lp, kp, symb;
uint8_t fi = 0;
double rho, alpha;
uint32_t beta = amp;
AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
switch (csi_params.row) {
// implementation of table 7.4.1.5.3-1 of 38.211
// lprime and kprime are the max value of l' and k'
case 1:
ports = 1;
kprime = 0;
lprime = 0;
size = 3;
while (found < 1) {
if ((b >> fi) & 0x01) {
k_n[found] = fi;
found++;
}
else
fi++;
}
for (i=0; i<size; i++) {
j[i] = 0;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[0] + (i<<2);
}
break;
case 2:
ports = 1;
kprime = 0;
lprime = 0;
size = 1;
while (found < 1) {
if ((b >> fi) & 0x01) {
k_n[found] = fi;
found++;
}
else
fi++;
}
for (i=0; i<size; i++) {
j[i] = 0;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[0];
}
break;
case 3:
ports = 2;
kprime = 1;
lprime = 0;
size = 1;
while (found < 1) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
else
fi++;
}
for (i=0; i<size; i++) {
j[i] = 0;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[0];
}
break;
case 4:
ports = 4;
kprime = 1;
lprime = 0;
size = 2;
while (found < 1) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<2;
found++;
}
else
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[0] + (i<<1);
}
break;
case 5:
ports = 4;
kprime = 1;
lprime = 0;
size = 2;
while (found < 1) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
else
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0 + i;
koverline[i] = k_n[0];
}
break;
case 6:
ports = 8;
kprime = 1;
lprime = 0;
size = 4;
while (found < 4) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
case 7:
ports = 8;
kprime = 1;
lprime = 0;
size = 4;
while (found < 2) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0 + (i>>1);
koverline[i] = k_n[i%2];
}
break;
case 8:
ports = 8;
kprime = 1;
lprime = 1;
size = 2;
while (found < 2) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
case 9:
ports = 12;
kprime = 1;
lprime = 0;
size = 6;
while (found < 6) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
case 10:
ports = 12;
kprime = 1;
lprime = 1;
size = 3;
while (found < 3) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
case 11:
ports = 16;
kprime = 1;
lprime = 0;
size = 8;
while (found < 4) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0 + (i>>2);
koverline[i] = k_n[i%4];
}
break;
case 12:
ports = 16;
kprime = 1;
lprime = 1;
size = 4;
while (found < 4) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
case 13:
ports = 24;
kprime = 1;
lprime = 0;
size = 12;
while (found < 3) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
if (i<6)
loverline[i] = csi_params.symb_l0 + i/3;
else
loverline[i] = csi_params.symb_l1 + i/9;
koverline[i] = k_n[i%3];
}
break;
case 14:
ports = 24;
kprime = 1;
lprime = 1;
size = 6;
while (found < 3) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
if (i<3)
loverline[i] = csi_params.symb_l0;
else
loverline[i] = csi_params.symb_l1;
koverline[i] = k_n[i%3];
}
break;
case 15:
ports = 24;
kprime = 1;
lprime = 3;
size = 3;
while (found < 3) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
case 16:
ports = 32;
kprime = 1;
lprime = 0;
size = 16;
while (found < 4) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
if (i<8)
loverline[i] = csi_params.symb_l0 + (i>>2);
else
loverline[i] = csi_params.symb_l1 + (i/12);
koverline[i] = k_n[i%4];
}
break;
case 17:
ports = 32;
kprime = 1;
lprime = 1;
size = 8;
while (found < 4) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
if (i<4)
loverline[i] = csi_params.symb_l0;
else
loverline[i] = csi_params.symb_l1;
koverline[i] = k_n[i%4];
}
break;
case 18:
ports = 32;
kprime = 1;
lprime = 3;
size = 4;
while (found < 4) {
if ((b >> fi) & 0x01) {
k_n[found] = fi<<1;
found++;
}
fi++;
}
for (i=0; i<size; i++) {
j[i] = i;
loverline[i] = csi_params.symb_l0;
koverline[i] = k_n[i];
}
break;
default:
AssertFatal(0==1, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csi_params.row);
}
#ifdef NR_CSIRS_DEBUG
printf(" row %d, n. of ports %d\n k' ",csi_params.row,ports);
for (kp=0; kp<=kprime; kp++)
printf("%d, ",kp);
printf("l' ");
for (lp=0; lp<=lprime; lp++)
printf("%d, ",lp);
printf("\n k overline ");
for (i=0; i<size; i++)
printf("%d, ",koverline[i]);
printf("\n l overline ");
for (i=0; i<size; i++)
printf("%d, ",loverline[i]);
printf("\n");
#endif
// setting the frequency density from its index
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(0==1, "Invalid frequency density index for CSI\n");
}
if (ports == 1)
alpha = rho;
else
alpha = 2*rho;
#ifdef NR_CSIRS_DEBUG
printf(" rho %f, alpha %f\n",rho,alpha);
#endif
// CDM group size from CDM type index
switch (csi_params.cdm_type) {
case 0:
gs = 1;
break;
case 1:
gs = 2;
break;
case 2:
gs = 4;
break;
case 3:
gs = 8;
break;
default:
AssertFatal(0==1, "Invalid cdm type index for CSI\n");
}
// according to 38.214 5.2.2.3.1 last paragraph
if (csi_params.start_rb<csi_params.bwp_start)
csi_start = csi_params.bwp_start;
else