diff --git a/lib/include/srsran/adt/interval.h b/lib/include/srsran/adt/interval.h index e59d2d607..cecb7d891 100644 --- a/lib/include/srsran/adt/interval.h +++ b/lib/include/srsran/adt/interval.h @@ -77,6 +77,17 @@ public: bool contains(T point) const { return start_ <= point and point < stop_; } + interval& intersect(const interval& other) + { + if (not overlaps(other)) { + *this = interval{}; + } else { + start_ = std::max(start(), other.start()); + stop_ = std::min(stop(), other.stop()); + } + return *this; + } + private: T start_; T stop_; diff --git a/srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h b/srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h index 4aa1f93e2..21541c5b6 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h +++ b/srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h @@ -99,8 +99,8 @@ public: uint32_t aggr_idx, prb_interval interv, srsran::const_span pending_rars); - alloc_result alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant); - alloc_result alloc_pusch(slot_ue& ue, const prb_grant& dl_mask); + alloc_result alloc_pdsch(slot_ue& ue, prb_grant dl_grant); + alloc_result alloc_pusch(slot_ue& ue, prb_grant dl_mask); slot_point get_pdcch_tti() const { return pdcch_slot; } slot_point get_tti_rx() const { return pdcch_slot - TX_ENB_DELAY; } diff --git a/srsgnb/hdr/stack/mac/sched_nr_rb.h b/srsgnb/hdr/stack/mac/sched_nr_rb.h index ec0af28a6..e7b19843b 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_rb.h +++ b/srsgnb/hdr/stack/mac/sched_nr_rb.h @@ -106,6 +106,16 @@ struct prb_grant { return alloc.interv; } + prb_grant& operator&=(const prb_interval interv) + { + if (is_alloc_type0()) { + alloc.rbgs &= rbg_bitmap{alloc.rbgs.size()}.fill(interv.start(), interv.stop()); + } else { + alloc.interv.intersect(interv); + } + return *this; + } + private: bool alloc_type_0 = false; union alloc_t { diff --git a/srsgnb/hdr/stack/mac/sched_nr_ue.h b/srsgnb/hdr/stack/mac/sched_nr_ue.h index f3f556a0c..59389d2a0 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_ue.h +++ b/srsgnb/hdr/stack/mac/sched_nr_ue.h @@ -118,6 +118,7 @@ public: slot_ue make_slot_ue(slot_point pdcch_slot, uint32_t cc); + /// Update UE CC configuration void set_cfg(const ue_cfg_t& cfg); const ue_cfg_t& cfg() const { return ue_cfg; } diff --git a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc index 280f0b9ae..e9e03951c 100644 --- a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc +++ b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc @@ -295,7 +295,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t // ue is the UE (1 only) that will be allocated // func computes the grant allocation for this UE -alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant) +alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, 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}; @@ -334,6 +334,9 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr return alloc_result::no_cch_space; } uint32_t coreset_id = ss[0]->coreset_id; + if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss[0]->type)) { + dl_grant &= prb_interval{ue->phy().pdcch.coreset[ss[0]->coreset_id].offset_rb, ue->phy().carrier.nof_prb}; + } 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; @@ -406,7 +409,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr return alloc_result::success; } -alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_prbs) +alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, prb_grant ul_grant) { 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}; @@ -422,7 +425,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr return ret; } pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.dl.phy.pdcch_ul; - if (bwp_pusch_slot.ul_prbs.collides(ul_prbs)) { + if (bwp_pusch_slot.ul_prbs.collides(ul_grant)) { return alloc_result::sch_collision; } @@ -435,6 +438,9 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr return alloc_result::no_cch_space; } uint32_t coreset_id = ss[0]->coreset_id; + if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss[0]->type)) { + ul_grant &= prb_interval{ue->phy().pdcch.coreset[ss[0]->coreset_id].offset_rb, ue->phy().carrier.nof_prb}; + } if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci( pdcch_grant_type_t::ul_data, aggr_idx, ss[0]->id, &ue.cfg())) { // Could not find space in PDCCH @@ -445,10 +451,10 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr if (ue.h_ul->empty()) { int mcs = ue->fixed_pusch_mcs(); - bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, ue->ue_cfg().maxharq_tx); + bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_grant, 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); + bool success = ue.h_ul->new_retx(ue.pusch_slot, ue.pusch_slot, ul_grant); srsran_assert(success, "Failed to allocate UL HARQ retx"); } @@ -457,7 +463,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr 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; + bwp_pusch_slot.ul_prbs |= ul_grant; bwp_pusch_slot.ul.pusch.emplace_back(); pusch_t& pusch = bwp_pusch_slot.ul.pusch.back(); srsran_slot_cfg_t slot_cfg; diff --git a/srsgnb/src/stack/mac/sched_nr_helpers.cc b/srsgnb/src/stack/mac/sched_nr_helpers.cc index 898e9d67f..dfeb1fdd0 100644 --- a/srsgnb/src/stack/mac/sched_nr_helpers.cc +++ b/srsgnb/src/stack/mac/sched_nr_helpers.cc @@ -22,7 +22,7 @@ namespace sched_nr_impl { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template -void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, DciDlOrUl& dci) +void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, const srsran_dci_ctx_t& dci_ctx, DciDlOrUl& dci) { const static uint32_t rv_idx[4] = {0, 2, 3, 1}; @@ -40,9 +40,16 @@ void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, DciDlOrUl& const prb_grant& grant = h->prbs(); if (grant.is_alloc_type0()) { dci.freq_domain_assigment = grant.rbgs().to_uint64(); + if (SRSRAN_SEARCH_SPACE_IS_COMMON(dci_ctx.ss_type) and dci_ctx.coreset_start_rb > 0) { + dci.freq_domain_assigment = + (dci.freq_domain_assigment << dci_ctx.coreset_start_rb) & ((1U << grant.rbgs().size()) - 1); + } } else { - dci.freq_domain_assigment = - srsran_ra_nr_type1_riv(bwp_cfg.cfg.rb_width, grant.prbs().start(), grant.prbs().length()); + uint32_t rb_start = grant.prbs().start(); + if (SRSRAN_SEARCH_SPACE_IS_COMMON(dci_ctx.ss_type)) { + rb_start -= dci_ctx.coreset_start_rb; + } + dci.freq_domain_assigment = srsran_ra_nr_type1_riv(bwp_cfg.cfg.rb_width, rb_start, grant.prbs().length()); } dci.time_domain_assigment = 0; } @@ -51,13 +58,14 @@ bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp { uint32_t cs_id = bwp_cfg.cfg.pdcch.ra_search_space.coreset_id; - dci.mcs = 5; dci.ctx.format = srsran_dci_format_nr_1_0; dci.ctx.ss_type = srsran_search_space_type_common_1; dci.ctx.rnti_type = srsran_rnti_type_ra; dci.ctx.rnti = ra_rnti; dci.ctx.coreset_id = cs_id; - dci.ctx.coreset_start_rb = bwp_cfg.cfg.pdcch.coreset[cs_id].offset_rb; + dci.ctx.coreset_start_rb = srsran_coreset_start_rb(&bwp_cfg.cfg.pdcch.coreset[cs_id]); + + dci.mcs = 5; if (bwp_cfg.cfg.pdcch.coreset_present[0] and cs_id == 0) { dci.coreset0_bw = srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[cs_id]); } @@ -73,7 +81,6 @@ 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->phy().pdcch.ra_search_space.coreset_id; msg3_dci.ctx.rnti_type = srsran_rnti_type_tc; msg3_dci.ctx.rnti = ue->rnti; @@ -83,6 +90,7 @@ bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul } else { msg3_dci.ctx.format = srsran_dci_format_nr_0_0; } + fill_dci_common(ue, bwp_cfg, msg3_dci.ctx, msg3_dci); return true; } @@ -98,7 +106,7 @@ void fill_dl_dci_ue_fields(const slot_ue& ue, 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); + fill_dci_common(ue, bwp_cfg, dci.ctx, dci); if (dci.ctx.format == srsran_dci_format_nr_1_0) { dci.harq_feedback = (ue.uci_slot - ue.pdsch_slot) - 1; } else { @@ -115,7 +123,7 @@ void fill_ul_dci_ue_fields(const slot_ue& ue, 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); + fill_dci_common(ue, bwp_cfg, dci.ctx, dci); } void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues)