Merge remote-tracking branch 'origin/develop' into NR_BWP_config

This commit is contained in:
francescomani
2022-08-03 10:59:12 +02:00
69 changed files with 2101 additions and 1332 deletions
+11 -11
View File
@@ -596,20 +596,20 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
// 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");
gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
gNB->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **));
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n");
for (int slot=0; slot<fp->slots_per_frame; 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);
gNB->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
AssertFatal(gNB->nr_csi_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++) {
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->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t));
AssertFatal(gNB->nr_csi_info->nr_gold_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->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);
gNB->nr_csi_info->csi_gold_init = cfg->cell_config.phy_cell_id.value;
nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_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));
@@ -760,14 +760,14 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
}
free_and_zero(pusch_dmrs);
uint32_t ***nr_gold_csi_rs = gNB->nr_csi_rs_info->nr_gold_csi_rs;
uint32_t ***nr_gold_csi_rs = gNB->nr_csi_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(nr_gold_csi_rs[slot][symb]);
free_and_zero(nr_gold_csi_rs[slot]);
}
free_and_zero(nr_gold_csi_rs);
free_and_zero(gNB->nr_csi_rs_info);
free_and_zero(gNB->nr_csi_info);
for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
free_and_zero(gNB->nr_srs_info[id]);
+17 -57
View File
@@ -34,19 +34,6 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/MODULATION/nr_modulation.h"
#if 0
void phy_config_harq_ue(module_id_t Mod_id,
int CC_id,
uint8_t gNB_id,
uint16_t max_harq_tx) {
int num_of_threads,num_of_code_words;
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
for (num_of_threads=0; num_of_threads<RX_NB_TH_MAX; num_of_threads++)
for (num_of_code_words=0; num_of_code_words<NR_MAX_NB_CODEWORDS; num_of_code_words++)
phy_vars_ue->ulsch[num_of_threads][gNB_id][num_of_code_words]->Mlimit = max_harq_tx;
}
#endif
extern uint16_t beta_cqi[16];
@@ -159,7 +146,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
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;
int i, 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);
@@ -347,33 +334,20 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
// 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");
ue->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
ue->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **));
AssertFatal(ue->nr_csi_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);
ue->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
AssertFatal(ue->nr_csi_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_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t));
AssertFatal(ue->nr_csi_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 *) );
ue->nr_csi_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_csi_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
}
ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
@@ -470,39 +444,25 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
}
}
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
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]);
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]);
}
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal);
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_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_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);
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs);
free_and_zero(ue->nr_csi_info);
free_and_zero(ue->nr_srs_info);
@@ -151,9 +151,9 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
NR_gNB_COMMON *common_vars = &gNB->common_vars;
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
int rb, nb_symb[275]={0};
memset(measurements->n0_subband_power, 0, sizeof(measurements->n0_subband_power));
for (int s=first_symb;s<(first_symb+num_symb);s++) {
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
if (s==first_symb /*&& ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0)*/) {
@@ -168,7 +168,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
int offset = offset0 + (s*frame_parms->ofdm_symbol_size);
int32_t *ul_ch = &common_vars->rxdataF[aarx][offset];
int len = 12;
if (((frame_parms->N_RB_UL&1) == 1) &&
if (((frame_parms->N_RB_UL&1) == 1) &&
(rb==(frame_parms->N_RB_UL>>1))) {
len=6;
}
@@ -1115,7 +1115,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12;
const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3;
const uint8_t n_noise_estimates = frame_parms->nb_antennas_rx*srs_symbols_per_rb;
const uint8_t n_noise_est = frame_parms->nb_antennas_rx * srs_symbols_per_rb;
uint8_t count_estimates = 0;
uint64_t sum_re = 0;
uint64_t sum_re2 = 0;
@@ -1138,9 +1138,9 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx];
count_estimates++;
if (count_estimates == n_noise_estimates) {
noise_power_per_rb[rb] = sum_re2/n_noise_estimates - (sum_re/n_noise_estimates)*(sum_re/n_noise_estimates) +
sum_im2/n_noise_estimates - (sum_im/n_noise_estimates)*(sum_im/n_noise_estimates);
if (count_estimates == n_noise_est) {
noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) +
sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1);
snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB;
count_estimates = 0;
sum_re = 0;
+1 -1
View File
@@ -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(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
void nr_init_csi_rs(const 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);
+1 -1
View File
@@ -68,6 +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);
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
#endif
+47 -37
View File
@@ -27,7 +27,7 @@
//#define NR_CSIRS_DEBUG
void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
void nr_init_csi_rs(const 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;
@@ -43,12 +43,20 @@ void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
}
}
void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
int32_t **dataF,
int16_t amp,
nr_csi_rs_info_t *nr_csi_rs_info,
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
int slot){
const int16_t amp,
nr_csi_info_t *nr_csi_info,
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
const int slot,
uint8_t *N_cdm_groups,
uint8_t *CDM_group_size,
uint8_t *k_prime,
uint8_t *l_prime,
uint8_t *N_ports,
uint8_t *j_cdm,
uint8_t *k_overline,
uint8_t *l_overline) {
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
@@ -67,11 +75,11 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
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];
int dataF_offset = slot*frame_parms->samples_per_slot_wCP;
uint32_t **nr_gold_csi_rs = nr_csi_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)));
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, p, k, l, mprime, na, kpn;
uint8_t size, ports, kprime, lprime, i, gs;
@@ -81,14 +89,14 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
uint8_t fi = 0;
double rho, alpha;
uint32_t beta = amp;
nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp);
nr_csi_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 != 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);
if (csi_params->scramb_id != nr_csi_info->csi_gold_init) {
nr_csi_info->csi_gold_init = csi_params->scramb_id;
nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id);
}
switch (csi_params->row) {
@@ -584,7 +592,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
}
}
uint16_t start_sc = frame_parms.first_carrier_offset;
uint16_t start_sc = frame_parms->first_carrier_offset;
// resource mapping according to 38.211 7.4.1.5.3
for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) {
@@ -593,7 +601,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
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
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
if (kp == 0)
wf = 1;
@@ -620,17 +628,17 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
// ZP CSI RS
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;
((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*)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;
((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*)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)]);
((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
}
}
@@ -638,23 +646,25 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
}
}
}
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));
if (N_cdm_groups) *N_cdm_groups = size;
if (CDM_group_size) *CDM_group_size = gs;
if (k_prime) *k_prime = kprime;
if (l_prime) *l_prime = lprime;
if (N_ports) *N_ports = ports;
if (j_cdm) memcpy(j_cdm,j,16*sizeof(uint8_t));
if (k_overline) memcpy(k_overline,koverline,16*sizeof(uint8_t));
if (l_overline) memcpy(l_overline,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]);
if (N_ports) LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports);
if (N_cdm_groups) LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups);
if (CDM_group_size) LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size);
if (k_prime) LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime);
if (l_prime) LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime);
if (N_cdm_groups) {
for(int ji=0; ji<*N_cdm_groups; ji++) {
LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]);
}
}
#endif
}
+9 -9
View File
@@ -111,9 +111,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// DMRS length is per OFDM symbol
uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d),Scrambling_Id %d,ScramblingRNTI %x,PayloadSizeBits %d\n",
rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
if (dci_pdu->RNTI != 0xFFFF)
LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n",
rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
/// DMRS QPSK modulation
@@ -122,11 +123,11 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_PDCCH_DMRS
if(dci_pdu->RNTI!=0xFFFF) {
for (int i=0; i<dmrs_length>>1; i++)
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
}
if(dci_pdu->RNTI!=0xFFFF) {
for (int i=0; i<dmrs_length>>1; i++)
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]);
}
#endif
}
@@ -265,7 +266,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx,
int16_t amp,
NR_DL_FRAME_PARMS *frame_parms) {
for (int i=0; i<msgTx->num_ul_pdcch; i++)
nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
for (int i=0; i<msgTx->num_dl_pdcch; i++)
@@ -123,7 +123,6 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
dlsch->Kmimo = Kmimo;
dlsch->Mdlharq = Mdlharq;
dlsch->Mlimit = 4;
dlsch->Nsoft = Nsoft;
int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer
+13 -5
View File
@@ -337,12 +337,20 @@ 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(NR_DL_FRAME_PARMS frame_parms,
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
int32_t **dataF,
int16_t amp,
nr_csi_rs_info_t *nr_csi_rs_info,
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
int slot);
const int16_t amp,
nr_csi_info_t *nr_csi_info,
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
const int slot,
uint8_t *N_cdm_groups,
uint8_t *CDM_group_size,
uint8_t *k_prime,
uint8_t *l_prime,
uint8_t *N_ports,
uint8_t *j_cdm,
uint8_t *k_overline,
uint8_t *l_overline);
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
+13 -5
View File
@@ -68,12 +68,20 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
ulsch->rnti = ulsch_pdu->rnti;
//ulsch->rnti_type;
ulsch->harq_mask |= 1<<harq_pid;
ulsch->harq_process_id[slot] = harq_pid;
ulsch->harq_processes[harq_pid]->frame=frame;
ulsch->harq_processes[harq_pid]->slot=slot;
ulsch->harq_processes[harq_pid]->handled= 0;
ulsch->harq_processes[harq_pid]->status= NR_ACTIVE;
NR_UL_gNB_HARQ_t *harq = ulsch->harq_processes[harq_pid];
harq->frame=frame;
harq->slot=slot;
harq->handled = 0;
harq->status= NR_ACTIVE;
harq->new_rx = harq->ndi != ulsch_pdu->pusch_data.new_data_indicator;
if (harq->new_rx) {
harq->ndi = ulsch_pdu->pusch_data.new_data_indicator;
harq->round = 0;
} else {
harq->round++;
}
memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
@@ -101,7 +101,6 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t));
ulsch->max_ldpc_iterations = max_ldpc_iterations;
ulsch->Mlimit = 4;
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
@@ -136,10 +135,8 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
ulsch->rnti_type = 0;
ulsch->cyclicShift = 0;
ulsch->cooperation_flag = 0;
ulsch->Mlimit = 0;
ulsch->max_ldpc_iterations = 0;
ulsch->last_iteration_cnt = 0;
for (i=0;i<NR_MAX_SLOTS_PER_FRAME;i++) ulsch->harq_process_id[i] = 0;
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
if (ulsch->harq_processes[i]){
+2 -2
View File
@@ -331,8 +331,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n];
corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
}
corr[aa][l].r >>= 31;
corr[aa][l].i >>= 31;
corr[aa][l].r >>= 31;
corr[aa][l].i >>= 31;
}
}
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
+678 -89
View File
@@ -33,16 +33,103 @@
#include <stdlib.h>
#include <string.h>
#include "executables/nr-softmodem-common.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"
// 10*log10(pow(2,30))
#define pow_2_30_dB 90
//#define NR_CSIRS_DEBUG
//#define NR_CSIIM_DEBUG
bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol) {
void nr_det_A_MF_2x2(int32_t *a_mf_00,
int32_t *a_mf_01,
int32_t *a_mf_10,
int32_t *a_mf_11,
int32_t *det_fin,
const unsigned short nb_rb) {
int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
__m128i ad_re_128, bc_re_128, det_re_128;
__m128i *a_mf_00_128 = (__m128i *)a_mf_00;
__m128i *a_mf_01_128 = (__m128i *)a_mf_01;
__m128i *a_mf_10_128 = (__m128i *)a_mf_10;
__m128i *a_mf_11_128 = (__m128i *)a_mf_11;
__m128i *det_fin_128 = (__m128i *)det_fin;
for (int rb = 0; rb<3*nb_rb; rb++) {
//complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d)
//The imag part is often zero, we compute only the real part
ad_re_128 = _mm_sign_epi16(a_mf_00_128[0],*(__m128i*)&nr_conjug2[0]);
ad_re_128 = _mm_madd_epi16(ad_re_128,a_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1
//complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c)
//The imag part is often zero, we compute only the real part
bc_re_128 = _mm_sign_epi16(a_mf_01_128[0],*(__m128i*)&nr_conjug2[0]);
bc_re_128 = _mm_madd_epi16(bc_re_128,a_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1
det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
//det in Q30 format
det_fin_128[0] = _mm_abs_epi32(det_re_128);
det_fin_128+=1;
a_mf_00_128+=1;
a_mf_01_128+=1;
a_mf_10_128+=1;
a_mf_11_128+=1;
}
_mm_empty();
_m_empty();
}
void nr_squared_matrix_element(int32_t *a,
int32_t *a_sq,
const unsigned short nb_rb) {
__m128i *a_128 = (__m128i *)a;
__m128i *a_sq_128 = (__m128i *)a_sq;
for (int rb=0; rb<3*nb_rb; rb++) {
a_sq_128[0] = _mm_madd_epi16(a_128[0], a_128[0]);
a_sq_128+=1;
a_128+=1;
}
_mm_empty();
_m_empty();
}
void nr_numer_2x2(int32_t *a_00_sq,
int32_t *a_01_sq,
int32_t *a_10_sq,
int32_t *a_11_sq,
int32_t *num_fin,
const unsigned short nb_rb) {
__m128i *a_00_sq_128 = (__m128i *)a_00_sq;
__m128i *a_01_sq_128 = (__m128i *)a_01_sq;
__m128i *a_10_sq_128 = (__m128i *)a_10_sq;
__m128i *a_11_sq_128 = (__m128i *)a_11_sq;
__m128i *num_fin_128 = (__m128i *)num_fin;
for (int rb=0; rb<3*nb_rb; rb++) {
__m128i sq_a_plus_sq_d_128 = _mm_add_epi32(a_00_sq_128[0], a_11_sq_128[0]);
__m128i sq_b_plus_sq_c_128 = _mm_add_epi32(a_01_sq_128[0], a_10_sq_128[0]);
num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128);
num_fin_128+=1;
a_00_sq_128+=1;
a_01_sq_128+=1;
a_10_sq_128+=1;
a_11_sq_128+=1;
}
_mm_empty();
_m_empty();
}
bool is_csi_rs_in_symbol(const fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, const int symbol) {
bool ret = false;
@@ -90,17 +177,27 @@ bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, i
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) {
int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const nr_csi_info_t *nr_csi_info,
const uint8_t N_cdm_groups,
const uint8_t CDM_group_size,
const uint8_t k_prime,
const uint8_t l_prime,
const uint8_t *j_cdm,
const uint8_t *k_overline,
const uint8_t *l_overline,
int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
uint32_t *rsrp,
int *rsrp_dBm) {
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;
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
uint16_t meas_count = 0;
uint32_t rsrp_sum = 0;
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++) {
@@ -109,36 +206,41 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
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++) {
for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) {
for (int s = 0; s < CDM_group_size; s++) {
// loop over frequency resource elements within a group
for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
for (int kp = 0; kp <= k_prime; 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;
uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+k_overline[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];
for (int lp = 0; lp <= l_prime; lp++) {
uint16_t symb = lp + l_overline[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];
c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset];
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
rx_csi_rs_signal[k].r = rx_signal[k].r;
rx_csi_rs_signal[k].i = rx_signal[k].i;
rsrp_sum += (((int32_t)(rx_csi_rs_signal[k].r)*rx_csi_rs_signal[k].r) +
((int32_t)(rx_csi_rs_signal[k].i)*rx_csi_rs_signal[k].i));
meas_count++;
#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];
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_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],
tx_csi_rs_signal[k].r,
tx_csi_rs_signal[k].i,
ant_rx,
rx_csi_rs_signal[k<<1],
rx_csi_rs_signal[(k<<1)+1]);
rx_csi_rs_signal[k].r,
rx_csi_rs_signal[k].i);
#endif
}
}
@@ -147,10 +249,19 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
}
}
*rsrp = rsrp_sum/meas_count;
*rsrp_dBm = dB_fixed(*rsrp) + 30 - pow_2_30_dB
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm);
#endif
return 0;
}
uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) {
uint32_t calc_power_csirs(const uint16_t *x, const 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;
@@ -165,25 +276,38 @@ uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csir
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,
int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const nr_csi_info_t *nr_csi_info,
const int32_t **csi_rs_generated_signal,
const int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
const uint8_t N_cdm_groups,
const uint8_t CDM_group_size,
const uint8_t k_prime,
const uint8_t l_prime,
const uint8_t N_ports,
const uint8_t *j_cdm,
const uint8_t *k_overline,
const uint8_t *l_overline,
int32_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size],
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size],
int16_t *log2_re,
int16_t *log2_maxh,
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;
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
const int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
*noise_power = 0;
int maxh = 0;
int count = 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(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
memset(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++) {
@@ -193,32 +317,32 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
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++) {
for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) {
for (int s = 0; s < CDM_group_size; s++) {
uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
// loop over frequency resource elements within a group
for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
for (int kp = 0; kp <= k_prime; 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;
uint16_t k = kinit + k_overline[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];
for (int lp = 0; lp <= l_prime; lp++) {
uint16_t symb = lp + l_overline[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];
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&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);
int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].r + (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].i)>>nr_csi_info->csi_rs_generated_signal_bits);
int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].i - (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].r)>>nr_csi_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;
csi_rs_ls_estimated_channel16[kinit].r += csi_rs_ls_estimated_channel_re;
csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im;
}
}
}
@@ -232,16 +356,16 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
}
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++) {
for(uint16_t port_tx = 0; port_tx<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];
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&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]);
tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i,
rx_csi_rs_signal[k].r, rx_csi_rs_signal[k].i,
csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i);
}
printf("\n");
}
@@ -250,7 +374,7 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
/// Channel interpolation
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
}
@@ -261,37 +385,40 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
continue;
}
count++;
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];
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
int16_t *csi_rs_ls_estimated_channel16 = (int16_t*)&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);
multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, 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);
multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, 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);
multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, 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];
uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
uint16_t noise_imag[frame_parms->nb_antennas_rx][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<N_ports; port_tx++) {
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
c16_t *csi_rs_estimated_channel16 = (c16_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_channel16->r-csi_rs_estimated_channel16->r);
noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->i-csi_rs_estimated_channel16->i);
maxh = cmax3(maxh, abs(csi_rs_estimated_channel16->r), abs(csi_rs_estimated_channel16->i));
}
}
for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
for(uint16_t port_tx = 0; port_tx<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));
}
@@ -301,13 +428,13 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
(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];
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
c16_t *csi_rs_estimated_channel16 = (c16_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],
csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i,
csi_rs_estimated_channel16[k].r, csi_rs_estimated_channel16[k].i,
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]);
}
@@ -317,7 +444,9 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
}
*noise_power /= (frame_parms->nb_antennas_rx*nr_csi_rs_info->N_ports);
*noise_power /= (frame_parms->nb_antennas_rx*N_ports);
*log2_maxh = log2_approx(maxh-1);
*log2_re = log2_approx(count-1);
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power);
@@ -326,7 +455,371 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
return 0;
}
int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const nr_csi_info_t *nr_csi_info,
const uint8_t N_ports,
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size],
const int16_t log2_maxh,
uint8_t *rank_indicator) {
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
const int16_t cond_dB_threshold = 5;
int count = 0;
*rank_indicator = 0;
if (ue->frame_parms.nb_antennas_rx == 1 || N_ports == 1) {
return 0;
} else if( !(ue->frame_parms.nb_antennas_rx == 2 && N_ports == 2) ) {
LOG_W(NR_PHY, "Rank indicator computation is not implemented for %i x %i system\n",
ue->frame_parms.nb_antennas_rx, N_ports);
return -1;
}
/* Example 2x2: Hh x H =
* | conjch00 conjch10 | x | ch00 ch01 | = | conjch00*ch00+conjch10*ch10 conjch00*ch01+conjch10*ch11 |
* | conjch01 conjch11 | | ch10 ch11 | | conjch01*ch00+conjch11*ch10 conjch01*ch01+conjch11*ch11 |
*/
int32_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t csi_rs_estimated_determ_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
int32_t csi_rs_estimated_numer_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
const uint8_t sum_shift = 1; // log2(2x2) = 2, which is a shift of 1 bit
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 (int ant_rx_conjch = 0; ant_rx_conjch < frame_parms->nb_antennas_rx; ant_rx_conjch++) {
for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) {
for (int ant_rx_ch = 0; ant_rx_ch < frame_parms->nb_antennas_rx; ant_rx_ch++) {
for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) {
// conjch x ch computation
nr_conjch0_mult_ch1(&csi_rs_estimated_channel_freq[ant_rx_conjch][port_tx_conjch][k],
&csi_rs_estimated_channel_freq[ant_rx_ch][port_tx_ch][k],
&csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k],
1,
log2_maxh);
// construct Hh x H elements
if(ant_rx_conjch == ant_rx_ch) {
nr_a_sum_b((__m128i *)&csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k],
(__m128i *)&csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k],
1);
}
}
}
}
}
// compute the determinant of A_MF (denominator)
nr_det_A_MF_2x2(&csi_rs_estimated_A_MF[0][0][k],
&csi_rs_estimated_A_MF[0][1][k],
&csi_rs_estimated_A_MF[1][0][k],
&csi_rs_estimated_A_MF[1][1][k],
&csi_rs_estimated_determ_fin[k],
1);
// compute the square of A_MF (numerator)
nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][0][k], &csi_rs_estimated_A_MF_sq[0][0][k], 1);
nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][1][k], &csi_rs_estimated_A_MF_sq[0][1][k], 1);
nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][0][k], &csi_rs_estimated_A_MF_sq[1][0][k], 1);
nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][1][k], &csi_rs_estimated_A_MF_sq[1][1][k], 1);
nr_numer_2x2(&csi_rs_estimated_A_MF_sq[0][0][k],
&csi_rs_estimated_A_MF_sq[0][1][k],
&csi_rs_estimated_A_MF_sq[1][0][k],
&csi_rs_estimated_A_MF_sq[1][1][k],
&csi_rs_estimated_numer_fin[k],
1);
#ifdef NR_CSIRS_DEBUG
for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) {
for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) {
c16_t *csi_rs_estimated_A_MF_k = (c16_t *) &csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k];
LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF[%i][%i] = (%i, %i)\n",
k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_k->r, csi_rs_estimated_A_MF_k->i);
c16_t *csi_rs_estimated_A_MF_sq_k = (c16_t *) &csi_rs_estimated_A_MF_sq[port_tx_conjch][port_tx_ch][k];
LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF_sq[%i][%i] = (%i, %i)\n",
k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_sq_k->r, csi_rs_estimated_A_MF_sq_k->i);
}
}
LOG_I(NR_PHY, "(%i) csi_rs_estimated_determ_fin = %i\n", k, csi_rs_estimated_determ_fin[k]);
LOG_I(NR_PHY, "(%i) csi_rs_estimated_numer_fin = %i\n", k, csi_rs_estimated_numer_fin[k]>>sum_shift);
#endif
// compute the conditional number
for (int sc_idx=0; sc_idx < NR_NB_SC_PER_RB; sc_idx++) {
int8_t csi_rs_estimated_denum_db = dB_fixed(csi_rs_estimated_determ_fin[k + sc_idx]);
int8_t csi_rs_estimated_numer_db = dB_fixed(csi_rs_estimated_numer_fin[k + sc_idx]>>sum_shift);
int8_t cond_db = csi_rs_estimated_numer_db - csi_rs_estimated_denum_db;
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "csi_rs_estimated_denum_db = %i\n", csi_rs_estimated_denum_db);
LOG_I(NR_PHY, "csi_rs_estimated_numer_db = %i\n", csi_rs_estimated_numer_db);
LOG_I(NR_PHY, "cond_db = %i\n", cond_db);
#endif
if (cond_db < cond_dB_threshold) {
count++;
} else {
count--;
}
}
}
// conditional number is lower than cond_dB_threshold in half on more REs
if (count > 0) {
*rank_indicator = 1;
}
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "count = %i\n", count);
LOG_I(NR_PHY, "rank = %i\n", (*rank_indicator)+1);
#endif
return 0;
}
int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const nr_csi_info_t *nr_csi_info,
const uint8_t N_ports,
const int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size],
const uint32_t interference_plus_noise_power,
const uint8_t rank_indicator,
const int16_t log2_re,
uint8_t *i1,
uint8_t *i2,
uint32_t *precoded_sinr_dB) {
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
memset(i1,0,3*sizeof(uint8_t));
i2[0] = 0;
// i1 is a three-element vector in the form of [i11 i12 i13], when CodebookType is specified as 'Type1SinglePanel'.
// Note that i13 is not applicable when the number of transmission layers is one of {1, 5, 6, 7, 8}.
// i2, for 'Type1SinglePanel' codebook type, it is a scalar when PMIMode is specified as 'wideband', and when PMIMode
// is specified as 'subband' or when PRGSize, the length of the i2 vector equals to the number of subbands or PRGs.
// Note that when the number of CSI-RS ports is 2, the applicable codebook type is 'Type1SinglePanel'. In this case,
// the precoding matrix is obtained by a single index (i2 field here) based on TS 38.214 Table 5.2.2.2.1-1.
// The first column is applicable if the UE is reporting a Rank = 1, whereas the second column is applicable if the
// UE is reporting a Rank = 2.
if(N_ports == 1 || interference_plus_noise_power == 0) {
return 0;
}
if(rank_indicator == 0 || rank_indicator == 1) {
int32_t sum_re[4] = {0};
int32_t sum_im[4] = {0};
int32_t sum2_re[4] = {0};
int32_t sum2_im[4] = {0};
int32_t tested_precoded_sinr[4] = {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;
}
uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
c16_t *csi_rs_estimated_channel_p0 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][0][k];
c16_t *csi_rs_estimated_channel_p1 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][1][k];
// H_p0 + 1*H_p1 = (H_p0_re + H_p1_re) + 1j*(H_p0_im + H_p1_im)
sum_re[0] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r);
sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i);
sum2_re[0] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r))>>log2_re;
sum2_im[0] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i))>>log2_re;
// H_p0 + 1j*H_p1 = (H_p0_re - H_p1_im) + 1j*(H_p0_im + H_p1_re)
sum_re[1] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i);
sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r);
sum2_re[1] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i))>>log2_re;
sum2_im[1] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r))>>log2_re;
// H_p0 - 1*H_p1 = (H_p0_re - H_p1_re) + 1j*(H_p0_im - H_p1_im)
sum_re[2] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r);
sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i);
sum2_re[2] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r))>>log2_re;
sum2_im[2] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i))>>log2_re;
// H_p0 - 1j*H_p1 = (H_p0_re + H_p1_im) + 1j*(H_p0_im - H_p1_re)
sum_re[3] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i);
sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r);
sum2_re[3] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i))>>log2_re;
sum2_im[3] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r))>>log2_re;
}
}
// We should perform >>nr_csi_info->log2_re here for all terms, but since sum2_re and sum2_im can be high values,
// we performed this above.
for(int p = 0; p<4; p++) {
int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re);
int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>log2_re);
tested_precoded_sinr[p] = (power_re+power_im)/(int32_t)interference_plus_noise_power;
}
if(rank_indicator == 0) {
for(int tested_i2 = 0; tested_i2 < 4; tested_i2++) {
if(tested_precoded_sinr[tested_i2] > tested_precoded_sinr[i2[0]]) {
i2[0] = tested_i2;
}
}
*precoded_sinr_dB = dB_fixed(tested_precoded_sinr[i2[0]]);
} else {
i2[0] = tested_precoded_sinr[0]+tested_precoded_sinr[2] > tested_precoded_sinr[1]+tested_precoded_sinr[3] ? 0 : 1;
*precoded_sinr_dB = dB_fixed((tested_precoded_sinr[i2[0]] + tested_precoded_sinr[i2[0]+2])>>1);
}
} else {
LOG_W(NR_PHY, "PMI computation is not implemented for rank indicator %i\n", rank_indicator+1);
return -1;
}
return 0;
}
int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr,
uint8_t *cqi) {
*cqi = 0;
// Default SINR table for an AWGN channel for SISO scenario, considering 0.1 BLER condition and TS 38.214 Table 5.2.2.1-2
if(precoded_sinr>0 && precoded_sinr<=2) {
*cqi = 4;
} else if(precoded_sinr==3) {
*cqi = 5;
} else if(precoded_sinr>3 && precoded_sinr<=5) {
*cqi = 6;
} else if(precoded_sinr>5 && precoded_sinr<=7) {
*cqi = 7;
} else if(precoded_sinr>7 && precoded_sinr<=9) {
*cqi = 8;
} else if(precoded_sinr==10) {
*cqi = 9;
} else if(precoded_sinr>10 && precoded_sinr<=12) {
*cqi = 10;
} else if(precoded_sinr>12 && precoded_sinr<=15) {
*cqi = 11;
} else if(precoded_sinr==16) {
*cqi = 12;
} else if(precoded_sinr>16 && precoded_sinr<=18) {
*cqi = 13;
} else if(precoded_sinr==19) {
*cqi = 14;
} else if(precoded_sinr>19) {
*cqi = 15;
}
return 0;
}
int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu,
uint32_t *interference_plus_noise_power) {
int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ?
csiim_config_pdu->bwp_size : csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs;
int32_t count = 0;
int32_t sum_re = 0;
int32_t sum_im = 0;
int32_t sum2_re = 0;
int32_t sum2_im = 0;
int l_csiim[4] = {-1, -1, -1, -1};
for(int symb_idx = 0; symb_idx < 4; symb_idx++) {
uint8_t symb = csiim_config_pdu->l_csiim[symb_idx];
bool done = false;
for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) {
if (l_csiim[symb_idx2] == symb) {
done = true;
}
}
if (done) {
continue;
}
l_csiim[symb_idx] = symb;
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset];
for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) {
uint16_t sc0_offset = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
for (int sc_idx = 0; sc_idx<4; sc_idx++) {
uint16_t sc = sc0_offset + csiim_config_pdu->k_csiim[sc_idx];
#ifdef NR_CSIIM_DEBUG
LOG_I(NR_PHY, "(ant_rx %i, sc %i) real %i, imag %i\n", ant_rx, rb, rx_signal[sc].r, rx_signal[sc].i);
#endif
sum_re += rx_signal[sc].r;
sum_im += rx_signal[sc].i;
sum2_re += rx_signal[sc].r*rx_signal[sc].r;
sum2_im += rx_signal[sc].i*rx_signal[sc].i;
count++;
}
}
}
}
int32_t power_re = sum2_re/count - (sum_re/count)*(sum_re/count);
int32_t power_im = sum2_im/count - (sum_im/count)*(sum_im/count);
*interference_plus_noise_power = power_re + power_im;
#ifdef NR_CSIIM_DEBUG
LOG_I(NR_PHY, "interference_plus_noise_power based on CSI-IM = %i\n", *interference_plus_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) {
if(!ue->csiim_vars[gNB_id]->active) {
return -1;
}
const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = (fapi_nr_dl_config_csiim_pdu_rel15_t*)&ue->csiim_vars[gNB_id]->csiim_config_pdu;
#ifdef NR_CSIIM_DEBUG
LOG_I(NR_PHY, "csiim_config_pdu->bwp_size = %i\n", csiim_config_pdu->bwp_size);
LOG_I(NR_PHY, "csiim_config_pdu->bwp_start = %i\n", csiim_config_pdu->bwp_start);
LOG_I(NR_PHY, "csiim_config_pdu->subcarrier_spacing = %i\n", csiim_config_pdu->subcarrier_spacing);
LOG_I(NR_PHY, "csiim_config_pdu->start_rb = %i\n", csiim_config_pdu->start_rb);
LOG_I(NR_PHY, "csiim_config_pdu->nr_of_rbs = %i\n", csiim_config_pdu->nr_of_rbs);
LOG_I(NR_PHY, "csiim_config_pdu->k_csiim = %i.%i.%i.%i\n", csiim_config_pdu->k_csiim[0], csiim_config_pdu->k_csiim[1], csiim_config_pdu->k_csiim[2], csiim_config_pdu->k_csiim[3]);
LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]);
#endif
nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power);
ue->nr_csi_info->csi_im_meas_computed = true;
return 0;
}
@@ -336,7 +829,7 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
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;
const 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);
@@ -355,26 +848,122 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
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,
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
uint8_t N_cdm_groups = 0;
uint8_t CDM_group_size = 0;
uint8_t k_prime = 0;
uint8_t l_prime = 0;
uint8_t N_ports = 0;
uint8_t j_cdm[16];
uint8_t k_overline[16];
uint8_t l_overline[16];
int16_t log2_re = 0;
int16_t log2_maxh = 0;
uint32_t rsrp = 0;
int rsrp_dBm = 0;
uint32_t noise_power = 0;
uint8_t rank_indicator = 0;
uint32_t precoded_sinr_dB = 0;
uint8_t cqi = 0;
uint8_t i1[3];
uint8_t i2[1];
nr_generate_csi_rs(frame_parms,
ue->nr_csi_info->csi_rs_generated_signal,
AMP,
ue->nr_csi_rs_info,
ue->nr_csi_info,
(nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu,
proc->nr_slot_rx);
proc->nr_slot_rx,
&N_cdm_groups,
&CDM_group_size,
&k_prime,
&l_prime,
&N_ports,
j_cdm,
k_overline,
l_overline);
int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
nr_get_csi_rs_signal(ue,
proc,
csirs_config_pdu,
ue->nr_csi_rs_info,
ue->nr_csi_rs_info->csi_rs_received_signal);
ue->nr_csi_info,
N_cdm_groups,
CDM_group_size,
k_prime,
l_prime,
j_cdm,
k_overline,
l_overline,
csi_rs_received_signal,
&rsrp,
&rsrp_dBm);
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);
ue->nr_csi_info,
(const int32_t **) ue->nr_csi_info->csi_rs_generated_signal,
csi_rs_received_signal,
N_cdm_groups,
CDM_group_size,
k_prime,
l_prime,
N_ports,
j_cdm,
k_overline,
l_overline,
csi_rs_ls_estimated_channel,
csi_rs_estimated_channel_freq,
&log2_re,
&log2_maxh,
&noise_power);
nr_csi_rs_ri_estimation(ue,
csirs_config_pdu,
ue->nr_csi_info,
N_ports,
csi_rs_estimated_channel_freq,
log2_maxh,
&rank_indicator);
nr_csi_rs_pmi_estimation(ue,
csirs_config_pdu,
ue->nr_csi_info,
N_ports,
csi_rs_estimated_channel_freq,
ue->nr_csi_info->csi_im_meas_computed ? ue->nr_csi_info->interference_plus_noise_power : noise_power,
rank_indicator,
log2_re,
i1,
i2,
&precoded_sinr_dB);
nr_csi_rs_cqi_estimation(precoded_sinr_dB, &cqi);
LOG_I(NR_PHY, "RSRP = %i dBm, RI = %i, i1 = %i.%i.%i, i2 = %i, SINR = %i dB, CQI = %i\n",
rsrp_dBm, rank_indicator+1, i1[0], i1[1], i1[2], i2[0], precoded_sinr_dB, cqi);
// Send CSI measurements to MAC
fapi_nr_csirs_measurements_t csirs_measurements;
csirs_measurements.rsrp = rsrp;
csirs_measurements.rsrp_dBm = rsrp_dBm;
csirs_measurements.rank_indicator = rank_indicator;
csirs_measurements.i1 = *i1;
csirs_measurements.i2 = *i2;
csirs_measurements.cqi = cqi;
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1);
nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, gNB_id, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements);
if (ue->if_inst && ue->if_inst->dl_indication) {
ue->if_inst->dl_indication(&dl_indication, NULL);
} else {
free(rx_ind);
}
return 0;
}
@@ -140,7 +140,6 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
dlsch->Mdlharq = Mdlharq;
dlsch->number_harq_processes_for_pdsch = Mdlharq;
dlsch->Nsoft = Nsoft;
dlsch->Mlimit = 4;
dlsch->max_ldpc_iterations = max_ldpc_iterations;
for (int i=0; i<Mdlharq; i++) {
@@ -222,7 +221,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
harq_process->status = SCH_IDLE;
harq_process->DLround = 0;
harq_process->ack = 1;
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
@@ -237,11 +235,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
harq_process->ack = 0;
if (harq_process->DLround >= dlsch->Mlimit) {
harq_process->status = SCH_IDLE;
harq_process->DLround = 0;
phy_vars_ue->dl_stats[4]++;
}
//if(is_crnti) {
// LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
@@ -496,8 +489,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
*/
nb_rb = harq_process->nb_rb;
harq_process->trials[harq_process->DLround]++;
A = harq_process->TBS;
ret = dlsch->max_ldpc_iterations + 1;
dlsch->last_iteration_cnt = ret;
@@ -362,7 +362,7 @@ 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);
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
// initialize the pusch dmrs
for (int i=0; i<NR_NB_NSCID; i++) {
@@ -855,10 +855,6 @@ void construct_HhH_elements(int *ch0conj_ch0,
int32_t *after_mf_11,
unsigned short nb_rb);
void squared_matrix_element(int32_t *Hh_h_00,
int32_t *Hh_h_00_sq,
unsigned short nb_rb);
void dlsch_channel_level_TM34_meas(int *ch00,
int *ch01,
int *ch10,
@@ -885,19 +881,15 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
unsigned short nb_rb,
int length);
void det_HhH(int32_t *after_mf_00,
int32_t *after_mf_01,
int32_t *after_mf_10,
int32_t *after_mf_11,
int32_t *det_fin_128,
unsigned short nb_rb);
void nr_conjch0_mult_ch1(int *ch0,
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0);
void numer(int32_t *Hh_h_00_sq,
int32_t *Hh_h_01_sq,
int32_t *Hh_h_10_sq,
int32_t *Hh_h_11_sq,
int32_t *num_fin,
unsigned short nb_rb);
void nr_a_sum_b(__m128i *input_x,
__m128i *input_y,
unsigned short nb_rb);
uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
int *dl_ch_estimates_01,
+2 -10
View File
@@ -161,15 +161,13 @@ typedef struct {
//uint8_t num_cba_dci[10];
/// allocated CBA RNTI
//uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
/// UL max-harq-retransmission
uint16_t Mlimit;
} NR_UE_ULSCH_t;
typedef struct {
/// Indicator of first reception
uint8_t first_rx;
/// Last Ndi received for this process on DCI (used for C-RNTI only)
uint8_t DCINdi;
uint8_t Ndi;
/// DLSCH status flag indicating
SCH_status_t status;
/// Transport block size
@@ -241,10 +239,6 @@ typedef struct {
vrb_t vrb_type;
/// downlink power offset field
uint8_t dl_power_off;
/// trials per round statistics
uint32_t trials[8];
/// error statistics per round
uint32_t errors[8];
/// codeword this transport block is mapped to
uint8_t codeword;
/// HARQ-ACKs
@@ -311,9 +305,7 @@ typedef struct {
/// Maximum number of LDPC iterations
uint8_t max_ldpc_iterations;
/// number of iterations used in last turbo decoding
uint8_t last_iteration_cnt;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
uint8_t last_iteration_cnt;
} NR_UE_DLSCH_t;
typedef enum {format0_0,
@@ -130,10 +130,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_
memset(ulsch, 0, sizeof(*ulsch));
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
ulsch->Mlimit = 4; // maximum harq retransmissions
//for (i=0; i<10; i++)
//ulsch->harq_ids[i] = 0;
for (int i = 0; i < number_of_harq_pids; i++) {
+2 -8
View File
@@ -188,8 +188,6 @@ typedef struct {
uint8_t codebook_index;
/// Maximum number of HARQ processes
uint8_t Mdlharq;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
/// MIMO transmission mode indicator for this sub-frame
uint8_t Kmimo;
/// Nsoft parameter related to UE Category
@@ -345,8 +343,6 @@ typedef struct {
typedef struct {
/// Pointers to 16 HARQ processes for the ULSCH
NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
/// Current HARQ process id
int harq_process_id[NR_MAX_SLOTS_PER_FRAME];
/// HARQ process mask, indicates which processes are currently active
uint16_t harq_mask;
/// ACK/NAK Bundling flag
@@ -373,8 +369,6 @@ typedef struct {
uint8_t cyclicShift;
/// for cooperative communication
uint8_t cooperation_flag;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
/// Maximum number of LDPC iterations
uint8_t max_ldpc_iterations;
/// number of iterations used in last LDPC decoding
@@ -765,8 +759,8 @@ 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;
/// CSI variables
nr_csi_info_t *nr_csi_info;
uint8_t pbch_configured;
char gNB_generate_rar;
+4 -4
View File
@@ -878,8 +878,8 @@ typedef struct {
/// SRS variables
nr_srs_info_t *nr_srs_info;
/// CSI-RS variables
nr_csi_rs_info_t *nr_csi_rs_info;
/// CSI variables
nr_csi_info_t *nr_csi_info;
//#if defined(UPGRADE_RAT_NR)
#if 1
@@ -978,8 +978,8 @@ typedef struct {
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
#endif
int dl_stats[5];
int dl_errors;
int dl_stats[8];
void* scopeData;
} PHY_VARS_NR_UE;
+4 -13
View File
@@ -43,6 +43,7 @@
#define nr_slot_t lte_subframe_t
#define MAX_NUM_SUBCARRIER_SPACING 5
#define NR_MAX_OFDM_SYMBOL_SIZE 4096
#define NR_NB_SC_PER_RB 12
#define NR_NB_REG_PER_CCE 6
@@ -247,23 +248,13 @@ typedef struct {
} 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;
bool csi_im_meas_computed;
uint32_t interference_plus_noise_power;
} nr_csi_info_t;
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
+4 -20
View File
@@ -172,7 +172,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
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->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot);
nr_generate_csi_rs(&gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_info, csi_params, slot, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
csirs->active = 0;
}
}
@@ -242,13 +242,6 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
ulsch_harq->ulsch_pdu.rb_size,
ulsch_harq->TBS,
r);
ulsch_harq->round++;
if (ulsch_harq->round >= ulsch->Mlimit) {
ulsch_harq->status = SCH_IDLE;
ulsch_harq->round = 0;
ulsch_harq->handled = 0;
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
}
ulsch_harq->handled = 1;
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
@@ -413,17 +406,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
if (timing_advance_update > 63) timing_advance_update = 63;
if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update);
else if (harq_process->round>0 || dtx_flag == 0) { // increment round if crc_flag == 1 and not(dtx_flag ==1 and round==0)
harq_process->round++;
if (harq_process->round >= ulsch->Mlimit) {
harq_process->status = SCH_IDLE;
harq_process->round = 0;
harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
}
}
// estimate UL_CQI for MAC
// estimate UL_CQI for MAC
int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) -
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot);
@@ -858,8 +842,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols;
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32)));
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32)));
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
uint32_t noise_power_per_rb[srs_pdu->bwp_size];
int8_t snr_per_rb[srs_pdu->bwp_size];
+1 -1
View File
@@ -405,7 +405,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc,
void * typeSpecific);
void *typeSpecific);
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
+1 -1
View File
@@ -393,7 +393,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
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;
csiim_vars->active = true;
break;
case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15;
+6 -7
View File
@@ -308,7 +308,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
dl_harq->status = SCH_IDLE;
dl_harq->first_rx = 1;
dl_harq->DLround = 0;
dl_harq->DCINdi = 1;
dl_harq->Ndi = 1;
dl_harq->ack = DL_ACKNACK_NO_SET;
}
@@ -329,7 +329,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
*
*********************************************************************/
void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int rv, uint8_t rnti_type) {
void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int dci_ndi, int rv, uint8_t rnti_type) {
if (rnti_type == _SI_RNTI_ ||
rnti_type == _P_RNTI_ ||
@@ -339,10 +339,9 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
dl_harq->first_rx = 1;
} else {
LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n",
dl_harq, harq_pid, rv, ndi, rnti_type, dl_harq->DCINdi != ndi ? "yes":"no");
dl_harq, harq_pid, rv, dci_ndi, rnti_type, dl_harq->Ndi != dci_ndi ? "yes":"no");
AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv);
if (ndi!=dl_harq->DCINdi) {
if (dci_ndi!=dl_harq->Ndi) {
if (dl_harq->ack == DL_NACK)
LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid);
else
@@ -354,7 +353,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv);
}
if (ndi!=dl_harq->DCINdi) {
if (dci_ndi!=dl_harq->Ndi) {
dl_harq->first_rx = true;
dl_harq->DLround = 0;
} else {
@@ -364,7 +363,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
dl_harq->status = ACTIVE;
dl_harq->DCINdi = ndi;
dl_harq->Ndi = dci_ndi;
//dl_harq->status = SCH_IDLE;
}
}
+31 -4
View File
@@ -121,9 +121,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc,
void * typeSpecific){
UE_nr_rxtx_proc_t *proc,
void *typeSpecific){
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
@@ -176,6 +175,11 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier;
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.rsrp_dBm[gNB_id];
break;
case FAPI_NR_CSIRS_IND:
memcpy(&rx_ind->rx_indication_body[n_pdus - 1].csirs_measurements,
(fapi_nr_csirs_measurements_t*)typeSpecific,
sizeof(*(fapi_nr_csirs_measurements_t*)typeSpecific));
break;
default:
break;
}
@@ -1476,7 +1480,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
LOG_I(NR_PHY,"============================================\n");
LOG_I(NR_PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]);
// fixed text + 8 HARQs rounds à 10 ("999999999/") + NULL
// if we use 999999999 HARQs, that should be sufficient for at least 138 hours
const size_t harq_output_len = 31 + 10 * 8 + 1;
char output[harq_output_len];
char *p = output;
const char *end = output + harq_output_len;
p += snprintf(p, end - p, "Harq round stats for Downlink: %d", ue->dl_stats[0]);
for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round)
p += snprintf(p, end - p,"/%d", ue->dl_stats[round]);
LOG_I(NR_PHY,"%s/0\n", output);
LOG_I(NR_PHY,"============================================\n");
}
@@ -1691,6 +1705,19 @@ 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)) {
int l_csiim[4] = {-1, -1, -1, -1};
for(int symb_idx = 0; symb_idx < 4; symb_idx++) {
bool nr_slot_fep_done = false;
for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) {
if (l_csiim[symb_idx2] == ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]) {
nr_slot_fep_done = true;
}
}
l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx];
if(nr_slot_fep_done == false) {
nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], nr_slot_rx);
}
}
nr_ue_csi_im_procedures(ue, proc, gNB_id);
ue->csiim_vars[gNB_id]->active = 0;
}
+11 -11
View File
@@ -114,16 +114,16 @@ int main(int argc, char **argv)
//int run_initial_sync=0;
int loglvl = OAILOG_WARNING;
uint8_t dlsch_threads = 0;
float target_error_rate = 0.01;
uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
uint8_t mcs_table = 0;
double DS_TDL = .03;
cpuf = get_cpu_freq_GHz();
char gNBthreads[128]="n";
int Tbslbrm = 950984;
float target_error_rate = 0.01;
uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
uint8_t mcs_table = 0;
double DS_TDL = .03;
cpuf = get_cpu_freq_GHz();
char gNBthreads[128]="n";
int Tbslbrm = 950984;
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n");
@@ -299,7 +299,7 @@ int main(int argc, char **argv)
break;
case 'X':
strncpy(gNBthreads, optarg, sizeof(gNBthreads));
strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1);
gNBthreads[sizeof(gNBthreads)-1]=0;
break;
+14 -4
View File
@@ -100,9 +100,17 @@ nfapi_ue_release_request_body_t release_rntis;
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0;
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
return 0;
teid_t newGtpuCreateTunnel(instance_t instance,
rnti_t rnti,
int incoming_bearer_id,
int outgoing_bearer_id,
teid_t outgoing_teid,
int qfi,
transport_layer_addr_t remoteAddr,
int port,
gtpCallback callBack,
gtpCallbackSDAP callBackSDAP) {
return 0;
}
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
@@ -665,7 +673,7 @@ int main(int argc, char **argv)
break;
case 'X':
strncpy(gNBthreads, optarg, sizeof(gNBthreads));
strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1);
gNBthreads[sizeof(gNBthreads)-1]=0;
break;
@@ -756,6 +764,8 @@ int main(int argc, char **argv)
gNB_RRC_INST rrc;
memset((void*)&rrc,0,sizeof(rrc));
gNB_mac->dl_bler.harq_round_max = num_rounds;
/*
// read in SCGroupConfig
AssertFatal(scg_fd != NULL,"no reconfig.raw file\n");
@@ -40,4 +40,4 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc,
void * typeSpecific ) {}
void *typeSpecific ) {}
+11 -3
View File
@@ -92,9 +92,17 @@ int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0);
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0;
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
return 0;
teid_t newGtpuCreateTunnel(instance_t instance,
rnti_t rnti,
int incoming_bearer_id,
int outgoing_bearer_id,
teid_t outgoing_teid,
int qfi,
transport_layer_addr_t remoteAddr,
int port,
gtpCallback callBack,
gtpCallbackSDAP callBackSDAP) {
return 0;
}
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
+11 -3
View File
@@ -95,9 +95,17 @@ nfapi_ue_release_request_body_t release_rntis;
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0;
teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
return 0;
teid_t newGtpuCreateTunnel(instance_t instance,
rnti_t rnti,
int incoming_bearer_id,
int outgoing_bearer_id,
teid_t outgoing_teid,
int qfi,
transport_layer_addr_t remoteAddr,
int port,
gtpCallback callBack,
gtpCallbackSDAP callBackSDAP) {
return 0;
}
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {