precompute nof_re_table[sf][prb][slot][cfi] for faster nof_re computation and for more accurate lower bound nof_re computation

This commit is contained in:
Francisco Paisana 2021-01-15 12:31:10 +00:00
parent d0a17b0a40
commit d4242f2db7
8 changed files with 154 additions and 52 deletions

View File

@ -48,6 +48,8 @@ srslte_ra_dl_grant_to_grant_prb_allocation(const srslte_dci_dl_t* dci, srslte_pd
/** Functions used by the eNodeB scheduler */ /** Functions used by the eNodeB scheduler */
SRSLTE_API uint32_t srslte_ra_dl_approx_nof_re(const srslte_cell_t* cell, uint32_t nof_prb, uint32_t nof_ctrl_symbols); SRSLTE_API uint32_t srslte_ra_dl_approx_nof_re(const srslte_cell_t* cell, uint32_t nof_prb, uint32_t nof_ctrl_symbols);
SRSLTE_API uint32_t ra_re_x_prb(const srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, uint32_t slot, uint32_t prb_idx);
SRSLTE_API uint32_t srslte_ra_dl_grant_nof_re(const srslte_cell_t* cell, SRSLTE_API uint32_t srslte_ra_dl_grant_nof_re(const srslte_cell_t* cell,
srslte_dl_sf_cfg_t* sf, srslte_dl_sf_cfg_t* sf,
srslte_pdsch_grant_t* grant); srslte_pdsch_grant_t* grant);

View File

@ -29,13 +29,8 @@ const int tbs_format1c_table[32] = {40, 56, 72, 120, 136, 144, 176, 208
296, 328, 336, 392, 488, 552, 600, 632, 696, 776, 840, 296, 328, 336, 392, 488, 552, 600, 632, 696, 776, 840,
904, 1000, 1064, 1128, 1224, 1288, 1384, 1480, 1608, 1736}; 904, 1000, 1064, 1128, 1224, 1288, 1384, 1480, 1608, 1736};
/**********
* STATIC FUNCTIONS
*
**********/
/* Returns the number of RE in a PRB in a slot and subframe */ /* Returns the number of RE in a PRB in a slot and subframe */
static uint32_t ra_re_x_prb(const srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, uint32_t slot, uint32_t prb_idx) uint32_t ra_re_x_prb(const srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, uint32_t slot, uint32_t prb_idx)
{ {
uint32_t subframe = sf->tti % 10; uint32_t subframe = sf->tti % 10;

View File

@ -47,8 +47,10 @@ public:
const sched_interface::cell_cfg_t& cfg_, const sched_interface::cell_cfg_t& cfg_,
const sched_interface::sched_args_t& sched_args); const sched_interface::sched_args_t& sched_args);
// convenience getters // convenience getters
uint32_t prb_to_rbg(uint32_t nof_prbs) const { return srslte::ceil_div(nof_prbs, P); } uint32_t nof_prbs_to_rbgs(uint32_t nof_prbs) const { return srslte::ceil_div(nof_prbs, P); }
uint32_t nof_prb() const { return cfg.cell.nof_prb; } uint32_t nof_prb() const { return cfg.cell.nof_prb; }
uint32_t get_dl_lb_nof_re(tti_point tti_tx_dl, uint32_t nof_prbs_alloc) const;
uint32_t get_dl_nof_res(srslte::tti_point tti_tx_dl, const srslte_dci_dl_t& dci, uint32_t cfi) const;
uint32_t enb_cc_idx = 0; uint32_t enb_cc_idx = 0;
sched_interface::cell_cfg_t cfg = {}; sched_interface::cell_cfg_t cfg = {};
@ -59,6 +61,16 @@ public:
std::array<uint32_t, 3> nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH std::array<uint32_t, 3> nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH
uint32_t P = 0; uint32_t P = 0;
uint32_t nof_rbgs = 0; uint32_t nof_rbgs = 0;
using dl_nof_re_table = srslte::bounded_vector<
std::array<std::array<std::array<uint32_t, SRSLTE_NOF_CFI>, SRSLTE_NOF_SLOTS_PER_SF>, SRSLTE_NOF_SF_X_FRAME>,
SRSLTE_MAX_PRB>;
using dl_lb_nof_re_table = std::array<srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB>, SRSLTE_NOF_SF_X_FRAME>;
/// Table of nof REs
dl_nof_re_table nof_re_table;
/// Cached computation of Lower bound of nof REs
dl_lb_nof_re_table nof_re_lb_table;
}; };
using ue_cce_locations_table = std::array<std::array<sched_dci_cce_t, SRSLTE_NOF_SF_X_FRAME>, SRSLTE_NOF_CFI>; using ue_cce_locations_table = std::array<std::array<sched_dci_cce_t, SRSLTE_NOF_SF_X_FRAME>, SRSLTE_NOF_CFI>;

View File

@ -100,6 +100,12 @@ inline uint32_t count_prb_per_tb(const rbgmask_t& bitmask)
return nof_prb; return nof_prb;
} }
inline uint32_t count_prb_per_tb_approx(uint32_t nof_rbgs, uint32_t cell_nof_prb)
{
uint32_t P = srslte_ra_type0_P(cell_nof_prb);
return std::min(nof_rbgs * P, cell_nof_prb);
}
ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg); ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg);
/** /**

View File

@ -39,7 +39,7 @@ struct cc_sched_ue {
const static int SCHED_MAX_HARQ_PROC = FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS; const static int SCHED_MAX_HARQ_PROC = FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS;
cc_sched_ue(const sched_interface::ue_cfg_t& cfg_, cc_sched_ue(const sched_interface::ue_cfg_t& cfg_,
const sched_cell_params_t& cell_cfg_, const sched_ue_cell& cell_ue_,
uint16_t rnti_, uint16_t rnti_,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
srslte::tti_point current_tti); srslte::tti_point current_tti);
@ -51,9 +51,9 @@ struct cc_sched_ue {
tbs_info alloc_tbs(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, bool is_ul); tbs_info alloc_tbs(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, bool is_ul);
tbs_info alloc_tbs_dl(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes); tbs_info alloc_tbs_dl(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes);
tbs_info alloc_tbs_ul(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, int explicit_mcs = -1); tbs_info alloc_tbs_ul(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, int explicit_mcs = -1);
int get_required_prb_dl(uint32_t req_bytes, uint32_t nof_ctrl_symbols); int get_required_prb_dl(tti_point tti_tx_dl, uint32_t req_bytes);
uint32_t get_required_prb_ul(uint32_t req_bytes); uint32_t get_required_prb_ul(uint32_t req_bytes);
const sched_cell_params_t* get_cell_cfg() const { return cell_params; } const sched_cell_params_t* get_cell_cfg() const { return cell_ue->cell_cfg; }
uint32_t get_ue_cc_idx() const { return ue_cc_idx; } uint32_t get_ue_cc_idx() const { return ue_cc_idx; }
void set_dl_cqi(tti_point tti_rx, uint32_t dl_cqi); void set_dl_cqi(tti_point tti_rx, uint32_t dl_cqi);
int cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint32_t* mcs); int cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint32_t* mcs);
@ -79,8 +79,8 @@ struct cc_sched_ue {
private: private:
// config // config
srslte::log_ref log_h; srslte::log_ref log_h;
const sched_interface::ue_cfg_t* cfg = nullptr; const sched_interface::ue_cfg_t* cfg = nullptr;
const sched_cell_params_t* cell_params = nullptr; const sched_ue_cell* cell_ue = nullptr;
uint16_t rnti; uint16_t rnti;
uint32_t ue_cc_idx = 0; uint32_t ue_cc_idx = 0;
srslte::tti_point cfg_tti; srslte::tti_point cfg_tti;

View File

@ -183,6 +183,54 @@ prb_interval prb_interval::riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_
* Sched Params * Sched Params
*******************************************************/ *******************************************************/
sched_cell_params_t::dl_nof_re_table generate_nof_re_table(const srslte_cell_t& cell)
{
sched_cell_params_t::dl_nof_re_table table(cell.nof_prb);
srslte_dl_sf_cfg_t dl_sf = {};
dl_sf.sf_type = SRSLTE_SF_NORM;
dl_sf.tdd_config.configured = false;
for (uint32_t cfi = 0; cfi < SRSLTE_NOF_CFI; ++cfi) {
dl_sf.cfi = cfi + 1;
for (uint32_t sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; ++sf_idx) {
dl_sf.tti = sf_idx;
for (uint32_t s = 0; s < SRSLTE_NOF_SLOTS_PER_SF; ++s) {
for (uint32_t n = 0; n < cell.nof_prb; ++n) {
table[n][sf_idx][s][cfi] = ra_re_x_prb(&cell, &dl_sf, s, n);
}
}
}
}
return table;
}
sched_cell_params_t::dl_lb_nof_re_table get_lb_nof_re_x_prb(const sched_cell_params_t::dl_nof_re_table& table)
{
sched_cell_params_t::dl_lb_nof_re_table ret;
for (uint32_t sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; ++sf_idx) {
ret[sf_idx].resize(table.size());
srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB> re_prb_vec(table.size());
for (uint32_t p = 0; p < table.size(); ++p) {
for (uint32_t s = 0; s < SRSLTE_NOF_SLOTS_PER_SF; ++s) {
re_prb_vec[p] += table[p][sf_idx][s][SRSLTE_NOF_CFI - 1];
}
}
srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB> re_prb_vec2(re_prb_vec);
ret[sf_idx][0] = *std::min_element(re_prb_vec2.begin(), re_prb_vec2.end());
for (uint32_t p = 1; p < table.size(); ++p) {
std::transform(re_prb_vec2.begin(),
re_prb_vec2.end() - 1,
re_prb_vec.begin() + p,
re_prb_vec2.begin(),
std::plus<uint32_t>());
re_prb_vec2.pop_back();
ret[sf_idx][p] = *std::min_element(re_prb_vec2.begin(), re_prb_vec2.end());
}
}
return ret;
}
void sched_cell_params_t::regs_deleter::operator()(srslte_regs_t* p) void sched_cell_params_t::regs_deleter::operator()(srslte_regs_t* p)
{ {
if (p != nullptr) { if (p != nullptr) {
@ -269,9 +317,49 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id
P = srslte_ra_type0_P(cfg.cell.nof_prb); P = srslte_ra_type0_P(cfg.cell.nof_prb);
nof_rbgs = srslte::ceil_div(cfg.cell.nof_prb, P); nof_rbgs = srslte::ceil_div(cfg.cell.nof_prb, P);
nof_re_table = generate_nof_re_table(cfg.cell);
nof_re_lb_table = get_lb_nof_re_x_prb(nof_re_table);
return true; return true;
} }
uint32_t sched_cell_params_t::get_dl_lb_nof_re(tti_point tti_tx_dl, uint32_t nof_prbs_alloc) const
{
assert(nof_prbs_alloc <= nof_prb());
if (nof_prbs_alloc == 0) {
return 0;
}
uint32_t sf_idx = tti_tx_dl.sf_idx();
uint32_t nof_re = nof_re_lb_table[sf_idx][nof_prbs_alloc - 1];
// sanity check
assert(nof_re <= srslte_ra_dl_approx_nof_re(&cfg.cell, nof_prbs_alloc, SRSLTE_NOF_CFI));
return nof_re;
}
uint32_t
sched_cell_params_t::get_dl_nof_res(srslte::tti_point tti_tx_dl, const srslte_dci_dl_t& dci, uint32_t cfi) const
{
srslte_pdsch_grant_t grant = {};
srslte_dl_sf_cfg_t dl_sf = {};
dl_sf.cfi = cfi;
dl_sf.tti = tti_tx_dl.to_uint();
srslte_ra_dl_grant_to_grant_prb_allocation(&dci, &grant, nof_prb());
uint32_t nof_re = 0;
for (uint32_t p = 0; p < nof_prb(); ++p) {
for (uint32_t s = 0; s < SRSLTE_NOF_SLOTS_PER_SF; ++s) {
if (grant.prb_idx[s][p]) {
nof_re += nof_re_table[p][tti_tx_dl.sf_idx()][s][cfi - 1];
}
}
}
// sanity check
assert(nof_re == srslte_ra_dl_grant_nof_re(&cfg.cell, &dl_sf, &grant));
return nof_re;
}
ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg) ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg)
{ {
ue_cce_locations_table dci_locations; ue_cce_locations_table dci_locations;

View File

@ -149,10 +149,10 @@ void sched_ue::set_cfg(const ue_cfg_t& cfg_)
if (ue_idx >= prev_supported_cc_list.size()) { if (ue_idx >= prev_supported_cc_list.size()) {
// New carrier needs to be added // New carrier needs to be added
carriers.emplace_back(cfg, *cells[cc_cfg.enb_cc_idx].cell_cfg, rnti, ue_idx, current_tti); carriers.emplace_back(cfg, cells[cc_cfg.enb_cc_idx], rnti, ue_idx, current_tti);
} else if (cc_cfg.enb_cc_idx != prev_supported_cc_list[ue_idx].enb_cc_idx) { } else if (cc_cfg.enb_cc_idx != prev_supported_cc_list[ue_idx].enb_cc_idx) {
// One carrier was added in the place of another // One carrier was added in the place of another
carriers[ue_idx] = cc_sched_ue{cfg, *cells[cc_cfg.enb_cc_idx].cell_cfg, rnti, ue_idx, current_tti}; carriers[ue_idx] = cc_sched_ue{cfg, cells[cc_cfg.enb_cc_idx], rnti, ue_idx, current_tti};
if (ue_idx == 0) { if (ue_idx == 0) {
log_h->info("SCHED: rnti=0x%x PCell is now enb_cc_idx=%d.\n", rnti, cc_cfg.enb_cc_idx); log_h->info("SCHED: rnti=0x%x PCell is now enb_cc_idx=%d.\n", rnti, cc_cfg.enb_cc_idx);
} }
@ -558,12 +558,7 @@ tbs_info sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_idx,
srslte::interval<uint32_t> req_bytes = get_requested_dl_bytes(ue_cc_idx); srslte::interval<uint32_t> req_bytes = get_requested_dl_bytes(ue_cc_idx);
// Calculate exact number of RE for this PRB allocation // Calculate exact number of RE for this PRB allocation
srslte_pdsch_grant_t grant = {}; uint32_t nof_re = carriers[ue_cc_idx].get_cell_cfg()->get_dl_nof_res(tti_tx_dl, dci, cfi);
srslte_dl_sf_cfg_t dl_sf = {};
dl_sf.cfi = cfi;
dl_sf.tti = tti_tx_dl.to_uint();
srslte_ra_dl_grant_to_grant_prb_allocation(&dci, &grant, carriers[ue_cc_idx].get_cell_cfg()->nof_prb());
uint32_t nof_re = srslte_ra_dl_grant_nof_re(&carriers[ue_cc_idx].get_cell_cfg()->cfg.cell, &dl_sf, &grant);
// Compute MCS+TBS // Compute MCS+TBS
tbs_info tb = carriers[ue_cc_idx].alloc_tbs_dl(nof_alloc_prbs, nof_re, req_bytes.stop()); tbs_info tb = carriers[ue_cc_idx].alloc_tbs_dl(nof_alloc_prbs, nof_re, req_bytes.stop());
@ -831,9 +826,8 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t ue_cc_idx)
if (req_bytes == srslte::interval<uint32_t>{0, 0}) { if (req_bytes == srslte::interval<uint32_t>{0, 0}) {
return {0, 0}; return {0, 0};
} }
const auto* cellparams = carriers[ue_cc_idx].get_cell_cfg(); const auto* cellparams = carriers[ue_cc_idx].get_cell_cfg();
int pending_prbs = int pending_prbs = carriers[ue_cc_idx].get_required_prb_dl(to_tx_dl(current_tti), req_bytes.start());
carriers[ue_cc_idx].get_required_prb_dl(req_bytes.start(), cellparams->sched_cfg->max_nof_ctrl_symbols);
if (pending_prbs < 0) { if (pending_prbs < 0) {
// Cannot fit allocation in given PRBs // Cannot fit allocation in given PRBs
log_h->error("SCHED: DL CQI=%d does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. " log_h->error("SCHED: DL CQI=%d does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. "
@ -842,10 +836,10 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t ue_cc_idx)
req_bytes.start()); req_bytes.start());
return {cellparams->nof_prb(), cellparams->nof_prb()}; return {cellparams->nof_prb(), cellparams->nof_prb()};
} }
uint32_t min_pending_rbg = cellparams->prb_to_rbg(pending_prbs); uint32_t min_pending_rbg = cellparams->nof_prbs_to_rbgs(pending_prbs);
pending_prbs = carriers[ue_cc_idx].get_required_prb_dl(req_bytes.stop(), cellparams->sched_cfg->max_nof_ctrl_symbols); pending_prbs = carriers[ue_cc_idx].get_required_prb_dl(to_tx_dl(current_tti), req_bytes.stop());
pending_prbs = (pending_prbs < 0) ? cellparams->nof_prb() : pending_prbs; pending_prbs = (pending_prbs < 0) ? cellparams->nof_prb() : pending_prbs;
uint32_t max_pending_rbg = cellparams->prb_to_rbg(pending_prbs); uint32_t max_pending_rbg = cellparams->nof_prbs_to_rbgs(pending_prbs);
return {min_pending_rbg, max_pending_rbg}; return {min_pending_rbg, max_pending_rbg};
} }
@ -922,12 +916,9 @@ uint32_t sched_ue::get_pending_dl_rlc_data() const
uint32_t sched_ue::get_expected_dl_bitrate(uint32_t ue_cc_idx, int nof_rbgs) const uint32_t sched_ue::get_expected_dl_bitrate(uint32_t ue_cc_idx, int nof_rbgs) const
{ {
const cc_sched_ue* cc = &carriers[ue_cc_idx]; const cc_sched_ue* cc = &carriers[ue_cc_idx];
auto* cell_cfg = carriers[ue_cc_idx].get_cell_cfg(); uint32_t nof_re = cc->get_cell_cfg()->get_dl_lb_nof_re(
uint32_t nof_prbs_alloc = nof_rbgs < 0 ? cell_cfg->nof_prb() : std::min(nof_rbgs * cell_cfg->P, cell_cfg->nof_prb()); to_tx_dl(current_tti), count_prb_per_tb_approx(nof_rbgs, cc->get_cell_cfg()->nof_prb()));
uint32_t nof_re =
srslte_ra_dl_approx_nof_re(&cell_cfg->cfg.cell, nof_prbs_alloc, cell_cfg->sched_cfg->max_nof_ctrl_symbols);
float max_coderate = srslte_cqi_to_coderate(std::min(cc->dl_cqi + 1u, 15u), cfg.use_tbs_index_alt); float max_coderate = srslte_cqi_to_coderate(std::min(cc->dl_cqi + 1u, 15u), cfg.use_tbs_index_alt);
// Inverse of srslte_coderate(tbs, nof_re) // Inverse of srslte_coderate(tbs, nof_re)
@ -1227,27 +1218,29 @@ int cc_sched_ue::cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint3
***********************************************************************************************/ ***********************************************************************************************/
cc_sched_ue::cc_sched_ue(const sched_interface::ue_cfg_t& cfg_, cc_sched_ue::cc_sched_ue(const sched_interface::ue_cfg_t& cfg_,
const sched_cell_params_t& cell_cfg_, const sched_ue_cell& cell_ue_,
uint16_t rnti_, uint16_t rnti_,
uint32_t ue_cc_idx_, uint32_t ue_cc_idx_,
tti_point current_tti) : tti_point current_tti) :
cell_params(&cell_cfg_), cell_ue(&cell_ue_),
rnti(rnti_), rnti(rnti_),
log_h(srslte::logmap::get("MAC ")), log_h(srslte::logmap::get("MAC")),
ue_cc_idx(ue_cc_idx_), ue_cc_idx(ue_cc_idx_),
last_tti(current_tti), last_tti(current_tti),
harq_ent(SCHED_MAX_HARQ_PROC, SCHED_MAX_HARQ_PROC), harq_ent(SCHED_MAX_HARQ_PROC, SCHED_MAX_HARQ_PROC),
tpc_fsm(cell_cfg_.nof_prb(), cell_cfg_.cfg.target_ul_sinr, cell_cfg_.cfg.enable_phr_handling) tpc_fsm(cell_ue_.cell_cfg->nof_prb(),
cell_ue_.cell_cfg->cfg.target_ul_sinr,
cell_ue_.cell_cfg->cfg.enable_phr_handling)
{ {
dl_cqi_rx = false; dl_cqi_rx = false;
dl_cqi = (ue_cc_idx == 0) ? cell_params->cfg.initial_dl_cqi : 0; dl_cqi = (ue_cc_idx == 0) ? cell_ue_.cell_cfg->cfg.initial_dl_cqi : 0;
set_cfg(cfg_); set_cfg(cfg_);
max_aggr_level = cell_params->sched_cfg->max_aggr_level >= 0 ? cell_params->sched_cfg->max_aggr_level : 3; max_aggr_level = cell_ue->cell_cfg->sched_cfg->max_aggr_level >= 0 ? cell_ue->cell_cfg->sched_cfg->max_aggr_level : 3;
// set fixed mcs // set fixed mcs
fixed_mcs_dl = cell_params->sched_cfg->pdsch_mcs; fixed_mcs_dl = cell_ue->cell_cfg->sched_cfg->pdsch_mcs;
fixed_mcs_ul = cell_params->sched_cfg->pusch_mcs; fixed_mcs_ul = cell_ue->cell_cfg->sched_cfg->pusch_mcs;
} }
void cc_sched_ue::reset() void cc_sched_ue::reset()
@ -1269,12 +1262,13 @@ void cc_sched_ue::set_cfg(const sched_interface::ue_cfg_t& cfg_)
cfg_tti = last_tti; cfg_tti = last_tti;
// set max mcs // set max mcs
max_mcs_ul = cell_params->sched_cfg->pusch_max_mcs >= 0 ? cell_params->sched_cfg->pusch_max_mcs : 28u; max_mcs_ul = get_cell_cfg()->sched_cfg->pusch_max_mcs >= 0 ? get_cell_cfg()->sched_cfg->pusch_max_mcs : 28u;
if (cell_params->cfg.enable_64qam) { if (get_cell_cfg()->cfg.enable_64qam) {
const uint32_t max_64qam_mcs[] = {20, 24, 28}; const uint32_t max_64qam_mcs[] = {20, 24, 28};
max_mcs_ul = std::min(max_mcs_ul, max_64qam_mcs[(size_t)cfg->support_ul64qam]); max_mcs_ul = std::min(max_mcs_ul, max_64qam_mcs[(size_t)cfg->support_ul64qam]);
} }
max_mcs_dl = cell_params->sched_cfg->pdsch_max_mcs >= 0 ? std::min(cell_params->sched_cfg->pdsch_max_mcs, 28) : 28u; max_mcs_dl =
get_cell_cfg()->sched_cfg->pdsch_max_mcs >= 0 ? std::min(get_cell_cfg()->sched_cfg->pdsch_max_mcs, 28) : 28u;
if (cfg->use_tbs_index_alt) { if (cfg->use_tbs_index_alt) {
max_mcs_dl = std::min(max_mcs_dl, 27u); max_mcs_dl = std::min(max_mcs_dl, 27u);
} }
@ -1325,7 +1319,7 @@ void cc_sched_ue::finish_tti(tti_point tti_rx)
uint32_t cc_sched_ue::get_aggr_level(uint32_t nof_bits) uint32_t cc_sched_ue::get_aggr_level(uint32_t nof_bits)
{ {
return srsenb::get_aggr_level(nof_bits, dl_cqi, max_aggr_level, cell_params->nof_prb(), cfg->use_tbs_index_alt); return srsenb::get_aggr_level(nof_bits, dl_cqi, max_aggr_level, get_cell_cfg()->nof_prb(), cfg->use_tbs_index_alt);
} }
/* In this scheduler we tend to use all the available bandwidth and select the MCS /* In this scheduler we tend to use all the available bandwidth and select the MCS
@ -1407,16 +1401,16 @@ tbs_info cc_sched_ue::alloc_tbs_ul(uint32_t nof_prb, uint32_t nof_re, uint32_t r
return ret; return ret;
} }
int cc_sched_ue::get_required_prb_dl(uint32_t req_bytes, uint32_t nof_ctrl_symbols) int cc_sched_ue::get_required_prb_dl(tti_point tti_tx_dl, uint32_t req_bytes)
{ {
auto compute_tbs_approx = [this, nof_ctrl_symbols](uint32_t nof_prb) { auto compute_tbs_approx = [tti_tx_dl, this](uint32_t nof_prb) {
uint32_t nof_re = srslte_ra_dl_approx_nof_re(&cell_params->cfg.cell, nof_prb, nof_ctrl_symbols); uint32_t nof_re = cell_ue->cell_cfg->get_dl_lb_nof_re(tti_tx_dl, nof_prb);
tbs_info tb = alloc_tbs_dl(nof_prb, nof_re, 0); tbs_info tb = alloc_tbs_dl(nof_prb, nof_re, 0);
return tb.tbs_bytes; return tb.tbs_bytes;
}; };
std::tuple<uint32_t, int, uint32_t, int> ret = false_position_method( std::tuple<uint32_t, int, uint32_t, int> ret = false_position_method(
1u, cell_params->nof_prb(), (int)req_bytes, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; }); 1u, get_cell_cfg()->nof_prb(), (int)req_bytes, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; });
int upper_tbs = std::get<3>(ret); int upper_tbs = std::get<3>(ret);
uint32_t upper_nprb = std::get<2>(ret); uint32_t upper_nprb = std::get<2>(ret);
return (upper_tbs < 0) ? 0 : ((upper_tbs < (int)req_bytes) ? -1 : upper_nprb); return (upper_tbs < 0) ? 0 : ((upper_tbs < (int)req_bytes) ? -1 : upper_nprb);
@ -1429,17 +1423,17 @@ uint32_t cc_sched_ue::get_required_prb_ul(uint32_t req_bytes)
} }
auto compute_tbs_approx = [this](uint32_t nof_prb) { auto compute_tbs_approx = [this](uint32_t nof_prb) {
const uint32_t N_srs = 0; const uint32_t N_srs = 0;
uint32_t nof_re = (2 * (SRSLTE_CP_NSYMB(cell_params->cfg.cell.cp) - 1) - N_srs) * nof_prb * SRSLTE_NRE; uint32_t nof_re = (2 * (SRSLTE_CP_NSYMB(get_cell_cfg()->cfg.cell.cp) - 1) - N_srs) * nof_prb * SRSLTE_NRE;
return alloc_tbs_ul(nof_prb, nof_re, 0).tbs_bytes; return alloc_tbs_ul(nof_prb, nof_re, 0).tbs_bytes;
}; };
// find nof prbs that lead to a tbs just above req_bytes // find nof prbs that lead to a tbs just above req_bytes
int target_tbs = req_bytes + 4; int target_tbs = req_bytes + 4;
uint32_t max_prbs = std::min(tpc_fsm.max_ul_prbs(), cell_params->nof_prb()); uint32_t max_prbs = std::min(tpc_fsm.max_ul_prbs(), get_cell_cfg()->nof_prb());
std::tuple<uint32_t, int, uint32_t, int> ret = std::tuple<uint32_t, int, uint32_t, int> ret =
false_position_method(1u, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; }); false_position_method(1u, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; });
uint32_t req_prbs = std::get<2>(ret); uint32_t req_prbs = std::get<2>(ret);
while (!srslte_dft_precoding_valid_prb(req_prbs) && req_prbs < cell_params->nof_prb()) { while (!srslte_dft_precoding_valid_prb(req_prbs) && req_prbs < get_cell_cfg()->nof_prb()) {
req_prbs++; req_prbs++;
} }
return req_prbs; return req_prbs;

View File

@ -12,9 +12,14 @@
#include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h" #include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h"
#include "srsenb/hdr/stack/mac/sched_helpers.h" #include "srsenb/hdr/stack/mac/sched_helpers.h"
#include <numeric>
namespace srsenb { namespace srsenb {
/*******************************************************
* sched_ue_cell
*******************************************************/
sched_ue_cell::sched_ue_cell(uint16_t rnti_, const sched_cell_params_t& cell_cfg_) : sched_ue_cell::sched_ue_cell(uint16_t rnti_, const sched_cell_params_t& cell_cfg_) :
rnti(rnti_), cell_cfg(&cell_cfg_), dci_locations(generate_cce_location_table(rnti_, cell_cfg_)) rnti(rnti_), cell_cfg(&cell_cfg_), dci_locations(generate_cce_location_table(rnti_, cell_cfg_))
{} {}