mirror of https://github.com/pvnis/srsRAN_4G.git
sched,feature - creation of sched_cqi class to manage the update of CQI in a subband CQI setting
parent
f25dbea4de
commit
eeb8ad6571
@ -0,0 +1,131 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSRAN_SCHED_CQI_H
|
||||||
|
#define SRSRAN_SCHED_CQI_H
|
||||||
|
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||||
|
#include "srsran/adt/accumulators.h"
|
||||||
|
#include "srsran/common/common_lte.h"
|
||||||
|
#include "srsran/phy/phch/cqi.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
class sched_cqi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sched_cqi(uint32_t cell_nof_prb_, uint32_t K_) :
|
||||||
|
cell_nof_prb(cell_nof_prb_),
|
||||||
|
cell_nof_rbg(cell_nof_prb_to_rbg(cell_nof_prb_)),
|
||||||
|
K(K_),
|
||||||
|
wb_cqi_avg(0.01),
|
||||||
|
bp_list(nof_bandwidth_parts(cell_nof_prb_)),
|
||||||
|
subband_cqi(srsran_cqi_hl_get_no_subbands(cell_nof_prb), 0)
|
||||||
|
{
|
||||||
|
srsran_assert(K <= 4, "K=%d outside of {0, 4}", K);
|
||||||
|
}
|
||||||
|
|
||||||
|
void new_tti(tti_point tti) {}
|
||||||
|
|
||||||
|
void cqi_wb_info(tti_point tti, uint32_t cqi_value)
|
||||||
|
{
|
||||||
|
last_wb_tti = tti;
|
||||||
|
wb_cqi_avg.push(static_cast<float>(cqi_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cqi_sb_info(tti_point tti, uint32_t sb_index, uint32_t cqi_value)
|
||||||
|
{
|
||||||
|
uint32_t bp_idx = get_bp_index(sb_index);
|
||||||
|
bp_list[bp_idx].last_feedback_tti = tti;
|
||||||
|
bp_list[bp_idx].last_cqi_subband_idx = sb_index;
|
||||||
|
bp_list[bp_idx].cqi_val.push(static_cast<float>(cqi_value));
|
||||||
|
|
||||||
|
// just cap all sub-bands in the same bandwidth part
|
||||||
|
srsran::interval<uint32_t> interv = get_bp_sb_indexes(bp_idx);
|
||||||
|
for (uint32_t sb_index2 = interv.start(); sb_index2 < interv.stop(); ++sb_index2) {
|
||||||
|
subband_cqi[sb_index2] = bp_list[bp_idx].cqi_val.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_rbg_grant_avg_cqi(rbg_interval interv) const
|
||||||
|
{
|
||||||
|
float cqi = 0;
|
||||||
|
for (uint32_t rbg = interv.start(); rbg < interv.stop(); ++rbg) {
|
||||||
|
cqi += subband_cqi[rbg_to_sb_index(rbg)];
|
||||||
|
}
|
||||||
|
return static_cast<int>(cqi / interv.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_rbg_grant_avg_cqi(const rbgmask_t& mask) const
|
||||||
|
{
|
||||||
|
float cqi = 0;
|
||||||
|
for (int rbg = mask.find_lowest(0, mask.size()); rbg != -1; rbg = mask.find_lowest(rbg + 1, mask.size())) {
|
||||||
|
cqi += subband_cqi[rbg_to_sb_index(rbg)];
|
||||||
|
}
|
||||||
|
return static_cast<int>(cqi / mask.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TS 36.321, 7.2.2 - Parameter N
|
||||||
|
uint32_t nof_subbands() const { return subband_cqi.size(); }
|
||||||
|
|
||||||
|
/// TS 36.321, 7.2.2 - Parameter J
|
||||||
|
uint32_t nof_bandwidth_parts() const { return bp_list.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const uint32_t max_subband_size = 8;
|
||||||
|
static const uint32_t max_nof_subbands = 13;
|
||||||
|
static const uint32_t max_bandwidth_parts = 4;
|
||||||
|
|
||||||
|
static uint32_t nof_bandwidth_parts(uint32_t nof_prb)
|
||||||
|
{
|
||||||
|
static const uint32_t nrb[] = {0, 1, 2, 3, 4};
|
||||||
|
return nrb[srsran::lte_cell_nof_prb_to_index(nof_prb)];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t J() const { return nof_bandwidth_parts(); }
|
||||||
|
uint32_t N() const { return nof_subbands(); }
|
||||||
|
|
||||||
|
uint32_t get_bp_index(uint32_t sb_index) const { return sb_index * J() / N(); }
|
||||||
|
|
||||||
|
uint32_t get_sb_index(uint32_t prb_index) const { return prb_index * N() / cell_nof_prb; }
|
||||||
|
|
||||||
|
uint32_t rbg_to_sb_index(uint32_t rbg_index) const { return rbg_index * N() / cell_nof_rbg; }
|
||||||
|
|
||||||
|
srsran::interval<uint32_t> get_bp_sb_indexes(uint32_t bp_idx) const
|
||||||
|
{
|
||||||
|
return srsran::interval<uint32_t>{bp_idx * N() / J(), (bp_idx + 1) * N() / J()};
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t cell_nof_prb;
|
||||||
|
uint32_t cell_nof_rbg;
|
||||||
|
uint32_t K; ///< set in RRC
|
||||||
|
|
||||||
|
/// context of bandwidth part
|
||||||
|
struct bandwidth_part_context {
|
||||||
|
tti_point last_feedback_tti;
|
||||||
|
uint32_t last_cqi_subband_idx;
|
||||||
|
srsran::exp_average_fast_start<float> cqi_val;
|
||||||
|
|
||||||
|
explicit bandwidth_part_context() : cqi_val(0), last_cqi_subband_idx(max_nof_subbands) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
tti_point last_wb_tti;
|
||||||
|
srsran::exp_average_fast_start<float> wb_cqi_avg;
|
||||||
|
|
||||||
|
srsran::bounded_vector<bandwidth_part_context, max_bandwidth_parts> bp_list;
|
||||||
|
srsran::bounded_vector<float, max_nof_subbands> subband_cqi;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsenb
|
||||||
|
|
||||||
|
#endif // SRSRAN_SCHED_CQI_H
|
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_cqi.h"
|
||||||
|
#include "srsran/common/test_common.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
void test_sched_cqi_one_subband_cqi()
|
||||||
|
{
|
||||||
|
sched_cqi ue_cqi(50, 4);
|
||||||
|
|
||||||
|
// J == 3, N == 9
|
||||||
|
TESTASSERT(ue_cqi.nof_bandwidth_parts() == 3);
|
||||||
|
TESTASSERT(ue_cqi.nof_subbands() == 9);
|
||||||
|
|
||||||
|
// Ni = 0 -> cqi=5
|
||||||
|
ue_cqi.cqi_sb_info(tti_point(0), 0, 5);
|
||||||
|
|
||||||
|
// TEST: updated part has positive cqi. Non-updated cqi didn't change
|
||||||
|
TESTASSERT(ue_cqi.get_rbg_grant_avg_cqi(rbg_interval(0, 1)) == 5);
|
||||||
|
for (uint32_t i = 1; i < 5; ++i) {
|
||||||
|
TESTASSERT(ue_cqi.get_rbg_grant_avg_cqi(rbg_interval(i, i + 1)) > 0);
|
||||||
|
}
|
||||||
|
TESTASSERT(ue_cqi.get_rbg_grant_avg_cqi(rbg_interval(6, cell_nof_prb_to_rbg(50))) == 0);
|
||||||
|
|
||||||
|
// TEST: Check average cqi over a mask of RBGs
|
||||||
|
rbgmask_t mask(cell_nof_prb_to_rbg(50));
|
||||||
|
mask.fill(10, mask.size());
|
||||||
|
TESTASSERT(ue_cqi.get_rbg_grant_avg_cqi(mask) == 0);
|
||||||
|
mask.reset();
|
||||||
|
mask.set(1);
|
||||||
|
TESTASSERT(ue_cqi.get_rbg_grant_avg_cqi(mask) == 5);
|
||||||
|
mask.fill(0, mask.size());
|
||||||
|
TESTASSERT(ue_cqi.get_rbg_grant_avg_cqi(mask) > 0 and ue_cqi.get_rbg_grant_avg_cqi(mask) < 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsenb
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
srsran::test_init(argc, argv);
|
||||||
|
|
||||||
|
srsenb::test_sched_cqi_one_subband_cqi();
|
||||||
|
|
||||||
|
return SRSRAN_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue