sched,nr: integrate mac-phy interface types into the scheduler

master
Francisco 4 years ago committed by Andre Puschmann
parent 5b3c5ded63
commit 4c316aa9ea

@ -25,6 +25,8 @@ static const size_t MAX_NOF_AGGR_LEVELS = 5;
namespace sched_nr_impl { namespace sched_nr_impl {
const static size_t MAX_GRANTS = sched_nr_interface::MAX_GRANTS;
using sched_cfg_t = sched_nr_interface::sched_cfg_t; using sched_cfg_t = sched_nr_interface::sched_cfg_t;
using cell_cfg_t = sched_nr_interface::cell_cfg_t; using cell_cfg_t = sched_nr_interface::cell_cfg_t;

@ -34,6 +34,8 @@ public:
uint32_t nof_retx() const { return tb[0].n_rtx; } uint32_t nof_retx() const { return tb[0].n_rtx; }
uint32_t max_nof_retx() const { return max_retx; } uint32_t max_nof_retx() const { return max_retx; }
uint32_t tbs() const { return tb[0].tbs; } uint32_t tbs() const { return tb[0].tbs; }
uint32_t ndi() const { return tb[0].ndi; }
uint32_t mcs() const { return tb[0].mcs; }
bool ack_info(uint32_t tb_idx, bool ack); bool ack_info(uint32_t tb_idx, bool ack);

@ -17,6 +17,7 @@
#include "srsran/adt/bounded_vector.h" #include "srsran/adt/bounded_vector.h"
#include "srsran/adt/span.h" #include "srsran/adt/span.h"
#include "srsran/common/tti_point.h" #include "srsran/common/tti_point.h"
#include "srsran/interfaces/gnb_interfaces.h"
#include "srsran/interfaces/rrc_nr_interface_types.h" #include "srsran/interfaces/rrc_nr_interface_types.h"
#include "srsran/phy/phch/dci_nr.h" #include "srsran/phy/phch/dci_nr.h"
@ -78,15 +79,22 @@ public:
///// Sched Result ///// ///// Sched Result /////
struct pdsch_grant { const static int MAX_GRANTS = 64;
srsran_dci_dl_nr_t dci;
rbg_bitmap bitmap; using pdcch_dl_t = mac_interface_phy_nr::pdcch_dl_t;
using pdcch_ul_t = mac_interface_phy_nr::pdcch_ul_t;
using pdcch_dl_list_t = srsran::bounded_vector<pdcch_dl_t, MAX_GRANTS>;
using pdcch_ul_list_t = srsran::bounded_vector<pdcch_ul_t, MAX_GRANTS>;
struct pdsch_t {
srsran_sch_cfg_nr_t sch = {}; ///< PDSCH configuration
}; };
using pdsch_list = srsran::bounded_vector<pdsch_grant, SCHED_NR_MAX_PDSCH_DATA>; using pdsch_list_t = srsran::bounded_vector<pdsch_t, SCHED_NR_MAX_PDSCH_DATA>;
struct dl_tti_request_t { struct dl_tti_request_t {
tti_point pdsch_tti; tti_point pdsch_tti;
pdsch_list pdsch; pdcch_dl_list_t pdcchs;
pdsch_list_t pdschs;
}; };
struct pusch_grant { struct pusch_grant {

@ -29,12 +29,10 @@ enum class pdcch_grant_type_t { sib, dl_data, ul_data };
class slot_ue; class slot_ue;
struct pdcch_dl_t { using pdcch_dl_t = sched_nr_interface::pdcch_dl_t;
srsran_dci_cfg_nr_t dci_cfg = {}; using pdcch_dl_list_t = sched_nr_interface::pdcch_dl_list_t;
srsran_dci_dl_nr_t dci = {}; using pdcch_ul_t = sched_nr_interface::pdcch_ul_t;
}; using pdcch_ul_list_t = sched_nr_interface::pdcch_ul_list_t;
static const size_t MAX_NOF_PDCCH_DL_GRANTS = 16;
using pdcch_dl_list_t = srsran::bounded_vector<pdcch_dl_t, MAX_NOF_PDCCH_DL_GRANTS>;
class coreset_region class coreset_region
{ {
@ -76,8 +74,8 @@ private:
pdcch_grant_type_t alloc_type; pdcch_grant_type_t alloc_type;
slot_ue* ue; slot_ue* ue;
}; };
srsran::bounded_vector<alloc_record, MAX_NOF_PDCCH_DL_GRANTS> dci_list; srsran::bounded_vector<alloc_record, MAX_GRANTS> dci_list;
pdcch_dl_list_t& pdcch_dl_list; pdcch_dl_list_t& pdcch_dl_list;
// DFS decision tree of PDCCH grants // DFS decision tree of PDCCH grants
struct tree_node { struct tree_node {
@ -88,7 +86,7 @@ private:
/// Accumulation of all PDCCH masks for the current solution (DFS path) /// Accumulation of all PDCCH masks for the current solution (DFS path)
coreset_bitmap total_mask, current_mask; coreset_bitmap total_mask, current_mask;
}; };
using alloc_tree_dfs_t = srsran::bounded_vector<tree_node, MAX_NOF_PDCCH_DL_GRANTS>; using alloc_tree_dfs_t = srsran::bounded_vector<tree_node, MAX_GRANTS>;
alloc_tree_dfs_t dfs_tree, saved_dfs_tree; alloc_tree_dfs_t dfs_tree, saved_dfs_tree;
srsran::span<const uint32_t> get_cce_loc_table(const alloc_record& record) const; srsran::span<const uint32_t> get_cce_loc_table(const alloc_record& record) const;

@ -0,0 +1,33 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSRAN_SCHED_NR_PHY_HELPERS_H
#define SRSRAN_SCHED_NR_PHY_HELPERS_H
#include "sched_nr_common.h"
namespace srsenb {
namespace sched_nr_impl {
uint32_t get_P(uint32_t bwp_nof_prb, bool config_1_or_2);
uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, uint32_t bwp_start, bool config1_or_2);
void bitmap_to_prb_array(const rbgmask_t& bitmap, uint32_t bwp_nof_prb, srsran_sch_grant_nr_t& grant);
class slot_ue;
void fill_dci_ue_cfg(const slot_ue& ue, srsran_dci_dl_nr_t& dci);
void fill_dci_ue_cfg(const slot_ue& ue, srsran_dci_ul_nr_t& dci);
} // namespace sched_nr_impl
} // namespace srsenb
#endif // SRSRAN_SCHED_NR_PHY_HELPERS_H

@ -25,7 +25,9 @@ namespace sched_nr_impl {
using pdsch_bitmap = srsran::bounded_bitset<25, true>; using pdsch_bitmap = srsran::bounded_bitset<25, true>;
using pusch_bitmap = srsran::bounded_bitset<25, true>; using pusch_bitmap = srsran::bounded_bitset<25, true>;
using pdsch_list = sched_nr_interface::pdsch_list; using pdsch_t = sched_nr_interface::pdsch_t;
using pdsch_list_t = sched_nr_interface::pdsch_list_t;
using pusch_list = sched_nr_interface::pusch_list; using pusch_list = sched_nr_interface::pusch_list;
struct pucch_t {}; struct pucch_t {};
@ -35,9 +37,10 @@ using slot_coreset_list = srsran::bounded_vector<coreset_region,
struct bwp_slot_grid { struct bwp_slot_grid {
pdcch_dl_list_t pdcch_dl_list; pdcch_dl_list_t pdcch_dl_list;
pdcch_ul_list_t pdcch_ul_list;
slot_coreset_list coresets; slot_coreset_list coresets;
pdsch_bitmap dl_rbgs; pdsch_bitmap dl_rbgs;
pdsch_list pdsch_grants; pdsch_list_t pdsch_grants;
pusch_bitmap ul_rbgs; pusch_bitmap ul_rbgs;
pusch_list pusch_grants; pusch_list pusch_grants;
srsran::bounded_vector<pucch_t, SCHED_NR_MAX_PDSCH_DATA> pucch_grants; srsran::bounded_vector<pucch_t, SCHED_NR_MAX_PDSCH_DATA> pucch_grants;
@ -53,9 +56,12 @@ struct bwp_res_grid {
bwp_slot_grid& operator[](tti_point tti) { return slots[tti.sf_idx()]; }; bwp_slot_grid& operator[](tti_point tti) { return slots[tti.sf_idx()]; };
const bwp_slot_grid& operator[](tti_point tti) const { return slots[tti.sf_idx()]; }; const bwp_slot_grid& operator[](tti_point tti) const { return slots[tti.sf_idx()]; };
uint32_t id() const { return bwp_id; } uint32_t id() const { return bwp_id; }
uint32_t nof_prbs() const { return cell_cfg->cell_cfg.nof_prb; }
private: private:
uint32_t bwp_id; uint32_t bwp_id;
const sched_cell_params* cell_cfg = nullptr;
srsran::bounded_vector<bwp_slot_grid, TTIMOD_SZ> slots; srsran::bounded_vector<bwp_slot_grid, TTIMOD_SZ> slots;
}; };

@ -6,6 +6,6 @@
# the distribution. # the distribution.
# #
set(SOURCES mac_nr.cc sched_nr.cc sched_nr_ue.cc sched_nr_worker.cc sched_nr_rb_grid.cc sched_nr_harq.cc sched_nr_pdcch.cc sched_nr_common.cc) set(SOURCES mac_nr.cc sched_nr.cc sched_nr_ue.cc sched_nr_worker.cc sched_nr_rb_grid.cc sched_nr_harq.cc sched_nr_pdcch.cc sched_nr_common.cc sched_nr_phy_helpers.cc)
add_library(srsgnb_mac STATIC ${SOURCES}) add_library(srsgnb_mac STATIC ${SOURCES})

@ -0,0 +1,102 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy_helpers.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr_harq.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr_ue.h"
namespace srsenb {
namespace sched_nr_impl {
/// Table 6.1.2.2.1-1 - Nominal RBG size P
uint32_t get_P(uint32_t bwp_nof_prb, bool config_1_or_2)
{
srsran_assert(bwp_nof_prb > 0 and bwp_nof_prb <= 275, "Invalid BWP size");
if (bwp_nof_prb <= 36) {
return config_1_or_2 ? 2 : 4;
}
if (bwp_nof_prb <= 72) {
return config_1_or_2 ? 4 : 8;
}
if (bwp_nof_prb <= 144) {
return config_1_or_2 ? 8 : 16;
}
return 16;
}
uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, uint32_t bwp_start, bool config1_or_2)
{
uint32_t P = get_P(bwp_nof_prb, config1_or_2);
return srsran::ceil_div(bwp_nof_prb + (bwp_start % P), P);
}
uint32_t get_rbg_size(uint32_t bwp_nof_prb, uint32_t bwp_start, bool config1_or_2, uint32_t rbg_idx)
{
uint32_t P = get_P(bwp_nof_prb, config1_or_2);
uint32_t nof_rbgs = get_nof_rbgs(bwp_nof_prb, bwp_start, config1_or_2);
if (rbg_idx == 0) {
return P - (bwp_start % P);
}
if (rbg_idx == nof_rbgs - 1) {
uint32_t ret = (bwp_start + bwp_nof_prb) % P;
return ret > 0 ? ret : P;
}
return P;
}
void bitmap_to_prb_array(const rbgmask_t& bitmap, uint32_t bwp_nof_prb, srsran_sch_grant_nr_t& grant)
{
uint32_t count = 0;
grant.nof_prb = bwp_nof_prb;
for (uint32_t rbg = 0; rbg < bitmap.size(); ++rbg) {
bool val = bitmap.test(rbg);
uint32_t rbg_size = get_rbg_size(bwp_nof_prb, 0, true, rbg);
for (uint32_t prb = count; prb < count + rbg_size; ++prb) {
grant.prb_idx[prb] = val;
}
}
}
void fill_dci_harq(const harq_proc& h, srsran_dci_dl_nr_t& dci)
{
dci.pid = h.pid;
dci.ndi = h.ndi();
dci.mcs = h.mcs();
}
void fill_dci_ue_cfg(const slot_ue& ue, srsran_dci_dl_nr_t& dci)
{
dci.bwp_id = ue.bwp_id;
dci.cc_id = ue.cc;
dci.ctx.rnti = ue.rnti;
dci.tpc = 1;
fill_dci_harq(*ue.h_dl, dci);
}
void fill_dci_harq(const harq_proc& h, srsran_dci_ul_nr_t& dci)
{
dci.pid = h.pid;
dci.ndi = h.ndi();
dci.mcs = h.mcs();
}
void fill_dci_ue_cfg(const slot_ue& ue, srsran_dci_ul_nr_t& dci)
{
dci.bwp_id = ue.bwp_id;
dci.cc_id = ue.cc;
dci.ctx.rnti = ue.rnti;
dci.tpc = 1;
fill_dci_harq(*ue.h_ul, dci);
}
} // namespace sched_nr_impl
} // namespace srsenb

@ -11,11 +11,11 @@
*/ */
#include "srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy_helpers.h"
namespace srsenb { namespace srsenb {
namespace sched_nr_impl { namespace sched_nr_impl {
using pdsch_grant = sched_nr_interface::pdsch_grant;
using pusch_grant = sched_nr_interface::pusch_grant; using pusch_grant = sched_nr_interface::pusch_grant;
bwp_slot_grid::bwp_slot_grid(const sched_cell_params& cell_params, uint32_t bwp_id_, uint32_t slot_idx_) : bwp_slot_grid::bwp_slot_grid(const sched_cell_params& cell_params, uint32_t bwp_id_, uint32_t slot_idx_) :
@ -37,7 +37,7 @@ void bwp_slot_grid::reset()
pucch_grants.clear(); pucch_grants.clear();
} }
bwp_res_grid::bwp_res_grid(const sched_cell_params& cell_cfg_, uint32_t bwp_id_) : bwp_id(bwp_id_) bwp_res_grid::bwp_res_grid(const sched_cell_params& cell_cfg_, uint32_t bwp_id_) : bwp_id(bwp_id_), cell_cfg(&cell_cfg_)
{ {
for (uint32_t sl = 0; sl < SCHED_NR_NOF_SUBFRAMES; ++sl) { for (uint32_t sl = 0; sl < SCHED_NR_NOF_SUBFRAMES; ++sl) {
slots.emplace_back(cell_cfg_, bwp_id, sl); slots.emplace_back(cell_cfg_, bwp_id, sl);
@ -63,7 +63,7 @@ alloc_result slot_bwp_sched::alloc_pdsch(slot_ue& ue, const rbgmask_t& dl_mask)
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; return alloc_result::no_rnti_opportunity;
} }
pdsch_list& pdsch_grants = bwp_grid[ue.pdsch_tti].pdsch_grants; pdsch_list_t& pdsch_grants = bwp_grid[ue.pdsch_tti].pdsch_grants;
if (pdsch_grants.full()) { if (pdsch_grants.full()) {
logger.warning("SCHED: Maximum number of DL allocations reached"); logger.warning("SCHED: Maximum number of DL allocations reached");
return alloc_result::no_grant_space; return alloc_result::no_grant_space;
@ -91,11 +91,12 @@ alloc_result slot_bwp_sched::alloc_pdsch(slot_ue& ue, const rbgmask_t& dl_mask)
} }
// Allocation Successful // Allocation Successful
pdcch_dl_t& pdcch = bwp_grid[ue.pdcch_tti].pdcch_dl_list.back();
fill_dci_ue_cfg(ue, pdcch.dci);
pdsch_grants.emplace_back(); pdsch_grants.emplace_back();
pdsch_grant& grant = pdsch_grants.back(); pdsch_t& grant = pdsch_grants.back();
grant.dci.ctx.rnti = ue.rnti; grant.sch.grant.rnti = ue.rnti;
grant.dci.pid = ue.h_dl->pid; bitmap_to_prb_array(dl_mask, bwp_grid.nof_prbs(), grant.sch.grant);
grant.bitmap = dl_mask;
pdsch_mask |= dl_mask; pdsch_mask |= dl_mask;
return alloc_result::success; return alloc_result::success;
@ -116,6 +117,12 @@ alloc_result slot_bwp_sched::alloc_pusch(slot_ue& ue, const rbgmask_t& ul_mask)
if ((pusch_mask & ul_mask).any()) { if ((pusch_mask & ul_mask).any()) {
return alloc_result::sch_collision; return alloc_result::sch_collision;
} }
const uint32_t aggr_idx = 3, coreset_id = 0;
if (not bwp_grid[ue.pdcch_tti].coresets[coreset_id].alloc_dci(
pdcch_grant_type_t::ul_data, aggr_idx, coreset_id, &ue)) {
// Could not find space in PDCCH
return alloc_result::no_cch_space;
}
int mcs = -1, tbs = -1; int mcs = -1, tbs = -1;
if (ue.h_ul->empty()) { if (ue.h_ul->empty()) {
@ -129,11 +136,11 @@ alloc_result slot_bwp_sched::alloc_pusch(slot_ue& ue, const rbgmask_t& ul_mask)
} }
// Allocation Successful // Allocation Successful
pdcch_ul_t& pdcch = bwp_grid[ue.pdcch_tti].pdcch_ul_list.back();
fill_dci_ue_cfg(ue, pdcch.dci);
pusch_grants.emplace_back(); pusch_grants.emplace_back();
pusch_grant& grant = pusch_grants.back(); pusch_grant& grant = pusch_grants.back();
grant.dci.ctx.rnti = ue.rnti; grant.dci.ctx.rnti = ue.rnti;
grant.dci.pid = ue.h_dl->pid;
grant.dci.mcs = mcs;
grant.bitmap = ul_mask; grant.bitmap = ul_mask;
pusch_mask |= ul_mask; pusch_mask |= ul_mask;

@ -158,7 +158,8 @@ bool sched_worker_manager::run_tti(tti_point tti_rx_, uint32_t cc, slot_res_t& t
// Copy requested TTI DL and UL sched result // Copy requested TTI DL and UL sched result
tti_req.dl_res.pdsch_tti = tti_rx_ + TX_ENB_DELAY; tti_req.dl_res.pdsch_tti = tti_rx_ + TX_ENB_DELAY;
tti_req.dl_res.pdsch = cell_grid_list[cc].bwps[0][tti_req.dl_res.pdsch_tti].pdsch_grants; tti_req.dl_res.pdcchs = cell_grid_list[cc].bwps[0][tti_req.dl_res.pdsch_tti].pdcch_dl_list;
tti_req.dl_res.pdschs = cell_grid_list[cc].bwps[0][tti_req.dl_res.pdsch_tti].pdsch_grants;
cell_grid_list[cc].bwps[0][tti_req.dl_res.pdsch_tti].reset(); cell_grid_list[cc].bwps[0][tti_req.dl_res.pdsch_tti].reset();
tti_req.ul_res.pusch_tti = tti_rx_ + TX_ENB_DELAY; tti_req.ul_res.pusch_tti = tti_rx_ + TX_ENB_DELAY;
tti_req.ul_res.pusch = cell_grid_list[cc].bwps[0][tti_req.ul_res.pusch_tti].pusch_grants; tti_req.ul_res.pusch = cell_grid_list[cc].bwps[0][tti_req.ul_res.pusch_tti].pusch_grants;

@ -44,8 +44,8 @@ int sched_nr_ue_sim::update(const sched_nr_cc_output_res_t& cc_out)
void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out) void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out)
{ {
uint32_t cc = cc_out.cc; uint32_t cc = cc_out.cc;
for (uint32_t i = 0; i < cc_out.dl_cc_result->pdsch.size(); ++i) { for (uint32_t i = 0; i < cc_out.dl_cc_result->pdschs.size(); ++i) {
const auto& data = cc_out.dl_cc_result->pdsch[i]; const auto& data = cc_out.dl_cc_result->pdcchs[i];
if (data.dci.ctx.rnti != ctxt.rnti) { if (data.dci.ctx.rnti != ctxt.rnti) {
continue; continue;
} }

@ -64,9 +64,9 @@ struct task_job_manager {
void finish_task(const sched_nr_interface::tti_request_t& res) void finish_task(const sched_nr_interface::tti_request_t& res)
{ {
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
TESTASSERT(res.dl_res.pdsch.size() <= 1); TESTASSERT(res.dl_res.pdschs.size() <= 1);
res_count++; res_count++;
pdsch_count += res.dl_res.pdsch.size(); pdsch_count += res.dl_res.pdschs.size();
if (tasks-- >= max_tasks or tasks == 0) { if (tasks-- >= max_tasks or tasks == 0) {
cond_var.notify_one(); cond_var.notify_one();
} }
@ -111,7 +111,7 @@ void sched_nr_cfg_serialized_test()
sched_nr_cc_output_res_t out{tti, cc, &res.dl_res, &res.ul_res}; sched_nr_cc_output_res_t out{tti, cc, &res.dl_res, &res.ul_res};
sched_tester.update(out); sched_tester.update(out);
tasks.finish_task(res); tasks.finish_task(res);
TESTASSERT(res.dl_res.pdsch.size() == 1); TESTASSERT(res.dl_res.pdschs.size() == 1);
} }
} }

Loading…
Cancel
Save