sched,nr: add logic for allocation of RAR and Msg3 grants

master
Francisco Paisana 3 years ago
parent bc5a548fe8
commit 592d9332ba

@ -35,12 +35,14 @@ public:
explicit ra_sched(const bwp_params& bwp_cfg_);
int dl_rach_info(const dl_sched_rar_info_t& rar_info);
void run_slot(bwp_slot_allocator& slot_grid);
void run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues);
size_t empty() const { return pending_rars.empty(); }
private:
alloc_result
allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc);
alloc_result allocate_pending_rar(bwp_slot_allocator& slot_grid,
const pending_rar_t& rar,
slot_ue_map_t& slot_ues,
uint32_t& nof_grants_alloc);
const bwp_params* bwp_cfg = nullptr;
srslog::basic_logger& logger;
@ -69,14 +71,9 @@ public:
explicit serv_cell_manager(const sched_cell_params& cell_cfg_);
void add_user(uint16_t rnti, ue_carrier* ue);
void rem_user(uint16_t rnti);
srsran::bounded_vector<bwp_ctxt, SCHED_NR_MAX_BWP_PER_CELL> bwps;
const sched_cell_params& cfg;
srsran::static_circular_map<uint16_t, ue_carrier*, SCHED_NR_MAX_USERS> ues;
private:
srslog::basic_logger& logger;
};

@ -47,6 +47,13 @@ struct bwp_params {
uint32_t P;
uint32_t N_rbg;
struct pusch_rach_time_cfg {
uint32_t msg3_delay; ///< Includes K2 and delta. See TS 36.214 6.1.2.1.1-2/4/5
uint32_t S;
uint32_t L;
};
std::vector<pusch_rach_time_cfg> pusch_rach_list;
bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, uint32_t cc, uint32_t bwp_id);
};

@ -83,7 +83,11 @@ public:
void new_slot(tti_point pdcch_tti_) { pdcch_tti = pdcch_tti_; }
alloc_result alloc_rar(uint32_t aggr_idx, const pending_rar_t& rar, prb_interval interv, uint32_t max_nof_grants);
alloc_result alloc_rar_and_msg3(uint32_t aggr_idx,
const pending_rar_t& rar,
prb_interval interv,
slot_ue_map_t& ues,
uint32_t max_nof_grants);
alloc_result alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant);
alloc_result alloc_pusch(slot_ue& ue, const rbgmask_t& dl_mask);
@ -93,6 +97,8 @@ public:
const bwp_params& cfg;
private:
alloc_result verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid = nullptr) const;
srslog::basic_logger& logger;
bwp_res_grid& bwp_grid;

@ -102,7 +102,8 @@ private:
ue_cfg_t ue_cfg;
};
using ue_map_t = srsran::static_circular_map<uint16_t, std::unique_ptr<ue>, SCHED_NR_MAX_USERS>;
using ue_map_t = srsran::static_circular_map<uint16_t, std::unique_ptr<ue>, SCHED_NR_MAX_USERS>;
using slot_ue_map_t = srsran::static_circular_map<uint16_t, slot_ue, SCHED_NR_MAX_USERS>;
} // namespace sched_nr_impl

@ -19,8 +19,10 @@ namespace sched_nr_impl {
ra_sched::ra_sched(const bwp_params& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger("MAC")) {}
alloc_result
ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc)
alloc_result ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid,
const pending_rar_t& rar,
slot_ue_map_t& slot_ues,
uint32_t& nof_grants_alloc)
{
const uint32_t rar_aggr_level = 2;
const prb_bitmap& prbs = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].dl_prbs.prbs();
@ -29,11 +31,11 @@ ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_
for (nof_grants_alloc = rar.msg3_grant.size(); nof_grants_alloc > 0; nof_grants_alloc--) {
ret = alloc_result::invalid_coderate;
uint32_t start_prb_idx = 0;
for (uint32_t nprb = 1; nprb < bwp_cfg->cfg.rb_width and ret == alloc_result::invalid_coderate; ++nprb) {
for (uint32_t nprb = 4; nprb < bwp_cfg->cfg.rb_width and ret == alloc_result::invalid_coderate; ++nprb) {
prb_interval interv = find_empty_interval_of_length(prbs, nprb, start_prb_idx);
start_prb_idx = interv.stop();
if (interv.length() == nprb) {
ret = slot_grid.alloc_rar(rar_aggr_level, rar, interv, nof_grants_alloc);
ret = slot_grid.alloc_rar_and_msg3(rar_aggr_level, rar, interv, slot_ues, nof_grants_alloc);
} else {
ret = alloc_result::no_sch_space;
}
@ -50,10 +52,14 @@ ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_
return ret;
}
void ra_sched::run_slot(bwp_slot_allocator& slot_grid)
void ra_sched::run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues)
{
static const uint32_t PRACH_RAR_OFFSET = 3;
tti_point pdcch_tti = slot_grid.get_pdcch_tti();
tti_point msg3_tti = pdcch_tti + bwp_cfg->pusch_rach_list[0].msg3_delay;
if (not slot_grid.res_grid()[msg3_tti].is_ul) {
return;
}
for (auto it = pending_rars.begin(); it != pending_rars.end();) {
pending_rar_t& rar = *it;
@ -79,9 +85,9 @@ void ra_sched::run_slot(bwp_slot_allocator& slot_grid)
return;
}
// Try to schedule DCI + RBGs for RAR Grant
// Try to schedule DCIs + RBGs for RAR Grants
uint32_t nof_rar_allocs = 0;
alloc_result ret = allocate_pending_rar(slot_grid, rar, nof_rar_allocs);
alloc_result ret = allocate_pending_rar(slot_grid, rar, slot_ues, nof_rar_allocs);
if (ret == alloc_result::success) {
// If RAR allocation was successful:

@ -12,6 +12,9 @@
#include "srsenb/hdr/stack/mac/nr/sched_nr_cfg.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h"
extern "C" {
#include "srsran/phy/phch/ra_ul_nr.h"
}
namespace srsenb {
namespace sched_nr_impl {
@ -19,10 +22,23 @@ namespace sched_nr_impl {
bwp_params::bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, uint32_t cc_, uint32_t bwp_id_) :
cell_cfg(cell), sched_cfg(sched_cfg_), cc(cc_), bwp_id(bwp_id_), cfg(cell.bwps[bwp_id_])
{
srsran_assert(bwp_id != 0 or cfg.pdcch.coreset_present[0], "CORESET#0 has to be active for initial BWP");
P = get_P(cfg.rb_width, cfg.pdsch.rbg_size_cfg_1);
N_rbg = get_nof_rbgs(cfg.rb_width, cfg.start_rb, cfg.pdsch.rbg_size_cfg_1);
srsran_assert(bwp_id != 0 or cfg.pdcch.coreset_present[0], "CORESET#0 has to be active for initial BWP");
pusch_rach_list.resize(cfg.pusch.nof_common_time_ra);
const uint32_t coreset_id = 0;
srsran_sch_grant_nr_t grant;
for (uint32_t m = 0; m < cfg.pusch.nof_common_time_ra; ++m) {
int ret =
srsran_ra_ul_nr_time(&cfg.pusch, srsran_rnti_type_ra, srsran_search_space_type_rar, coreset_id, m, &grant);
srsran_assert(ret == SRSRAN_SUCCESS, "Failed to obtain RA config");
pusch_rach_list[m].msg3_delay = grant.k;
pusch_rach_list[m].S = grant.S;
pusch_rach_list[m].L = grant.L;
}
srsran_assert(not pusch_rach_list.empty(), "Time-Domain Resource Allocation not valid");
}
sched_cell_params::sched_cell_params(uint32_t cc_, const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_) :

@ -21,7 +21,10 @@ namespace sched_nr_impl {
bool fill_dci_rar(prb_interval interv, const bwp_params& cell, srsran_dci_dl_nr_t& dci)
{
dci.mcs = 5;
dci.mcs = 5;
dci.ctx.format = srsran_dci_format_nr_1_0;
// TODO: Fill
return true;
}

@ -11,6 +11,7 @@
*/
#include "srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h"
namespace srsenb {
@ -63,15 +64,21 @@ bwp_slot_allocator::bwp_slot_allocator(bwp_res_grid& bwp_grid_) :
logger(srslog::fetch_basic_logger("MAC")), cfg(*bwp_grid_.cfg), bwp_grid(bwp_grid_)
{}
alloc_result bwp_slot_allocator::alloc_rar(uint32_t aggr_idx,
const srsenb::sched_nr_impl::pending_rar_t& rar,
prb_interval interv,
uint32_t nof_grants)
alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint32_t aggr_idx,
const srsenb::sched_nr_impl::pending_rar_t& rar,
prb_interval interv,
slot_ue_map_t& ues,
uint32_t max_nof_grants)
{
static const uint32_t msg3_nof_prbs = 3;
static const uint32_t msg3_nof_prbs = 3, m = 0;
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_tti];
bwp_slot_grid& bwp_msg3_slot = bwp_grid[pdcch_tti + 4];
tti_point msg3_tti = pdcch_tti + cfg.pusch_rach_list[m].msg3_delay;
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_tti];
alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr);
if (ret != alloc_result::success) {
return ret;
}
if (bwp_pdcch_slot.dl_pdcchs.full()) {
logger.warning("SCHED: Maximum number of DL allocations reached");
@ -88,10 +95,10 @@ alloc_result bwp_slot_allocator::alloc_rar(uint32_t
}
// Check Msg3 RB collision
uint32_t total_ul_nof_prbs = msg3_nof_prbs * nof_grants;
uint32_t total_ul_nof_prbs = msg3_nof_prbs * max_nof_grants;
uint32_t total_ul_nof_rbgs = srsran::ceil_div(total_ul_nof_prbs, get_P(bwp_grid.nof_prbs(), false));
prb_interval msg3_rbgs = find_empty_interval_of_length(bwp_msg3_slot.ul_prbs.prbs(), total_ul_nof_rbgs);
if (msg3_rbgs.length() < total_ul_nof_rbgs) {
prb_interval msg3_rbs = find_empty_interval_of_length(bwp_msg3_slot.ul_prbs.prbs(), total_ul_nof_rbgs);
if (msg3_rbs.length() < total_ul_nof_rbgs) {
logger.debug("SCHED: No space in PUSCH for Msg3.");
return alloc_result::sch_collision;
}
@ -105,6 +112,8 @@ alloc_result bwp_slot_allocator::alloc_rar(uint32_t
return alloc_result::no_cch_space;
}
// RAR allocation successful.
// Generate DCI for RAR
pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back();
if (not fill_dci_rar(interv, *bwp_grid.cfg, pdcch.dci)) {
@ -112,10 +121,39 @@ alloc_result bwp_slot_allocator::alloc_rar(uint32_t
bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci();
return alloc_result::invalid_coderate;
}
// RAR allocation successful.
// Generate RAR PDSCH
bwp_pdcch_slot.dl_prbs.add(interv);
// Generate Msg3 grants in PUSCH
uint32_t last_msg3 = msg3_rbs.start();
const int mcs = 0, max_harq_msg3_retx = 4;
int dai = 0;
srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = msg3_tti.sf_idx();
for (const auto& grant : rar.msg3_grant) {
slot_ue& ue = ues[grant.temp_crnti];
bool success = ue.h_ul->new_tx(
msg3_tti, msg3_tti, prb_interval{last_msg3, last_msg3 + msg3_nof_prbs}, mcs, 100, max_harq_msg3_retx);
srsran_assert(success, "Failed to allocate Msg3");
last_msg3 += msg3_nof_prbs;
srsran_dci_ul_nr_t msg3_dci; // Create dummy Msg3 DCI
msg3_dci.ctx.coreset_id = 1;
msg3_dci.ctx.rnti_type = srsran_rnti_type_ra;
msg3_dci.ctx.ss_type = srsran_search_space_type_rar;
msg3_dci.ctx.format = srsran_dci_format_nr_0_0;
msg3_dci.cc_id = cfg.cc;
msg3_dci.bwp_id = cfg.bwp_id;
msg3_dci.rv = 0;
msg3_dci.mcs = 0;
msg3_dci.time_domain_assigment = dai++;
bwp_msg3_slot.puschs.emplace_back();
pusch_t& pusch = bwp_msg3_slot.puschs.back();
success = ue.cfg->phy().get_pusch_cfg(slot_cfg, 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();
}
bwp_msg3_slot.ul_prbs.add(msg3_rbs);
return alloc_result::success;
}
@ -207,21 +245,18 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_mask)
{
auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti];
auto& bwp_pusch_slot = bwp_grid[ue.pusch_tti];
alloc_result ret = verify_pusch_space(bwp_pusch_slot, &bwp_pdcch_slot);
if (ret != alloc_result::success) {
return ret;
}
if (ue.h_ul == nullptr) {
logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue.rnti);
return alloc_result::no_rnti_opportunity;
}
auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti];
auto& bwp_pusch_slot = bwp_grid[ue.pusch_tti];
if (not bwp_pusch_slot.is_ul) {
logger.warning("SCHED: Trying to allocate PUSCH in TDD non-UL slot index=%d", bwp_pusch_slot.slot_idx);
return alloc_result::no_sch_space;
}
pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs;
if (pdcchs.full()) {
logger.warning("SCHED: Maximum number of UL allocations reached");
return alloc_result::no_grant_space;
}
pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs;
const rbg_bitmap& pusch_mask = bwp_pusch_slot.ul_prbs.rbgs();
if ((pusch_mask & ul_mask).any()) {
return alloc_result::sch_collision;
@ -235,10 +270,10 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m
if (ue.h_ul->empty()) {
srsran_assert(ue.cfg->ue_cfg()->fixed_ul_mcs >= 0, "Dynamic MCS not yet supported");
int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs;
int tbs = 100;
bool ret = ue.h_ul->new_tx(ue.pusch_tti, ue.pusch_tti, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx);
srsran_assert(ret, "Failed to allocate UL HARQ");
int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs;
int tbs = 100;
bool success = ue.h_ul->new_tx(ue.pusch_tti, ue.pusch_tti, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx);
srsran_assert(success, "Failed to allocate UL HARQ");
} else {
srsran_assert(ue.h_ul->new_retx(ue.pusch_tti, ue.pusch_tti, ul_mask), "Failed to allocate UL HARQ retx");
}
@ -254,12 +289,36 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m
pusch_t& pusch = bwp_pusch_slot.puschs.back();
srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = ue.pusch_tti.sf_idx();
bool ret = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch);
srsran_assert(ret, "Error converting DCI to PUSCH grant");
bool success = ue.cfg->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();
return alloc_result::success;
}
alloc_result bwp_slot_allocator::verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_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->ul_pdcchs.full()) {
logger.warning("SCHED: Maximum number of PUSCH allocations reached");
return alloc_result::no_grant_space;
}
}
if (pusch_grid.puschs.full()) {
logger.warning("SCHED: Maximum number of PUSCH allocations reached");
return alloc_result::no_grant_space;
}
return alloc_result::success;
}
} // namespace sched_nr_impl
} // namespace srsenb

@ -81,7 +81,7 @@ void slot_cc_worker::run()
bwp_alloc.new_slot(tti_rx + TX_ENB_DELAY);
// Allocate pending RARs
cell.bwps[0].ra.run_slot(bwp_alloc);
cell.bwps[0].ra.run_slot(bwp_alloc, slot_ues);
// TODO: Prioritize PDCCH scheduling for DL and UL data in a Round-Robin fashion
alloc_dl_ues();

@ -40,6 +40,7 @@ sched_nr_interface::cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t&
cell_cfg.bwps.resize(1);
cell_cfg.bwps[0].pdcch = phy_cfg.pdcch;
cell_cfg.bwps[0].pdsch = phy_cfg.pdsch;
cell_cfg.bwps[0].pusch = phy_cfg.pusch;
cell_cfg.bwps[0].rb_width = phy_cfg.carrier.nof_prb;
cell_cfg.bwps[0].pdcch.coreset_present[0] = true;

Loading…
Cancel
Save