diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 40dc85df1..e358a181d 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -64,8 +64,8 @@ private: int add_ue_impl(uint16_t rnti, std::unique_ptr u); // args - sched_nr_impl::sched_params cfg; - srslog::basic_logger* logger = nullptr; + sched_nr_impl::sched_params_t cfg; + srslog::basic_logger* logger = nullptr; // slot-specific slot_point current_slot_tx; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index 4cd1e69d3..f6f05b375 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -107,26 +107,30 @@ struct cell_params_t { }; /// Structure packing both the sched args and all gNB NR cell configurations -struct sched_params { +struct sched_params_t { sched_args_t sched_cfg; std::vector cells; - sched_params() = default; - explicit sched_params(const sched_args_t& sched_cfg_); + sched_params_t() = default; + explicit sched_params_t(const sched_args_t& sched_cfg_); }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/// Configuration of a UE for a given BWP -class bwp_ue_cfg +/// Semi-static configuration of a UE for a given CC. +class ue_carrier_params_t { public: - bwp_ue_cfg() = default; - explicit bwp_ue_cfg(uint16_t rnti, const bwp_params_t& bwp_cfg, const ue_cfg_t& uecfg_); + ue_carrier_params_t() = default; + explicit ue_carrier_params_t(uint16_t rnti, const bwp_params_t& active_bwp_cfg, const ue_cfg_t& uecfg_); + + uint16_t rnti = SRSRAN_INVALID_RNTI; + uint32_t cc = SRSRAN_MAX_CARRIERS; + + const ue_cfg_t& ue_cfg() const { return *cfg_; } + const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } + const bwp_params_t& active_bwp() const { return *bwp_cfg; } - const ue_cfg_t* ue_cfg() const { return cfg_; } - const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } - const bwp_params_t& active_bwp() const { return *bwp_cfg; } srsran::const_span cce_pos_list(uint32_t search_id, uint32_t slot_idx, uint32_t aggr_idx) const { if (cce_positions_list.size() > ss_id_to_cce_idx[search_id]) { @@ -150,7 +154,6 @@ public: int fixed_pusch_mcs() const { return bwp_cfg->sched_cfg.fixed_ul_mcs; } private: - uint16_t rnti = SRSRAN_INVALID_RNTI; const ue_cfg_t* cfg_ = nullptr; const bwp_params_t* bwp_cfg = nullptr; 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 4ffff68a2..c3068f61d 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h @@ -118,7 +118,7 @@ private: bwp_res_grid& bwp_grid; slot_point pdcch_slot; - slot_ue_map_t* slot_ues = nullptr; + slot_ue_map_t& slot_ues; }; } // namespace sched_nr_impl diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 39d9eb73c..4d43bccd3 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -26,50 +26,19 @@ namespace srsenb { namespace sched_nr_impl { -class ue_carrier; - -class slot_ue -{ -public: - slot_ue() = default; - explicit slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc); - slot_ue(slot_ue&&) noexcept = default; - slot_ue& operator=(slot_ue&&) noexcept = default; - bool empty() const { return rnti == SCHED_NR_INVALID_RNTI; } - void release() { rnti = SCHED_NR_INVALID_RNTI; } - - uint16_t rnti = SCHED_NR_INVALID_RNTI; - slot_point slot_rx; - uint32_t cc = SCHED_NR_MAX_CARRIERS; - - // UE parameters common to all sectors - int dl_pending_bytes = 0, ul_pending_bytes = 0; - - // UE parameters that are sector specific - const bwp_ue_cfg* cfg = nullptr; - harq_entity* harq_ent = nullptr; - slot_point pdcch_slot; - slot_point pdsch_slot; - slot_point pusch_slot; - slot_point uci_slot; - uint32_t dl_cqi = 0; - uint32_t ul_cqi = 0; - dl_harq_proc* h_dl = nullptr; - ul_harq_proc* h_ul = nullptr; - srsran_uci_cfg_nr_t uci_cfg = {}; -}; +class slot_ue; class ue_carrier { public: ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_); - void set_cfg(const ue_cfg_t& ue_cfg); + + void set_cfg(const ue_cfg_t& ue_cfg); + const ue_carrier_params_t& cfg() const { return bwp_cfg; } int dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack); int ul_crc_info(uint32_t pid, bool crc); - slot_ue try_reserve(slot_point pdcch_slot, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); - const uint16_t rnti; const uint32_t cc; @@ -83,15 +52,17 @@ public: mac_ue_metrics_t metrics = {}; private: + friend class slot_ue; + srslog::basic_logger& logger; - bwp_ue_cfg bwp_cfg; + ue_carrier_params_t bwp_cfg; const cell_params_t& cell_params; }; class ue { public: - ue(uint16_t rnti, const ue_cfg_t& cfg, const sched_params& sched_cfg_); + ue(uint16_t rnti, const ue_cfg_t& cfg, const sched_params_t& sched_cfg_); void new_slot(slot_point pdcch_slot); @@ -118,7 +89,7 @@ public: const uint16_t rnti; private: - const sched_params& sched_cfg; + const sched_params_t& sched_cfg; slot_point last_pdcch_slot; slot_point last_sr_slot; @@ -127,6 +98,40 @@ private: ue_cfg_t ue_cfg; }; +class slot_ue +{ +public: + slot_ue() = default; + explicit slot_ue(ue_carrier& ue, slot_point slot_tx_, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes); + slot_ue(slot_ue&&) noexcept = default; + slot_ue& operator=(slot_ue&&) noexcept = default; + bool empty() const { return ue == nullptr; } + void release() { ue = nullptr; } + + const ue_carrier_params_t& operator*() const { return ue->bwp_cfg; } + const ue_carrier_params_t* operator->() const { return &ue->bwp_cfg; } + + // mutable interface to ue_carrier state + dl_harq_proc* find_empty_dl_harq(); + ul_harq_proc* find_empty_ul_harq(); + + // UE parameters common to all sectors + uint32_t dl_pending_bytes = 0, ul_pending_bytes = 0; + + // UE parameters that are sector specific + bool dl_active; + bool ul_active; + slot_point pdcch_slot; + slot_point pdsch_slot; + slot_point pusch_slot; + slot_point uci_slot; + dl_harq_proc* h_dl = nullptr; + ul_harq_proc* h_ul = nullptr; + +private: + ue_carrier* ue = nullptr; +}; + using ue_map_t = rnti_map_t >; using slot_ue_map_t = rnti_map_t; diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index ad2bb137c..e98b53e71 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -110,7 +110,7 @@ public: fmt::memory_buffer event_fmtbuf; }; - explicit event_manager(sched_params& params) : + explicit event_manager(sched_params_t& params) : sched_logger(srslog::fetch_basic_logger(params.sched_cfg.logger_name)), carriers(params.cells.size()) {} @@ -333,7 +333,7 @@ void sched_nr::stop() int sched_nr::config(const sched_args_t& sched_cfg, srsran::const_span cell_list) { - cfg = sched_params{sched_cfg}; + cfg = sched_params_t{sched_cfg}; logger = &srslog::fetch_basic_logger(sched_cfg.logger_name); // Initiate Common Sched Configuration diff --git a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc index ecbb30e4c..ee7063e5a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc @@ -101,7 +101,7 @@ cell_params_t::cell_params_t(uint32_t cc_, const cell_cfg_t& cell, const sched_a srsran_assert(not bwps.empty(), "No BWPs were configured"); } -sched_params::sched_params(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) +sched_params_t::sched_params_t(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) { srsran_assert(sched_cfg.fixed_dl_mcs >= 0, "Dynamic DL MCS not supported"); srsran_assert(sched_cfg.fixed_ul_mcs >= 0, "Dynamic DL MCS not supported"); @@ -109,8 +109,8 @@ sched_params::sched_params(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bwp_ue_cfg::bwp_ue_cfg(uint16_t rnti_, const bwp_params_t& bwp_cfg_, const ue_cfg_t& uecfg_) : - rnti(rnti_), cfg_(&uecfg_), bwp_cfg(&bwp_cfg_) +ue_carrier_params_t::ue_carrier_params_t(uint16_t rnti_, const bwp_params_t& bwp_cfg_, const ue_cfg_t& uecfg_) : + rnti(rnti_), cc(bwp_cfg_.cc), cfg_(&uecfg_), bwp_cfg(&bwp_cfg_) { std::fill(ss_id_to_cce_idx.begin(), ss_id_to_cce_idx.end(), SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE); const auto& pdcch = phy().pdcch; 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 0c068b906..783697f2a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -62,7 +62,7 @@ bwp_res_grid::bwp_res_grid(const bwp_params_t& bwp_cfg_) : cfg(&bwp_cfg_) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bwp_slot_allocator::bwp_slot_allocator(bwp_res_grid& bwp_grid_, slot_point pdcch_slot_, slot_ue_map_t& ues_) : - logger(bwp_grid_.cfg->logger), cfg(*bwp_grid_.cfg), bwp_grid(bwp_grid_), pdcch_slot(pdcch_slot_), slot_ues(&ues_) + logger(bwp_grid_.cfg->logger), cfg(*bwp_grid_.cfg), bwp_grid(bwp_grid_), pdcch_slot(pdcch_slot_), slot_ues(ues_) {} alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx, uint32_t si_idx, uint32_t si_ntx, const prb_interval& prbs) @@ -118,7 +118,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t return alloc_result::invalid_grant_params; } for (auto& rar : pending_rars) { - if (not slot_ues->contains(rar.temp_crnti)) { + if (not slot_ues.contains(rar.temp_crnti)) { logger.info("SCHED: Postponing rnti=0x%x RAR allocation. Cause: The ue object not yet fully created", rar.temp_crnti); return alloc_result::no_rnti_opportunity; @@ -158,7 +158,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci(); return alloc_result::invalid_coderate; } - auto& phy_cfg = (*slot_ues)[pending_rars[0].temp_crnti].cfg->phy(); + auto& phy_cfg = slot_ues[pending_rars[0].temp_crnti]->phy(); pdcch.dci_cfg = phy_cfg.get_dci_cfg(); // Generate RAR PDSCH // TODO: Properly fill Msg3 grants @@ -177,7 +177,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t bwp_pdcch_slot.rar.emplace_back(); sched_nr_interface::rar_t& rar_out = bwp_pdcch_slot.rar.back(); for (const dl_sched_rar_info_t& grant : pending_rars) { - slot_ue& ue = (*slot_ues)[grant.temp_crnti]; + slot_ue& ue = slot_ues[grant.temp_crnti]; // Generate RAR grant rar_out.grants.emplace_back(); @@ -185,7 +185,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t rar_grant.data = grant; prb_interval msg3_interv{last_msg3, last_msg3 + msg3_nof_prbs}; last_msg3 += msg3_nof_prbs; - ue.h_ul = ue.harq_ent->find_empty_ul_harq(); + ue.h_ul = ue.find_empty_ul_harq(); success = ue.h_ul->new_tx(msg3_slot, msg3_slot, msg3_interv, mcs, max_harq_msg3_retx); srsran_assert(success, "Failed to allocate Msg3"); fill_dci_msg3(ue, *bwp_grid.cfg, rar_grant.msg3_dci); @@ -193,7 +193,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t // Generate PUSCH bwp_msg3_slot.puschs.emplace_back(); pusch_t& pusch = bwp_msg3_slot.puschs.back(); - success = ue.cfg->phy().get_pusch_cfg(slot_cfg, rar_grant.msg3_dci, pusch.sch); + success = ue->phy().get_pusch_cfg(slot_cfg, rar_grant.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(); ue.h_ul->set_tbs(pusch.sch.grant.tb[0].tbs); @@ -207,13 +207,13 @@ 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) { - if (ue.cfg->active_bwp().bwp_id != bwp_grid.cfg->bwp_id) { + if (ue->active_bwp().bwp_id != bwp_grid.cfg->bwp_id) { logger.warning( - "SCHED: Trying to allocate PDSCH for rnti=0x%x in inactive BWP id=%d", ue.rnti, ue.cfg->active_bwp().bwp_id); + "SCHED: Trying to allocate PDSCH for rnti=0x%x in inactive BWP id=%d", ue->rnti, ue->active_bwp().bwp_id); return alloc_result::no_rnti_opportunity; } if (ue.h_dl == nullptr) { - logger.warning("SCHED: Trying to allocate PDSCH for rnti=0x%x with no available HARQs", ue.rnti); + logger.warning("SCHED: Trying to allocate PDSCH for rnti=0x%x with no available HARQs", ue->rnti); return alloc_result::no_rnti_opportunity; } bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; @@ -224,7 +224,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr return result; } if (bwp_uci_slot.pending_acks.full()) { - logger.warning("SCHED: PDSCH allocation for rnti=0x%x failed due to lack of space for respective ACK", ue.rnti); + logger.warning("SCHED: PDSCH allocation for rnti=0x%x failed due to lack of space for respective ACK", ue->rnti); return alloc_result::no_grant_space; } if (bwp_pdsch_slot.dl_prbs.collides(dl_grant)) { @@ -233,7 +233,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr if (not bwp_pdcch_slot.ssb.empty()) { // TODO: support concurrent PDSCH and SSB logger.info("SCHED: skipping rnti=0x%x PDSCH allocation. Cause: concurrent PDSCH and SSB not yet supported", - ue.rnti); + ue->rnti); return alloc_result::no_sch_space; } @@ -245,20 +245,20 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // Choose the ss_id the highest number of candidates uint32_t ss_id = 0, max_nof_candidates = 0; for (uint32_t i = 0; i < 3; ++i) { - uint32_t nof_candidates = ue.cfg->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); + uint32_t nof_candidates = ue->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); if (nof_candidates > max_nof_candidates) { ss_id = i; max_nof_candidates = nof_candidates; } } - uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; + uint32_t coreset_id = ue->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss_id, &ue)) { // Could not find space in PDCCH return alloc_result::no_cch_space; } // Allocate HARQ - int mcs = ue.cfg->fixed_pdsch_mcs(); + int mcs = ue->fixed_pdsch_mcs(); if (ue.h_dl->empty()) { bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4); srsran_assert(ret, "Failed to allocate DL HARQ"); @@ -278,14 +278,14 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr pdcch.dci.pucch_resource = 0; pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(), bwp_uci_slot.pending_acks.end(), - [&ue](const harq_ack_t& p) { return p.res.rnti == ue.rnti; }); + [&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; }); pdcch.dci.dai %= 4; - pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg(); + pdcch.dci_cfg = ue->phy().get_dci_cfg(); // Generate PUCCH bwp_uci_slot.pending_acks.emplace_back(); - bwp_uci_slot.pending_acks.back().phy_cfg = &ue.cfg->phy(); - srsran_assert(ue.cfg->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res), + bwp_uci_slot.pending_acks.back().phy_cfg = &ue->phy(); + srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res), "Error getting ack resource"); // Generate PDSCH @@ -294,7 +294,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back(); srsran_slot_cfg_t slot_cfg; slot_cfg.idx = ue.pdsch_slot.to_uint(); - bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); + bool ret = ue->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); srsran_assert(ret, "Error converting DCI to grant"); pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); @@ -330,7 +330,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr } if (ue.h_ul == nullptr) { - logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue.rnti); + logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue->rnti); return alloc_result::no_rnti_opportunity; } pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs; @@ -341,22 +341,22 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr // Choose the ss_id the highest number of candidates uint32_t ss_id = 0, max_nof_candidates = 0; for (uint32_t i = 0; i < 3; ++i) { - uint32_t nof_candidates = ue.cfg->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); + uint32_t nof_candidates = ue->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); if (nof_candidates > max_nof_candidates) { ss_id = i; max_nof_candidates = nof_candidates; } } - uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; + uint32_t coreset_id = ue->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci(pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue)) { // Could not find space in PDCCH return alloc_result::no_cch_space; } if (ue.h_ul->empty()) { - int mcs = ue.cfg->fixed_pusch_mcs(); + int mcs = ue->fixed_pusch_mcs(); int tbs = 100; - bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, ue.cfg->ue_cfg()->maxharq_tx); + bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, ue->ue_cfg().maxharq_tx); srsran_assert(success, "Failed to allocate UL HARQ"); } else { bool success = ue.h_ul->new_retx(ue.pusch_slot, ue.pusch_slot, ul_prbs); @@ -367,7 +367,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); - pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg(); + pdcch.dci_cfg = ue->phy().get_dci_cfg(); // Generate PUSCH bwp_pusch_slot.ul_prbs |= ul_prbs; bwp_pusch_slot.puschs.emplace_back(); @@ -375,7 +375,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr srsran_slot_cfg_t slot_cfg; slot_cfg.idx = ue.pusch_slot.to_uint(); pusch.pid = ue.h_ul->pid; - bool success = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch); + bool success = ue->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(); if (ue.h_ul->nof_retx() == 0) { diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index e1ed7032b..898955371 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -26,8 +26,8 @@ void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, DciDlOrUl& { const static uint32_t rv_idx[4] = {0, 2, 3, 1}; - dci.bwp_id = ue.cfg->active_bwp().bwp_id; - dci.cc_id = ue.cc; + dci.bwp_id = ue->active_bwp().bwp_id; + dci.cc_id = ue->cc; dci.tpc = 1; // harq harq_proc* h = std::is_same::value ? static_cast(ue.h_dl) @@ -68,9 +68,9 @@ bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& msg3_dci) { fill_dci_common(ue, bwp_cfg, msg3_dci); - msg3_dci.ctx.coreset_id = ue.cfg->phy().pdcch.ra_search_space.coreset_id; + msg3_dci.ctx.coreset_id = ue->phy().pdcch.ra_search_space.coreset_id; msg3_dci.ctx.rnti_type = srsran_rnti_type_tc; - msg3_dci.ctx.rnti = ue.rnti; + msg3_dci.ctx.rnti = ue->rnti; msg3_dci.ctx.ss_type = srsran_search_space_type_rar; if (ue.h_ul->nof_retx() == 0) { msg3_dci.ctx.format = srsran_dci_format_nr_rar; @@ -89,7 +89,7 @@ void fill_dl_dci_ue_fields(const slot_ue& ue, { // Note: DCI location may not be the final one, as scheduler may rellocate the UE PDCCH. However, the remaining DCI // params are independent of the exact DCI location - bool ret = ue.cfg->phy().get_dci_ctx_pdsch_rnti_c(ss_id, dci_pos, ue.rnti, dci.ctx); + bool ret = ue->phy().get_dci_ctx_pdsch_rnti_c(ss_id, dci_pos, ue->rnti, dci.ctx); srsran_assert(ret, "Invalid DL DCI format"); fill_dci_common(ue, bwp_cfg, dci); @@ -106,7 +106,7 @@ void fill_ul_dci_ue_fields(const slot_ue& ue, srsran_dci_location_t dci_pos, srsran_dci_ul_nr_t& dci) { - bool ret = ue.cfg->phy().get_dci_ctx_pusch_rnti_c(ss_id, dci_pos, ue.rnti, dci.ctx); + bool ret = ue->phy().get_dci_ctx_pusch_rnti_c(ss_id, dci_pos, ue->rnti, dci.ctx); srsran_assert(ret, "Invalid DL DCI format"); fill_dci_common(ue, bwp_cfg, dci); @@ -126,7 +126,7 @@ void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uin auto& ue = ue_pair->second; fmt::format_to( - fmtbuf, "{}{{rnti=0x{:x}, dl_bs={}, ul_bs={}}}", use_comma, ue.rnti, ue.dl_pending_bytes, ue.ul_pending_bytes); + fmtbuf, "{}{{rnti=0x{:x}, dl_bs={}, ul_bs={}}}", use_comma, ue->rnti, ue.dl_pending_bytes, ue.ul_pending_bytes); use_comma = ", "; } @@ -146,10 +146,10 @@ void log_sched_bwp_result(srslog::basic_logger& logger, const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; fmt::format_to(fmtbuf, "SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, prbs={}, nrtx={}, dai={}, " - "tbs={}, bs={}, pdsch_slot={}, tti_ack={}", + "tbs={}, bs={}, pdsch_slot={}, ack_slot={}", ue.h_dl->nof_retx() == 0 ? "tx" : "retx", res_grid.cfg->cc, - ue.rnti, + ue->rnti, pdcch.dci.pid, pdcch.dci.ctx.coreset_id, srsran_dci_format_nr_string(pdcch.dci.ctx.format), @@ -185,10 +185,10 @@ void log_sched_bwp_result(srslog::basic_logger& logger, if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; fmt::format_to(fmtbuf, - "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, nrtx={}, tbs={}, bs={}, tti_pusch={}", + "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, nrtx={}, tbs={}, bs={}, pusch_slot={}", ue.h_ul->nof_retx() == 0 ? "tx" : "retx", res_grid.cfg->cc, - ue.rnti, + ue->rnti, pdcch.dci.pid, pdcch.dci.ctx.coreset_id, srsran_dci_format_nr_string(pdcch.dci.ctx.format), @@ -201,7 +201,7 @@ void log_sched_bwp_result(srslog::basic_logger& logger, fmt::format_to(fmtbuf, "SCHED: UL Msg3, cc={}, tc-rnti=0x{:x}, pid={}, nrtx={}, f={}, tti_pusch={}", res_grid.cfg->cc, - ue.rnti, + ue->rnti, pdcch.dci.pid, ue.h_ul->nof_retx(), srsran_dci_format_nr_string(pdcch.dci.ctx.format), diff --git a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc index c6098b80d..04f19e8fe 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc @@ -141,7 +141,7 @@ bool coreset_region::alloc_dfs_node(const alloc_record& record, uint32_t start_d tree_node node; node.dci_pos_idx = start_dci_idx; node.dci_pos.L = record.aggr_idx; - node.rnti = record.ue != nullptr ? record.ue->rnti : SRSRAN_INVALID_RNTI; + node.rnti = record.ue != nullptr ? (*record.ue)->rnti : SRSRAN_INVALID_RNTI; node.current_mask.resize(nof_cces()); // get cumulative pdcch bitmap if (not alloc_dfs.empty()) { @@ -180,9 +180,8 @@ srsran::span coreset_region::get_cce_loc_table(const alloc_recor { switch (record.alloc_type) { case pdcch_grant_type_t::dl_data: - return record.ue->cfg->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); case pdcch_grant_type_t::ul_data: - return record.ue->cfg->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); + return (*record.ue)->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); case pdcch_grant_type_t::rar: return rar_cce_list[slot_idx][record.aggr_idx]; default: diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 819383c65..847ae61a5 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -17,7 +17,44 @@ namespace srsenb { namespace sched_nr_impl { -slot_ue::slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc_) : rnti(rnti_), slot_rx(slot_rx_), cc(cc_) {} +slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_, uint32_t dl_bytes, uint32_t ul_bytes) : + ue(&ue_), pdcch_slot(slot_tx_) +{ + const uint32_t k0 = 0; + pdsch_slot = pdcch_slot + k0; + uint32_t k1 = ue->bwp_cfg.get_k1(pdsch_slot); + uci_slot = pdsch_slot + k1; + uint32_t k2 = ue->bwp_cfg.active_bwp().pusch_ra_list[0].K; + pusch_slot = pdcch_slot + k2; + + const srsran_duplex_config_nr_t& tdd_cfg = ue->cell_params.cfg.duplex; + + dl_active = srsran_duplex_nr_is_dl(&tdd_cfg, 0, pdsch_slot.slot_idx()); + if (dl_active) { + dl_pending_bytes = dl_bytes; + h_dl = ue->harq_ent.find_pending_dl_retx(); + if (h_dl == nullptr) { + h_dl = ue->harq_ent.find_empty_dl_harq(); + } + } + ul_active = srsran_duplex_nr_is_ul(&tdd_cfg, 0, pusch_slot.slot_idx()); + if (ul_active) { + ul_pending_bytes = ul_bytes; + h_ul = ue->harq_ent.find_pending_ul_retx(); + if (h_ul == nullptr) { + h_ul = ue->harq_ent.find_empty_ul_harq(); + } + } +} + +dl_harq_proc* slot_ue::find_empty_dl_harq() +{ + return dl_active ? ue->harq_ent.find_empty_dl_harq() : nullptr; +} +ul_harq_proc* slot_ue::find_empty_ul_harq() +{ + return ul_active ? ue->harq_ent.find_empty_ul_harq() : nullptr; +} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,7 +69,7 @@ ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg) { - bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], ue_cfg); + bwp_cfg = ue_carrier_params_t(rnti, cell_params.bwps[0], ue_cfg); } int ue_carrier::dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) @@ -60,50 +97,9 @@ int ue_carrier::ul_crc_info(uint32_t pid, bool crc) return ret; } -slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) -{ - slot_point slot_rx = pdcch_slot - TX_ENB_DELAY; - - // copy cc-specific parameters and find available HARQs - slot_ue sfu(rnti, slot_rx, cc); - sfu.cfg = &bwp_cfg; - sfu.pdcch_slot = pdcch_slot; - sfu.harq_ent = &harq_ent; - const uint32_t k0 = 0; - sfu.pdsch_slot = sfu.pdcch_slot + k0; - uint32_t k1 = sfu.cfg->get_k1(sfu.pdsch_slot); - sfu.uci_slot = sfu.pdsch_slot + k1; - uint32_t k2 = bwp_cfg.active_bwp().pusch_ra_list[0].K; - sfu.pusch_slot = sfu.pdcch_slot + k2; - sfu.dl_cqi = dl_cqi; - sfu.ul_cqi = ul_cqi; - - // set UE-common parameters - sfu.dl_pending_bytes = dl_pending_bytes; - sfu.ul_pending_bytes = ul_pending_bytes; - - const srsran_duplex_config_nr_t& tdd_cfg = cell_params.cfg.duplex; - if (srsran_duplex_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_slot.slot_idx())) { - // If DL enabled - sfu.h_dl = harq_ent.find_pending_dl_retx(); - if (sfu.h_dl == nullptr and sfu.dl_pending_bytes > 0) { - sfu.h_dl = harq_ent.find_empty_dl_harq(); - } - } - if (srsran_duplex_nr_is_ul(&tdd_cfg, 0, sfu.pusch_slot.slot_idx())) { - // If UL enabled - sfu.h_ul = harq_ent.find_pending_ul_retx(); - if (sfu.h_ul == nullptr and sfu.ul_pending_bytes > 0) { - sfu.h_ul = harq_ent.find_empty_ul_harq(); - } - } - - return sfu; -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params& sched_cfg_) : +ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params_t& sched_cfg_) : rnti(rnti_), sched_cfg(sched_cfg_), buffers(rnti_, srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)) { set_cfg(cfg); @@ -167,7 +163,7 @@ void ue::new_slot(slot_point pdcch_slot) slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc) { srsran_assert(carriers[cc] != nullptr, "try_reserve() called for inexistent rnti=0x%x,cc=%d", rnti, cc); - return carriers[cc]->try_reserve(pdcch_slot, dl_pending_bytes, ul_pending_bytes); + return slot_ue(*carriers[cc], pdcch_slot, dl_pending_bytes, ul_pending_bytes); } } // namespace sched_nr_impl diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index fe4619b95..9afc84961 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -56,9 +56,6 @@ void cc_worker::dl_rach_info(const sched_nr_interface::rar_info_t& rar_info) /// Called within a locked context, to generate {slot, cc} scheduling decision void cc_worker::run_slot(slot_point pdcch_slot, ue_map_t& ue_db, dl_sched_res_t& dl_res, ul_sched_t& ul_res) { - // Create an BWP allocator object that will passed along to RA, SI, Data schedulers - bwp_slot_allocator bwp_alloc{bwps[0].grid, pdcch_slot, slot_ues}; - // Reserve UEs for this worker slot (select candidate UEs) for (auto& ue_pair : ue_db) { uint16_t rnti = ue_pair.first; @@ -77,6 +74,9 @@ void cc_worker::run_slot(slot_point pdcch_slot, ue_map_t& ue_db, dl_sched_res_t& // UE acquired successfully for scheduling in this {slot, cc} } + // Create an BWP allocator object that will passed along to RA, SI, Data schedulers + bwp_slot_allocator bwp_alloc{bwps[0].grid, pdcch_slot, slot_ues}; + // Log UEs state for slot log_sched_slot_ues(logger, pdcch_slot, cfg.cc, slot_ues); @@ -132,7 +132,7 @@ void cc_worker::postprocess_decisions(bwp_slot_allocator& bwp_alloc) srsran_pdsch_ack_nr_t ack = {}; for (auto& h_ack : bwp_slot.pending_acks) { - if (h_ack.res.rnti == ue.rnti) { + if (h_ack.res.rnti == ue->rnti) { ack.nof_cc = 1; srsran_harq_ack_m_t ack_m = {}; @@ -143,7 +143,7 @@ void cc_worker::postprocess_decisions(bwp_slot_allocator& bwp_alloc) } srsran_uci_cfg_nr_t uci_cfg = {}; - if (not ue.cfg->phy().get_uci_cfg(slot_cfg, ack, uci_cfg)) { + if (not ue->phy().get_uci_cfg(slot_cfg, ack, uci_cfg)) { logger.error("Error getting UCI configuration"); continue; } @@ -154,14 +154,14 @@ void cc_worker::postprocess_decisions(bwp_slot_allocator& bwp_alloc) bool has_pusch = false; for (auto& pusch : bwp_slot.puschs) { - if (pusch.sch.grant.rnti == ue.rnti) { + if (pusch.sch.grant.rnti == ue->rnti) { // Put UCI configuration in PUSCH config has_pusch = true; // If has PUSCH, no SR shall be received uci_cfg.o_sr = 0; - if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { + if (not ue->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { logger.error("Error setting UCI configuration in PUSCH"); continue; } @@ -177,10 +177,10 @@ void cc_worker::postprocess_decisions(bwp_slot_allocator& bwp_alloc) bwp_slot.pucch.emplace_back(); mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back(); - uci_cfg.pucch.rnti = ue.rnti; + uci_cfg.pucch.rnti = ue->rnti; pucch.candidates.emplace_back(); pucch.candidates.back().uci_cfg = uci_cfg; - if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + if (not ue->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { logger.error("Error getting UCI CFG"); continue; } @@ -196,7 +196,7 @@ void cc_worker::postprocess_decisions(bwp_slot_allocator& bwp_alloc) // Append new resource pucch.candidates.emplace_back(); pucch.candidates.back().uci_cfg = uci_cfg; - if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + if (not ue->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { logger.error("Error getting UCI CFG"); continue; } diff --git a/srsenb/test/mac/nr/sched_nr_rar_test.cc b/srsenb/test/mac/nr/sched_nr_rar_test.cc index b0b81d742..626242cee 100644 --- a/srsenb/test/mac/nr/sched_nr_rar_test.cc +++ b/srsenb/test/mac/nr/sched_nr_rar_test.cc @@ -35,7 +35,7 @@ void test_single_prach() // Set cells configuration std::vector cells_cfg = get_default_cells_cfg(1); - sched_params schedparams{sched_cfg}; + sched_params_t schedparams{sched_cfg}; schedparams.cells.emplace_back(0, cells_cfg[0], sched_cfg); const bwp_params_t& bwpparams = schedparams.cells[0].bwps[0]; slot_ue_map_t slot_ues; diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 6c7dabf7b..59d870fcc 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -96,7 +96,7 @@ sched_nr_base_tester::sched_nr_base_tester(const sched_nr_interface::sched_args_ std::string test_name_, uint32_t nof_workers) : logger(srslog::fetch_basic_logger("TEST")), - mac_logger(srslog::fetch_basic_logger("MAC")), + mac_logger(srslog::fetch_basic_logger("MAC-NR")), sched_ptr(new sched_nr()), test_name(std::move(test_name_)) {