Merge remote-tracking branch 'origin/NR_RRC_MAC_CellGroup' into NR_BWP_config
This commit is contained in:
+16
-18
@@ -593,26 +593,23 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
nr_gold_pusch(gNB, nscid, gNB->pusch_gold_init[nscid]);
|
||||
}
|
||||
|
||||
//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");
|
||||
|
||||
// CSI RS init
|
||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||
|
||||
gNB->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t));
|
||||
gNB->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||
AssertFatal(gNB->nr_csi_rs_info->nr_gold_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);
|
||||
|
||||
gNB->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
||||
AssertFatal(gNB->nr_csi_rs_info->nr_gold_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(csi_dmrs_init_length*sizeof(uint32_t));
|
||||
AssertFatal(csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
|
||||
AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
|
||||
gNB->csi_gold_init = cfg->cell_config.phy_cell_id.value;
|
||||
nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value);
|
||||
gNB->nr_csi_rs_info->csi_gold_init = cfg->cell_config.phy_cell_id.value;
|
||||
nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_rs_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value);
|
||||
|
||||
for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
|
||||
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
||||
@@ -778,13 +775,14 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
}
|
||||
free_and_zero(pusch_dmrs);
|
||||
|
||||
uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
|
||||
uint32_t ***nr_gold_csi_rs = gNB->nr_csi_rs_info->nr_gold_csi_rs;
|
||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
||||
free_and_zero(csi_rs[slot][symb]);
|
||||
free_and_zero(csi_rs[slot]);
|
||||
free_and_zero(nr_gold_csi_rs[slot][symb]);
|
||||
free_and_zero(nr_gold_csi_rs[slot]);
|
||||
}
|
||||
free_and_zero(csi_rs);
|
||||
free_and_zero(nr_gold_csi_rs);
|
||||
free_and_zero(gNB->nr_csi_rs_info);
|
||||
|
||||
for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
|
||||
for (int i = 0; i < Prx; i++) {
|
||||
@@ -1050,7 +1048,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
||||
|
||||
for (int i=0; i<gNB->number_of_nr_ulsch_max; i++) {
|
||||
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max);
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max);
|
||||
|
||||
gNB->ulsch[i] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL);
|
||||
|
||||
|
||||
@@ -124,9 +124,10 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
ru->num_gNB,NUMBER_OF_gNB_MAX);
|
||||
|
||||
LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
|
||||
if (ru->do_precoding == 1) {
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
int beam_count = 0;
|
||||
if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
|
||||
if (ru->nb_tx>1) { //Enable beamforming when nb_tx > 1
|
||||
|
||||
for (p=0;p<ru->nb_log_antennas;p++) {
|
||||
//if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
|
||||
@@ -149,7 +150,7 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
} // for j
|
||||
//}
|
||||
} // for p
|
||||
} //for i
|
||||
} // for i
|
||||
}
|
||||
|
||||
ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
|
||||
|
||||
@@ -155,10 +155,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
NR_UE_COMMON *const common_vars = &ue->common_vars;
|
||||
NR_UE_PBCH **const pbch_vars = ue->pbch_vars;
|
||||
NR_UE_PRACH **const prach_vars = ue->prach_vars;
|
||||
int i,slot,symb, gNB_id, th_id;
|
||||
|
||||
NR_UE_CSI_IM **const csiim_vars = ue->csiim_vars;
|
||||
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
|
||||
NR_UE_SRS **const srs_vars = ue->srs_vars;
|
||||
|
||||
int i, j, slot, symb, gNB_id, th_id;
|
||||
|
||||
LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
|
||||
|
||||
phy_init_nr_top(ue);
|
||||
@@ -335,9 +337,45 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
|
||||
prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
|
||||
pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
|
||||
csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM));
|
||||
csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS));
|
||||
srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS));
|
||||
|
||||
csiim_vars[gNB_id]->active = false;
|
||||
csirs_vars[gNB_id]->active = false;
|
||||
srs_vars[gNB_id]->active = false;
|
||||
|
||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||
ue->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t));
|
||||
ue->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||
AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
ue->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
||||
AssertFatal(ue->nr_csi_rs_info->nr_gold_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++) {
|
||||
ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
|
||||
AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
ue->nr_csi_rs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t));
|
||||
ue->nr_csi_rs_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) );
|
||||
for (i=0; i<NR_MAX_NB_PORTS; i++) {
|
||||
ue->nr_csi_rs_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
}
|
||||
ue->nr_csi_rs_info->csi_rs_received_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) );
|
||||
ue->nr_csi_rs_info->csi_rs_ls_estimated_channel = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) );
|
||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) );
|
||||
for (i=0; i<fp->nb_antennas_rx; i++) {
|
||||
ue->nr_csi_rs_info->csi_rs_received_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
||||
for (j=0; j<NR_MAX_NB_PORTS; j++) {
|
||||
ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t));
|
||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
|
||||
ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
||||
ue->nr_srs_info->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t));
|
||||
ue->nr_srs_info->srs_generated_signal = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) );
|
||||
@@ -456,6 +494,32 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
|
||||
}
|
||||
|
||||
for (int i=0; i<NR_MAX_NB_PORTS; i++) {
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal[i]);
|
||||
}
|
||||
for (int i = 0; i < fp->nb_antennas_rx; i++) {
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal[i]);
|
||||
for (int j=0; j<NR_MAX_NB_PORTS; j++) {
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j]);
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j]);
|
||||
}
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i]);
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i]);
|
||||
}
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]);
|
||||
}
|
||||
free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]);
|
||||
}
|
||||
free_and_zero(ue->nr_csi_rs_info->noise_power);
|
||||
free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs);
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal);
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal);
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel);
|
||||
free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq);
|
||||
free_and_zero(ue->nr_csi_rs_info);
|
||||
|
||||
for (int i = 0; i < fp->nb_antennas_rx; i++) {
|
||||
free_and_zero(ue->nr_srs_info->srs_received_signal[i]);
|
||||
free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]);
|
||||
@@ -473,6 +537,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted);
|
||||
free_and_zero(ue->nr_srs_info);
|
||||
|
||||
free_and_zero(ue->csiim_vars[gNB_id]);
|
||||
free_and_zero(ue->csirs_vars[gNB_id]);
|
||||
free_and_zero(ue->srs_vars[gNB_id]);
|
||||
|
||||
free_and_zero(ue->pbch_vars[gNB_id]);
|
||||
|
||||
@@ -123,27 +123,3 @@ void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, 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;
|
||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||
|
||||
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<csi_dmrs_init_length; n++) {
|
||||
csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +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, uint8_t nscid, uint32_t Nid);
|
||||
void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
||||
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
||||
|
||||
void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
|
||||
|
||||
|
||||
@@ -68,4 +68,6 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
|
||||
uint16_t N_n_scid,
|
||||
uint8_t n_scid);
|
||||
|
||||
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,20 +27,53 @@
|
||||
//#define NR_CSIRS_DEBUG
|
||||
|
||||
|
||||
void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
|
||||
uint32_t x1, x2;
|
||||
uint8_t reset;
|
||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||
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<csi_dmrs_init_length; n++) {
|
||||
csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
||||
int32_t **dataF,
|
||||
int16_t amp,
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
|
||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||
int slot){
|
||||
|
||||
NR_DL_FRAME_PARMS frame_parms=gNB->frame_parms;
|
||||
int32_t **txdataF = gNB->common_vars.txdataF;
|
||||
int txdataF_offset = slot*frame_parms.samples_per_slot_wCP;
|
||||
uint32_t **gold_csi_rs = gNB->nr_gold_csi_rs[slot];
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
|
||||
LOG_I(NR_PHY, "csi_params->cyclic_prefix = %i\n", csi_params->cyclic_prefix);
|
||||
LOG_I(NR_PHY, "csi_params->start_rb = %i\n", csi_params->start_rb);
|
||||
LOG_I(NR_PHY, "csi_params->nr_of_rbs = %i\n", csi_params->nr_of_rbs);
|
||||
LOG_I(NR_PHY, "csi_params->csi_type = %i (0:TRS, 1:CSI-RS NZP, 2:CSI-RS ZP)\n", csi_params->csi_type);
|
||||
LOG_I(NR_PHY, "csi_params->row = %i\n", csi_params->row);
|
||||
LOG_I(NR_PHY, "csi_params->freq_domain = %i\n", csi_params->freq_domain);
|
||||
LOG_I(NR_PHY, "csi_params->symb_l0 = %i\n", csi_params->symb_l0);
|
||||
LOG_I(NR_PHY, "csi_params->symb_l1 = %i\n", csi_params->symb_l1);
|
||||
LOG_I(NR_PHY, "csi_params->cdm_type = %i\n", csi_params->cdm_type);
|
||||
LOG_I(NR_PHY, "csi_params->freq_density = %i (0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three)\n", csi_params->freq_density);
|
||||
LOG_I(NR_PHY, "csi_params->scramb_id = %i\n", csi_params->scramb_id);
|
||||
LOG_I(NR_PHY, "csi_params->power_control_offset = %i\n", csi_params->power_control_offset);
|
||||
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;
|
||||
uint32_t **nr_gold_csi_rs = nr_csi_rs_info->nr_gold_csi_rs[slot];
|
||||
//*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)));;
|
||||
uint16_t b = csi_params.freq_domain;
|
||||
uint16_t n, csi_bw, csi_start, p, k, l, mprime, na, kpn, csi_length;
|
||||
int16_t mod_csi[frame_parms.symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
|
||||
uint16_t b = csi_params->freq_domain;
|
||||
uint16_t n, p, k, l, mprime, na, kpn;
|
||||
uint8_t size, ports, kprime, lprime, i, gs;
|
||||
uint8_t j[16], k_n[6], koverline[16], loverline[16];
|
||||
int found = 0;
|
||||
@@ -48,16 +81,17 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
uint8_t fi = 0;
|
||||
double rho, alpha;
|
||||
uint32_t beta = amp;
|
||||
nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp);
|
||||
|
||||
AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||
|
||||
// if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
|
||||
if (csi_params.scramb_id != gNB->csi_gold_init) {
|
||||
gNB->csi_gold_init = csi_params.scramb_id;
|
||||
nr_init_csi_rs(gNB, csi_params.scramb_id);
|
||||
if (csi_params->scramb_id != nr_csi_rs_info->csi_gold_init) {
|
||||
nr_csi_rs_info->csi_gold_init = csi_params->scramb_id;
|
||||
nr_init_csi_rs(&frame_parms, nr_csi_rs_info->nr_gold_csi_rs, csi_params->scramb_id);
|
||||
}
|
||||
|
||||
switch (csi_params.row) {
|
||||
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:
|
||||
@@ -75,7 +109,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = 0;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0] + (i<<2);
|
||||
}
|
||||
break;
|
||||
@@ -95,7 +129,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = 0;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
@@ -115,7 +149,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = 0;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
@@ -135,7 +169,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0] + (i<<1);
|
||||
}
|
||||
break;
|
||||
@@ -155,7 +189,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0 + i;
|
||||
loverline[i] = csi_params->symb_l0 + i;
|
||||
koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
@@ -174,7 +208,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
@@ -193,7 +227,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0 + (i>>1);
|
||||
loverline[i] = csi_params->symb_l0 + (i>>1);
|
||||
koverline[i] = k_n[i%2];
|
||||
}
|
||||
break;
|
||||
@@ -212,7 +246,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
@@ -231,7 +265,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
@@ -250,7 +284,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
@@ -269,7 +303,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0 + (i>>2);
|
||||
loverline[i] = csi_params->symb_l0 + (i>>2);
|
||||
koverline[i] = k_n[i%4];
|
||||
}
|
||||
break;
|
||||
@@ -288,7 +322,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
@@ -308,9 +342,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
if (i<6)
|
||||
loverline[i] = csi_params.symb_l0 + i/3;
|
||||
loverline[i] = csi_params->symb_l0 + i/3;
|
||||
else
|
||||
loverline[i] = csi_params.symb_l1 + i/9;
|
||||
loverline[i] = csi_params->symb_l1 + i/9;
|
||||
koverline[i] = k_n[i%3];
|
||||
}
|
||||
break;
|
||||
@@ -330,9 +364,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
if (i<3)
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
else
|
||||
loverline[i] = csi_params.symb_l1;
|
||||
loverline[i] = csi_params->symb_l1;
|
||||
koverline[i] = k_n[i%3];
|
||||
}
|
||||
break;
|
||||
@@ -351,7 +385,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
@@ -371,9 +405,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
if (i<8)
|
||||
loverline[i] = csi_params.symb_l0 + (i>>2);
|
||||
loverline[i] = csi_params->symb_l0 + (i>>2);
|
||||
else
|
||||
loverline[i] = csi_params.symb_l1 + (i/12);
|
||||
loverline[i] = csi_params->symb_l1 + (i/12);
|
||||
koverline[i] = k_n[i%4];
|
||||
}
|
||||
break;
|
||||
@@ -393,9 +427,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
if (i<4)
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
else
|
||||
loverline[i] = csi_params.symb_l1;
|
||||
loverline[i] = csi_params->symb_l1;
|
||||
koverline[i] = k_n[i%4];
|
||||
}
|
||||
break;
|
||||
@@ -414,17 +448,17 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params.symb_l0;
|
||||
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);
|
||||
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);
|
||||
printf(" row %d, n. of ports %d\n k' ",csi_params->row,ports);
|
||||
for (kp=0; kp<=kprime; kp++)
|
||||
printf("%d, ",kp);
|
||||
printf("l' ");
|
||||
@@ -441,7 +475,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
|
||||
|
||||
// setting the frequency density from its index
|
||||
switch (csi_params.freq_density) {
|
||||
switch (csi_params->freq_density) {
|
||||
|
||||
case 0:
|
||||
rho = 0.5;
|
||||
@@ -473,7 +507,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
#endif
|
||||
|
||||
// CDM group size from CDM type index
|
||||
switch (csi_params.cdm_type) {
|
||||
switch (csi_params->cdm_type) {
|
||||
|
||||
case 0:
|
||||
gs = 1;
|
||||
@@ -495,39 +529,31 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
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
|
||||
csi_start = csi_params.start_rb;
|
||||
if (csi_params.nr_of_rbs > (csi_params.bwp_start+csi_params.bwp_size-csi_start))
|
||||
csi_bw = csi_params.bwp_start+csi_params.bwp_size-csi_start;
|
||||
else
|
||||
csi_bw = csi_params.nr_of_rbs;
|
||||
|
||||
uint16_t csi_length;
|
||||
if (rho < 1) {
|
||||
if (csi_params.freq_density == 0)
|
||||
csi_length = (((csi_bw + csi_start)>>1)<<kprime)<<1;
|
||||
else
|
||||
csi_length = ((((csi_bw + csi_start)>>1)<<kprime)+1)<<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;
|
||||
}
|
||||
else
|
||||
csi_length = (((uint16_t) rho*(csi_bw + csi_start))<<kprime)<<1;
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
printf(" start rb %d, n. rbs %d, csi length %d\n",csi_start,csi_bw,csi_length);
|
||||
printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length);
|
||||
#endif
|
||||
|
||||
|
||||
// TRS
|
||||
if (csi_params.csi_type == 0) {
|
||||
if (csi_params->csi_type == 0) {
|
||||
// ???
|
||||
}
|
||||
|
||||
// NZP CSI RS
|
||||
if (csi_params.csi_type == 1) {
|
||||
if (csi_params->csi_type == 1) {
|
||||
// assuming amp is the amplitude of SSB channels
|
||||
switch (csi_params.power_control_offset_ss) {
|
||||
switch (csi_params->power_control_offset_ss) {
|
||||
case 0:
|
||||
beta = (amp*ONE_OVER_SQRT2_Q15)>>15;
|
||||
break;
|
||||
@@ -545,15 +571,15 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
for (lp=0; lp<=lprime; lp++){
|
||||
symb = csi_params.symb_l0;
|
||||
nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
|
||||
if ((csi_params.row == 5) || (csi_params.row == 7) || (csi_params.row == 11) || (csi_params.row == 13) || (csi_params.row == 16))
|
||||
nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
|
||||
if ((csi_params.row == 14) || (csi_params.row == 13) || (csi_params.row == 16) || (csi_params.row == 17)) {
|
||||
symb = csi_params.symb_l1;
|
||||
nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
|
||||
if ((csi_params.row == 13) || (csi_params.row == 16))
|
||||
nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
|
||||
symb = csi_params->symb_l0;
|
||||
nr_modulation(nr_gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
|
||||
if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16))
|
||||
nr_modulation(nr_gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
|
||||
if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) {
|
||||
symb = csi_params->symb_l1;
|
||||
nr_modulation(nr_gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
|
||||
if ((csi_params->row == 13) || (csi_params->row == 16))
|
||||
nr_modulation(nr_gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -561,14 +587,14 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
uint16_t start_sc = frame_parms.first_carrier_offset;
|
||||
|
||||
// resource mapping according to 38.211 7.4.1.5.3
|
||||
for (n=csi_start; n<(csi_start+csi_bw); 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 (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<size; ji++) { // loop over CDM groups
|
||||
for (int s=0 ; s<gs; s++) { // loop over each CDM group size
|
||||
p = s+j[ji]*gs; // port index
|
||||
for (kp=0; kp<=kprime; kp++) { // loop over frequency resource elements within a group
|
||||
k = (start_sc+(n*NR_NB_SC_PER_RB)+koverline[ji]+kp)%(frame_parms.ofdm_symbol_size); // frequency index of current resource element
|
||||
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
if (kp == 0)
|
||||
wf = 1;
|
||||
else
|
||||
@@ -591,24 +617,44 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
else
|
||||
wt = -1;
|
||||
}
|
||||
|
||||
// ZP CSI RS
|
||||
if (csi_params.csi_type == 2) {
|
||||
((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)] = 0;
|
||||
((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)] = 0;
|
||||
if (csi_params->csi_type == 2) {
|
||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0;
|
||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0;
|
||||
}
|
||||
else {
|
||||
((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
|
||||
((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
|
||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
|
||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (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*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)],
|
||||
((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)]);
|
||||
printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000,
|
||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)],
|
||||
((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nr_csi_rs_info->N_cdm_groups = size;
|
||||
nr_csi_rs_info->CDM_group_size = gs;
|
||||
nr_csi_rs_info->kprime = kprime;
|
||||
nr_csi_rs_info->lprime = lprime;
|
||||
nr_csi_rs_info->N_ports = ports;
|
||||
memcpy(nr_csi_rs_info->j,j,16*sizeof(uint8_t));
|
||||
memcpy(nr_csi_rs_info->koverline,koverline,16*sizeof(uint8_t));
|
||||
memcpy(nr_csi_rs_info->loverline,loverline,16*sizeof(uint8_t));
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "nr_csi_rs_info->N_ports = %d\n", nr_csi_rs_info->N_ports);
|
||||
LOG_I(NR_PHY, "nr_csi_rs_info->N_cdm_groups = %d\n", nr_csi_rs_info->N_cdm_groups);
|
||||
LOG_I(NR_PHY, "nr_csi_rs_info->CDM_group_size = %d\n", nr_csi_rs_info->CDM_group_size);
|
||||
LOG_I(NR_PHY, "nr_csi_rs_info->kprime = %d\n", nr_csi_rs_info->kprime);
|
||||
LOG_I(NR_PHY, "nr_csi_rs_info->lprime = %d\n", nr_csi_rs_info->lprime);
|
||||
for(int ji=0; ji<nr_csi_rs_info->N_cdm_groups; ji++) {
|
||||
LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, nr_csi_rs_info->j[ji], nr_csi_rs_info->koverline[ji], nr_csi_rs_info->loverline[ji]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -214,6 +214,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
#endif
|
||||
|
||||
stop_meas(&gNB->dlsch_layer_mapping_stats);
|
||||
|
||||
/// Resource mapping
|
||||
|
||||
// Non interleaved VRB to PRB mapping
|
||||
@@ -235,6 +236,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
for (int nl=0; nl<rel15->nrOfLayers; nl++) {
|
||||
|
||||
int dmrs_port = get_dmrs_port(nl,rel15->dmrsPorts);
|
||||
|
||||
// DMRS params for this dmrs port
|
||||
get_Wt(Wt, dmrs_port, dmrs_Type);
|
||||
get_Wf(Wf, dmrs_port, dmrs_Type);
|
||||
@@ -312,7 +314,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
|
||||
/* check if cuurent RE is PTRS RE*/
|
||||
is_ptrs_re = 0;
|
||||
if (ptrs_symbol)
|
||||
/* check for PTRS symbol and set flag for PTRS RE */
|
||||
if(ptrs_symbol){
|
||||
is_ptrs_re = is_ptrs_subcarrier(k,
|
||||
rel15->rnti,
|
||||
nl,
|
||||
@@ -322,6 +325,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
rel15->PTRSReOffset,
|
||||
start_sc,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
}
|
||||
/* Map DMRS Symbol */
|
||||
if ( (dmrs_symbol_map & (1 << l)) &&
|
||||
(k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
|
||||
@@ -337,6 +341,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
k_prime&=1;
|
||||
n+=(k_prime)?0:1;
|
||||
}
|
||||
/* Map PTRS Symbol */
|
||||
else if(is_ptrs_re){
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
|
||||
|
||||
@@ -337,9 +337,11 @@ void init_prach_ru_list(RU_t *ru);
|
||||
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
|
||||
uint8_t get_nr_prach_duration(uint8_t prach_format);
|
||||
|
||||
void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
|
||||
void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
|
||||
int32_t **dataF,
|
||||
int16_t amp,
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
|
||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||
int slot);
|
||||
|
||||
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
|
||||
|
||||
@@ -1545,7 +1545,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
|
||||
#endif
|
||||
LOG_D(PHY,"slot %d PUCCH2 cw_ML %d, metric %d dB\n",slot,cw_ML,corr_dB);
|
||||
LOG_D(PHY,"slot %d PUCCH2 cw_ML %d, metric %d dB\n", slot, cw_ML, corr_dB);
|
||||
|
||||
decodedPayload[0]=(uint64_t)cw_ML;
|
||||
}
|
||||
|
||||
@@ -282,4 +282,17 @@ short filt16_middle4[16] = {
|
||||
4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16_end[16] = {
|
||||
4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0};
|
||||
4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0};
|
||||
|
||||
// CSI-RS
|
||||
short filt24_start[24] = {
|
||||
12288,11605,10923,10240,9557,8875,8192,7509,6827,6144,5461,4779,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt24_end[24] = {
|
||||
4096,4779,5461,6144,6827,7509,8192,8875,9557,10240,10923,11605,
|
||||
16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384};
|
||||
|
||||
short filt24_middle[24] = {
|
||||
4096,4779,5461,6144,6827,7509,8192,8875,9557,10240,10923,11605,
|
||||
12288,11605,10923,10240,9557,8875,8192,7509,6827,6144,5461,4779};
|
||||
@@ -193,4 +193,10 @@ extern short filt8_end[8];
|
||||
extern short filt16_start[16];
|
||||
extern short filt16_middle4[16];
|
||||
extern short filt16_end[16];
|
||||
|
||||
/*CSI-RS*/
|
||||
extern short filt24_start[24];
|
||||
extern short filt24_end[24];
|
||||
extern short filt24_middle[24];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : csi_rx.c
|
||||
*
|
||||
* MODULE :
|
||||
*
|
||||
* DESCRIPTION : function to receive the channel state information
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nr_transport_proto_ue.h"
|
||||
#include "PHY/phy_extern_nr_ue.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||
|
||||
|
||||
//#define NR_CSIRS_DEBUG
|
||||
|
||||
bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol) {
|
||||
|
||||
bool ret = false;
|
||||
|
||||
// 38.211-Table 7.4.1.5.3-1: CSI-RS locations within a slot
|
||||
switch(csirs_config_pdu.row){
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 6:
|
||||
case 9:
|
||||
if(symbol == csirs_config_pdu.symb_l0) {
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
if(symbol == csirs_config_pdu.symb_l0 || symbol == (csirs_config_pdu.symb_l0+1) ) {
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
case 14:
|
||||
case 16:
|
||||
case 17:
|
||||
if(symbol == csirs_config_pdu.symb_l0 || symbol == (csirs_config_pdu.symb_l0+1) ||
|
||||
symbol == csirs_config_pdu.symb_l1 || symbol == (csirs_config_pdu.symb_l1+1)) {
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
case 18:
|
||||
if(symbol == csirs_config_pdu.symb_l0 || symbol == (csirs_config_pdu.symb_l0+1) || symbol == (csirs_config_pdu.symb_l0+2) ) {
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0==1, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csirs_config_pdu.row);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
||||
int32_t **csi_rs_received_signal) {
|
||||
|
||||
int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
|
||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||
memset(csi_rs_received_signal[ant_rx], 0, frame_parms->samples_per_frame_wCP*sizeof(int32_t));
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
|
||||
// for freq density 0.5 checks if even or odd RB
|
||||
if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) {
|
||||
for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) {
|
||||
|
||||
// loop over frequency resource elements within a group
|
||||
for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
|
||||
|
||||
uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+nr_csi_rs_info->koverline[cdm_id] + kp) % frame_parms->ofdm_symbol_size;
|
||||
|
||||
// loop over time resource elements within a group
|
||||
for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) {
|
||||
uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
|
||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||
int16_t *rx_signal = (int16_t*)&rxdataF[ant_rx][symbol_offset];
|
||||
int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
rx_csi_rs_signal[k<<1] = rx_signal[k<<1];
|
||||
rx_csi_rs_signal[(k<<1)+1] = rx_signal[(k<<1)+1];
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
||||
uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
|
||||
int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||
LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
|
||||
symb,
|
||||
k,
|
||||
port_tx+3000,
|
||||
tx_csi_rs_signal[k<<1],
|
||||
tx_csi_rs_signal[(k<<1)+1],
|
||||
ant_rx,
|
||||
rx_csi_rs_signal[k<<1],
|
||||
rx_csi_rs_signal[(k<<1)+1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) {
|
||||
uint64_t sum_x = 0;
|
||||
uint64_t sum_x2 = 0;
|
||||
uint16_t size = 0;
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||
continue;
|
||||
}
|
||||
sum_x = sum_x + x[rb-csirs_config_pdu->start_rb];
|
||||
sum_x2 = sum_x2 + x[rb]*x[rb-csirs_config_pdu->start_rb];
|
||||
size++;
|
||||
}
|
||||
return sum_x2/size - (sum_x/size)*(sum_x/size);
|
||||
}
|
||||
|
||||
int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
nr_csi_rs_info_t *nr_csi_rs_info,
|
||||
int32_t **csi_rs_generated_signal,
|
||||
int32_t **csi_rs_received_signal,
|
||||
int32_t ***csi_rs_estimated_channel_freq,
|
||||
uint32_t *noise_power) {
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
||||
*noise_power = 0;
|
||||
|
||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||
|
||||
/// LS channel estimation
|
||||
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
memset(nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||
}
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
|
||||
// for freq density 0.5 checks if even or odd RB
|
||||
if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) {
|
||||
for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) {
|
||||
|
||||
uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
|
||||
|
||||
// loop over frequency resource elements within a group
|
||||
for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
|
||||
|
||||
uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
uint16_t k = kinit + nr_csi_rs_info->koverline[cdm_id] + kp;
|
||||
|
||||
// loop over time resource elements within a group
|
||||
for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) {
|
||||
uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
|
||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||
int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||
int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||
|
||||
int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[k<<1] + (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[(k<<1)+1])>>nr_csi_rs_info->csi_rs_generated_signal_bits);
|
||||
int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[(k<<1)+1] - (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[k<<1])>>nr_csi_rs_info->csi_rs_generated_signal_bits);
|
||||
|
||||
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions
|
||||
// for the sake of optimizing the memory used.
|
||||
csi_rs_ls_estimated_channel[kinit<<1] += csi_rs_ls_estimated_channel_re;
|
||||
csi_rs_ls_estimated_channel[(kinit<<1)+1] += csi_rs_ls_estimated_channel_im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
|
||||
if(!is_csi_rs_in_symbol(*csirs_config_pdu,symb)) {
|
||||
continue;
|
||||
}
|
||||
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
|
||||
LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k);
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||
int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||
int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||
printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ",
|
||||
port_tx+3000, ant_rx,
|
||||
tx_csi_rs_signal[k<<1], tx_csi_rs_signal[(k<<1)+1],
|
||||
rx_csi_rs_signal[k<<1], rx_csi_rs_signal[(k<<1)+1],
|
||||
csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Channel interpolation
|
||||
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||
}
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
|
||||
// for freq density 0.5 checks if even or odd RB
|
||||
if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
|
||||
if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
|
||||
multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16, 24);
|
||||
} else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) ||
|
||||
(rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case
|
||||
multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
||||
} else { // Middle case
|
||||
multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Power noise estimation
|
||||
uint16_t noise_real[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs];
|
||||
uint16_t noise_imag[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs];
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||
continue;
|
||||
}
|
||||
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
|
||||
noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[0]-csi_rs_estimated_channel16[0]);
|
||||
noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[1]-csi_rs_estimated_channel16[1]);
|
||||
}
|
||||
}
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
*noise_power += (calc_power_csirs(noise_real[ant_rx][port_tx], csirs_config_pdu) + calc_power_csirs(noise_imag[ant_rx][port_tx],csirs_config_pdu));
|
||||
}
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
|
||||
int rb = k >= frame_parms->first_carrier_offset ?
|
||||
(k - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB :
|
||||
(k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB;
|
||||
LOG_I(NR_PHY, "(k = %4d) |\t", k);
|
||||
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
|
||||
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0];
|
||||
printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
|
||||
port_tx+3000, ant_rx,
|
||||
csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1],
|
||||
csi_rs_estimated_channel16[k<<1], csi_rs_estimated_channel16[(k<<1)+1],
|
||||
rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb],
|
||||
rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
*noise_power /= (frame_parms->nb_antennas_rx*nr_csi_rs_info->N_ports);
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
|
||||
|
||||
if(!ue->csirs_vars[gNB_id]->active) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu;
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->subcarrier_spacing = %i\n", csirs_config_pdu->subcarrier_spacing);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->cyclic_prefix = %i\n", csirs_config_pdu->cyclic_prefix);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->start_rb = %i\n", csirs_config_pdu->start_rb);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->nr_of_rbs = %i\n", csirs_config_pdu->nr_of_rbs);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->csi_type = %i (0:TRS, 1:CSI-RS NZP, 2:CSI-RS ZP)\n", csirs_config_pdu->csi_type);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->row = %i\n", csirs_config_pdu->row);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->freq_domain = %i\n", csirs_config_pdu->freq_domain);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->symb_l0 = %i\n", csirs_config_pdu->symb_l0);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->symb_l1 = %i\n", csirs_config_pdu->symb_l1);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->cdm_type = %i\n", csirs_config_pdu->cdm_type);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->freq_density = %i (0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three)\n", csirs_config_pdu->freq_density);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->scramb_id = %i\n", csirs_config_pdu->scramb_id);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset = %i\n", csirs_config_pdu->power_control_offset);
|
||||
LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset_ss = %i\n", csirs_config_pdu->power_control_offset_ss);
|
||||
#endif
|
||||
|
||||
nr_generate_csi_rs(ue->frame_parms,
|
||||
ue->nr_csi_rs_info->csi_rs_generated_signal,
|
||||
AMP,
|
||||
ue->nr_csi_rs_info,
|
||||
(nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu,
|
||||
proc->nr_slot_rx);
|
||||
|
||||
nr_get_csi_rs_signal(ue,
|
||||
proc,
|
||||
csirs_config_pdu,
|
||||
ue->nr_csi_rs_info,
|
||||
ue->nr_csi_rs_info->csi_rs_received_signal);
|
||||
|
||||
nr_csi_rs_channel_estimation(ue,
|
||||
proc,
|
||||
csirs_config_pdu,
|
||||
ue->nr_csi_rs_info,
|
||||
ue->nr_csi_rs_info->csi_rs_generated_signal,
|
||||
ue->nr_csi_rs_info->csi_rs_received_signal,
|
||||
ue->nr_csi_rs_info->csi_rs_estimated_channel_freq,
|
||||
ue->nr_csi_rs_info->noise_power);
|
||||
return 0;
|
||||
}
|
||||
@@ -362,6 +362,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
||||
}
|
||||
|
||||
nr_init_csi_rs(fp, ue->nr_csi_rs_info->nr_gold_csi_rs, fp->Nid_cell);
|
||||
|
||||
// initialize the pusch dmrs
|
||||
for (int i=0; i<NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_ulsch[i]=fp->Nid_cell;
|
||||
|
||||
@@ -763,6 +763,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/// SRS variables
|
||||
nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX];
|
||||
|
||||
/// CSI-RS variables
|
||||
nr_csi_rs_info_t *nr_csi_rs_info;
|
||||
|
||||
uint8_t pbch_configured;
|
||||
char gNB_generate_rar;
|
||||
|
||||
@@ -794,9 +797,6 @@ typedef struct PHY_VARS_gNB_s {
|
||||
// Mask of occupied RBs, per symbol and PRB
|
||||
uint32_t rb_mask_ul[14][9];
|
||||
|
||||
/// CSI RS sequence
|
||||
uint32_t ***nr_gold_csi_rs;
|
||||
|
||||
/// Indicator set to 0 after first SR
|
||||
uint8_t first_sr[NUMBER_OF_NR_SR_MAX];
|
||||
|
||||
@@ -833,7 +833,6 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/// counter to average prach energh over first 100 prach opportunities
|
||||
int prach_energy_counter;
|
||||
|
||||
int csi_gold_init;
|
||||
int pdcch_gold_init;
|
||||
int pdsch_gold_init[2];
|
||||
int pusch_gold_init[2];
|
||||
|
||||
@@ -594,6 +594,16 @@ typedef struct {
|
||||
fapi_nr_ul_config_prach_pdu prach_pdu;
|
||||
} NR_UE_PRACH;
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
fapi_nr_dl_config_csiim_pdu_rel15_t csiim_config_pdu;
|
||||
} NR_UE_CSI_IM;
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu;
|
||||
} NR_UE_CSI_RS;
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
fapi_nr_ul_config_srs_pdu srs_config_pdu;
|
||||
@@ -707,6 +717,8 @@ typedef struct {
|
||||
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_CSI_IM *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_CSI_RS *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_SRS *srs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_PUCCH *pucch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_LAYERS>4 ? 2:1]; // two RxTx Threads
|
||||
@@ -865,6 +877,9 @@ typedef struct {
|
||||
/// SRS variables
|
||||
nr_srs_info_t *nr_srs_info;
|
||||
|
||||
/// CSI-RS variables
|
||||
nr_csi_rs_info_t *nr_csi_rs_info;
|
||||
|
||||
//#if defined(UPGRADE_RAT_NR)
|
||||
#if 1
|
||||
SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#define NR_MAX_NB_RBG 18
|
||||
|
||||
#define NR_MAX_NB_LAYERS 4 // 8
|
||||
#define NR_MAX_NB_PORTS 32
|
||||
|
||||
#define NR_MAX_NB_HARQ_PROCESSES 16
|
||||
|
||||
@@ -251,6 +252,25 @@ typedef struct {
|
||||
uint32_t *noise_power;
|
||||
} nr_srs_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t N_cdm_groups;
|
||||
uint8_t CDM_group_size;
|
||||
uint8_t kprime;
|
||||
uint8_t lprime;
|
||||
uint8_t N_ports;
|
||||
uint8_t j[16];
|
||||
uint8_t koverline[16];
|
||||
uint8_t loverline[16];
|
||||
uint16_t csi_gold_init;
|
||||
uint32_t ***nr_gold_csi_rs;
|
||||
uint8_t csi_rs_generated_signal_bits;
|
||||
int32_t **csi_rs_generated_signal;
|
||||
int32_t **csi_rs_received_signal;
|
||||
int32_t ***csi_rs_ls_estimated_channel;
|
||||
int32_t ***csi_rs_estimated_channel_freq;
|
||||
uint32_t *noise_power;
|
||||
} nr_csi_rs_info_t;
|
||||
|
||||
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
|
||||
|
||||
typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp);
|
||||
|
||||
@@ -178,8 +178,8 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
|
||||
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;
|
||||
nr_generate_csi_rs(gNB, AMP, csi_params, slot);
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
|
||||
nr_generate_csi_rs(gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot);
|
||||
csirs->active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,6 +373,7 @@ int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx);
|
||||
|
||||
int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp);
|
||||
int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp);
|
||||
bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol);
|
||||
|
||||
/*! \brief This function prepares the dl indication to pass to the MAC
|
||||
@param
|
||||
@@ -427,6 +428,9 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
|
||||
NR_UE_PDCCH_CONFIG *phy_pdcch_config,
|
||||
int n_ss);
|
||||
|
||||
int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
|
||||
|
||||
int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
|
||||
|
||||
const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH"};
|
||||
const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM"};
|
||||
const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"};
|
||||
queue_t nr_rx_ind_queue;
|
||||
queue_t nr_crc_ind_queue;
|
||||
@@ -360,12 +360,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
NR_UE_DLSCH_t *dlsch0 = NULL;
|
||||
NR_UE_ULSCH_t *ulsch = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0];
|
||||
NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
|
||||
NR_UE_CSI_IM *csiim_vars = PHY_vars_UE_g[module_id][cc_id]->csiim_vars[0];
|
||||
NR_UE_CSI_RS *csirs_vars = PHY_vars_UE_g[module_id][cc_id]->csirs_vars[0];
|
||||
NR_UE_PDCCH_CONFIG *phy_pdcch_config = NULL;
|
||||
|
||||
if(scheduled_response->dl_config != NULL){
|
||||
fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu;
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config;
|
||||
fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu;
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu;
|
||||
|
||||
for (int i = 0; i < dl_config->number_pdus; ++i){
|
||||
AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
|
||||
@@ -387,10 +391,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
LOG_D(PHY,"Number of DCI SearchSpaces %d\n",phy_pdcch_config->nb_search_space);
|
||||
break;
|
||||
case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
|
||||
LOG_I(PHY,"Received CSI-IM PDU at FAPI\n");
|
||||
csiim_config_pdu = &dl_config->dl_config_list[i].csiim_config_pdu.csiim_config_rel15;
|
||||
memcpy((void*)&(csiim_vars->csiim_config_pdu), (void*)csiim_config_pdu, sizeof(fapi_nr_dl_config_csiim_pdu_rel15_t));
|
||||
csirs_vars->active = true;
|
||||
break;
|
||||
case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
|
||||
LOG_I(PHY,"Received CSI-RS PDU at FAPI\n");
|
||||
csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15;
|
||||
memcpy((void*)&(csirs_vars->csirs_config_pdu), (void*)csirs_config_pdu, sizeof(fapi_nr_dl_config_csirs_pdu_rel15_t));
|
||||
csirs_vars->active = true;
|
||||
break;
|
||||
case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH:
|
||||
dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
|
||||
|
||||
@@ -1379,7 +1379,6 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t gNB_id,
|
||||
@@ -1681,6 +1680,23 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
|
||||
}
|
||||
|
||||
// do procedures for CSI-IM
|
||||
if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) {
|
||||
nr_ue_csi_im_procedures(ue, proc, gNB_id);
|
||||
ue->csiim_vars[gNB_id]->active = 0;
|
||||
}
|
||||
|
||||
// do procedures for CSI-RS
|
||||
if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) {
|
||||
for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
|
||||
if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) {
|
||||
nr_slot_fep(ue, proc, symb, nr_slot_rx);
|
||||
}
|
||||
}
|
||||
nr_ue_csi_rs_procedures(ue, proc, gNB_id);
|
||||
ue->csirs_vars[gNB_id]->active = 0;
|
||||
}
|
||||
|
||||
start_meas(&ue->generic_stat);
|
||||
|
||||
if (nr_slot_rx==9) {
|
||||
|
||||
@@ -613,7 +613,7 @@ int main(int argc, char **argv)
|
||||
//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-G Offset of samples to read from file (0 default)\n");
|
||||
printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");
|
||||
printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");
|
||||
printf("-M Multiple SSB positions in burst\n");
|
||||
printf("-N Nid_cell\n");
|
||||
printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
|
||||
Reference in New Issue
Block a user