Commit 8b0409d3 authored by rmagueta's avatar rmagueta

Channel estimation based on CSI-RS and interpolation working for a gNB with 2 antenna ports

parent e07f32f1
......@@ -130,7 +130,7 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
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,%3d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
symb,
k,
port_tx+3000,
......@@ -150,6 +150,34 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
return 0;
}
int get_wf(int kp, int s) {
int wf = 0;
if (kp == 0) {
wf = 1;
} else {
wf = -2*(s%2)+1;
}
return wf;
}
int get_wt(int lp, int s) {
int wt = 0;
if (s < 2) {
wt = 1;
} else if (s < 4) {
wt = -2*(lp%2)+1;
} else if (s < 6) {
wt = -2*(lp/2)+1;
} else {
if ((lp == 0) || (lp == 3)) {
wt = 1;
} else {
wt = -1;
}
}
return wt;
}
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,
......@@ -223,8 +251,6 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
}
int16_t ls_estimated[2];
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
......@@ -232,52 +258,55 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
continue;
}
// TODO: Extend this to multiple antenna ports
int cdm_id = 0;
int s = 0;
int kp = 0;
int lp = 0;
int16_t ls_estimated[nr_csi_rs_info->N_ports][2];
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
memset(ls_estimated[port_tx], 0, 2*sizeof(int16_t));
}
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;
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;
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 *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][symbol_offset];
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
ls_estimated[0] = (int16_t) csi_rs_ls_estimated_channel[k<<1];
ls_estimated[1] = (int16_t) csi_rs_ls_estimated_channel[(k<<1)+1];
int w = get_wf(kp,s)*get_wt(lp,s);
ls_estimated[port_tx][0] += (int16_t) w*csi_rs_ls_estimated_channel[k<<1];
ls_estimated[port_tx][1] += (int16_t) w*csi_rs_ls_estimated_channel[(k<<1)+1];
}
}
}
}
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_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, ls_estimated, csi_rs_estimated_channel16, 24);
multadd_real_vector_complex_scalar(filt24_start, ls_estimated[port_tx], 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, ls_estimated, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
multadd_real_vector_complex_scalar(filt24_end, ls_estimated[port_tx], csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
} else { // Middle case
multadd_real_vector_complex_scalar(filt24_middle, ls_estimated, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
multadd_real_vector_complex_scalar(filt24_middle, ls_estimated[port_tx], csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
}
}
}
#ifdef NR_CSIRS_DEBUG
int cdm_id = 0;
int s = 0;
int lp = 0;
uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
uint64_t symbol_offset = csirs_config_pdu->symb_l0*frame_parms->ofdm_symbol_size;
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
LOG_I(NR_PHY, "(k = %4d) |\t", k);
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
printf("Channel port_tx %d --> ant_rx %d : ", port_tx+3000, ant_rx);
int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][symbol_offset];
printf("ls (%4d,%4d), ", csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1]);
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0];
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
LOG_I(NR_PHY, "(%4d) |\tls (%4d,%4d)\tint (%4d,%4d)\n",
k,
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]);
printf("int (%4d,%4d) | ", csi_rs_estimated_channel16[k<<1], csi_rs_estimated_channel16[(k<<1)+1]);
}
printf("\n");
}
#endif
......
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