diff --git a/srsgnb/hdr/stack/mac/sched_nr_cfg.h b/srsgnb/hdr/stack/mac/sched_nr_cfg.h index 6c70e24b6..b7af47215 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_cfg.h +++ b/srsgnb/hdr/stack/mac/sched_nr_cfg.h @@ -146,32 +146,7 @@ public: { return cce_positions_list[ss_id_to_cce_idx[search_id]]; } - const srsran_search_space_t* find_ss_with_dci_format(srsran_dci_format_nr_t valid_format) const - { - auto active_ss_lst = view_active_search_spaces(phy().pdcch); - for (const srsran_search_space_t& ss : active_ss_lst) { - for (uint32_t i = 0; i < ss.nof_formats; ++i) { - if (ss.formats[i] == valid_format) { - return &ss; - } - } - } - return nullptr; - } - const srsran_search_space_t* find_ss(uint32_t aggr_idx, bool is_dl) const - { - using format_list_t = std::array; - static const format_list_t ul_formats{srsran_dci_format_nr_0_1, srsran_dci_format_nr_0_0}; - static const format_list_t dl_formats{srsran_dci_format_nr_1_1, srsran_dci_format_nr_1_0}; - const format_list_t& formats = is_dl ? dl_formats : ul_formats; - for (srsran_dci_format_nr_t f : formats) { - const srsran_search_space_t* ss = find_ss_with_dci_format(f); - if (ss != nullptr and ss->nof_candidates[aggr_idx] > 0) { - return ss; - } - } - return nullptr; - } + uint32_t get_k1(slot_point pdsch_slot) const { if (phy().duplex.mode == SRSRAN_DUPLEX_MODE_TDD) { diff --git a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc index 4155a3fb3..280f0b9ae 100644 --- a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc +++ b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc @@ -17,6 +17,64 @@ namespace srsenb { namespace sched_nr_impl { +using candidate_ss_list_t = + srsran::bounded_vector; + +candidate_ss_list_t find_ss(const srsran_pdcch_cfg_nr_t& pdcch, + uint32_t aggr_idx, + srsran_rnti_type_t rnti_type, + srsran::const_span prio_dcis) +{ + candidate_ss_list_t ret; + auto active_ss_lst = view_active_search_spaces(pdcch); + + auto has_dci_fmt_helper = [prio_dcis, aggr_idx](const srsran_search_space_t& ss) { + if (ss.nof_candidates[aggr_idx] > 0 and ss.nof_formats > 0) { + for (uint32_t i = 0; i < prio_dcis.size(); ++i) { + for (uint32_t j = 0; j < prio_dcis.size(); ++j) { + if (ss.formats[j] == prio_dcis[i]) { + return true; + } + } + } + } + return false; + }; + auto is_common_ss_allowed = [rnti_type](srsran_search_space_type_t ss_type) { + switch (rnti_type) { + case srsran_rnti_type_c: + return ss_type == srsran_search_space_type_common_1 or ss_type == srsran_search_space_type_common_3; + case srsran_rnti_type_tc: + case srsran_rnti_type_ra: + // TODO: Fix UE config to not use common3 + return ss_type == srsran_search_space_type_common_1 or ss_type == srsran_search_space_type_common_3; + case srsran_rnti_type_si: + return ss_type == srsran_search_space_type_common_0; + default: + // TODO: Remaining cases + break; + } + return false; + }; + + if (rnti_type == srsran_rnti_type_c) { + // First search UE-specific + for (const srsran_search_space_t& ss : active_ss_lst) { + if (ss.type == srsran_search_space_type_ue and has_dci_fmt_helper(ss)) { + ret.push_back(&ss); + } + } + } + for (const srsran_search_space_t& ss : active_ss_lst) { + if (is_common_ss_allowed(ss.type) and has_dci_fmt_helper(ss)) { + ret.push_back(&ss); + } + } + return ret; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bwp_slot_grid::bwp_slot_grid(const bwp_params_t& bwp_cfg_, uint32_t slot_idx_) : dl_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1), ul_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1), @@ -239,6 +297,9 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t // func computes the grant allocation for this UE alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant) { + static const uint32_t aggr_idx = 2; + static const std::array dci_fmt_list{srsran_dci_format_nr_1_1, srsran_dci_format_nr_1_0}; + bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot]; bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info @@ -263,16 +324,17 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // TODO // Find space and allocate PDCCH - const uint32_t aggr_idx = 2; + srsran_rnti_type_t rnti_type = + ue->ue_cfg().ue_bearers[1].direction == mac_lc_ch_cfg_t::IDLE ? srsran_rnti_type_tc : srsran_rnti_type_c; // Choose the ss_id the highest number of candidates - const srsran_search_space_t* ss = ue->find_ss(aggr_idx, true); - if (ss == nullptr) { + candidate_ss_list_t ss = find_ss(ue->phy().pdcch, aggr_idx, rnti_type, dci_fmt_list); + if (ss.empty()) { // Could not find space in PDCCH logger.warning("SCHED: No PDCCH candidates for any of the rnti=0x%x search spaces", ue->rnti); return alloc_result::no_cch_space; } - uint32_t coreset_id = ss->coreset_id; - if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss->id, &ue.cfg())) { + uint32_t coreset_id = ss[0]->coreset_id; + if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss[0]->id, &ue.cfg())) { // Could not find space in PDCCH return alloc_result::no_cch_space; } @@ -294,7 +356,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr while (true) { // Generate PDCCH pdcch_dl_t& pdcch = bwp_pdcch_slot.dl.phy.pdcch_dl.back(); - fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss->id, pdcch.dci.ctx.location, pdcch.dci); + fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss[0]->id, pdcch.dci.ctx.location, pdcch.dci); pdcch.dci.pucch_resource = 0; pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(), bwp_uci_slot.pending_acks.end(), @@ -346,6 +408,9 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_prbs) { + static const uint32_t aggr_idx = 2; + static const std::array dci_fmt_list{srsran_dci_format_nr_0_1, srsran_dci_format_nr_0_0}; + auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; auto& bwp_pusch_slot = bwp_grid[ue.pusch_slot]; alloc_result ret = verify_pusch_space(bwp_pusch_slot, &bwp_pdcch_slot); @@ -360,16 +425,18 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr if (bwp_pusch_slot.ul_prbs.collides(ul_prbs)) { return alloc_result::sch_collision; } - const uint32_t aggr_idx = 2; - const srsran_search_space_t* ss = ue->find_ss(aggr_idx, false); - if (ss == nullptr) { + + srsran_rnti_type_t rnti_type = + ue->ue_cfg().ue_bearers[1].direction == mac_lc_ch_cfg_t::IDLE ? srsran_rnti_type_tc : srsran_rnti_type_c; + candidate_ss_list_t ss = find_ss(ue->phy().pdcch, aggr_idx, rnti_type, dci_fmt_list); + if (ss.empty()) { // Could not find space in PDCCH logger.warning("SCHED: No PDCCH candidates for any of the rnti=0x%x search spaces", ue->rnti); return alloc_result::no_cch_space; } - uint32_t coreset_id = ss->coreset_id; + uint32_t coreset_id = ss[0]->coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci( - pdcch_grant_type_t::ul_data, aggr_idx, ss->id, &ue.cfg())) { + pdcch_grant_type_t::ul_data, aggr_idx, ss[0]->id, &ue.cfg())) { // Could not find space in PDCCH return alloc_result::no_cch_space; } @@ -387,7 +454,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr // Generate PDCCH pdcch_ul_t& pdcch = pdcchs.back(); - fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss->id, pdcch.dci.ctx.location, pdcch.dci); + fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss[0]->id, pdcch.dci.ctx.location, pdcch.dci); pdcch.dci_cfg = ue->phy().get_dci_cfg(); // Generate PUSCH bwp_pusch_slot.ul_prbs |= ul_prbs;