From 9b10e1c45df97d51a6beeb8baa99a00635b5088a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 19 Jul 2021 21:48:32 +0200 Subject: [PATCH] Fix sub-band CQI in UE. Refactor variable names --- lib/include/srsran/phy/phch/cqi.h | 7 ++++ lib/src/phy/phch/cqi.c | 66 +++++++++++++++++++++++++++---- lib/src/phy/ue/ue_dl.c | 3 +- srsenb/src/phy/phy_ue_db.cc | 24 +++++++++-- 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/lib/include/srsran/phy/phch/cqi.h b/lib/include/srsran/phy/phch/cqi.h index 9a251f7b8..6dc9c1fbf 100644 --- a/lib/include/srsran/phy/phch/cqi.h +++ b/lib/include/srsran/phy/phch/cqi.h @@ -154,10 +154,17 @@ SRSRAN_API bool srsran_cqi_periodic_is_subband(const srsran_cqi_report_cfg_t* cf SRSRAN_API bool srsran_cqi_periodic_ri_send(const srsran_cqi_report_cfg_t* periodic_cfg, uint32_t tti, srsran_frame_type_t frame_type); +SRSRAN_API uint32_t srsran_cqi_periodic_sb_bw_part_idx(const srsran_cqi_report_cfg_t* cfg, + uint32_t tti, + uint32_t nof_prb, + srsran_frame_type_t frame_type); + SRSRAN_API int srsran_cqi_hl_get_no_subbands(int nof_prb); SRSRAN_API int srsran_cqi_hl_get_L(int nof_prb); +SRSRAN_API int srsran_cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb); + SRSRAN_API uint8_t srsran_cqi_from_snr(float snr); SRSRAN_API float srsran_cqi_to_coderate(uint32_t cqi, bool use_alt_table); diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index 9d407aae8..2ee775eaa 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -544,17 +544,37 @@ static int cqi_hl_get_bwp_J(int nof_prb) { if (nof_prb < 7) { return 0; + } else if (nof_prb <= 10) { + return 1; } else if (nof_prb <= 26) { - return 4; + return 2; } else if (nof_prb <= 63) { - return 6; - } else if (nof_prb <= 110) { - return 8; + return 3; + } else if (nof_prb <= 63) { + return 4; } else { return -1; } } +/* Returns the number of subbands in the j-th bandwidth part + */ +int srsran_cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb) +{ + uint32_t J = cqi_hl_get_bwp_J(nof_prb); + if (J == 1) { + return (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb)); + } else { + // all bw parts have the same number of subbands except the last one + uint32_t Nj = (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb) / J); + if (j < J - 1) { + return Nj; + } else { + return Nj - 1; + } + } +} + /* Returns the number of bits to index a bandwidth part (L) * L = ceil(log2(nof_prb/k/J)) */ @@ -574,19 +594,51 @@ bool srsran_cqi_periodic_send(const srsran_cqi_report_cfg_t* cfg, uint32_t tti, return cfg->periodic_configured && cqi_send(cfg->pmi_idx, tti, frame_type == SRSRAN_FDD, 1); } +uint32_t cqi_sb_get_H(const srsran_cqi_report_cfg_t* cfg, uint32_t nof_prb) +{ + uint32_t K = cfg->subband_wideband_ratio; + uint32_t J = cqi_hl_get_bwp_J(nof_prb); + uint32_t H = J * K + 1; + return H; +} + bool srsran_cqi_periodic_is_subband(const srsran_cqi_report_cfg_t* cfg, uint32_t tti, uint32_t nof_prb, srsran_frame_type_t frame_type) { - uint32_t K = cfg->subband_wideband_ratio; - uint32_t J = cqi_hl_get_bwp_J(nof_prb); - uint32_t H = J * K + 1; + uint32_t H = cqi_sb_get_H(cfg, nof_prb); // A periodic report is subband if it's a CQI opportunity and is not wideband return srsran_cqi_periodic_send(cfg, tti, frame_type) && !cqi_send(cfg->pmi_idx, tti, frame_type == SRSRAN_FDD, H); } +uint32_t srsran_cqi_periodic_sb_bw_part_idx(const srsran_cqi_report_cfg_t* cfg, + uint32_t tti, + uint32_t nof_prb, + srsran_frame_type_t frame_type) +{ + uint32_t H = cqi_sb_get_H(cfg, nof_prb); + uint32_t N_p = 0, N_offset = 0; + + if (frame_type == SRSRAN_FDD) { + if (!cqi_get_N_fdd(cfg->pmi_idx, &N_p, &N_offset)) { + return false; + } + } else { + if (!cqi_get_N_tdd(cfg->pmi_idx, &N_p, &N_offset)) { + return false; + } + } + + uint32_t x = ((tti - N_offset) / N_p) % H; + if (x > 0) { + return (x - 1) % cqi_hl_get_bwp_J(nof_prb); + } else { + return 0; + } +} + // CQI-to-Spectral Efficiency: 36.213 Table 7.2.3-1 static float cqi_to_coderate[16] = {0, 0.1523, diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 24ac0bb54..ce5766992 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -853,7 +853,8 @@ void srsran_ue_dl_gen_cqi_periodic(srsran_ue_dl_t* q, uci_data->cfg.cqi.ri_len = 1; uci_data->value.ri = cfg->last_ri; } else if (srsran_cqi_periodic_send(&cfg->cfg.cqi_report, tti, q->cell.frame_type)) { - if (cfg->cfg.cqi_report.format_is_subband) { + if (cfg->cfg.cqi_report.format_is_subband && + srsran_cqi_periodic_is_subband(&cfg->cfg.cqi_report, tti, q->cell.nof_prb, q->cell.frame_type)) { // TODO: Implement subband periodic reports uci_data->cfg.cqi.type = SRSRAN_CQI_TYPE_SUBBAND_UE; uci_data->value.cqi.subband_ue.subband_cqi = wideband_value; diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index 837924e76..50dab80b7 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -634,7 +634,8 @@ int phy_ue_db::send_uci_data(uint32_t tti, // Get ACK info srsran_pdsch_ack_t& pdsch_ack = ue.pdsch_ack[tti]; - srsran_enb_dl_get_ack(&cell_cfg_list->at(ue.cell_info[0].enb_cc_idx).cell, &uci_cfg, &uci_value, &pdsch_ack); + const srsran_cell_t& cell = cell_cfg_list->at(ue.cell_info[0].enb_cc_idx).cell; + srsran_enb_dl_get_ack(&cell, &uci_cfg, &uci_value, &pdsch_ack); // Iterate over the ACK information for (uint32_t ue_cc_idx = 0; ue_cc_idx < SRSRAN_MAX_CARRIERS; ue_cc_idx++) { @@ -663,22 +664,37 @@ int phy_ue_db::send_uci_data(uint32_t tti, if (uci_value.cqi.data_crc) { // Channel quality indicator itself if (uci_cfg.cqi.data_enable) { - uint8_t cqi_value = 0; + uint8_t cqi_value = 0; + uint32_t sb_idx = 0; + uint32_t bw_part_idx = 0; switch (uci_cfg.cqi.type) { case SRSRAN_CQI_TYPE_WIDEBAND: cqi_value = uci_value.cqi.wideband.wideband_cqi; + printf("tti=%d, wide\n", tti); + stack->cqi_info(tti, rnti, cqi_cc_idx, cqi_value); break; case SRSRAN_CQI_TYPE_SUBBAND_UE: - cqi_value = uci_value.cqi.subband_ue.subband_cqi; + cqi_value = uci_value.cqi.subband_ue.subband_cqi; + bw_part_idx = srsran_cqi_periodic_sb_bw_part_idx( + &ue.cell_info[0].phy_cfg.dl_cfg.cqi_report, tti, cell.nof_prb, cell.frame_type); + sb_idx = + uci_value.cqi.subband_ue.subband_label + bw_part_idx * srsran_cqi_sb_get_Nj(bw_part_idx, cell.nof_prb); + stack->sb_cqi_info(tti, rnti, cqi_cc_idx, sb_idx, cqi_value); break; case SRSRAN_CQI_TYPE_SUBBAND_HL: cqi_value = uci_value.cqi.subband_hl.wideband_cqi_cw0; + // Todo: change interface + stack->cqi_info(tti, rnti, cqi_cc_idx, cqi_value); break; case SRSRAN_CQI_TYPE_SUBBAND_UE_DIFF: cqi_value = uci_value.cqi.subband_ue_diff.wideband_cqi; + stack->sb_cqi_info(tti, + rnti, + cqi_cc_idx, + uci_value.cqi.subband_ue_diff.position_subband, + cqi_value + uci_value.cqi.subband_ue_diff.subband_diff_cqi); break; } - stack->cqi_info(tti, rnti, cqi_cc_idx, cqi_value); } // Precoding Matrix indicator (TM4)