mirror of https://github.com/PentHertz/srsLTE.git
nr,gnb,sched: wrap coreset list in pdcch_scheduler
This commit is contained in:
parent
8f6ead0d55
commit
0929177fa2
|
@ -106,6 +106,11 @@ struct bwp_params_t {
|
|||
return cached_empty_prb_mask;
|
||||
}
|
||||
|
||||
const srsran_search_space_t* get_ss(uint32_t ss_id) const
|
||||
{
|
||||
return cfg.pdcch.search_space_present[ss_id] ? &cfg.pdcch.search_space[ss_id] : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
prb_bitmap cached_empty_prb_mask;
|
||||
srsran::optional_vector<prb_bitmap> used_common_prb_masks;
|
||||
|
@ -148,6 +153,16 @@ public:
|
|||
const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; }
|
||||
const bwp_params_t& active_bwp() const { return *bwp_cfg; }
|
||||
|
||||
/// Get SearchSpace based on SearchSpaceId
|
||||
const srsran_search_space_t* get_ss(uint32_t ss_id) const
|
||||
{
|
||||
if (phy().pdcch.search_space_present[ss_id]) {
|
||||
// UE-dedicated SearchSpace
|
||||
return &bwp_cfg->cfg.pdcch.search_space[ss_id];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
srsran::const_span<uint32_t> 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]) {
|
||||
|
|
|
@ -47,22 +47,20 @@ struct bwp_slot_grid {
|
|||
uint32_t slot_idx = 0;
|
||||
const bwp_params_t* cfg = nullptr;
|
||||
|
||||
bwp_rb_bitmap dl_prbs;
|
||||
bwp_rb_bitmap ul_prbs;
|
||||
dl_sched_res_t dl;
|
||||
ul_sched_t ul;
|
||||
slot_coreset_list coresets;
|
||||
harq_ack_list_t pending_acks;
|
||||
bwp_rb_bitmap dl_prbs;
|
||||
bwp_rb_bitmap ul_prbs;
|
||||
dl_sched_res_t dl;
|
||||
ul_sched_t ul;
|
||||
harq_ack_list_t pending_acks;
|
||||
pdcch_scheduler pdcch_sched; /// slot PDCCH resource scheduler
|
||||
|
||||
srsran::unique_pool_ptr<tx_harq_softbuffer> rar_softbuffer;
|
||||
|
||||
bwp_slot_grid() = default;
|
||||
explicit bwp_slot_grid(const bwp_params_t& bwp_params, uint32_t slot_idx_);
|
||||
void reset();
|
||||
|
||||
bool is_dl() const { return cfg->slots[slot_idx].is_dl; }
|
||||
bool is_ul() const { return cfg->slots[slot_idx].is_ul; }
|
||||
|
||||
bool is_dl() const { return cfg->slots[slot_idx].is_dl; }
|
||||
bool is_ul() const { return cfg->slots[slot_idx].is_ul; }
|
||||
prb_bitmap used_prbs(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const
|
||||
{
|
||||
return dl_prbs.prbs() | cfg->used_prbs(ss_id, dci_fmt);
|
||||
|
@ -119,7 +117,7 @@ public:
|
|||
private:
|
||||
alloc_result
|
||||
verify_pdsch_space(bwp_slot_grid& pdsch_grid, bwp_slot_grid& pdcch_grid, bwp_slot_grid* uci_grid = nullptr) const;
|
||||
alloc_result verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid = nullptr) const;
|
||||
alloc_result verify_pusch_space(bwp_slot_grid& pusch_grid) const;
|
||||
alloc_result verify_ue_cfg(const ue_carrier_params_t& ue_cfg, harq_proc* harq) const;
|
||||
|
||||
bwp_res_grid& bwp_grid;
|
||||
|
|
|
@ -27,8 +27,6 @@ using coreset_bitmap = srsran::bounded_bitset<SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZ
|
|||
|
||||
enum class pdcch_grant_type_t { sib, rar, dl_data, ul_data };
|
||||
|
||||
class slot_ue;
|
||||
|
||||
class coreset_region
|
||||
{
|
||||
public:
|
||||
|
@ -46,12 +44,12 @@ public:
|
|||
* @param user UE object or null in case of broadcast/RAR/paging allocation
|
||||
* @return if the allocation was successful
|
||||
*/
|
||||
bool alloc_dci(pdcch_grant_type_t alloc_type,
|
||||
uint32_t aggr_idx,
|
||||
uint32_t search_space_id,
|
||||
const ue_carrier_params_t* user = nullptr);
|
||||
bool alloc_pdcch(pdcch_grant_type_t alloc_type,
|
||||
uint32_t aggr_idx,
|
||||
uint32_t search_space_id,
|
||||
const ue_carrier_params_t* user = nullptr);
|
||||
|
||||
void rem_last_dci();
|
||||
void rem_last_pdcch();
|
||||
|
||||
uint32_t get_td_symbols() const { return coreset_cfg->duration; }
|
||||
uint32_t get_freq_resources() const { return nof_freq_res; }
|
||||
|
@ -96,6 +94,60 @@ private:
|
|||
bool get_next_dfs();
|
||||
};
|
||||
|
||||
class pdcch_scheduler
|
||||
{
|
||||
public:
|
||||
pdcch_scheduler(const bwp_params_t& bwp_cfg_,
|
||||
uint32_t slot_idx,
|
||||
pdcch_dl_list_t& pdcch_dl_list,
|
||||
pdcch_ul_list_t& pdcch_ul_list);
|
||||
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Allocates RE space for DL DCI in PDCCH, avoiding in the process collisions with other PDCCH allocations
|
||||
* @param pdcch_grant_type_t allocation type (e.g. DL data, UL data, SI, RAR)
|
||||
* @param ss_id Search space ID
|
||||
* @param aggr_idx Aggregation level index (0..4)
|
||||
* @param user UE object or null in case of broadcast/RAR/paging allocation
|
||||
* @return pdcch object if the allocation was successful
|
||||
*/
|
||||
pdcch_dl_t* alloc_dl_pdcch(pdcch_grant_type_t alloc_type,
|
||||
uint32_t ss_id,
|
||||
uint32_t aggr_idx,
|
||||
const ue_carrier_params_t* user = nullptr);
|
||||
|
||||
/**
|
||||
* Allocates RE space for UL DCI in PDCCH, avoiding in the process collisions with other PDCCH allocations
|
||||
* @param ss_id Search space ID
|
||||
* @param aggr_idx Aggregation level index (0..4)
|
||||
* @param user UE object parameters
|
||||
* @return pdcch object if the allocation was successful
|
||||
*/
|
||||
pdcch_ul_t* alloc_ul_pdcch(uint32_t ss_id, uint32_t aggr_idx, const ue_carrier_params_t* user);
|
||||
|
||||
/**
|
||||
* Cancel and remove last PDCCH allocation
|
||||
* @param ss_id Search space ID
|
||||
*/
|
||||
void rem_last_pdcch(uint32_t ss_id);
|
||||
|
||||
private:
|
||||
const static size_t MAX_CORESET_PER_BWP = 3; /// limit set in TS 38.331, ControlResourceSetId
|
||||
using slot_coreset_list = std::array<srsran::optional<coreset_region>, MAX_CORESET_PER_BWP>;
|
||||
|
||||
bool check_args_valid(uint32_t ss_id, uint32_t aggr_idx, const ue_carrier_params_t* user, bool is_dl) const;
|
||||
|
||||
// args
|
||||
const bwp_params_t& bwp_cfg;
|
||||
srslog::basic_logger& logger;
|
||||
const uint32_t slot_idx;
|
||||
|
||||
pdcch_dl_list_t& pdcch_dl_list;
|
||||
pdcch_ul_list_t& pdcch_ul_list;
|
||||
slot_coreset_list coresets;
|
||||
};
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -80,23 +80,13 @@ bwp_slot_grid::bwp_slot_grid(const bwp_params_t& bwp_cfg_, uint32_t slot_idx_) :
|
|||
ul_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1),
|
||||
slot_idx(slot_idx_),
|
||||
cfg(&bwp_cfg_),
|
||||
pdcch_sched(bwp_cfg_, slot_idx_, dl.phy.pdcch_dl, dl.phy.pdcch_ul),
|
||||
rar_softbuffer(harq_softbuffer_pool::get_instance().get_tx(bwp_cfg_.cfg.rb_width))
|
||||
{
|
||||
for (uint32_t cs_idx = 0; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; ++cs_idx) {
|
||||
if (cfg->cfg.pdcch.coreset_present[cs_idx]) {
|
||||
uint32_t cs_id = cfg->cfg.pdcch.coreset[cs_idx].id;
|
||||
coresets[cs_id].emplace(*cfg, cs_id, slot_idx_, dl.phy.pdcch_dl, dl.phy.pdcch_ul);
|
||||
}
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
void bwp_slot_grid::reset()
|
||||
{
|
||||
for (auto& coreset : coresets) {
|
||||
if (coreset.has_value()) {
|
||||
coreset->reset();
|
||||
}
|
||||
}
|
||||
pdcch_sched.reset();
|
||||
dl_prbs.reset();
|
||||
ul_prbs.reset();
|
||||
dl.phy.ssb.clear();
|
||||
|
@ -140,9 +130,9 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx,
|
|||
return alloc_result::sch_collision;
|
||||
}
|
||||
|
||||
const uint32_t coreset_id = 0;
|
||||
const uint32_t ss_id = 0;
|
||||
if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::sib, aggr_idx, ss_id)) {
|
||||
const uint32_t ss_id = 0;
|
||||
pdcch_dl_t* pdcch = bwp_pdcch_slot.pdcch_sched.alloc_dl_pdcch(pdcch_grant_type_t::sib, ss_id, aggr_idx);
|
||||
if (pdcch == nullptr) {
|
||||
logger.warning("SCHED: Cannot allocate SIB1 due to lack of PDCCH space.");
|
||||
return alloc_result::no_cch_space;
|
||||
}
|
||||
|
@ -150,11 +140,10 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx,
|
|||
// RAR allocation successful.
|
||||
bwp_pdcch_slot.dl_prbs |= prbs;
|
||||
// Generate DCI for SIB
|
||||
pdcch_dl_t& pdcch = bwp_pdcch_slot.dl.phy.pdcch_dl.back();
|
||||
pdcch.dci_cfg.coreset0_bw = srsran_coreset_get_bw(&cfg.cfg.pdcch.coreset[0]);
|
||||
if (not fill_dci_sib(prbs, si_idx, si_ntx, *bwp_grid.cfg, pdcch.dci)) {
|
||||
pdcch->dci_cfg.coreset0_bw = srsran_coreset_get_bw(&cfg.cfg.pdcch.coreset[0]);
|
||||
if (not fill_dci_sib(prbs, si_idx, si_ntx, *bwp_grid.cfg, pdcch->dci)) {
|
||||
// Cancel on-going PDCCH allocation
|
||||
bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci();
|
||||
bwp_pdcch_slot.pdcch_sched.rem_last_pdcch(ss_id);
|
||||
return alloc_result::invalid_coderate;
|
||||
}
|
||||
|
||||
|
@ -164,10 +153,10 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx,
|
|||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = pdcch_slot.to_uint();
|
||||
int code = srsran_ra_dl_dci_to_grant_nr(
|
||||
&cfg.cell_cfg.carrier, &slot_cfg, &cfg.cfg.pdsch, &pdcch.dci, &pdsch.sch, &pdsch.sch.grant);
|
||||
&cfg.cell_cfg.carrier, &slot_cfg, &cfg.cfg.pdsch, &pdcch->dci, &pdsch.sch, &pdsch.sch.grant);
|
||||
if (code != SRSRAN_SUCCESS) {
|
||||
logger.warning("Error generating SIB PDSCH grant.");
|
||||
bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci();
|
||||
bwp_pdcch_slot.pdcch_sched.rem_last_pdcch(ss_id);
|
||||
bwp_pdcch_slot.dl.phy.pdsch.pop_back();
|
||||
return alloc_result::other_cause;
|
||||
}
|
||||
|
@ -189,7 +178,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot];
|
||||
slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay;
|
||||
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot];
|
||||
alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr);
|
||||
alloc_result ret = verify_pusch_space(bwp_msg3_slot);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -233,7 +222,8 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
// Find PDCCH position
|
||||
const uint32_t coreset_id = cfg.cfg.pdcch.ra_search_space.coreset_id;
|
||||
const uint32_t search_space_id = cfg.cfg.pdcch.ra_search_space.id;
|
||||
if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::rar, aggr_idx, search_space_id, nullptr)) {
|
||||
pdcch_dl_t* pdcch = bwp_pdcch_slot.pdcch_sched.alloc_dl_pdcch(pdcch_grant_type_t::rar, search_space_id, aggr_idx);
|
||||
if (pdcch == nullptr) {
|
||||
// Could not find space in PDCCH
|
||||
logger.debug("SCHED: No space in PDCCH for DL tx.");
|
||||
return alloc_result::no_cch_space;
|
||||
|
@ -242,21 +232,20 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
// RAR allocation successful.
|
||||
bwp_pdcch_slot.dl_prbs |= interv;
|
||||
// Generate DCI for RAR with given RA-RNTI
|
||||
pdcch_dl_t& pdcch = bwp_pdcch_slot.dl.phy.pdcch_dl.back();
|
||||
if (not fill_dci_rar(interv, ra_rnti, *bwp_grid.cfg, pdcch.dci)) {
|
||||
if (not fill_dci_rar(interv, ra_rnti, *bwp_grid.cfg, pdcch->dci)) {
|
||||
// Cancel on-going PDCCH allocation
|
||||
bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci();
|
||||
bwp_pdcch_slot.pdcch_sched.rem_last_pdcch(search_space_id);
|
||||
return alloc_result::invalid_coderate;
|
||||
}
|
||||
auto& phy_cfg = slot_ues[pending_rachs[0].temp_crnti]->phy();
|
||||
pdcch.dci_cfg = phy_cfg.get_dci_cfg();
|
||||
auto& phy_cfg = slot_ues[pending_rachs[0].temp_crnti]->phy();
|
||||
pdcch->dci_cfg = phy_cfg.get_dci_cfg();
|
||||
// Generate RAR PDSCH
|
||||
// TODO: Properly fill Msg3 grants
|
||||
bwp_pdcch_slot.dl.phy.pdsch.emplace_back();
|
||||
pdsch_t& pdsch = bwp_pdcch_slot.dl.phy.pdsch.back();
|
||||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = pdcch_slot.to_uint();
|
||||
bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
|
||||
bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch->dci, pdsch.sch);
|
||||
srsran_assert(success, "Error converting DCI to grant");
|
||||
pdsch.sch.grant.tb[0].softbuffer.tx = bwp_pdcch_slot.rar_softbuffer->get();
|
||||
|
||||
|
@ -336,9 +325,11 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant)
|
|||
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())) {
|
||||
pdcch_dl_t* pdcch =
|
||||
bwp_pdcch_slot.pdcch_sched.alloc_dl_pdcch(pdcch_grant_type_t::dl_data, ss.id, aggr_idx, &ue.cfg());
|
||||
if (pdcch == nullptr) {
|
||||
// Could not find space in PDCCH
|
||||
logger.debug("Could not find PDCCH space for rnti=0x%x PDSCH allocation", ue->rnti);
|
||||
return alloc_result::no_cch_space;
|
||||
}
|
||||
|
||||
|
@ -361,19 +352,18 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant)
|
|||
const static float max_R = 0.93;
|
||||
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.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(),
|
||||
[&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; });
|
||||
pdcch.dci.dai %= 4;
|
||||
pdcch.dci_cfg = ue->phy().get_dci_cfg();
|
||||
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(),
|
||||
[&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; });
|
||||
pdcch->dci.dai %= 4;
|
||||
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->phy();
|
||||
srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res),
|
||||
srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch->dci, bwp_uci_slot.pending_acks.back().res),
|
||||
"Error getting ack resource");
|
||||
|
||||
// Generate PDSCH
|
||||
|
@ -382,7 +372,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant)
|
|||
pdsch_t& pdsch = bwp_pdsch_slot.dl.phy.pdsch.back();
|
||||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = ue.pdsch_slot.to_uint();
|
||||
bool ret = ue->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();
|
||||
|
@ -419,7 +409,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, prb_grant ul_grant)
|
|||
|
||||
auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
|
||||
auto& bwp_pusch_slot = bwp_grid[ue.pusch_slot];
|
||||
alloc_result ret = verify_pusch_space(bwp_pusch_slot, &bwp_pdcch_slot);
|
||||
alloc_result ret = verify_pusch_space(bwp_pusch_slot);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -443,10 +433,10 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, prb_grant ul_grant)
|
|||
}
|
||||
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.id, &ue.cfg())) {
|
||||
pdcch_ul_t* pdcch = bwp_pdcch_slot.pdcch_sched.alloc_ul_pdcch(ss.id, aggr_idx, &ue.cfg());
|
||||
if (pdcch == nullptr) {
|
||||
// Could not find space in PDCCH
|
||||
logger.debug("Could not find PDCCH space for rnti=0x%x PUSCH allocation", ue->rnti);
|
||||
return alloc_result::no_cch_space;
|
||||
}
|
||||
|
||||
|
@ -462,9 +452,8 @@ 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.id, pdcch.dci.ctx.location, pdcch.dci);
|
||||
pdcch.dci_cfg = ue->phy().get_dci_cfg();
|
||||
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;
|
||||
bwp_pusch_slot.ul.pusch.emplace_back();
|
||||
|
@ -472,7 +461,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, prb_grant ul_grant)
|
|||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = ue.pusch_slot.to_uint();
|
||||
pusch.pid = ue.h_ul->pid;
|
||||
bool success = ue->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) {
|
||||
|
@ -492,10 +481,6 @@ alloc_result bwp_slot_allocator::verify_pdsch_space(bwp_slot_grid& pdsch_grid,
|
|||
logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", pdsch_grid.slot_idx);
|
||||
return alloc_result::no_sch_space;
|
||||
}
|
||||
if (pdcch_grid.dl.phy.pdcch_dl.full()) {
|
||||
logger.warning("SCHED: Maximum number of DL PDCCH allocations reached");
|
||||
return alloc_result::no_cch_space;
|
||||
}
|
||||
if (pdsch_grid.dl.phy.pdsch.full()) {
|
||||
logger.warning("SCHED: Maximum number of DL PDSCH grants reached");
|
||||
return alloc_result::no_sch_space;
|
||||
|
@ -509,23 +494,12 @@ alloc_result bwp_slot_allocator::verify_pdsch_space(bwp_slot_grid& pdsch_grid,
|
|||
return alloc_result::success;
|
||||
}
|
||||
|
||||
alloc_result bwp_slot_allocator::verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid) const
|
||||
alloc_result bwp_slot_allocator::verify_pusch_space(bwp_slot_grid& pusch_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->dl.phy.pdcch_ul.full()) {
|
||||
logger.warning("SCHED: Maximum number of PUSCH allocations reached");
|
||||
return alloc_result::no_grant_space;
|
||||
}
|
||||
}
|
||||
if (pusch_grid.ul.pusch.full()) {
|
||||
logger.warning("SCHED: Maximum number of PUSCH allocations reached");
|
||||
return alloc_result::no_grant_space;
|
||||
|
|
|
@ -47,10 +47,10 @@ void coreset_region::reset()
|
|||
pdcch_ul_list.clear();
|
||||
}
|
||||
|
||||
bool coreset_region::alloc_dci(pdcch_grant_type_t alloc_type,
|
||||
uint32_t aggr_idx,
|
||||
uint32_t search_space_id,
|
||||
const ue_carrier_params_t* user)
|
||||
bool coreset_region::alloc_pdcch(pdcch_grant_type_t alloc_type,
|
||||
uint32_t aggr_idx,
|
||||
uint32_t search_space_id,
|
||||
const ue_carrier_params_t* user)
|
||||
{
|
||||
srsran_assert(aggr_idx <= 4, "Invalid DCI aggregation level=%d", 1U << aggr_idx);
|
||||
srsran_assert((user == nullptr) xor
|
||||
|
@ -63,6 +63,7 @@ bool coreset_region::alloc_dci(pdcch_grant_type_t alloc_type,
|
|||
record.aggr_idx = aggr_idx;
|
||||
record.ss_id = search_space_id;
|
||||
record.alloc_type = alloc_type;
|
||||
|
||||
if (record.alloc_type == pdcch_grant_type_t::ul_data) {
|
||||
record.idx = pdcch_ul_list.size();
|
||||
pdcch_ul_list.emplace_back();
|
||||
|
@ -95,7 +96,7 @@ bool coreset_region::alloc_dci(pdcch_grant_type_t alloc_type,
|
|||
return false;
|
||||
}
|
||||
|
||||
void coreset_region::rem_last_dci()
|
||||
void coreset_region::rem_last_pdcch()
|
||||
{
|
||||
srsran_assert(not dci_list.empty(), "%s called when no PDCCH have yet been allocated", __FUNCTION__);
|
||||
|
||||
|
@ -191,5 +192,112 @@ srsran::span<const uint32_t> coreset_region::get_cce_loc_table(const alloc_recor
|
|||
return {};
|
||||
}
|
||||
|
||||
pdcch_scheduler::pdcch_scheduler(const bwp_params_t& bwp_cfg_,
|
||||
uint32_t slot_idx_,
|
||||
pdcch_dl_list_t& dl_pdcchs,
|
||||
pdcch_ul_list_t& ul_pdcchs) :
|
||||
bwp_cfg(bwp_cfg_), pdcch_dl_list(dl_pdcchs), pdcch_ul_list(ul_pdcchs), slot_idx(slot_idx_), logger(bwp_cfg_.logger)
|
||||
{
|
||||
for (uint32_t cs_idx = 0; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; ++cs_idx) {
|
||||
if (bwp_cfg.cfg.pdcch.coreset_present[cs_idx]) {
|
||||
uint32_t cs_id = bwp_cfg.cfg.pdcch.coreset[cs_idx].id;
|
||||
coresets[cs_id].emplace(bwp_cfg, cs_id, slot_idx, pdcch_dl_list, pdcch_ul_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to verify valid inputs
|
||||
bool pdcch_scheduler::check_args_valid(uint32_t ss_id,
|
||||
uint32_t aggr_idx,
|
||||
const ue_carrier_params_t* user,
|
||||
bool is_dl) const
|
||||
{
|
||||
srsran_assert(ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE, "Invalid SearchSpace#%d", ss_id);
|
||||
srsran_assert(
|
||||
aggr_idx < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR, "Invalid aggregation level index=%d", aggr_idx);
|
||||
|
||||
// Common checks
|
||||
if (not bwp_cfg.slots[slot_idx].is_dl) {
|
||||
logger.warning("SCHED: Trying to allocate PDCCH in non");
|
||||
return false;
|
||||
}
|
||||
|
||||
const srsran_search_space_t* ss = (user == nullptr) ? bwp_cfg.get_ss(ss_id) : user->get_ss(ss_id);
|
||||
if (ss == nullptr) {
|
||||
logger.error("Failure to allocate PDCCH. Cause: SearchSpace#%d has not been configured in the scheduler", ss_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ss->nof_candidates[aggr_idx] == 0) {
|
||||
logger.warning("Chosen PDCCH doesn't have any valid candidates");
|
||||
return false;
|
||||
}
|
||||
if (is_dl and pdcch_dl_list.full()) {
|
||||
logger.warning("SCHED: Maximum number of DL PDCCH allocations=%zd was reached for BWP#%d, CORESET#%d",
|
||||
pdcch_dl_list.size(),
|
||||
bwp_cfg.bwp_id,
|
||||
bwp_cfg.cfg.pdcch.search_space[ss_id].coreset_id);
|
||||
return false;
|
||||
}
|
||||
if (not is_dl and pdcch_ul_list.full()) {
|
||||
logger.warning("SCHED: Maximum number of UL PDCCH allocations=%zd was reached for BWP#%d",
|
||||
pdcch_ul_list.size(),
|
||||
bwp_cfg.bwp_id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pdcch_dl_t* pdcch_scheduler::alloc_dl_pdcch(pdcch_grant_type_t alloc_type,
|
||||
uint32_t ss_id,
|
||||
uint32_t aggr_idx,
|
||||
const ue_carrier_params_t* user)
|
||||
{
|
||||
if (not check_args_valid(ss_id, aggr_idx, user, true)) {
|
||||
return nullptr;
|
||||
}
|
||||
const srsran_search_space_t& ss = (user == nullptr) ? *bwp_cfg.get_ss(ss_id) : *user->get_ss(ss_id);
|
||||
|
||||
if (alloc_type == pdcch_grant_type_t::rar) {
|
||||
srsran_assert(ss_id == bwp_cfg.cfg.pdcch.ra_search_space.id and bwp_cfg.cfg.pdcch.ra_search_space_present,
|
||||
"PDCCH grant type does not match search space");
|
||||
}
|
||||
|
||||
if (coresets[ss.coreset_id]->alloc_pdcch(alloc_type, aggr_idx, ss_id, user)) {
|
||||
return &pdcch_dl_list.back();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pdcch_ul_t* pdcch_scheduler::alloc_ul_pdcch(uint32_t ss_id, uint32_t aggr_idx, const ue_carrier_params_t* user)
|
||||
{
|
||||
if (not check_args_valid(ss_id, aggr_idx, user, false)) {
|
||||
return nullptr;
|
||||
}
|
||||
const srsran_search_space_t& ss = *user->get_ss(ss_id);
|
||||
|
||||
if (coresets[ss.coreset_id]->alloc_pdcch(pdcch_grant_type_t::ul_data, aggr_idx, ss_id, user)) {
|
||||
return &pdcch_ul_list.back();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void pdcch_scheduler::rem_last_pdcch(uint32_t ss_id)
|
||||
{
|
||||
const srsran_search_space_t& ss = bwp_cfg.cfg.pdcch.search_space[ss_id];
|
||||
|
||||
uint32_t coreset_id = ss.coreset_id;
|
||||
coresets[coreset_id]->rem_last_pdcch();
|
||||
}
|
||||
|
||||
void pdcch_scheduler::reset()
|
||||
{
|
||||
for (uint32_t i = 0; i < coresets.size(); ++i) {
|
||||
if (coresets[i].has_value()) {
|
||||
coresets[i]->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
||||
/**
|
||||
* @brief Algorithm to select next UE to allocate in a time-domain RR fashion
|
||||
* @param ue_db map of "slot_ue"
|
||||
* @param rr_count starting index to select next UE
|
||||
* @param p callable that returns true if UE allocation was successful
|
||||
* @return true if a UE was allocated
|
||||
*/
|
||||
template <typename Predicate>
|
||||
bool round_robin_apply(slot_ue_map_t& ue_db, uint32_t rr_count, Predicate p)
|
||||
{
|
||||
|
@ -25,6 +32,7 @@ bool round_robin_apply(slot_ue_map_t& ue_db, uint32_t rr_count, Predicate p)
|
|||
std::advance(it, (rr_count % ue_db.size()));
|
||||
for (uint32_t count = 0; count < ue_db.size(); ++count, ++it) {
|
||||
if (it == ue_db.end()) {
|
||||
// wrap-around
|
||||
it = ue_db.begin();
|
||||
}
|
||||
if (p(it->second)) {
|
||||
|
|
Loading…
Reference in New Issue