refactored cce position table structs

This commit is contained in:
Francisco 2021-02-15 16:18:56 +00:00 committed by Francisco Paisana
parent 823da24a8e
commit c1adaec038
10 changed files with 80 additions and 79 deletions

View File

@ -23,17 +23,24 @@ namespace srsenb {
* Constants
**********************/
constexpr float tti_duration_ms = 1;
constexpr float tti_duration_ms = 1;
constexpr uint32_t NOF_AGGR_LEVEL = 4;
/***********************
* Helper Types
**********************/
//! Struct used to store possible CCE locations.
struct sched_dci_cce_t {
uint32_t cce_start[4][6]; ///< Stores starting CCE for each aggr level index and CCE location index
uint32_t nof_loc[4]; ///< Number of possible CCE locations for each aggregation level index
};
/// List of CCE start positions in PDCCH
using cce_position_list = srslte::bounded_vector<uint32_t, 6>;
/// Map {L} -> list of CCE positions
using cce_cfi_position_table = std::array<cce_position_list, NOF_AGGR_LEVEL>;
/// Map {cfi, L} -> list of CCE positions
using cce_sf_position_table = std::array<std::array<cce_position_list, NOF_AGGR_LEVEL>, SRSLTE_NOF_CFI>;
/// Map {sf, cfi, L} -> list of CCE positions
using cce_frame_position_table = std::array<cce_sf_position_table, SRSLTE_NOF_SF_X_FRAME>;
/// structs to bundle together all the sched arguments, and share them with all the sched sub-components
class sched_cell_params_t
@ -52,15 +59,15 @@ public:
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;
sched_interface::cell_cfg_t cfg = {};
const sched_interface::sched_args_t* sched_cfg = nullptr;
std::unique_ptr<srslte_regs_t, regs_deleter> regs;
std::array<sched_dci_cce_t, 3> common_locations = {};
std::array<std::array<sched_dci_cce_t, 10>, 3> rar_locations = {};
std::array<uint32_t, 3> nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH
uint32_t P = 0;
uint32_t nof_rbgs = 0;
uint32_t enb_cc_idx = 0;
sched_interface::cell_cfg_t cfg = {};
const sched_interface::sched_args_t* sched_cfg = nullptr;
std::unique_ptr<srslte_regs_t, regs_deleter> regs;
cce_sf_position_table common_locations = {};
cce_frame_position_table rar_locations = {};
std::array<uint32_t, SRSLTE_NOF_CFI> nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH
uint32_t P = 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>,
@ -73,8 +80,6 @@ public:
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>;
//! Bitmask used for CCE allocations
using pdcch_mask_t = srslte::bounded_bitset<sched_interface::max_cce, true>;

View File

@ -107,7 +107,7 @@ inline uint32_t count_prb_per_tb_approx(uint32_t nof_rbgs, uint32_t 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);
cce_frame_position_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg);
/**
* Generate possible CCE locations a user can use to allocate DCIs
@ -117,11 +117,11 @@ ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_ce
* @param sf_idx subframe index specific to the tx TTI (relevant only for data and RAR transmissions)
* @param rnti identity of the user (invalid RNTI for RAR and BC transmissions)
*/
void generate_cce_location(srslte_regs_t* regs,
sched_dci_cce_t* location,
uint32_t cfi,
uint32_t sf_idx = 0,
uint16_t rnti = SRSLTE_INVALID_RNTI);
void generate_cce_location(srslte_regs_t* regs,
cce_cfi_position_table& locations,
uint32_t cfi,
uint32_t sf_idx = 0,
uint16_t rnti = SRSLTE_INVALID_RNTI);
/// Obtains TB size *in bytes* for a given MCS and nof allocated prbs
inline uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool use_tbs_index_alt, bool is_ul)

View File

@ -69,16 +69,16 @@ private:
alloc_type_t alloc_type;
};
const alloc_tree_t& get_alloc_tree() const { return alloc_trees[current_cfix]; }
const sched_dci_cce_t* get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const;
const alloc_tree_t& get_alloc_tree() const { return alloc_trees[current_cfix]; }
const cce_cfi_position_table* get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const;
// PDCCH allocation algorithm
bool alloc_dci_record(const alloc_record_t& record, uint32_t cfix);
static bool add_tree_node_leaves(alloc_tree_t& tree,
int node_idx,
const alloc_record_t& dci_record,
const sched_dci_cce_t& dci_locs,
tti_point tti_tx_dl);
static bool add_tree_node_leaves(alloc_tree_t& tree,
int node_idx,
const alloc_record_t& dci_record,
const cce_cfi_position_table& dci_locs,
tti_point tti_tx_dl);
// consts
const sched_cell_params_t* cc_cfg = nullptr;

View File

@ -126,8 +126,8 @@ public:
int explicit_mcs = -1,
uci_pusch_t uci_type = UCI_PUSCH_NONE);
srslte_dci_format_t get_dci_format();
const sched_dci_cce_t* get_locations(uint32_t enb_cc_idx, uint32_t current_cfi, uint32_t sf_idx) const;
srslte_dci_format_t get_dci_format();
const cce_cfi_position_table* get_locations(uint32_t enb_cc_idx, uint32_t current_cfi, uint32_t sf_idx) const;
sched_ue_cell* find_ue_carrier(uint32_t enb_cc_idx);
size_t nof_carriers_configured() const { return cfg.supported_cc_list.size(); }

View File

@ -52,7 +52,7 @@ struct sched_ue_cell {
const sched_cell_params_t* cell_cfg = nullptr;
/// Allowed DCI locations per per CFI and per subframe
const ue_cce_locations_table dci_locations;
const cce_frame_position_table dci_locations;
/// Cell HARQ Entity
harq_entity harq_ent;

View File

@ -51,7 +51,6 @@ void sched::init(rrc_interface_mac* rrc_, const sched_args_t& sched_cfg_)
int sched::reset()
{
std::lock_guard<std::mutex> lock(sched_mutex);
configured.store(false, std::memory_order_release);
for (std::unique_ptr<carrier_sched>& c : carrier_schedulers) {
c->reset();
}

View File

@ -295,9 +295,9 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id
// Compute Common locations for DCI for each CFI
for (uint32_t cfix = 0; cfix < SRSLTE_NOF_CFI; cfix++) {
generate_cce_location(regs.get(), &common_locations[cfix], cfix + 1);
generate_cce_location(regs.get(), common_locations[cfix], cfix + 1);
}
if (common_locations[sched_cfg->max_nof_ctrl_symbols - 1].nof_loc[2] == 0) {
if (common_locations[sched_cfg->max_nof_ctrl_symbols - 1][2].empty()) {
Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).",
sched_cfg->max_nof_ctrl_symbols);
srslte::console(
@ -307,9 +307,9 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id
}
// Compute UE locations for RA-RNTI
for (uint32_t cfi = 0; cfi < 3; cfi++) {
for (uint32_t sf_idx = 0; sf_idx < 10; sf_idx++) {
generate_cce_location(regs.get(), &rar_locations[cfi][sf_idx], cfi + 1, sf_idx);
for (uint32_t cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) {
for (uint32_t sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) {
generate_cce_location(regs.get(), rar_locations[sf_idx][cfi], cfi + 1, sf_idx);
}
}
@ -369,25 +369,25 @@ sched_cell_params_t::get_dl_nof_res(srslte::tti_point tti_tx_dl, const srslte_dc
return nof_re;
}
ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg)
cce_frame_position_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg)
{
ue_cce_locations_table dci_locations;
cce_frame_position_table dci_locations = {};
// Generate allowed CCE locations
for (int cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) {
for (int sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) {
generate_cce_location(cell_cfg.regs.get(), &dci_locations[cfi][sf_idx], cfi + 1, sf_idx, rnti);
generate_cce_location(cell_cfg.regs.get(), dci_locations[sf_idx][cfi], cfi + 1, sf_idx, rnti);
}
}
return dci_locations;
}
void generate_cce_location(srslte_regs_t* regs_,
sched_dci_cce_t* location,
uint32_t cfi,
uint32_t sf_idx,
uint16_t rnti)
void generate_cce_location(srslte_regs_t* regs_,
cce_cfi_position_table& locations,
uint32_t cfi,
uint32_t sf_idx,
uint16_t rnti)
{
*location = {};
locations = {};
srslte_dci_location_t loc[64];
uint32_t nloc = 0;
@ -399,9 +399,8 @@ void generate_cce_location(srslte_regs_t* regs_,
// Save to different format
for (uint32_t i = 0; i < nloc; i++) {
uint32_t l = loc[i].L;
location->cce_start[l][location->nof_loc[l]] = loc[i].ncce;
location->nof_loc[l]++;
uint32_t l = loc[i].L;
locations[l].push_back(loc[i].ncce);
}
}

View File

@ -45,7 +45,8 @@ void pdcch_sched::new_tti(tti_point tti_rx_)
current_cfix = cc_cfg->sched_cfg->min_nof_ctrl_symbols - 1;
}
const sched_dci_cce_t* pdcch_sched::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const
const cce_cfi_position_table*
pdcch_sched::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const
{
switch (alloc_type) {
case alloc_type_t::DL_BC:
@ -53,7 +54,7 @@ const sched_dci_cce_t* pdcch_sched::get_cce_loc_table(alloc_type_t alloc_type, s
case alloc_type_t::DL_PCCH:
return &cc_cfg->common_locations[cfix];
case alloc_type_t::DL_RAR:
return &cc_cfg->rar_locations[cfix][to_tx_dl(tti_rx).sf_idx()];
return &cc_cfg->rar_locations[to_tx_dl(tti_rx).sf_idx()][cfix];
case alloc_type_t::DL_DATA:
return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx());
case alloc_type_t::UL_DATA:
@ -95,8 +96,8 @@ bool pdcch_sched::alloc_dci_record(const alloc_record_t& record, uint32_t cfix)
auto& tree = alloc_trees[cfix];
// Get DCI Location Table
const sched_dci_cce_t* dci_locs = get_cce_loc_table(record.alloc_type, record.user, cfix);
if (dci_locs == nullptr or dci_locs->nof_loc[record.aggr_idx] == 0) {
const cce_cfi_position_table* dci_locs = get_cce_loc_table(record.alloc_type, record.user, cfix);
if (dci_locs == nullptr or (*dci_locs)[record.aggr_idx].empty()) {
return ret;
}
@ -117,11 +118,11 @@ bool pdcch_sched::alloc_dci_record(const alloc_record_t& record, uint32_t cfix)
}
//! Algorithm to compute a valid PDCCH allocation
bool pdcch_sched::add_tree_node_leaves(alloc_tree_t& tree,
int parent_node_idx,
const alloc_record_t& dci_record,
const sched_dci_cce_t& dci_locs,
tti_point tti_tx_dl)
bool pdcch_sched::add_tree_node_leaves(alloc_tree_t& tree,
int parent_node_idx,
const alloc_record_t& dci_record,
const cce_cfi_position_table& dci_locs,
tti_point tti_tx_dl)
{
bool ret = false;
@ -137,9 +138,8 @@ bool pdcch_sched::add_tree_node_leaves(alloc_tree_t& tree,
cum_mask.resize(tree.nof_cces);
}
uint32_t nof_locs = dci_locs.nof_loc[dci_record.aggr_idx];
for (uint32_t i = 0; i < nof_locs; ++i) {
uint32_t startpos = dci_locs.cce_start[dci_record.aggr_idx][i];
for (uint32_t i = 0; i < dci_locs[dci_record.aggr_idx].size(); ++i) {
uint32_t startpos = dci_locs[dci_record.aggr_idx][i];
if (dci_record.alloc_type == alloc_type_t::DL_DATA and dci_record.user->pucch_sr_collision(tti_tx_dl, startpos)) {
// will cause a collision in the PUCCH

View File

@ -1047,13 +1047,13 @@ srslte_dci_format_t sched_ue::get_dci_format()
return ret;
}
const sched_dci_cce_t* sched_ue::get_locations(uint32_t enb_cc_idx, uint32_t cfi, uint32_t sf_idx) const
const cce_cfi_position_table* sched_ue::get_locations(uint32_t enb_cc_idx, uint32_t cfi, uint32_t sf_idx) const
{
if (cfi > 0 && cfi <= 3) {
return &cells[enb_cc_idx].dci_locations[cfi - 1][sf_idx];
return &cells[enb_cc_idx].dci_locations[sf_idx][cfi - 1];
} else {
logger.error("SCHED: Invalid CFI=%d", cfi);
return &cells[enb_cc_idx].dci_locations[0][sf_idx];
return &cells[enb_cc_idx].dci_locations[sf_idx][0];
}
}

View File

@ -66,12 +66,12 @@ int test_pdcch_one_ue()
sched_ue.set_dl_cqi(to_tx_dl(tti_rx), ENB_CC_IDX, dl_cqi);
uint32_t aggr_idx = get_aggr_level(sched_ue, PCell_IDX, cell_params);
uint32_t max_nof_cce_locs =
sched_ue.get_locations(ENB_CC_IDX, pdcch_sched::MAX_CFI, to_tx_dl(tti_rx).sf_idx())->nof_loc[aggr_idx];
(*sched_ue.get_locations(ENB_CC_IDX, pdcch_sched::MAX_CFI, to_tx_dl(tti_rx).sf_idx()))[aggr_idx].size();
// allocate DL user
uint32_t prev_cfi = pdcch.get_cfi();
const srsenb::sched_dci_cce_t* dci_cce = sched_ue.get_locations(ENB_CC_IDX, prev_cfi, to_tx_dl(tti_rx).sf_idx());
uint32_t prev_nof_cce_locs = dci_cce->nof_loc[aggr_idx];
uint32_t prev_cfi = pdcch.get_cfi();
const cce_cfi_position_table* dci_cce = sched_ue.get_locations(ENB_CC_IDX, prev_cfi, to_tx_dl(tti_rx).sf_idx());
uint32_t prev_nof_cce_locs = (*dci_cce)[aggr_idx].size();
TESTASSERT(pdcch.alloc_dci(alloc_type_t::DL_DATA, aggr_idx, &sched_ue));
TESTASSERT(pdcch.nof_allocs() == 1);
@ -83,9 +83,8 @@ int test_pdcch_one_ue()
TESTASSERT(pdcch.get_cfi() == prev_cfi);
}
dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx());
uint32_t nof_dci_locs = dci_cce->nof_loc[aggr_idx];
const uint32_t* dci_locs = dci_cce->cce_start[aggr_idx];
dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx());
const cce_position_list& dci_locs = (*dci_cce)[aggr_idx];
// TEST: Check the first alloc of the pdcch result (e.g. rnti, valid cce mask, etc.)
pdcch_sched::alloc_result_t pdcch_result;
@ -96,14 +95,14 @@ int test_pdcch_one_ue()
TESTASSERT(pdcch_result[0]->total_mask.size() == cell_params[ENB_CC_IDX].nof_cce_table[pdcch.get_cfi() - 1]);
TESTASSERT(pdcch_result[0]->current_mask == pdcch_result[0]->total_mask);
TESTASSERT(pdcch_result[0]->current_mask.count() == 1u << aggr_idx);
TESTASSERT(std::count(dci_locs, dci_locs + nof_dci_locs, pdcch_result[0]->dci_pos.ncce) > 0);
TESTASSERT(std::count(dci_locs.begin(), dci_locs.end(), pdcch_result[0]->dci_pos.ncce) > 0);
// allocate UL user
if (max_nof_cce_locs == pdcch.nof_allocs()) {
// no more space
continue;
}
prev_nof_cce_locs = nof_dci_locs;
prev_nof_cce_locs = dci_locs.size();
prev_cfi = pdcch.get_cfi();
TESTASSERT(pdcch.alloc_dci(alloc_type_t::UL_DATA, aggr_idx, &sched_ue));
TESTASSERT(pdcch.nof_allocs() == 2);
@ -115,9 +114,8 @@ int test_pdcch_one_ue()
TESTASSERT(pdcch.get_cfi() == prev_cfi);
}
dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx());
nof_dci_locs = dci_cce->nof_loc[aggr_idx];
dci_locs = dci_cce->cce_start[aggr_idx];
dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx());
const cce_position_list& dci_locs2 = (*dci_cce)[aggr_idx];
pdcch.get_allocs(&pdcch_result, &pdcch_mask, 0);
TESTASSERT(pdcch_result.size() == pdcch.nof_allocs());
@ -126,7 +124,7 @@ int test_pdcch_one_ue()
TESTASSERT((pdcch_result[1]->current_mask & pdcch_result[0]->current_mask).none());
TESTASSERT(pdcch_result[1]->current_mask.count() == 1u << aggr_idx);
TESTASSERT(pdcch_result[1]->total_mask == (pdcch_result[0]->current_mask | pdcch_result[1]->current_mask));
TESTASSERT(std::count(dci_locs, dci_locs + nof_dci_locs, pdcch_result[0]->dci_pos.ncce) > 0);
TESTASSERT(std::count(dci_locs2.begin(), dci_locs2.end(), pdcch_result[0]->dci_pos.ncce) > 0);
srslog::fetch_basic_logger("TEST").info("PDCCH alloc result: %s", pdcch.result_to_string(true).c_str());
}