From fe2a19c46dc7747c6d4fb6ed2afcd631f787975f Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 24 Nov 2021 20:30:36 +0000 Subject: [PATCH] nr,gnb,sched: consider CORESET RB limits in the computation of DCI riv --- srsgnb/hdr/stack/mac/sched_nr_helpers.h | 6 + .../src/stack/mac/sched_nr_grant_allocator.cc | 43 +++--- srsgnb/src/stack/mac/sched_nr_helpers.cc | 123 ++++++++++++------ 3 files changed, 115 insertions(+), 57 deletions(-) diff --git a/srsgnb/hdr/stack/mac/sched_nr_helpers.h b/srsgnb/hdr/stack/mac/sched_nr_helpers.h index 47be2e462..bcb7698fd 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_helpers.h +++ b/srsgnb/hdr/stack/mac/sched_nr_helpers.h @@ -24,6 +24,12 @@ class slot_ue; class ul_harq_proc; struct bwp_res_grid; +/// In case of Common SearchSpace, not all PRBs might be available +void reduce_to_dl_coreset_bw(const bwp_params_t& bwp_cfg, + uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + prb_grant& grant); + bool fill_dci_sib(prb_interval interv, uint32_t sib_idx, uint32_t si_ntx, diff --git a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc index e9e03951c..3e207a817 100644 --- a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc +++ b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc @@ -28,7 +28,7 @@ candidate_ss_list_t find_ss(const srsran_pdcch_cfg_nr_t& pdcch, 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) { + auto contains_dci_fmt = [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) { @@ -60,13 +60,13 @@ candidate_ss_list_t find_ss(const srsran_pdcch_cfg_nr_t& pdcch, 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)) { + if (ss.type == srsran_search_space_type_ue and contains_dci_fmt(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)) { + if (is_common_ss_allowed(ss.type) and contains_dci_fmt(ss)) { ret.push_back(&ss); } } @@ -323,25 +323,28 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant) // Find space in PUCCH // TODO - // Find space and allocate PDCCH + // Choose SearchSpace + DCI format 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 - candidate_ss_list_t ss = find_ss(ue->phy().pdcch, aggr_idx, rnti_type, dci_fmt_list); - if (ss.empty()) { + candidate_ss_list_t ss_candidates = find_ss(ue->phy().pdcch, aggr_idx, rnti_type, dci_fmt_list); + if (ss_candidates.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[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())) { + const srsran_search_space_t& ss = *ss_candidates[0]; + + // Find space and allocate PDCCH + 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())) { // Could not find space in PDCCH return alloc_result::no_cch_space; } + // Update PRB grant based on the start and end of CORESET RBs + reduce_to_dl_coreset_bw(cfg, ss.id, srsran_dci_format_nr_1_0, dl_grant); + // Allocate HARQ int mcs = ue->fixed_pdsch_mcs(); if (ue.h_dl->empty()) { @@ -359,7 +362,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant) 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[0]->id, pdcch.dci.ctx.location, pdcch.dci); + fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss.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(), @@ -429,20 +432,20 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, prb_grant ul_grant) return alloc_result::sch_collision; } + // Choose SearchSpace + DCI format 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()) { + candidate_ss_list_t ss_candidates = find_ss(ue->phy().pdcch, aggr_idx, rnti_type, dci_fmt_list); + if (ss_candidates.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[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}; - } + const srsran_search_space_t& ss = *ss_candidates[0]; + + uint32_t coreset_id = ss.coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci( - pdcch_grant_type_t::ul_data, aggr_idx, ss[0]->id, &ue.cfg())) { + pdcch_grant_type_t::ul_data, aggr_idx, ss.id, &ue.cfg())) { // Could not find space in PDCCH return alloc_result::no_cch_space; } @@ -460,7 +463,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, prb_grant ul_grant) // Generate PDCCH pdcch_ul_t& pdcch = pdcchs.back(); - fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss[0]->id, pdcch.dci.ctx.location, pdcch.dci); + fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss.id, pdcch.dci.ctx.location, pdcch.dci); pdcch.dci_cfg = ue->phy().get_dci_cfg(); // Generate PUSCH bwp_pusch_slot.ul_prbs |= ul_grant; diff --git a/srsgnb/src/stack/mac/sched_nr_helpers.cc b/srsgnb/src/stack/mac/sched_nr_helpers.cc index f2ed244ba..5b08610f8 100644 --- a/srsgnb/src/stack/mac/sched_nr_helpers.cc +++ b/srsgnb/src/stack/mac/sched_nr_helpers.cc @@ -21,60 +21,104 @@ namespace sched_nr_impl { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void reduce_to_dl_coreset_bw(const bwp_params_t& bwp_cfg, + uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + prb_grant& grant) +{ + const srsran_search_space_t& ss = + dci_fmt == srsran_dci_format_nr_rar ? bwp_cfg.cfg.pdcch.ra_search_space : bwp_cfg.cfg.pdcch.search_space[ss_id]; + if (not SRSRAN_SEARCH_SPACE_IS_COMMON(ss.type)) { + return; + } + uint32_t rb_start = 0, nof_prbs = bwp_cfg.nof_prb(); + if (dci_fmt == srsran_dci_format_nr_1_0) { + rb_start = srsran_coreset_start_rb(&bwp_cfg.cfg.pdcch.coreset[ss.coreset_id]); + } + if (ss.coreset_id == 0) { + nof_prbs = srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[0]); + } + grant &= prb_interval{rb_start, rb_start + nof_prbs}; +} + +void fill_dci_common(const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci) +{ + dci.bwp_id = bwp_cfg.bwp_id; + dci.cc_id = bwp_cfg.cc; + dci.tpc = 1; + dci.coreset0_bw = bwp_cfg.cfg.pdcch.coreset_present[0] ? srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[0]) : 0; +} + +void fill_dci_common(const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci) +{ + dci.bwp_id = bwp_cfg.bwp_id; + dci.cc_id = bwp_cfg.cc; + dci.tpc = 1; +} + template -void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, const srsran_dci_ctx_t& dci_ctx, DciDlOrUl& dci) +void fill_dci_harq(const slot_ue& ue, DciDlOrUl& dci) { const static uint32_t rv_idx[4] = {0, 2, 3, 1}; - 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) : static_cast(ue.h_ul); + dci.pid = h->pid; dci.ndi = h->ndi(); dci.mcs = h->mcs(); dci.rv = rv_idx[h->nof_retx() % 4]; - // PRB assignment - const prb_grant& grant = h->prbs(); +} + +void fill_dci_grant(const bwp_params_t& bwp_cfg, const prb_grant& grant, srsran_dci_dl_nr_t& dci) +{ + dci.time_domain_assigment = 0; if (grant.is_alloc_type0()) { + srsran_assert(not SRSRAN_SEARCH_SPACE_IS_COMMON(dci.ctx.ss_type), "AllocType0 for common search space"); 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 { - uint32_t rb_start = grant.prbs().start(); - if (SRSRAN_SEARCH_SPACE_IS_COMMON(dci_ctx.ss_type)) { - rb_start -= dci_ctx.coreset_start_rb; + uint32_t rb_start = 0, nof_prb = bwp_cfg.nof_prb(); + if (dci.ctx.format == srsran_dci_format_nr_1_0 && SRSRAN_SEARCH_SPACE_IS_COMMON(dci.ctx.ss_type)) { + rb_start = dci.ctx.coreset_start_rb; + } + if (dci.ctx.coreset_id == 0 and SRSRAN_SEARCH_SPACE_IS_COMMON(dci.ctx.ss_type)) { + nof_prb = dci.coreset0_bw; } - dci.freq_domain_assigment = srsran_ra_nr_type1_riv(bwp_cfg.cfg.rb_width, rb_start, grant.prbs().length()); + uint32_t grant_start = grant.prbs().start() - rb_start; + dci.freq_domain_assigment = srsran_ra_nr_type1_riv(nof_prb, grant_start, grant.prbs().length()); } +} + +void fill_dci_grant(const bwp_params_t& bwp_cfg, const prb_grant& grant, srsran_dci_ul_nr_t& dci) +{ dci.time_domain_assigment = 0; + if (grant.is_alloc_type0()) { + dci.freq_domain_assigment = grant.rbgs().to_uint64(); + } else { + uint32_t nof_prb = bwp_cfg.nof_prb(); + dci.freq_domain_assigment = srsran_ra_nr_type1_riv(nof_prb, grant.prbs().start(), grant.prbs().length()); + } } -bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci) +void fill_rar_dci_context(const bwp_params_t& bwp_cfg, uint16_t ra_rnti, srsran_dci_ctx_t& dci_ctx) { uint32_t cs_id = bwp_cfg.cfg.pdcch.ra_search_space.coreset_id; - // Fill DCI context - 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 = srsran_coreset_start_rb(&bwp_cfg.cfg.pdcch.coreset[cs_id]); + 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 = srsran_coreset_start_rb(&bwp_cfg.cfg.pdcch.coreset[cs_id]); +} + +bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci) +{ + fill_rar_dci_context(bwp_cfg, ra_rnti, dci.ctx); dci.mcs = 5; - if (cs_id == 0) { - dci.coreset0_bw = srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[cs_id]); - } - dci.freq_domain_assigment = srsran_ra_nr_type1_riv(bwp_cfg.cfg.rb_width, interv.start(), interv.length()); - dci.time_domain_assigment = 0; - dci.tpc = 1; - dci.bwp_id = bwp_cfg.bwp_id; - dci.cc_id = bwp_cfg.cc; + fill_dci_common(bwp_cfg, dci); + fill_dci_grant(bwp_cfg, interv, dci); // TODO: Fill return true; @@ -94,7 +138,9 @@ bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul } // Fill DCI content - fill_dci_common(ue, bwp_cfg, msg3_dci.ctx, msg3_dci); + fill_dci_common(bwp_cfg, msg3_dci); + fill_dci_harq(ue, msg3_dci); + fill_dci_grant(bwp_cfg, ue.h_ul->prbs(), msg3_dci); return true; } @@ -110,15 +156,14 @@ 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.ctx, dci); + fill_dci_common(bwp_cfg, dci); + fill_dci_harq(ue, dci); + fill_dci_grant(bwp_cfg, ue.h_dl->prbs(), dci); if (dci.ctx.format == srsran_dci_format_nr_1_0) { dci.harq_feedback = (ue.uci_slot - ue.pdsch_slot) - 1; } else { dci.harq_feedback = ue.pdsch_slot.slot_idx(); } - if (dci.ctx.coreset_id == 0 and dci.ctx.format == srsran_dci_format_nr_1_0) { - dci.coreset0_bw = srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[0]); - } } void fill_ul_dci_ue_fields(const slot_ue& ue, @@ -130,9 +175,13 @@ 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.ctx, dci); + fill_dci_common(bwp_cfg, dci); + fill_dci_harq(ue, dci); + fill_dci_grant(bwp_cfg, ue.h_ul->prbs(), dci); } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues) { if (not logger.debug.enabled() or slot_ues.empty()) {