diff --git a/srsenb/hdr/stack/mac/sched_common.h b/srsenb/hdr/stack/mac/sched_common.h index d5869a1d6..2732b3830 100644 --- a/srsenb/hdr/stack/mac/sched_common.h +++ b/srsenb/hdr/stack/mac/sched_common.h @@ -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; + +/// Map {L} -> list of CCE positions +using cce_cfi_position_table = std::array; + +/// Map {cfi, L} -> list of CCE positions +using cce_sf_position_table = std::array, SRSLTE_NOF_CFI>; + +/// Map {sf, cfi, L} -> list of CCE positions +using cce_frame_position_table = std::array; /// 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 regs; - std::array common_locations = {}; - std::array, 3> rar_locations = {}; - std::array 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 regs; + cce_sf_position_table common_locations = {}; + cce_frame_position_table rar_locations = {}; + std::array 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, 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, SRSLTE_NOF_CFI>; - //! Bitmask used for CCE allocations using pdcch_mask_t = srslte::bounded_bitset; diff --git a/srsenb/hdr/stack/mac/sched_helpers.h b/srsenb/hdr/stack/mac/sched_helpers.h index 776699f4b..bba6bcced 100644 --- a/srsenb/hdr/stack/mac/sched_helpers.h +++ b/srsenb/hdr/stack/mac/sched_helpers.h @@ -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) diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/pdcch_sched.h b/srsenb/hdr/stack/mac/sched_phy_ch/pdcch_sched.h index 2fec6af1d..b8f2c024c 100644 --- a/srsenb/hdr/stack/mac/sched_phy_ch/pdcch_sched.h +++ b/srsenb/hdr/stack/mac/sched_phy_ch/pdcch_sched.h @@ -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; diff --git a/srsenb/hdr/stack/mac/sched_ue.h b/srsenb/hdr/stack/mac/sched_ue.h index 862102410..bf009a5ac 100644 --- a/srsenb/hdr/stack/mac/sched_ue.h +++ b/srsenb/hdr/stack/mac/sched_ue.h @@ -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(); } diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index dd5fb0b80..47a503375 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h @@ -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; diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index e8f23ca27..7c414d9cf 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -51,7 +51,6 @@ void sched::init(rrc_interface_mac* rrc_, const sched_args_t& sched_cfg_) int sched::reset() { std::lock_guard lock(sched_mutex); - configured.store(false, std::memory_order_release); for (std::unique_ptr& c : carrier_schedulers) { c->reset(); } diff --git a/srsenb/src/stack/mac/sched_helpers.cc b/srsenb/src/stack/mac/sched_helpers.cc index 1575fab9e..a5891425d 100644 --- a/srsenb/src/stack/mac/sched_helpers.cc +++ b/srsenb/src/stack/mac/sched_helpers.cc @@ -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); } } diff --git a/srsenb/src/stack/mac/sched_phy_ch/pdcch_sched.cc b/srsenb/src/stack/mac/sched_phy_ch/pdcch_sched.cc index cea003227..e8c1929e4 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/pdcch_sched.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/pdcch_sched.cc @@ -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 diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index 43afb31a6..4c651cf51 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -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]; } } diff --git a/srsenb/test/mac/sched_grid_test.cc b/srsenb/test/mac/sched_grid_test.cc index 42e8b6e7b..5953bb106 100644 --- a/srsenb/test/mac/sched_grid_test.cc +++ b/srsenb/test/mac/sched_grid_test.cc @@ -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()); }