mirror of https://github.com/PentHertz/srsLTE.git
sched,nr: add RAR scheduler inspired in LTE one
This commit is contained in:
parent
4f0b954cde
commit
2db8b8d876
|
@ -27,7 +27,8 @@ namespace srsenb {
|
|||
|
||||
namespace sched_nr_impl {
|
||||
class sched_worker_manager;
|
||||
}
|
||||
class cell_sched;
|
||||
} // namespace sched_nr_impl
|
||||
|
||||
class ue_event_manager;
|
||||
class sched_result_manager;
|
||||
|
@ -66,6 +67,9 @@ private:
|
|||
|
||||
// management of Sched Result buffering
|
||||
std::unique_ptr<sched_result_manager> pending_results;
|
||||
|
||||
// management of cell resources
|
||||
std::vector<std::unique_ptr<sched_nr_impl::cell_sched> > cells;
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
*
|
||||
* \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_BWP_H
|
||||
#define SRSRAN_SCHED_NR_BWP_H
|
||||
|
||||
#include "sched_nr_cfg.h"
|
||||
#include "sched_nr_rb_grid.h"
|
||||
#include "srsran/adt/pool/cached_alloc.h"
|
||||
|
||||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
||||
using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t;
|
||||
|
||||
struct pending_rar_t {
|
||||
uint16_t ra_rnti = 0;
|
||||
tti_point prach_tti;
|
||||
srsran::bounded_vector<dl_sched_rar_info_t, sched_interface::MAX_RAR_LIST> msg3_grant;
|
||||
};
|
||||
|
||||
/// RAR/Msg3 scheduler
|
||||
class ra_sched
|
||||
{
|
||||
public:
|
||||
explicit ra_sched(const sched_cell_params& cell_cfg_);
|
||||
|
||||
int dl_rach_info(const dl_sched_rar_info_t& rar_info);
|
||||
void run_slot(bwp_slot_allocator& slot_grid);
|
||||
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);
|
||||
|
||||
const sched_cell_params* cell_cfg = nullptr;
|
||||
srslog::basic_logger& logger;
|
||||
|
||||
srsran::deque<pending_rar_t> pending_rars;
|
||||
};
|
||||
|
||||
class bwp_sched
|
||||
{
|
||||
public:
|
||||
explicit bwp_sched(const sched_cell_params& cell_cfg_, uint32_t bwp_id_);
|
||||
|
||||
const sched_cell_params* cell_cfg;
|
||||
const uint32_t bwp_id;
|
||||
|
||||
// channel-specific schedulers
|
||||
ra_sched ra;
|
||||
|
||||
// Pending allocations
|
||||
bwp_res_grid grid;
|
||||
};
|
||||
|
||||
class cell_sched
|
||||
{
|
||||
public:
|
||||
srsran::bounded_vector<bwp_sched, SCHED_NR_MAX_BWP_PER_CELL> bwps;
|
||||
|
||||
explicit cell_sched(const sched_cell_params& cell_cfg_);
|
||||
|
||||
const sched_cell_params* cfg;
|
||||
};
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSRAN_SCHED_NR_BWP_H
|
|
@ -33,6 +33,7 @@ using pucch_list_t = sched_nr_interface::pucch_list_t;
|
|||
|
||||
using sched_cfg_t = sched_nr_interface::sched_cfg_t;
|
||||
using cell_cfg_t = sched_nr_interface::cell_cfg_t;
|
||||
using bwp_cfg_t = sched_nr_interface::bwp_cfg_t;
|
||||
|
||||
struct sched_cell_params {
|
||||
const uint32_t cc;
|
||||
|
@ -49,9 +50,52 @@ struct sched_params {
|
|||
explicit sched_params(const sched_cfg_t& sched_cfg_);
|
||||
};
|
||||
|
||||
using pdcchmask_t = srsran::bounded_bitset<SCHED_NR_MAX_NOF_RBGS, true>;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using rbgmask_t = srsran::bounded_bitset<SCHED_NR_MAX_NOF_RBGS, true>;
|
||||
|
||||
using pdcchmask_t = srsran::bounded_bitset<SCHED_NR_MAX_NOF_RBGS, true>;
|
||||
|
||||
using pdcch_cce_pos_list = srsran::bounded_vector<uint32_t, SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR>;
|
||||
using bwp_cce_pos_list = std::array<std::array<pdcch_cce_pos_list, MAX_NOF_AGGR_LEVELS>, SRSRAN_NOF_SF_X_FRAME>;
|
||||
void get_dci_locs(const srsran_coreset_t& coreset,
|
||||
const srsran_search_space_t& search_space,
|
||||
uint16_t rnti,
|
||||
bwp_cce_pos_list& cce_locs);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ue_cfg_t = sched_nr_interface::ue_cfg_t;
|
||||
using ue_cc_cfg_t = sched_nr_interface::ue_cc_cfg_t;
|
||||
|
||||
class ue_cfg_extended : public ue_cfg_t
|
||||
{
|
||||
public:
|
||||
struct search_space_params {
|
||||
srsran_search_space_t* cfg = nullptr;
|
||||
};
|
||||
struct coreset_params {
|
||||
srsran_coreset_t* cfg = nullptr;
|
||||
std::vector<search_space_params*> ss_list;
|
||||
bwp_cce_pos_list cce_positions;
|
||||
};
|
||||
struct bwp_params {
|
||||
std::vector<search_space_params> search_spaces;
|
||||
std::vector<coreset_params> coresets;
|
||||
};
|
||||
struct cc_params {
|
||||
srsran::bounded_vector<bwp_params, SCHED_NR_MAX_BWP_PER_CELL> bwps;
|
||||
};
|
||||
|
||||
uint16_t rnti;
|
||||
std::vector<cc_params> cc_params;
|
||||
|
||||
ue_cfg_extended() = default;
|
||||
explicit ue_cfg_extended(uint16_t rnti, const ue_cfg_t& uecfg);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct resource_guard {
|
||||
public:
|
||||
resource_guard() = default;
|
||||
|
@ -92,44 +136,6 @@ private:
|
|||
bool flag = false;
|
||||
};
|
||||
|
||||
using pdcch_cce_pos_list = srsran::bounded_vector<uint32_t, SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR>;
|
||||
using bwp_cce_pos_list = std::array<std::array<pdcch_cce_pos_list, MAX_NOF_AGGR_LEVELS>, SRSRAN_NOF_SF_X_FRAME>;
|
||||
void get_dci_locs(const srsran_coreset_t& coreset,
|
||||
const srsran_search_space_t& search_space,
|
||||
uint16_t rnti,
|
||||
bwp_cce_pos_list& cce_locs);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ue_cfg_t = sched_nr_interface::ue_cfg_t;
|
||||
using ue_cc_cfg_t = sched_nr_interface::ue_cc_cfg_t;
|
||||
|
||||
class ue_cfg_extended : public ue_cfg_t
|
||||
{
|
||||
public:
|
||||
struct search_space_params {
|
||||
srsran_search_space_t* cfg = nullptr;
|
||||
};
|
||||
struct coreset_params {
|
||||
srsran_coreset_t* cfg = nullptr;
|
||||
std::vector<search_space_params*> ss_list;
|
||||
bwp_cce_pos_list cce_positions;
|
||||
};
|
||||
struct bwp_params {
|
||||
std::vector<search_space_params> search_spaces;
|
||||
std::vector<coreset_params> coresets;
|
||||
};
|
||||
struct cc_params {
|
||||
srsran::bounded_vector<bwp_params, SCHED_NR_MAX_BWP_PER_CELL> bwps;
|
||||
};
|
||||
|
||||
uint16_t rnti;
|
||||
std::vector<cc_params> cc_params;
|
||||
|
||||
ue_cfg_extended() = default;
|
||||
explicit ue_cfg_extended(uint16_t rnti, const ue_cfg_t& uecfg);
|
||||
};
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace srsenb {
|
|||
|
||||
const static size_t SCHED_NR_MAX_CARRIERS = 4;
|
||||
const static uint16_t SCHED_NR_INVALID_RNTI = 0;
|
||||
const static size_t SCHED_NR_MAX_NOF_RBGS = 25;
|
||||
const static size_t SCHED_NR_MAX_NOF_RBGS = 17;
|
||||
const static size_t SCHED_NR_MAX_TB = 1;
|
||||
const static size_t SCHED_NR_MAX_HARQ = 16;
|
||||
const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2;
|
||||
|
@ -55,11 +55,14 @@ public:
|
|||
uint32_t bwp_id = 1;
|
||||
uint32_t start_rb = 0;
|
||||
uint32_t rb_width = 100;
|
||||
srsran_sch_hl_cfg_nr_t pdsch = {};
|
||||
srsran_sch_hl_cfg_nr_t pusch = {};
|
||||
|
||||
std::array<srsran::optional<srsran_coreset_t>, SRSRAN_UE_DL_NR_MAX_NOF_CORESET> coresets;
|
||||
};
|
||||
|
||||
struct cell_cfg_t {
|
||||
uint32_t rar_window_size;
|
||||
uint32_t nof_prb = 100;
|
||||
uint32_t nof_rbg = 25;
|
||||
srsran_tdd_config_nr_t tdd = {};
|
||||
|
@ -82,6 +85,16 @@ public:
|
|||
srsran::phy_cfg_nr_t phy_cfg = {};
|
||||
};
|
||||
|
||||
////// RACH //////
|
||||
|
||||
struct dl_sched_rar_info_t {
|
||||
uint32_t preamble_idx;
|
||||
uint32_t ta_cmd;
|
||||
uint16_t temp_crnti;
|
||||
uint32_t msg3_size;
|
||||
uint32_t prach_tti;
|
||||
};
|
||||
|
||||
///// Sched Result /////
|
||||
|
||||
using dl_sched_t = mac_interface_phy_nr::dl_sched_t;
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace sched_nr_impl {
|
|||
|
||||
using coreset_bitmap = srsran::bounded_bitset<SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE * SRSRAN_CORESET_DURATION_MAX, true>;
|
||||
|
||||
enum class pdcch_grant_type_t { sib, dl_data, ul_data };
|
||||
enum class pdcch_grant_type_t { sib, rar, dl_data, ul_data };
|
||||
|
||||
class slot_ue;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSRAN_SCHED_NR_PHY_HELPERS_H
|
||||
#define SRSRAN_SCHED_NR_PHY_HELPERS_H
|
||||
#ifndef SRSRAN_SCHED_NR_PHY_H
|
||||
#define SRSRAN_SCHED_NR_PHY_H
|
||||
|
||||
#include "sched_nr_cfg.h"
|
||||
|
||||
|
@ -21,6 +21,16 @@ 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);
|
||||
|
||||
using pdsch_bitmap = srsran::bounded_bitset<SCHED_NR_MAX_NOF_RBGS, true>;
|
||||
using pusch_bitmap = srsran::bounded_bitset<SCHED_NR_MAX_NOF_RBGS, true>;
|
||||
using rbg_interval = srsran::interval<uint32_t>;
|
||||
|
||||
rbg_interval find_empty_rbg_interval(const pdsch_bitmap& bitmap, uint32_t max_nof_rbgs);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool fill_dci_rar(rbg_interval rbginterv, const sched_cell_params& cell, srsran_dci_dl_nr_t& dci);
|
||||
|
||||
class slot_ue;
|
||||
void fill_dci_ue_cfg(const slot_ue& ue,
|
||||
const rbgmask_t& rbgmask,
|
||||
|
@ -44,4 +54,4 @@ pucch_resource_grant find_pucch_resource(const slot_ue& ue, const rbgmask_t& rbg
|
|||
} // namespace sched_nr_impl
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSRAN_SCHED_NR_PHY_HELPERS_H
|
||||
#endif // SRSRAN_SCHED_NR_PHY_H
|
|
@ -17,13 +17,15 @@
|
|||
#include "lib/include/srsran/adt/circular_array.h"
|
||||
#include "sched_nr_interface.h"
|
||||
#include "sched_nr_pdcch.h"
|
||||
#include "sched_nr_phy.h"
|
||||
#include "sched_nr_ue.h"
|
||||
|
||||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
||||
using pdsch_bitmap = srsran::bounded_bitset<25, true>;
|
||||
using pusch_bitmap = srsran::bounded_bitset<25, true>;
|
||||
struct pending_rar_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const static size_t MAX_CORESET_PER_BWP = 3;
|
||||
using slot_coreset_list = srsran::bounded_vector<coreset_region, MAX_CORESET_PER_BWP>;
|
||||
|
@ -54,35 +56,35 @@ struct bwp_res_grid {
|
|||
const sched_cell_params& cell_params() const { return *cell_cfg; }
|
||||
const bwp_cfg_t& bwp_cfg() const { return cell_cfg->cell_cfg.bwps[id() - 1]; }
|
||||
|
||||
const sched_cell_params* cell_cfg = nullptr;
|
||||
|
||||
private:
|
||||
uint32_t bwp_id;
|
||||
const sched_cell_params* cell_cfg = nullptr;
|
||||
|
||||
srsran::bounded_vector<bwp_slot_grid, TTIMOD_SZ> slots;
|
||||
};
|
||||
|
||||
struct cell_res_grid {
|
||||
const sched_cell_params* cell_cfg = nullptr;
|
||||
srsran::bounded_vector<bwp_res_grid, SCHED_NR_MAX_BWP_PER_CELL> bwps;
|
||||
|
||||
explicit cell_res_grid(const sched_cell_params& cell_cfg);
|
||||
};
|
||||
|
||||
class slot_bwp_sched
|
||||
class bwp_slot_allocator
|
||||
{
|
||||
public:
|
||||
explicit slot_bwp_sched(uint32_t bwp_id, cell_res_grid& phy_grid_);
|
||||
explicit bwp_slot_allocator(bwp_res_grid& bwp_grid_);
|
||||
|
||||
void new_slot(tti_point pdcch_tti_) { pdcch_tti = pdcch_tti_; }
|
||||
|
||||
alloc_result alloc_rar(uint32_t aggr_idx, const pending_rar_t& rar, rbg_interval interv, uint32_t max_nof_grants);
|
||||
alloc_result alloc_pdsch(slot_ue& ue, const rbgmask_t& dl_mask);
|
||||
alloc_result alloc_pusch(slot_ue& ue, const rbgmask_t& dl_mask);
|
||||
|
||||
tti_point get_pdcch_tti() const { return pdcch_tti; }
|
||||
const bwp_res_grid& res_grid() const { return bwp_grid; }
|
||||
|
||||
const sched_cell_params& cfg;
|
||||
|
||||
private:
|
||||
srslog::basic_logger& logger;
|
||||
bwp_res_grid& bwp_grid;
|
||||
|
||||
tti_point tti_rx;
|
||||
tti_point pdcch_tti;
|
||||
};
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef SRSRAN_SCHED_NR_WORKER_H
|
||||
#define SRSRAN_SCHED_NR_WORKER_H
|
||||
|
||||
#include "sched_nr_bwp.h"
|
||||
#include "sched_nr_cfg.h"
|
||||
#include "sched_nr_rb_grid.h"
|
||||
#include "sched_nr_ue.h"
|
||||
|
@ -32,9 +33,7 @@ using ul_sched_t = sched_nr_interface::ul_sched_t;
|
|||
class slot_cc_worker
|
||||
{
|
||||
public:
|
||||
explicit slot_cc_worker(const sched_cell_params& cell_params, cell_res_grid& phy_grid) :
|
||||
cfg(cell_params), res_grid(0, phy_grid)
|
||||
{}
|
||||
explicit slot_cc_worker(cell_sched& sched);
|
||||
|
||||
void start(tti_point tti_rx_, ue_map_t& ue_db_);
|
||||
void run();
|
||||
|
@ -46,9 +45,10 @@ private:
|
|||
void alloc_ul_ues();
|
||||
|
||||
const sched_cell_params& cfg;
|
||||
cell_sched& cell;
|
||||
|
||||
tti_point tti_rx;
|
||||
slot_bwp_sched res_grid;
|
||||
bwp_slot_allocator bwp_alloc;
|
||||
|
||||
srsran::static_circular_map<uint16_t, slot_ue, SCHED_NR_MAX_USERS> slot_ues;
|
||||
};
|
||||
|
@ -80,9 +80,9 @@ private:
|
|||
ue_map_t& ue_db;
|
||||
std::mutex ue_db_mutex;
|
||||
|
||||
std::vector<std::unique_ptr<slot_worker_ctxt> > slot_ctxts;
|
||||
std::vector<std::unique_ptr<slot_worker_ctxt> > slot_worker_ctxts;
|
||||
|
||||
srsran::bounded_vector<cell_res_grid, SCHED_NR_MAX_CARRIERS> cell_grid_list;
|
||||
srsran::bounded_vector<cell_sched, SCHED_NR_MAX_CARRIERS> cell_grid_list;
|
||||
|
||||
slot_worker_ctxt& get_sf(tti_point tti_rx);
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# 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_cfg.cc sched_nr_phy_helpers.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_cfg.cc sched_nr_phy.cc sched_nr_bwp.cc)
|
||||
|
||||
add_library(srsgnb_mac STATIC ${SOURCES})
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_bwp.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h"
|
||||
#include "srsran/common/thread_pool.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
*
|
||||
* \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_bwp.h"
|
||||
#include "srsran/common/standard_streams.h"
|
||||
#include "srsran/common/string_helpers.h"
|
||||
|
||||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
||||
ra_sched::ra_sched(const sched_cell_params& cell_cfg_) : cell_cfg(&cell_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)
|
||||
{
|
||||
const uint32_t rar_aggr_level = 2;
|
||||
auto& pdsch_bitmap = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].dl_rbgs;
|
||||
|
||||
alloc_result ret = alloc_result::other_cause;
|
||||
for (nof_grants_alloc = rar.msg3_grant.size(); nof_grants_alloc > 0; nof_grants_alloc--) {
|
||||
ret = alloc_result::invalid_coderate;
|
||||
for (uint32_t nrbg = 1; nrbg < cell_cfg->cell_cfg.nof_rbg and ret == alloc_result::invalid_coderate; ++nrbg) {
|
||||
rbg_interval rbg_interv = find_empty_rbg_interval(pdsch_bitmap, nrbg);
|
||||
if (rbg_interv.length() == nrbg) {
|
||||
ret = slot_grid.alloc_rar(rar_aggr_level, rar, rbg_interv, nof_grants_alloc);
|
||||
} else {
|
||||
ret = alloc_result::no_sch_space;
|
||||
}
|
||||
}
|
||||
|
||||
// If allocation was not successful because there were not enough RBGs, try allocating fewer Msg3 grants
|
||||
if (ret != alloc_result::invalid_coderate and ret != alloc_result::no_sch_space) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret != alloc_result::success) {
|
||||
logger.info("SCHED: RAR allocation for L=%d was postponed. Cause=%s", rar_aggr_level, to_string(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ra_sched::run_slot(bwp_slot_allocator& slot_grid)
|
||||
{
|
||||
static const uint32_t PRACH_RAR_OFFSET = 3;
|
||||
tti_point pdcch_tti = slot_grid.get_pdcch_tti();
|
||||
|
||||
for (auto it = pending_rars.begin(); it != pending_rars.end();) {
|
||||
pending_rar_t& rar = *it;
|
||||
|
||||
// In case of RAR outside RAR window:
|
||||
// - if window has passed, discard RAR
|
||||
// - if window hasn't started, stop loop, as RARs are ordered by TTI
|
||||
tti_interval rar_window{rar.prach_tti + PRACH_RAR_OFFSET,
|
||||
rar.prach_tti + PRACH_RAR_OFFSET + cell_cfg->cell_cfg.rar_window_size};
|
||||
if (not rar_window.contains(pdcch_tti)) {
|
||||
if (pdcch_tti >= rar_window.stop()) {
|
||||
fmt::memory_buffer str_buffer;
|
||||
fmt::format_to(str_buffer,
|
||||
"SCHED: Could not transmit RAR within the window (RA={}, Window={}, RAR={}",
|
||||
rar.prach_tti,
|
||||
rar_window,
|
||||
pdcch_tti);
|
||||
srsran::console("%s\n", srsran::to_c_str(str_buffer));
|
||||
logger.warning("%s", srsran::to_c_str(str_buffer));
|
||||
it = pending_rars.erase(it);
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to schedule DCI + RBGs for RAR Grant
|
||||
uint32_t nof_rar_allocs = 0;
|
||||
alloc_result ret = allocate_pending_rar(slot_grid, rar, nof_rar_allocs);
|
||||
|
||||
if (ret == alloc_result::success) {
|
||||
// If RAR allocation was successful:
|
||||
// - in case all Msg3 grants were allocated, remove pending RAR, and continue with following RAR
|
||||
// - otherwise, erase only Msg3 grants that were allocated, and stop iteration
|
||||
|
||||
if (nof_rar_allocs == rar.msg3_grant.size()) {
|
||||
it = pending_rars.erase(it);
|
||||
} else {
|
||||
std::copy(rar.msg3_grant.begin() + nof_rar_allocs, rar.msg3_grant.end(), rar.msg3_grant.begin());
|
||||
rar.msg3_grant.resize(rar.msg3_grant.size() - nof_rar_allocs);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// If RAR allocation was not successful:
|
||||
// - in case of unavailable PDCCH space, try next pending RAR allocation
|
||||
// - otherwise, stop iteration
|
||||
if (ret != alloc_result::no_cch_space) {
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info)
|
||||
{
|
||||
logger.info("SCHED: New PRACH tti=%d, preamble=%d, temp_crnti=0x%x, ta_cmd=%d, msg3_size=%d",
|
||||
rar_info.prach_tti,
|
||||
rar_info.preamble_idx,
|
||||
rar_info.temp_crnti,
|
||||
rar_info.ta_cmd,
|
||||
rar_info.msg3_size);
|
||||
|
||||
// RA-RNTI = 1 + t_id + f_id
|
||||
// t_id = index of first subframe specified by PRACH (0<=t_id<10)
|
||||
// f_id = index of the PRACH within subframe, in ascending order of freq domain (0<=f_id<6) (for FDD, f_id=0)
|
||||
uint16_t ra_rnti = 1 + (uint16_t)(rar_info.prach_tti % 10u);
|
||||
|
||||
// find pending rar with same RA-RNTI
|
||||
for (pending_rar_t& r : pending_rars) {
|
||||
if (r.prach_tti.to_uint() == rar_info.prach_tti and ra_rnti == r.ra_rnti) {
|
||||
if (r.msg3_grant.size() >= sched_interface::MAX_RAR_LIST) {
|
||||
logger.warning("PRACH ignored, as the the maximum number of RAR grants per tti has been reached");
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
r.msg3_grant.push_back(rar_info);
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// create new RAR
|
||||
pending_rar_t p;
|
||||
p.ra_rnti = ra_rnti;
|
||||
p.prach_tti = tti_point{rar_info.prach_tti};
|
||||
p.msg3_grant.push_back(rar_info);
|
||||
pending_rars.push_back(p);
|
||||
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
bwp_sched::bwp_sched(const sched_cell_params& cell_cfg_, uint32_t bwp_id_) :
|
||||
cell_cfg(&cell_cfg_), bwp_id(bwp_id_), ra(cell_cfg_), grid(cell_cfg_, bwp_id_)
|
||||
{}
|
||||
|
||||
cell_sched::cell_sched(const sched_cell_params& cell_cfg_) : cfg(&cell_cfg_)
|
||||
{
|
||||
for (uint32_t bwp_id = 0; bwp_id < cfg->cell_cfg.bwps.size(); ++bwp_id) {
|
||||
bwps.emplace_back(cell_cfg_, bwp_id);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
} // namespace srsenb
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_cfg.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy.h"
|
||||
|
||||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy_helpers.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_harq.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_ue.h"
|
||||
|
||||
|
@ -82,6 +82,38 @@ int bitmap_to_riv(const rbgmask_t& bitmap, uint32_t cell_nof_prb)
|
|||
return srsran_ra_nr_type1_riv(cell_nof_prb, interv.start(), interv.length());
|
||||
}
|
||||
|
||||
rbg_interval find_empty_rbg_interval(const pdsch_bitmap& in_mask, uint32_t max_size)
|
||||
{
|
||||
rbg_interval max_interv;
|
||||
|
||||
for (size_t n = 0; n < in_mask.size();) {
|
||||
int pos = in_mask.find_lowest(n, in_mask.size(), false);
|
||||
if (pos < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
size_t max_pos = std::min(in_mask.size(), (size_t)pos + max_size);
|
||||
int pos2 = in_mask.find_lowest(pos + 1, max_pos, true);
|
||||
rbg_interval interv(pos, pos2 < 0 ? max_pos : pos2);
|
||||
if (interv.length() >= max_size) {
|
||||
return interv;
|
||||
}
|
||||
if (interv.length() > max_interv.length()) {
|
||||
max_interv = interv;
|
||||
}
|
||||
n = interv.stop();
|
||||
}
|
||||
return max_interv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool fill_dci_rar(rbg_interval rbginterv, const sched_cell_params& cell, srsran_dci_dl_nr_t& dci)
|
||||
{
|
||||
dci.mcs = 5;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename DciDlOrUl>
|
||||
void fill_dci_common(const slot_ue& ue, const rbgmask_t& bitmap, const sched_cell_params& cc_cfg, DciDlOrUl& dci)
|
||||
{
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_rb_grid.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy_helpers.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_phy.h"
|
||||
|
||||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
@ -49,20 +49,68 @@ bwp_res_grid::bwp_res_grid(const sched_cell_params& cell_cfg_, uint32_t bwp_id_)
|
|||
}
|
||||
}
|
||||
|
||||
cell_res_grid::cell_res_grid(const sched_cell_params& cell_cfg_) : cell_cfg(&cell_cfg_)
|
||||
{
|
||||
for (uint32_t bwp_id = 0; bwp_id < cell_cfg->cell_cfg.bwps.size(); ++bwp_id) {
|
||||
bwps.emplace_back(cell_cfg_, bwp_id);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
slot_bwp_sched::slot_bwp_sched(uint32_t bwp_id, cell_res_grid& phy_grid_) :
|
||||
logger(srslog::fetch_basic_logger("MAC")), cfg(*phy_grid_.cell_cfg), bwp_grid(phy_grid_.bwps[bwp_id])
|
||||
bwp_slot_allocator::bwp_slot_allocator(bwp_res_grid& bwp_grid_) :
|
||||
logger(srslog::fetch_basic_logger("MAC")), cfg(*bwp_grid_.cell_cfg), bwp_grid(bwp_grid_)
|
||||
{}
|
||||
|
||||
alloc_result slot_bwp_sched::alloc_pdsch(slot_ue& ue, const rbgmask_t& dl_mask)
|
||||
alloc_result bwp_slot_allocator::alloc_rar(uint32_t aggr_idx,
|
||||
const srsenb::sched_nr_impl::pending_rar_t& rar,
|
||||
srsenb::sched_nr_impl::rbg_interval interv,
|
||||
uint32_t nof_grants)
|
||||
{
|
||||
static const uint32_t msg3_nof_prbs = 3;
|
||||
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_tti];
|
||||
bwp_slot_grid& bwp_msg3_slot = bwp_grid[pdcch_tti + 4];
|
||||
|
||||
if (bwp_pdcch_slot.dl_pdcchs.full()) {
|
||||
logger.warning("SCHED: Maximum number of DL allocations reached");
|
||||
return alloc_result::no_grant_space;
|
||||
}
|
||||
|
||||
// Check DL RB collision
|
||||
rbgmask_t& pdsch_mask = bwp_pdcch_slot.dl_rbgs;
|
||||
rbgmask_t dl_mask(pdsch_mask.size());
|
||||
dl_mask.fill(interv.start(), interv.stop());
|
||||
if ((pdsch_mask & dl_mask).any()) {
|
||||
logger.debug("SCHED: Provided RBG mask collides with allocation previously made.");
|
||||
return alloc_result::sch_collision;
|
||||
}
|
||||
|
||||
// Check Msg3 RB collision
|
||||
uint32_t total_ul_nof_prbs = msg3_nof_prbs * nof_grants;
|
||||
uint32_t total_ul_nof_rbgs = srsran::ceil_div(total_ul_nof_prbs, get_P(bwp_grid.bwp_cfg().rb_width, false));
|
||||
rbg_interval msg3_rbgs = find_empty_rbg_interval(bwp_msg3_slot.ul_rbgs, total_ul_nof_rbgs);
|
||||
if (msg3_rbgs.length() < total_ul_nof_rbgs) {
|
||||
logger.debug("SCHED: No space in PUSCH for Msg3.");
|
||||
return alloc_result::sch_collision;
|
||||
}
|
||||
|
||||
// Find PDCCH position
|
||||
const uint32_t coreset_id = 0;
|
||||
if (not bwp_pdcch_slot.coresets[coreset_id].alloc_dci(pdcch_grant_type_t::rar, aggr_idx, nullptr)) {
|
||||
// Could not find space in PDCCH
|
||||
logger.debug("SCHED: No space in PDCCH for DL tx.");
|
||||
return alloc_result::no_cch_space;
|
||||
}
|
||||
|
||||
// Generate DCI for RAR
|
||||
pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back();
|
||||
if (not fill_dci_rar(interv, bwp_grid.cell_params(), pdcch.dci)) {
|
||||
// Cancel on-going PDCCH allocation
|
||||
bwp_pdcch_slot.coresets[coreset_id].rem_last_dci();
|
||||
return alloc_result::invalid_coderate;
|
||||
}
|
||||
|
||||
// RAR allocation successful.
|
||||
bwp_pdcch_slot.dl_rbgs.fill(interv.start(), interv.stop());
|
||||
|
||||
return alloc_result::success;
|
||||
}
|
||||
|
||||
alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const rbgmask_t& dl_mask)
|
||||
{
|
||||
if (ue.h_dl == nullptr) {
|
||||
logger.warning("SCHED: Trying to allocate PDSCH for rnti=0x%x with no available HARQs", ue.rnti);
|
||||
|
@ -121,7 +169,7 @@ alloc_result slot_bwp_sched::alloc_pdsch(slot_ue& ue, const rbgmask_t& dl_mask)
|
|||
return alloc_result::success;
|
||||
}
|
||||
|
||||
alloc_result slot_bwp_sched::alloc_pusch(slot_ue& ue, const rbgmask_t& ul_mask)
|
||||
alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbgmask_t& ul_mask)
|
||||
{
|
||||
if (ue.h_ul == nullptr) {
|
||||
logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue.rnti);
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
||||
slot_cc_worker::slot_cc_worker(cell_sched& cc_sched) :
|
||||
cell(cc_sched), cfg(*cc_sched.cfg), bwp_alloc(cc_sched.bwps[0].grid)
|
||||
{}
|
||||
|
||||
/// Called at the beginning of TTI in a locked context, to reserve available UE resources
|
||||
void slot_cc_worker::start(tti_point tti_rx_, ue_map_t& ue_db)
|
||||
{
|
||||
|
@ -34,15 +38,18 @@ void slot_cc_worker::start(tti_point tti_rx_, ue_map_t& ue_db)
|
|||
}
|
||||
// UE acquired successfully for scheduling in this {tti, cc}
|
||||
}
|
||||
|
||||
tti_rx = tti_rx_;
|
||||
}
|
||||
|
||||
void slot_cc_worker::run()
|
||||
{
|
||||
srsran_assert(running(), "scheduler worker::run() called for non-active worker");
|
||||
|
||||
// Prioritize PDCCH scheduling for DL and UL data in a RoundRobin fashion
|
||||
bwp_alloc.new_slot(tti_rx + TX_ENB_DELAY);
|
||||
|
||||
// Allocate pending RARs
|
||||
cell.bwps[0].ra.run_slot(bwp_alloc);
|
||||
|
||||
// Prioritize PDCCH scheduling for DL and UL data in a Round-Robin fashion
|
||||
if ((tti_rx.to_uint() & 0x1u) == 0) {
|
||||
alloc_dl_ues();
|
||||
alloc_ul_ues();
|
||||
|
@ -74,8 +81,9 @@ void slot_cc_worker::alloc_dl_ues()
|
|||
|
||||
rbgmask_t dlmask(cfg.cell_cfg.nof_rbg);
|
||||
dlmask.fill(0, dlmask.size(), true);
|
||||
res_grid.alloc_pdsch(ue, dlmask);
|
||||
bwp_alloc.alloc_pdsch(ue, dlmask);
|
||||
}
|
||||
|
||||
void slot_cc_worker::alloc_ul_ues()
|
||||
{
|
||||
if (slot_ues.empty()) {
|
||||
|
@ -88,7 +96,7 @@ void slot_cc_worker::alloc_ul_ues()
|
|||
|
||||
rbgmask_t ulmask(cfg.cell_cfg.nof_rbg);
|
||||
ulmask.fill(0, ulmask.size(), true);
|
||||
res_grid.alloc_pusch(ue, ulmask);
|
||||
bwp_alloc.alloc_pusch(ue, ulmask);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -100,12 +108,12 @@ sched_worker_manager::sched_worker_manager(ue_map_t& ue_db_, const sched_params&
|
|||
}
|
||||
|
||||
// Note: For now, we only allow parallelism at the sector level
|
||||
slot_ctxts.resize(cfg.sched_cfg.nof_concurrent_subframes);
|
||||
slot_worker_ctxts.resize(cfg.sched_cfg.nof_concurrent_subframes);
|
||||
for (size_t i = 0; i < cfg.sched_cfg.nof_concurrent_subframes; ++i) {
|
||||
slot_ctxts[i].reset(new slot_worker_ctxt());
|
||||
slot_ctxts[i]->workers.reserve(cfg.cells.size());
|
||||
slot_worker_ctxts[i].reset(new slot_worker_ctxt());
|
||||
slot_worker_ctxts[i]->workers.reserve(cfg.cells.size());
|
||||
for (uint32_t cc = 0; cc < cfg.cells.size(); ++cc) {
|
||||
slot_ctxts[i]->workers.emplace_back(cfg.cells[cc], cell_grid_list[cc]);
|
||||
slot_worker_ctxts[i]->workers.emplace_back(cell_grid_list[cc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +122,7 @@ sched_worker_manager::~sched_worker_manager() = default;
|
|||
|
||||
sched_worker_manager::slot_worker_ctxt& sched_worker_manager::get_sf(tti_point tti_rx)
|
||||
{
|
||||
return *slot_ctxts[tti_rx.to_uint() % slot_ctxts.size()];
|
||||
return *slot_worker_ctxts[tti_rx.to_uint() % slot_worker_ctxts.size()];
|
||||
}
|
||||
|
||||
void sched_worker_manager::start_slot(tti_point tti_rx, srsran::move_callback<void()> process_feedback)
|
||||
|
@ -189,7 +197,7 @@ void sched_worker_manager::release_slot(tti_point tti_rx_)
|
|||
|
||||
bool sched_worker_manager::get_sched_result(tti_point pdcch_tti, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res)
|
||||
{
|
||||
auto& pdcch_bwp_slot = cell_grid_list[cc].bwps[0][pdcch_tti];
|
||||
auto& pdcch_bwp_slot = cell_grid_list[cc].bwps[0].grid[pdcch_tti];
|
||||
|
||||
dl_res.pdcch_dl = pdcch_bwp_slot.dl_pdcchs;
|
||||
dl_res.pdcch_ul = pdcch_bwp_slot.ul_pdcchs;
|
||||
|
|
Loading…
Reference in New Issue