diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h b/srsenb/hdr/stack/mac/nr/sched_nr_cell.h index 252904f59..5d5fc7776 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cell.h @@ -21,6 +21,30 @@ namespace srsenb { namespace sched_nr_impl { +/// SIB scheduler +class si_sched +{ +public: + explicit si_sched(const bwp_params& bwp_cfg_); + + void run_slot(bwp_slot_allocator& slot_alloc); + +private: + const bwp_params* bwp_cfg = nullptr; + srslog::basic_logger& logger; + + struct sched_si_t { + uint32_t n = 0; + uint32_t len = 0; + uint32_t win_len = 0; + uint32_t period = 0; + uint32_t n_tx = 0; + alloc_result result = alloc_result::invalid_coderate; + slot_point win_start; + }; + srsran::bounded_vector pending_sis; +}; + using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t; /// RAR/Msg3 scheduler @@ -29,9 +53,9 @@ class ra_sched 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, slot_ue_map_t& slot_ues); - size_t empty() const { return pending_rars.empty(); } + int dl_rach_info(const dl_sched_rar_info_t& rar_info); + void run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues); + bool empty() const { return pending_rars.empty(); } private: struct pending_rar_t { diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h index 725320da2..ee9aed46e 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h @@ -85,6 +85,7 @@ public: void new_slot(slot_point pdcch_slot_) { pdcch_slot = pdcch_slot_; } + alloc_result alloc_si(uint32_t aggr_idx, uint32_t si_idx, uint32_t si_ntx, const prb_interval& prbs); alloc_result alloc_rar_and_msg3(uint16_t ra_rnti, uint32_t aggr_idx, prb_interval interv, diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 58e1156d9..1ae357df2 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -61,6 +61,7 @@ public: struct cell_cfg_t { srsran_carrier_nr_t carrier = {}; srsran_tdd_config_nr_t tdd = {}; + srsran::phy_cfg_nr_t::ssb_cfg_t ssb = {}; srsran::bounded_vector bwps{1}; // idx0 for BWP-common }; diff --git a/srsenb/src/stack/mac/nr/sched_nr_cell.cc b/srsenb/src/stack/mac/nr/sched_nr_cell.cc index 727061f5b..deefdbaee 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cell.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cell.cc @@ -17,6 +17,64 @@ namespace srsenb { namespace sched_nr_impl { +si_sched::si_sched(const bwp_params& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger("MAC")) {} + +void si_sched::run_slot(bwp_slot_allocator& slot_alloc) +{ + const uint32_t si_aggr_level = 2; + slot_point pdcch_slot = slot_alloc.get_pdcch_tti(); + const prb_bitmap& prbs = slot_alloc.res_grid()[pdcch_slot].dl_prbs.prbs(); + + // Update SI windows + uint32_t N = bwp_cfg->slots.size(); + for (sched_si_t& si : pending_sis) { + uint32_t x = (si.n - 1) * si.win_len; + + if (not si.win_start.valid() and (pdcch_slot.sfn() % si.period == x / N) and + pdcch_slot.slot_idx() == x % bwp_cfg->slots.size()) { + // If start o SI message window + si.win_start = pdcch_slot; + } else if (si.win_start.valid() and si.win_start + si.win_len >= pdcch_slot) { + // If end of SI message window + logger.warning( + "SCHED: Could not allocate SI message idx=%d, len=%d. Cause: %s", si.n, si.len, to_string(si.result)); + si.win_start.clear(); + } + } + + // Schedule pending SIs + if (bwp_cfg->slots[pdcch_slot.slot_idx()].is_dl) { + for (sched_si_t& si : pending_sis) { + if (not si.win_start.valid()) { + continue; + } + + // TODO: NOTE 2: The UE is not required to monitor PDCCH monitoring occasion(s) corresponding to each transmitted + // SSB in SI-window. + + // Attempt grants with increasing number of PRBs (if the number of PRBs is too low, the coderate is invalid) + si.result = alloc_result::invalid_coderate; + uint32_t prb_start_idx = 0; + for (uint32_t nprbs = 4; nprbs < bwp_cfg->cfg.rb_width and si.result == alloc_result::invalid_coderate; ++nprbs) { + prb_interval grant = find_empty_interval_of_length(prbs, nprbs, prb_start_idx); + prb_start_idx = grant.start(); + if (grant.length() != nprbs) { + si.result = alloc_result::no_sch_space; + break; + } + si.result = slot_alloc.alloc_si(si_aggr_level, si.n, si.n_tx, grant); + if (si.result == alloc_result::success) { + // SIB scheduled successfully + si.win_start.clear(); + si.n_tx++; + } + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 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, @@ -34,7 +92,7 @@ alloc_result ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, uint32_t start_prb_idx = 0; 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(); + start_prb_idx = interv.start(); if (interv.length() == nprb) { ret = slot_grid.alloc_rar_and_msg3( rar.ra_rnti, rar_aggr_level, interv, slot_ues, msg3_grants.subspan(0, nof_grants_alloc)); diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 8f582d188..76fc2ef23 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -60,6 +60,27 @@ 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_si(uint32_t aggr_idx, uint32_t si_idx, uint32_t si_ntx, const prb_interval& prbs) +{ + bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot]; + if (not bwp_pdcch_slot.is_dl()) { + logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", bwp_pdcch_slot.slot_idx); + return alloc_result::no_sch_space; + } + pdcch_dl_list_t& pdsch_grants = bwp_pdcch_slot.dl_pdcchs; + if (pdsch_grants.full()) { + logger.warning("SCHED: Maximum number of DL allocations reached"); + return alloc_result::no_grant_space; + } + if (bwp_pdcch_slot.dl_prbs.collides(prbs)) { + return alloc_result::sch_collision; + } + + // TODO: Allocate PDCCH and PDSCH + + return alloc_result::success; +} + alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t ra_rnti, uint32_t aggr_idx, prb_interval interv,