refactored cce position table structs

master
Francisco 4 years ago committed by Francisco Paisana
parent 823da24a8e
commit c1adaec038

@ -24,16 +24,23 @@ namespace srsenb {
**********************/ **********************/
constexpr float tti_duration_ms = 1; constexpr float tti_duration_ms = 1;
constexpr uint32_t NOF_AGGR_LEVEL = 4;
/*********************** /***********************
* Helper Types * Helper Types
**********************/ **********************/
//! Struct used to store possible CCE locations. /// List of CCE start positions in PDCCH
struct sched_dci_cce_t { using cce_position_list = srslte::bounded_vector<uint32_t, 6>;
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 /// 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 /// structs to bundle together all the sched arguments, and share them with all the sched sub-components
class sched_cell_params_t class sched_cell_params_t
@ -56,9 +63,9 @@ public:
sched_interface::cell_cfg_t cfg = {}; sched_interface::cell_cfg_t cfg = {};
const sched_interface::sched_args_t* sched_cfg = nullptr; const sched_interface::sched_args_t* sched_cfg = nullptr;
std::unique_ptr<srslte_regs_t, regs_deleter> regs; std::unique_ptr<srslte_regs_t, regs_deleter> regs;
std::array<sched_dci_cce_t, 3> common_locations = {}; cce_sf_position_table common_locations = {};
std::array<std::array<sched_dci_cce_t, 10>, 3> rar_locations = {}; cce_frame_position_table rar_locations = {};
std::array<uint32_t, 3> nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH std::array<uint32_t, SRSLTE_NOF_CFI> 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;
@ -73,8 +80,6 @@ public:
dl_lb_nof_re_table nof_re_lb_table; 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 //! Bitmask used for CCE allocations
using pdcch_mask_t = srslte::bounded_bitset<sched_interface::max_cce, true>; using pdcch_mask_t = srslte::bounded_bitset<sched_interface::max_cce, true>;

@ -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); 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 * Generate possible CCE locations a user can use to allocate DCIs
@ -118,7 +118,7 @@ ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_ce
* @param rnti identity of the user (invalid RNTI for RAR and BC transmissions) * @param rnti identity of the user (invalid RNTI for RAR and BC transmissions)
*/ */
void generate_cce_location(srslte_regs_t* regs, void generate_cce_location(srslte_regs_t* regs,
sched_dci_cce_t* location, cce_cfi_position_table& locations,
uint32_t cfi, uint32_t cfi,
uint32_t sf_idx = 0, uint32_t sf_idx = 0,
uint16_t rnti = SRSLTE_INVALID_RNTI); uint16_t rnti = SRSLTE_INVALID_RNTI);

@ -70,14 +70,14 @@ private:
}; };
const alloc_tree_t& get_alloc_tree() const { return alloc_trees[current_cfix]; } 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 cce_cfi_position_table* get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const;
// PDCCH allocation algorithm // PDCCH allocation algorithm
bool alloc_dci_record(const alloc_record_t& record, uint32_t cfix); bool alloc_dci_record(const alloc_record_t& record, uint32_t cfix);
static bool add_tree_node_leaves(alloc_tree_t& tree, static bool add_tree_node_leaves(alloc_tree_t& tree,
int node_idx, int node_idx,
const alloc_record_t& dci_record, const alloc_record_t& dci_record,
const sched_dci_cce_t& dci_locs, const cce_cfi_position_table& dci_locs,
tti_point tti_tx_dl); tti_point tti_tx_dl);
// consts // consts

@ -127,7 +127,7 @@ public:
uci_pusch_t uci_type = UCI_PUSCH_NONE); uci_pusch_t uci_type = UCI_PUSCH_NONE);
srslte_dci_format_t get_dci_format(); 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; 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); sched_ue_cell* find_ue_carrier(uint32_t enb_cc_idx);
size_t nof_carriers_configured() const { return cfg.supported_cc_list.size(); } size_t nof_carriers_configured() const { return cfg.supported_cc_list.size(); }

@ -52,7 +52,7 @@ struct sched_ue_cell {
const sched_cell_params_t* cell_cfg = nullptr; const sched_cell_params_t* cell_cfg = nullptr;
/// Allowed DCI locations per per CFI and per subframe /// 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 /// Cell HARQ Entity
harq_entity harq_ent; harq_entity harq_ent;

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

@ -295,9 +295,9 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id
// Compute Common locations for DCI for each CFI // Compute Common locations for DCI for each CFI
for (uint32_t cfix = 0; cfix < SRSLTE_NOF_CFI; cfix++) { 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).", 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); sched_cfg->max_nof_ctrl_symbols);
srslte::console( srslte::console(
@ -307,9 +307,9 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id
} }
// Compute UE locations for RA-RNTI // Compute UE locations for RA-RNTI
for (uint32_t cfi = 0; cfi < 3; cfi++) { for (uint32_t cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) {
for (uint32_t sf_idx = 0; sf_idx < 10; sf_idx++) { for (uint32_t sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) {
generate_cce_location(regs.get(), &rar_locations[cfi][sf_idx], cfi + 1, 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; 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 // Generate allowed CCE locations
for (int cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) { for (int cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) {
for (int sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) { 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; return dci_locations;
} }
void generate_cce_location(srslte_regs_t* regs_, void generate_cce_location(srslte_regs_t* regs_,
sched_dci_cce_t* location, cce_cfi_position_table& locations,
uint32_t cfi, uint32_t cfi,
uint32_t sf_idx, uint32_t sf_idx,
uint16_t rnti) uint16_t rnti)
{ {
*location = {}; locations = {};
srslte_dci_location_t loc[64]; srslte_dci_location_t loc[64];
uint32_t nloc = 0; uint32_t nloc = 0;
@ -400,8 +400,7 @@ void generate_cce_location(srslte_regs_t* regs_,
// Save to different format // Save to different format
for (uint32_t i = 0; i < nloc; i++) { for (uint32_t i = 0; i < nloc; i++) {
uint32_t l = loc[i].L; uint32_t l = loc[i].L;
location->cce_start[l][location->nof_loc[l]] = loc[i].ncce; locations[l].push_back(loc[i].ncce);
location->nof_loc[l]++;
} }
} }

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

@ -1047,13 +1047,13 @@ srslte_dci_format_t sched_ue::get_dci_format()
return ret; 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) { 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 { } else {
logger.error("SCHED: Invalid CFI=%d", cfi); 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];
} }
} }

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

Loading…
Cancel
Save