nr,gnb,sched: refactored slot_ue class to use pointer to ue_carrier instead of deriving all necessary parameters

master
Francisco 3 years ago committed by Francisco Paisana
parent da9c564ad4
commit 7b989d9976

@ -64,8 +64,8 @@ private:
int add_ue_impl(uint16_t rnti, std::unique_ptr<sched_nr_impl::ue> 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;

@ -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<cell_params_t> 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<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]) {
@ -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;

@ -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

@ -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<std::unique_ptr<ue> >;
using slot_ue_map_t = rnti_map_t<slot_ue>;

@ -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_cfg_t> 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

@ -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;

@ -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) {

@ -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<DciDlOrUl, srsran_dci_dl_nr_t>::value ? static_cast<harq_proc*>(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),

@ -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<const uint32_t> 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:

@ -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

@ -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;
}

@ -35,7 +35,7 @@ void test_single_prach()
// Set cells configuration
std::vector<sched_nr_interface::cell_cfg_t> 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;

@ -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_))
{

Loading…
Cancel
Save