From 592d9332ba8796c932621a5ac76d83fc00975da4 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 20 Jul 2021 21:26:00 +0100 Subject: [PATCH] sched,nr: add logic for allocation of RAR and Msg3 grants --- srsenb/hdr/stack/mac/nr/sched_nr_cell.h | 13 +-- srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 7 ++ srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h | 8 +- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 3 +- srsenb/src/stack/mac/nr/sched_nr_cell.cc | 20 ++-- srsenb/src/stack/mac/nr/sched_nr_cfg.cc | 18 ++- srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 5 +- srsenb/src/stack/mac/nr/sched_nr_rb_grid.cc | 115 ++++++++++++++----- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 2 +- srsenb/test/mac/nr/sched_nr_cfg_generators.h | 1 + 10 files changed, 144 insertions(+), 48 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h b/srsenb/hdr/stack/mac/nr/sched_nr_cell.h index f65323f12..fcf38564a 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cell.h @@ -35,12 +35,14 @@ public: explicit ra_sched(const bwp_params& bwp_cfg_); int dl_rach_info(const dl_sched_rar_info_t& rar_info); - void run_slot(bwp_slot_allocator& slot_grid); + void run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues); size_t empty() const { return pending_rars.empty(); } private: - alloc_result - allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc); + alloc_result allocate_pending_rar(bwp_slot_allocator& slot_grid, + const pending_rar_t& rar, + slot_ue_map_t& slot_ues, + uint32_t& nof_grants_alloc); const bwp_params* bwp_cfg = nullptr; srslog::basic_logger& logger; @@ -69,14 +71,9 @@ public: explicit serv_cell_manager(const sched_cell_params& cell_cfg_); - void add_user(uint16_t rnti, ue_carrier* ue); - void rem_user(uint16_t rnti); - srsran::bounded_vector bwps; const sched_cell_params& cfg; - srsran::static_circular_map ues; - private: srslog::basic_logger& logger; }; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index 8ec8bfe37..48608298b 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -47,6 +47,13 @@ struct bwp_params { uint32_t P; uint32_t N_rbg; + struct pusch_rach_time_cfg { + uint32_t msg3_delay; ///< Includes K2 and delta. See TS 36.214 6.1.2.1.1-2/4/5 + uint32_t S; + uint32_t L; + }; + std::vector pusch_rach_list; + bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, uint32_t cc, uint32_t bwp_id); }; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h b/srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h index a1425baf1..0b81d0dcd 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h @@ -83,7 +83,11 @@ public: void new_slot(tti_point pdcch_tti_) { pdcch_tti = pdcch_tti_; } - alloc_result alloc_rar(uint32_t aggr_idx, const pending_rar_t& rar, prb_interval interv, uint32_t max_nof_grants); + alloc_result alloc_rar_and_msg3(uint32_t aggr_idx, + const pending_rar_t& rar, + prb_interval interv, + slot_ue_map_t& ues, + uint32_t max_nof_grants); alloc_result alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant); alloc_result alloc_pusch(slot_ue& ue, const rbgmask_t& dl_mask); @@ -93,6 +97,8 @@ public: const bwp_params& cfg; private: + alloc_result verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid = nullptr) const; + srslog::basic_logger& logger; bwp_res_grid& bwp_grid; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 041aa2566..974d69449 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -102,7 +102,8 @@ private: ue_cfg_t ue_cfg; }; -using ue_map_t = srsran::static_circular_map, SCHED_NR_MAX_USERS>; +using ue_map_t = srsran::static_circular_map, SCHED_NR_MAX_USERS>; +using slot_ue_map_t = srsran::static_circular_map; } // namespace sched_nr_impl diff --git a/srsenb/src/stack/mac/nr/sched_nr_cell.cc b/srsenb/src/stack/mac/nr/sched_nr_cell.cc index b30970237..b48ffebd3 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cell.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cell.cc @@ -19,8 +19,10 @@ namespace sched_nr_impl { ra_sched::ra_sched(const bwp_params& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger("MAC")) {} -alloc_result -ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc) +alloc_result ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, + const pending_rar_t& rar, + slot_ue_map_t& slot_ues, + uint32_t& nof_grants_alloc) { const uint32_t rar_aggr_level = 2; const prb_bitmap& prbs = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].dl_prbs.prbs(); @@ -29,11 +31,11 @@ ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_ for (nof_grants_alloc = rar.msg3_grant.size(); nof_grants_alloc > 0; nof_grants_alloc--) { ret = alloc_result::invalid_coderate; uint32_t start_prb_idx = 0; - for (uint32_t nprb = 1; nprb < bwp_cfg->cfg.rb_width and ret == alloc_result::invalid_coderate; ++nprb) { + for (uint32_t nprb = 4; nprb < bwp_cfg->cfg.rb_width and ret == alloc_result::invalid_coderate; ++nprb) { prb_interval interv = find_empty_interval_of_length(prbs, nprb, start_prb_idx); start_prb_idx = interv.stop(); if (interv.length() == nprb) { - ret = slot_grid.alloc_rar(rar_aggr_level, rar, interv, nof_grants_alloc); + ret = slot_grid.alloc_rar_and_msg3(rar_aggr_level, rar, interv, slot_ues, nof_grants_alloc); } else { ret = alloc_result::no_sch_space; } @@ -50,10 +52,14 @@ ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_ return ret; } -void ra_sched::run_slot(bwp_slot_allocator& slot_grid) +void ra_sched::run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues) { static const uint32_t PRACH_RAR_OFFSET = 3; tti_point pdcch_tti = slot_grid.get_pdcch_tti(); + tti_point msg3_tti = pdcch_tti + bwp_cfg->pusch_rach_list[0].msg3_delay; + if (not slot_grid.res_grid()[msg3_tti].is_ul) { + return; + } for (auto it = pending_rars.begin(); it != pending_rars.end();) { pending_rar_t& rar = *it; @@ -79,9 +85,9 @@ void ra_sched::run_slot(bwp_slot_allocator& slot_grid) return; } - // Try to schedule DCI + RBGs for RAR Grant + // Try to schedule DCIs + RBGs for RAR Grants uint32_t nof_rar_allocs = 0; - alloc_result ret = allocate_pending_rar(slot_grid, rar, nof_rar_allocs); + alloc_result ret = allocate_pending_rar(slot_grid, rar, slot_ues, nof_rar_allocs); if (ret == alloc_result::success) { // If RAR allocation was successful: diff --git a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc index da954d094..c9542c430 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc @@ -12,6 +12,9 @@ #include "srsenb/hdr/stack/mac/nr/sched_nr_cfg.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h" +extern "C" { +#include "srsran/phy/phch/ra_ul_nr.h" +} namespace srsenb { namespace sched_nr_impl { @@ -19,10 +22,23 @@ namespace sched_nr_impl { bwp_params::bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, uint32_t cc_, uint32_t bwp_id_) : cell_cfg(cell), sched_cfg(sched_cfg_), cc(cc_), bwp_id(bwp_id_), cfg(cell.bwps[bwp_id_]) { + srsran_assert(bwp_id != 0 or cfg.pdcch.coreset_present[0], "CORESET#0 has to be active for initial BWP"); + P = get_P(cfg.rb_width, cfg.pdsch.rbg_size_cfg_1); N_rbg = get_nof_rbgs(cfg.rb_width, cfg.start_rb, cfg.pdsch.rbg_size_cfg_1); - srsran_assert(bwp_id != 0 or cfg.pdcch.coreset_present[0], "CORESET#0 has to be active for initial BWP"); + pusch_rach_list.resize(cfg.pusch.nof_common_time_ra); + const uint32_t coreset_id = 0; + srsran_sch_grant_nr_t grant; + for (uint32_t m = 0; m < cfg.pusch.nof_common_time_ra; ++m) { + int ret = + srsran_ra_ul_nr_time(&cfg.pusch, srsran_rnti_type_ra, srsran_search_space_type_rar, coreset_id, m, &grant); + srsran_assert(ret == SRSRAN_SUCCESS, "Failed to obtain RA config"); + pusch_rach_list[m].msg3_delay = grant.k; + pusch_rach_list[m].S = grant.S; + pusch_rach_list[m].L = grant.L; + } + srsran_assert(not pusch_rach_list.empty(), "Time-Domain Resource Allocation not valid"); } sched_cell_params::sched_cell_params(uint32_t cc_, const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_) : diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index 32a901272..8e54fdfb4 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -21,7 +21,10 @@ namespace sched_nr_impl { bool fill_dci_rar(prb_interval interv, const bwp_params& cell, srsran_dci_dl_nr_t& dci) { - dci.mcs = 5; + dci.mcs = 5; + dci.ctx.format = srsran_dci_format_nr_1_0; + // TODO: Fill + return true; } diff --git a/srsenb/src/stack/mac/nr/sched_nr_rb_grid.cc b/srsenb/src/stack/mac/nr/sched_nr_rb_grid.cc index 49affafa3..aee8c6c55 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_rb_grid.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_rb_grid.cc @@ -11,6 +11,7 @@ */ #include "srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h" +#include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h" namespace srsenb { @@ -63,15 +64,21 @@ bwp_slot_allocator::bwp_slot_allocator(bwp_res_grid& bwp_grid_) : logger(srslog::fetch_basic_logger("MAC")), cfg(*bwp_grid_.cfg), bwp_grid(bwp_grid_) {} -alloc_result bwp_slot_allocator::alloc_rar(uint32_t aggr_idx, - const srsenb::sched_nr_impl::pending_rar_t& rar, - prb_interval interv, - uint32_t nof_grants) +alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint32_t aggr_idx, + const srsenb::sched_nr_impl::pending_rar_t& rar, + prb_interval interv, + slot_ue_map_t& ues, + uint32_t max_nof_grants) { - static const uint32_t msg3_nof_prbs = 3; + static const uint32_t msg3_nof_prbs = 3, m = 0; bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_tti]; - bwp_slot_grid& bwp_msg3_slot = bwp_grid[pdcch_tti + 4]; + tti_point msg3_tti = pdcch_tti + cfg.pusch_rach_list[m].msg3_delay; + bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_tti]; + alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr); + if (ret != alloc_result::success) { + return ret; + } if (bwp_pdcch_slot.dl_pdcchs.full()) { logger.warning("SCHED: Maximum number of DL allocations reached"); @@ -88,10 +95,10 @@ alloc_result bwp_slot_allocator::alloc_rar(uint32_t } // Check Msg3 RB collision - uint32_t total_ul_nof_prbs = msg3_nof_prbs * nof_grants; + uint32_t total_ul_nof_prbs = msg3_nof_prbs * max_nof_grants; uint32_t total_ul_nof_rbgs = srsran::ceil_div(total_ul_nof_prbs, get_P(bwp_grid.nof_prbs(), false)); - prb_interval msg3_rbgs = find_empty_interval_of_length(bwp_msg3_slot.ul_prbs.prbs(), total_ul_nof_rbgs); - if (msg3_rbgs.length() < total_ul_nof_rbgs) { + prb_interval msg3_rbs = find_empty_interval_of_length(bwp_msg3_slot.ul_prbs.prbs(), total_ul_nof_rbgs); + if (msg3_rbs.length() < total_ul_nof_rbgs) { logger.debug("SCHED: No space in PUSCH for Msg3."); return alloc_result::sch_collision; } @@ -105,6 +112,8 @@ alloc_result bwp_slot_allocator::alloc_rar(uint32_t return alloc_result::no_cch_space; } + // RAR allocation successful. + // Generate DCI for RAR pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); if (not fill_dci_rar(interv, *bwp_grid.cfg, pdcch.dci)) { @@ -112,10 +121,39 @@ alloc_result bwp_slot_allocator::alloc_rar(uint32_t bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci(); return alloc_result::invalid_coderate; } - - // RAR allocation successful. + // Generate RAR PDSCH bwp_pdcch_slot.dl_prbs.add(interv); + // Generate Msg3 grants in PUSCH + uint32_t last_msg3 = msg3_rbs.start(); + const int mcs = 0, max_harq_msg3_retx = 4; + int dai = 0; + srsran_slot_cfg_t slot_cfg; + slot_cfg.idx = msg3_tti.sf_idx(); + for (const auto& grant : rar.msg3_grant) { + slot_ue& ue = ues[grant.temp_crnti]; + bool success = ue.h_ul->new_tx( + msg3_tti, msg3_tti, prb_interval{last_msg3, last_msg3 + msg3_nof_prbs}, mcs, 100, max_harq_msg3_retx); + srsran_assert(success, "Failed to allocate Msg3"); + last_msg3 += msg3_nof_prbs; + srsran_dci_ul_nr_t msg3_dci; // Create dummy Msg3 DCI + msg3_dci.ctx.coreset_id = 1; + msg3_dci.ctx.rnti_type = srsran_rnti_type_ra; + msg3_dci.ctx.ss_type = srsran_search_space_type_rar; + msg3_dci.ctx.format = srsran_dci_format_nr_0_0; + msg3_dci.cc_id = cfg.cc; + msg3_dci.bwp_id = cfg.bwp_id; + msg3_dci.rv = 0; + msg3_dci.mcs = 0; + msg3_dci.time_domain_assigment = dai++; + bwp_msg3_slot.puschs.emplace_back(); + pusch_t& pusch = bwp_msg3_slot.puschs.back(); + success = ue.cfg->phy().get_pusch_cfg(slot_cfg, msg3_dci, pusch.sch); + srsran_assert(success, "Error converting DCI to PUSCH grant"); + pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); + } + bwp_msg3_slot.ul_prbs.add(msg3_rbs); + return alloc_result::success; } @@ -207,21 +245,18 @@ 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 rbg_bitmap& ul_mask) { + auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti]; + auto& bwp_pusch_slot = bwp_grid[ue.pusch_tti]; + alloc_result ret = verify_pusch_space(bwp_pusch_slot, &bwp_pdcch_slot); + if (ret != alloc_result::success) { + return ret; + } + if (ue.h_ul == nullptr) { logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue.rnti); return alloc_result::no_rnti_opportunity; } - auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti]; - auto& bwp_pusch_slot = bwp_grid[ue.pusch_tti]; - if (not bwp_pusch_slot.is_ul) { - logger.warning("SCHED: Trying to allocate PUSCH in TDD non-UL slot index=%d", bwp_pusch_slot.slot_idx); - return alloc_result::no_sch_space; - } - pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs; - if (pdcchs.full()) { - logger.warning("SCHED: Maximum number of UL allocations reached"); - return alloc_result::no_grant_space; - } + pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs; const rbg_bitmap& pusch_mask = bwp_pusch_slot.ul_prbs.rbgs(); if ((pusch_mask & ul_mask).any()) { return alloc_result::sch_collision; @@ -235,10 +270,10 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m if (ue.h_ul->empty()) { srsran_assert(ue.cfg->ue_cfg()->fixed_ul_mcs >= 0, "Dynamic MCS not yet supported"); - int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs; - int tbs = 100; - bool ret = ue.h_ul->new_tx(ue.pusch_tti, ue.pusch_tti, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx); - srsran_assert(ret, "Failed to allocate UL HARQ"); + int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs; + int tbs = 100; + bool success = ue.h_ul->new_tx(ue.pusch_tti, ue.pusch_tti, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx); + srsran_assert(success, "Failed to allocate UL HARQ"); } else { srsran_assert(ue.h_ul->new_retx(ue.pusch_tti, ue.pusch_tti, ul_mask), "Failed to allocate UL HARQ retx"); } @@ -254,12 +289,36 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m pusch_t& pusch = bwp_pusch_slot.puschs.back(); srsran_slot_cfg_t slot_cfg; slot_cfg.idx = ue.pusch_tti.sf_idx(); - bool ret = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch); - srsran_assert(ret, "Error converting DCI to PUSCH grant"); + bool success = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch); + srsran_assert(success, "Error converting DCI to PUSCH grant"); pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); return alloc_result::success; } +alloc_result bwp_slot_allocator::verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid) const +{ + if (not pusch_grid.is_ul) { + logger.warning("SCHED: Trying to allocate PUSCH in TDD non-UL slot index=%d", pusch_grid.slot_idx); + return alloc_result::no_sch_space; + } + if (pdcch_grid != nullptr) { + // DCI needed + if (not pdcch_grid->is_dl) { + logger.warning("SCHED: Trying to allocate PDCCH in TDD non-DL slot index=%d", pdcch_grid->slot_idx); + return alloc_result::no_sch_space; + } + if (pdcch_grid->ul_pdcchs.full()) { + logger.warning("SCHED: Maximum number of PUSCH allocations reached"); + return alloc_result::no_grant_space; + } + } + if (pusch_grid.puschs.full()) { + logger.warning("SCHED: Maximum number of PUSCH allocations reached"); + return alloc_result::no_grant_space; + } + return alloc_result::success; +} + } // namespace sched_nr_impl } // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index af7191a47..98bc3bb50 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -81,7 +81,7 @@ void slot_cc_worker::run() bwp_alloc.new_slot(tti_rx + TX_ENB_DELAY); // Allocate pending RARs - cell.bwps[0].ra.run_slot(bwp_alloc); + cell.bwps[0].ra.run_slot(bwp_alloc, slot_ues); // TODO: Prioritize PDCCH scheduling for DL and UL data in a Round-Robin fashion alloc_dl_ues(); diff --git a/srsenb/test/mac/nr/sched_nr_cfg_generators.h b/srsenb/test/mac/nr/sched_nr_cfg_generators.h index 2587b8c24..1c6c84edc 100644 --- a/srsenb/test/mac/nr/sched_nr_cfg_generators.h +++ b/srsenb/test/mac/nr/sched_nr_cfg_generators.h @@ -40,6 +40,7 @@ sched_nr_interface::cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t& cell_cfg.bwps.resize(1); cell_cfg.bwps[0].pdcch = phy_cfg.pdcch; cell_cfg.bwps[0].pdsch = phy_cfg.pdsch; + cell_cfg.bwps[0].pusch = phy_cfg.pusch; cell_cfg.bwps[0].rb_width = phy_cfg.carrier.nof_prb; cell_cfg.bwps[0].pdcch.coreset_present[0] = true;