sched,nr: add slot_point to sched nr

This commit is contained in:
Francisco Paisana 2021-07-23 17:13:17 +01:00
parent a0a1af9d0f
commit 12e33483e1
21 changed files with 275 additions and 263 deletions

View File

@ -31,6 +31,11 @@ class slot_point
public: public:
slot_point() : numerology_(NOF_NUMEROLOGIES), count_(0) {} slot_point() : numerology_(NOF_NUMEROLOGIES), count_(0) {}
slot_point(uint8_t numerology, uint32_t count) : numerology_(numerology), count_(count)
{
srsran_assert(numerology < NOF_NUMEROLOGIES, "Invalid numerology idx=%d passed", (int)numerology);
srsran_assert(count < nof_slots_per_hf(), "Invalid slot count=%d passed", (int)count);
}
slot_point(uint8_t numerology, uint16_t sfn_val, uint8_t slot) : slot_point(uint8_t numerology, uint16_t sfn_val, uint8_t slot) :
numerology_(numerology), count_(slot + sfn_val * nof_slots_per_frame()) numerology_(numerology), count_(slot + sfn_val * nof_slots_per_frame())
{ {
@ -47,7 +52,7 @@ public:
uint8_t nof_slots_per_frame() const { return nof_slots_per_subframe() * NOF_SUBFRAMES_PER_FRAME; } uint8_t nof_slots_per_frame() const { return nof_slots_per_subframe() * NOF_SUBFRAMES_PER_FRAME; }
uint16_t sfn() const { return count_ / nof_slots_per_frame(); } uint16_t sfn() const { return count_ / nof_slots_per_frame(); }
uint16_t sf_idx() const { return slot_idx() / nof_slots_per_subframe(); } uint16_t subframe_idx() const { return slot_idx() / nof_slots_per_subframe(); }
uint8_t slot_idx() const { return count_ % nof_slots_per_frame(); } uint8_t slot_idx() const { return count_ % nof_slots_per_frame(); }
uint8_t numerology_idx() const { return numerology_; } uint8_t numerology_idx() const { return numerology_; }
uint32_t to_uint() const { return count_; } uint32_t to_uint() const { return count_; }
@ -56,11 +61,7 @@ public:
void clear() { numerology_ = NOF_NUMEROLOGIES; } void clear() { numerology_ = NOF_NUMEROLOGIES; }
// operators // operators
bool operator==(const slot_point& other) const bool operator==(const slot_point& other) const { return other.count_ == count_ and other.numerology_ == numerology_; }
{
srsran_assert(numerology_idx() == other.numerology_idx(), "Comparing slots of different numerologies");
return other.count_ == count_;
}
bool operator!=(const slot_point& other) const { return not(*this == other); } bool operator!=(const slot_point& other) const { return not(*this == other); }
bool operator<(const slot_point& other) const bool operator<(const slot_point& other) const
{ {
@ -164,7 +165,8 @@ struct formatter<srsran::slot_point> {
namespace srsenb { namespace srsenb {
using slot_point = srsran::slot_point; using slot_point = srsran::slot_point;
using slot_interval = srsran::slot_interval;
} } // namespace srsenb
#endif // SRSRAN_SLOT_POINT_H #endif // SRSRAN_SLOT_POINT_H

View File

@ -73,7 +73,7 @@ void test_nr_slot_type()
srsran::slot_point slot1; srsran::slot_point slot1;
TESTASSERT(not slot1.valid()); TESTASSERT(not slot1.valid());
srsran::slot_point slot2{0, 1, 5}; srsran::slot_point slot2{0, 1, 5};
TESTASSERT(slot2.valid() and slot2.numerology_idx() == 0 and slot2.slot_idx() == 5 and slot2.sf_idx() == 5 and TESTASSERT(slot2.valid() and slot2.numerology_idx() == 0 and slot2.slot_idx() == 5 and slot2.slot_idx() == 5 and
slot2.sfn() == 1); slot2.sfn() == 1);
srsran::slot_point slot3{slot2}; srsran::slot_point slot3{slot2};
TESTASSERT(slot3 == slot2); TESTASSERT(slot3 == slot2);

View File

@ -17,7 +17,7 @@
#include "sched_nr_interface.h" #include "sched_nr_interface.h"
#include "sched_nr_ue.h" #include "sched_nr_ue.h"
#include "srsran/adt/pool/cached_alloc.h" #include "srsran/adt/pool/cached_alloc.h"
#include "srsran/common/tti_point.h" #include "srsran/common/slot_point.h"
#include <array> #include <array>
extern "C" { extern "C" {
#include "srsran/config.h" #include "srsran/config.h"
@ -43,13 +43,13 @@ public:
void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override; void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override;
void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override; void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override;
void ul_sr_info(tti_point tti_rx, uint16_t rnti) override; void ul_sr_info(slot_point slot_rx, uint16_t rnti) override;
int get_dl_sched(tti_point pdsch_tti, uint32_t cc, dl_sched_t& result) override; int get_dl_sched(slot_point pdsch_tti, uint32_t cc, dl_sched_t& result) override;
int get_ul_sched(tti_point pusch_tti, uint32_t cc, ul_sched_t& result) override; int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_sched_t& result) override;
private: private:
int generate_slot_result(tti_point pdcch_tti, uint32_t cc); int generate_slot_result(slot_point pdcch_tti, uint32_t cc);
void ue_cfg_impl(uint16_t rnti, const ue_cfg_t& cfg); void ue_cfg_impl(uint16_t rnti, const ue_cfg_t& cfg);
// args // args

View File

@ -24,7 +24,7 @@ using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t;
struct pending_rar_t { struct pending_rar_t {
uint16_t ra_rnti = 0; uint16_t ra_rnti = 0;
tti_point prach_tti; slot_point prach_slot;
srsran::bounded_vector<dl_sched_rar_info_t, sched_interface::MAX_RAR_LIST> msg3_grant; srsran::bounded_vector<dl_sched_rar_info_t, sched_interface::MAX_RAR_LIST> msg3_grant;
}; };

View File

@ -15,7 +15,7 @@
#include "sched_nr_cfg.h" #include "sched_nr_cfg.h"
#include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h" #include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h"
#include "srsran/common/tti_point.h" #include "srsran/common/slot_point.h"
#include <array> #include <array>
namespace srsenb { namespace srsenb {
@ -31,23 +31,30 @@ public:
return std::all_of(tb.begin(), tb.end(), [](const tb_t& t) { return not t.active; }); return std::all_of(tb.begin(), tb.end(), [](const tb_t& t) { return not t.active; });
} }
bool empty(uint32_t tb_idx) const { return not tb[tb_idx].active; } bool empty(uint32_t tb_idx) const { return not tb[tb_idx].active; }
bool has_pending_retx(tti_point tti_rx) const { return not empty() and not tb[0].ack_state and tti_ack <= tti_rx; } bool has_pending_retx(slot_point slot_rx) const
{
return not empty() and not tb[0].ack_state and slot_ack <= slot_rx;
}
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 ndi() const { return tb[0].ndi; }
uint32_t mcs() const { return tb[0].mcs; } uint32_t mcs() const { return tb[0].mcs; }
const prb_grant& prbs() const { return prbs_; } const prb_grant& prbs() const { return prbs_; }
tti_point harq_tti_ack() const { return tti_ack; } slot_point harq_slot_ack() const { return slot_ack; }
bool ack_info(uint32_t tb_idx, bool ack); bool ack_info(uint32_t tb_idx, bool ack);
void new_tti(tti_point tti_rx); void new_slot(slot_point slot_rx);
void reset(); void reset();
bool bool new_tx(slot_point slot_tx,
new_tx(tti_point tti_tx, tti_point tti_ack, const prb_grant& grant, uint32_t mcs, uint32_t tbs, uint32_t max_retx); slot_point slot_ack,
bool new_retx(tti_point tti_tx, tti_point tti_ack, const prb_grant& grant); const prb_grant& grant,
bool new_retx(tti_point tti_tx, tti_point tti_ack); uint32_t mcs,
uint32_t tbs,
uint32_t max_retx);
bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant);
bool new_retx(slot_point slot_tx, slot_point slot_ack);
// NOTE: Has to be used before first tx is dispatched // NOTE: Has to be used before first tx is dispatched
bool set_tbs(uint32_t tbs); bool set_tbs(uint32_t tbs);
@ -65,8 +72,8 @@ private:
}; };
uint32_t max_retx = 1; uint32_t max_retx = 1;
tti_point tti_tx; slot_point slot_tx;
tti_point tti_ack; slot_point slot_ack;
prb_grant prbs_; prb_grant prbs_;
std::array<tb_t, SCHED_NR_MAX_TB> tb; std::array<tb_t, SCHED_NR_MAX_TB> tb;
}; };
@ -113,18 +120,18 @@ class harq_entity
{ {
public: public:
explicit harq_entity(uint32_t nprb, uint32_t nof_harq_procs = SCHED_NR_MAX_HARQ); explicit harq_entity(uint32_t nprb, uint32_t nof_harq_procs = SCHED_NR_MAX_HARQ);
void new_tti(tti_point tti_rx_); void new_slot(slot_point slot_rx_);
void dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) { dl_harqs[pid].ack_info(tb_idx, ack); } void dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) { dl_harqs[pid].ack_info(tb_idx, ack); }
void ul_crc_info(uint32_t pid, bool ack) { ul_harqs[pid].ack_info(0, ack); } void ul_crc_info(uint32_t pid, bool ack) { ul_harqs[pid].ack_info(0, ack); }
dl_harq_proc* find_pending_dl_retx() dl_harq_proc* find_pending_dl_retx()
{ {
return find_dl([this](const dl_harq_proc& h) { return h.has_pending_retx(tti_rx); }); return find_dl([this](const dl_harq_proc& h) { return h.has_pending_retx(slot_rx); });
} }
ul_harq_proc* find_pending_ul_retx() ul_harq_proc* find_pending_ul_retx()
{ {
return find_ul([this](const ul_harq_proc& h) { return h.has_pending_retx(tti_rx); }); return find_ul([this](const ul_harq_proc& h) { return h.has_pending_retx(slot_rx); });
} }
dl_harq_proc* find_empty_dl_harq() dl_harq_proc* find_empty_dl_harq()
{ {
@ -149,7 +156,7 @@ private:
return (it == ul_harqs.end()) ? nullptr : &(*it); return (it == ul_harqs.end()) ? nullptr : &(*it);
} }
tti_point tti_rx; slot_point slot_rx;
std::vector<dl_harq_proc> dl_harqs; std::vector<dl_harq_proc> dl_harqs;
std::vector<ul_harq_proc> ul_harqs; std::vector<ul_harq_proc> ul_harqs;
}; };

View File

@ -18,7 +18,7 @@
#include "srsran/adt/optional.h" #include "srsran/adt/optional.h"
#include "srsran/adt/span.h" #include "srsran/adt/span.h"
#include "srsran/common/phy_cfg_nr.h" #include "srsran/common/phy_cfg_nr.h"
#include "srsran/common/tti_point.h" #include "srsran/common/slot_point.h"
#include "srsran/interfaces/gnb_interfaces.h" #include "srsran/interfaces/gnb_interfaces.h"
#include "srsran/phy/phch/dci_nr.h" #include "srsran/phy/phch/dci_nr.h"
@ -85,7 +85,7 @@ public:
uint32_t ta_cmd; uint32_t ta_cmd;
uint16_t temp_crnti; uint16_t temp_crnti;
uint32_t msg3_size; uint32_t msg3_size;
uint32_t prach_tti; uint32_t prach_slot;
}; };
///// Sched Result ///// ///// Sched Result /////
@ -96,12 +96,12 @@ public:
virtual ~sched_nr_interface() = default; virtual ~sched_nr_interface() = default;
virtual int cell_cfg(srsran::const_span<sched_nr_interface::cell_cfg_t> ue_cfg) = 0; virtual int cell_cfg(srsran::const_span<sched_nr_interface::cell_cfg_t> ue_cfg) = 0;
virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0;
virtual int get_dl_sched(tti_point tti_rx, uint32_t cc, dl_sched_t& result) = 0; virtual int get_dl_sched(slot_point slot_rx, uint32_t cc, dl_sched_t& result) = 0;
virtual int get_ul_sched(tti_point tti_rx, uint32_t cc, ul_sched_t& result) = 0; virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0;
virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0;
virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0;
virtual void ul_sr_info(tti_point, uint16_t rnti) = 0; virtual void ul_sr_info(slot_point, uint16_t rnti) = 0;
}; };
} // namespace srsenb } // namespace srsenb

View File

@ -61,8 +61,8 @@ struct bwp_slot_grid {
struct bwp_res_grid { struct bwp_res_grid {
bwp_res_grid(const bwp_params& bwp_cfg_); bwp_res_grid(const bwp_params& bwp_cfg_);
bwp_slot_grid& operator[](tti_point tti) { return slots[tti.to_uint() % slots.capacity()]; }; bwp_slot_grid& operator[](slot_point tti) { return slots[tti.to_uint() % slots.capacity()]; };
const bwp_slot_grid& operator[](tti_point tti) const { return slots[tti.to_uint() % slots.capacity()]; }; const bwp_slot_grid& operator[](slot_point tti) const { return slots[tti.to_uint() % slots.capacity()]; };
uint32_t id() const { return cfg->bwp_id; } uint32_t id() const { return cfg->bwp_id; }
uint32_t nof_prbs() const { return cfg->cfg.rb_width; } uint32_t nof_prbs() const { return cfg->cfg.rb_width; }
@ -81,7 +81,7 @@ class bwp_slot_allocator
public: public:
explicit bwp_slot_allocator(bwp_res_grid& bwp_grid_); explicit bwp_slot_allocator(bwp_res_grid& bwp_grid_);
void new_slot(tti_point pdcch_tti_) { pdcch_tti = pdcch_tti_; } void new_slot(slot_point pdcch_slot_) { pdcch_slot = pdcch_slot_; }
alloc_result alloc_rar_and_msg3(uint32_t aggr_idx, alloc_result alloc_rar_and_msg3(uint32_t aggr_idx,
const pending_rar_t& rar, const pending_rar_t& rar,
@ -91,7 +91,7 @@ public:
alloc_result alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant); alloc_result alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant);
alloc_result alloc_pusch(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; } slot_point get_pdcch_tti() const { return pdcch_slot; }
const bwp_res_grid& res_grid() const { return bwp_grid; } const bwp_res_grid& res_grid() const { return bwp_grid; }
const bwp_params& cfg; const bwp_params& cfg;
@ -102,7 +102,7 @@ private:
srslog::basic_logger& logger; srslog::basic_logger& logger;
bwp_res_grid& bwp_grid; bwp_res_grid& bwp_grid;
tti_point pdcch_tti; slot_point pdcch_slot;
}; };
} // namespace sched_nr_impl } // namespace sched_nr_impl

View File

@ -30,14 +30,14 @@ class slot_ue
{ {
public: public:
slot_ue() = default; slot_ue() = default;
explicit slot_ue(uint16_t rnti_, tti_point tti_rx_, uint32_t cc); explicit slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc);
slot_ue(slot_ue&&) noexcept = default; slot_ue(slot_ue&&) noexcept = default;
slot_ue& operator=(slot_ue&&) noexcept = default; slot_ue& operator=(slot_ue&&) noexcept = default;
bool empty() const { return rnti == SCHED_NR_INVALID_RNTI; } bool empty() const { return rnti == SCHED_NR_INVALID_RNTI; }
void release() { rnti = SCHED_NR_INVALID_RNTI; } void release() { rnti = SCHED_NR_INVALID_RNTI; }
uint16_t rnti = SCHED_NR_INVALID_RNTI; uint16_t rnti = SCHED_NR_INVALID_RNTI;
tti_point tti_rx; slot_point slot_rx;
uint32_t cc = SCHED_NR_MAX_CARRIERS; uint32_t cc = SCHED_NR_MAX_CARRIERS;
// UE parameters common to all sectors // UE parameters common to all sectors
@ -45,10 +45,10 @@ public:
// UE parameters that are sector specific // UE parameters that are sector specific
const bwp_ue_cfg* cfg = nullptr; const bwp_ue_cfg* cfg = nullptr;
tti_point pdcch_tti; slot_point pdcch_slot;
tti_point pdsch_tti; slot_point pdsch_slot;
tti_point pusch_tti; slot_point pusch_slot;
tti_point uci_tti; slot_point uci_slot;
uint32_t dl_cqi; uint32_t dl_cqi;
uint32_t ul_cqi; uint32_t ul_cqi;
dl_harq_proc* h_dl = nullptr; dl_harq_proc* h_dl = nullptr;
@ -59,8 +59,8 @@ class ue_carrier
{ {
public: public:
ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const sched_cell_params& cell_params_); ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const sched_cell_params& cell_params_);
void new_tti(tti_point pdcch_tti, const ue_cfg_t& uecfg_); void new_slot(slot_point pdcch_slot, const ue_cfg_t& uecfg_);
slot_ue try_reserve(tti_point pdcch_tti); slot_ue try_reserve(slot_point pdcch_slot);
const uint16_t rnti; const uint16_t rnti;
const uint32_t cc; const uint32_t cc;
@ -81,12 +81,12 @@ class ue
public: 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& sched_cfg_);
slot_ue try_reserve(tti_point pdcch_tti, uint32_t cc); slot_ue try_reserve(slot_point pdcch_slot, uint32_t cc);
void set_cfg(const ue_cfg_t& cfg); void set_cfg(const ue_cfg_t& cfg);
const ue_cfg_t& cfg() const { return ue_cfg; } const ue_cfg_t& cfg() const { return ue_cfg; }
void ul_sr_info(tti_point tti_rx) { pending_sr = true; } void ul_sr_info(slot_point slot_rx) { pending_sr = true; }
bool has_ca() const { return ue_cfg.carriers.size() > 1; } bool has_ca() const { return ue_cfg.carriers.size() > 1; }
uint32_t pcell_cc() const { return ue_cfg.carriers[0].cc; } uint32_t pcell_cc() const { return ue_cfg.carriers[0].cc; }

View File

@ -37,10 +37,10 @@ public:
explicit slot_cc_worker(serv_cell_manager& sched); explicit slot_cc_worker(serv_cell_manager& sched);
void start(tti_point pdcch_tti, ue_map_t& ue_db_); void start(slot_point pdcch_slot, ue_map_t& ue_db_);
void run(); void run();
void finish(); void finish();
bool running() const { return tti_rx.is_valid(); } bool running() const { return slot_rx.valid(); }
/// Enqueue feedback directed at a given UE in a given cell /// Enqueue feedback directed at a given UE in a given cell
void enqueue_cc_feedback(uint16_t rnti, feedback_callback_t fdbk); void enqueue_cc_feedback(uint16_t rnti, feedback_callback_t fdbk);
@ -57,7 +57,7 @@ private:
serv_cell_manager& cell; serv_cell_manager& cell;
srslog::basic_logger& logger; srslog::basic_logger& logger;
tti_point tti_rx; slot_point slot_rx;
bwp_slot_allocator bwp_alloc; bwp_slot_allocator bwp_alloc;
// Process of UE cell-specific feedback // Process of UE cell-specific feedback
@ -76,7 +76,7 @@ class sched_worker_manager
struct slot_worker_ctxt { struct slot_worker_ctxt {
std::mutex slot_mutex; // lock of all workers of the same slot. std::mutex slot_mutex; // lock of all workers of the same slot.
std::condition_variable cvar; std::condition_variable cvar;
tti_point tti_rx; slot_point slot_rx;
int nof_workers_waiting = 0; int nof_workers_waiting = 0;
std::atomic<int> worker_count{0}; // variable shared across slot_cc_workers std::atomic<int> worker_count{0}; // variable shared across slot_cc_workers
std::vector<slot_cc_worker> workers; std::vector<slot_cc_worker> workers;
@ -90,7 +90,7 @@ public:
sched_worker_manager(sched_worker_manager&&) = delete; sched_worker_manager(sched_worker_manager&&) = delete;
~sched_worker_manager(); ~sched_worker_manager();
void run_slot(tti_point tti_tx, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res); void run_slot(slot_point slot_tx, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res);
void enqueue_event(uint16_t rnti, srsran::move_callback<void()> ev); void enqueue_event(uint16_t rnti, srsran::move_callback<void()> ev);
void enqueue_cc_feedback(uint16_t rnti, uint32_t cc, slot_cc_worker::feedback_callback_t fdbk) void enqueue_cc_feedback(uint16_t rnti, uint32_t cc, slot_cc_worker::feedback_callback_t fdbk)
@ -99,7 +99,7 @@ public:
} }
private: private:
bool save_sched_result(tti_point pdcch_tti, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res); bool save_sched_result(slot_point pdcch_slot, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res);
const sched_params& cfg; const sched_params& cfg;
ue_map_t& ue_db; ue_map_t& ue_db;
@ -124,7 +124,7 @@ private:
std::mutex slot_mutex; std::mutex slot_mutex;
std::condition_variable cvar; std::condition_variable cvar;
tti_point current_tti; slot_point current_slot;
std::atomic<int> worker_count{0}; // variable shared across slot_cc_workers std::atomic<int> worker_count{0}; // variable shared across slot_cc_workers
std::vector<std::unique_ptr<cc_context> > cc_worker_list; std::vector<std::unique_ptr<cc_context> > cc_worker_list;
}; };

View File

@ -34,40 +34,40 @@ public:
} }
} }
dl_sched_t& add_dl_result(tti_point tti, uint32_t cc) dl_sched_t& add_dl_result(slot_point tti, uint32_t cc)
{ {
if (not has_dl_result(tti, cc)) { if (not has_dl_result(tti, cc)) {
results[tti.to_uint()][cc].tti_dl = tti; results[tti.to_uint()][cc].slot_dl = tti;
results[tti.to_uint()][cc].dl_res = {}; results[tti.to_uint()][cc].dl_res = {};
} }
return results[tti.to_uint()][cc].dl_res; return results[tti.to_uint()][cc].dl_res;
} }
ul_sched_t& add_ul_result(tti_point tti, uint32_t cc) ul_sched_t& add_ul_result(slot_point tti, uint32_t cc)
{ {
if (not has_ul_result(tti, cc)) { if (not has_ul_result(tti, cc)) {
results[tti.to_uint()][cc].tti_ul = tti; results[tti.to_uint()][cc].slot_ul = tti;
results[tti.to_uint()][cc].ul_res = {}; results[tti.to_uint()][cc].ul_res = {};
} }
return results[tti.to_uint()][cc].ul_res; return results[tti.to_uint()][cc].ul_res;
} }
bool has_dl_result(tti_point tti, uint32_t cc) const { return results[tti.to_uint()][cc].tti_dl == tti; } bool has_dl_result(slot_point tti, uint32_t cc) const { return results[tti.to_uint()][cc].slot_dl == tti; }
bool has_ul_result(tti_point tti, uint32_t cc) const { return results[tti.to_uint()][cc].tti_ul == tti; } bool has_ul_result(slot_point tti, uint32_t cc) const { return results[tti.to_uint()][cc].slot_ul == tti; }
dl_sched_t pop_dl_result(tti_point tti, uint32_t cc) dl_sched_t pop_dl_result(slot_point tti, uint32_t cc)
{ {
if (has_dl_result(tti, cc)) { if (has_dl_result(tti, cc)) {
results[tti.to_uint()][cc].tti_dl.reset(); results[tti.to_uint()][cc].slot_dl.clear();
return results[tti.to_uint()][cc].dl_res; return results[tti.to_uint()][cc].dl_res;
} }
return {}; return {};
} }
ul_sched_t pop_ul_result(tti_point tti, uint32_t cc) ul_sched_t pop_ul_result(slot_point tti, uint32_t cc)
{ {
if (has_ul_result(tti, cc)) { if (has_ul_result(tti, cc)) {
results[tti.to_uint()][cc].tti_ul.reset(); results[tti.to_uint()][cc].slot_ul.clear();
return results[tti.to_uint()][cc].ul_res; return results[tti.to_uint()][cc].ul_res;
} }
return {}; return {};
@ -75,8 +75,8 @@ public:
private: private:
struct slot_result_t { struct slot_result_t {
tti_point tti_dl; slot_point slot_dl;
tti_point tti_ul; slot_point slot_ul;
dl_sched_t dl_res; dl_sched_t dl_res;
ul_sched_t ul_res; ul_sched_t ul_res;
}; };
@ -126,7 +126,7 @@ void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg)
} }
/// Generate {tti,cc} scheduling decision /// Generate {tti,cc} scheduling decision
int sched_nr::generate_slot_result(tti_point pdcch_tti, uint32_t cc) int sched_nr::generate_slot_result(slot_point pdcch_tti, uint32_t cc)
{ {
// Copy results to intermediate buffer // Copy results to intermediate buffer
dl_sched_t& dl_res = pending_results->add_dl_result(pdcch_tti, cc); dl_sched_t& dl_res = pending_results->add_dl_result(pdcch_tti, cc);
@ -138,16 +138,16 @@ int sched_nr::generate_slot_result(tti_point pdcch_tti, uint32_t cc)
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
int sched_nr::get_dl_sched(tti_point tti_tx, uint32_t cc, dl_sched_t& result) int sched_nr::get_dl_sched(slot_point slot_tx, uint32_t cc, dl_sched_t& result)
{ {
if (not pending_results->has_dl_result(tti_tx, cc)) { if (not pending_results->has_dl_result(slot_tx, cc)) {
generate_slot_result(tti_tx, cc); generate_slot_result(slot_tx, cc);
} }
result = pending_results->pop_dl_result(tti_tx, cc); result = pending_results->pop_dl_result(slot_tx, cc);
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
int sched_nr::get_ul_sched(tti_point pusch_tti, uint32_t cc, ul_sched_t& result) int sched_nr::get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_sched_t& result)
{ {
if (not pending_results->has_ul_result(pusch_tti, cc)) { if (not pending_results->has_ul_result(pusch_tti, cc)) {
// sched result hasn't been generated // sched result hasn't been generated
@ -169,9 +169,9 @@ void sched_nr::ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc)
sched_workers->enqueue_cc_feedback(rnti, cc, [pid, crc](ue_carrier& ue_cc) { ue_cc.harq_ent.ul_crc_info(pid, crc); }); sched_workers->enqueue_cc_feedback(rnti, cc, [pid, crc](ue_carrier& ue_cc) { ue_cc.harq_ent.ul_crc_info(pid, crc); });
} }
void sched_nr::ul_sr_info(tti_point tti_rx, uint16_t rnti) void sched_nr::ul_sr_info(slot_point slot_rx, uint16_t rnti)
{ {
sched_workers->enqueue_event(rnti, [this, rnti, tti_rx]() { ue_db[rnti]->ul_sr_info(tti_rx); }); sched_workers->enqueue_event(rnti, [this, rnti, slot_rx]() { ue_db[rnti]->ul_sr_info(slot_rx); });
} }
#define VERIFY_INPUT(cond, msg, ...) \ #define VERIFY_INPUT(cond, msg, ...) \

View File

@ -55,9 +55,9 @@ alloc_result ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid,
void ra_sched::run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues) void ra_sched::run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues)
{ {
static const uint32_t PRACH_RAR_OFFSET = 3; static const uint32_t PRACH_RAR_OFFSET = 3;
tti_point pdcch_tti = slot_grid.get_pdcch_tti(); slot_point pdcch_slot = slot_grid.get_pdcch_tti();
tti_point msg3_tti = pdcch_tti + bwp_cfg->pusch_ra_list[0].msg3_delay; slot_point msg3_slot = pdcch_slot + bwp_cfg->pusch_ra_list[0].msg3_delay;
if (not slot_grid.res_grid()[msg3_tti].is_ul) { if (not slot_grid.res_grid()[msg3_slot].is_ul) {
return; return;
} }
@ -67,16 +67,16 @@ void ra_sched::run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues)
// In case of RAR outside RAR window: // In case of RAR outside RAR window:
// - if window has passed, discard RAR // - if window has passed, discard RAR
// - if window hasn't started, stop loop, as RARs are ordered by TTI // - if window hasn't started, stop loop, as RARs are ordered by TTI
tti_interval rar_window{rar.prach_tti + PRACH_RAR_OFFSET, slot_interval rar_window{rar.prach_slot + PRACH_RAR_OFFSET,
rar.prach_tti + PRACH_RAR_OFFSET + bwp_cfg->cfg.rar_window_size}; rar.prach_slot + PRACH_RAR_OFFSET + bwp_cfg->cfg.rar_window_size};
if (not rar_window.contains(pdcch_tti)) { if (not rar_window.contains(pdcch_slot)) {
if (pdcch_tti >= rar_window.stop()) { if (pdcch_slot >= rar_window.stop()) {
fmt::memory_buffer str_buffer; fmt::memory_buffer str_buffer;
fmt::format_to(str_buffer, fmt::format_to(str_buffer,
"SCHED: Could not transmit RAR within the window (RA={}, Window={}, RAR={}", "SCHED: Could not transmit RAR within the window (RA={}, Window={}, RAR={}",
rar.prach_tti, rar.prach_slot,
rar_window, rar_window,
pdcch_tti); pdcch_slot);
srsran::console("%s\n", srsran::to_c_str(str_buffer)); srsran::console("%s\n", srsran::to_c_str(str_buffer));
logger.warning("%s", srsran::to_c_str(str_buffer)); logger.warning("%s", srsran::to_c_str(str_buffer));
it = pending_rars.erase(it); it = pending_rars.erase(it);
@ -116,7 +116,7 @@ void ra_sched::run_slot(bwp_slot_allocator& slot_grid, slot_ue_map_t& slot_ues)
int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info) 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", 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.prach_slot,
rar_info.preamble_idx, rar_info.preamble_idx,
rar_info.temp_crnti, rar_info.temp_crnti,
rar_info.ta_cmd, rar_info.ta_cmd,
@ -125,11 +125,11 @@ int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info)
// RA-RNTI = 1 + t_id + f_id // RA-RNTI = 1 + t_id + f_id
// t_id = index of first subframe specified by PRACH (0<=t_id<10) // 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) // 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); uint16_t ra_rnti = 1 + (uint16_t)(rar_info.prach_slot % 10u);
// find pending rar with same RA-RNTI // find pending rar with same RA-RNTI
for (pending_rar_t& r : pending_rars) { 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.prach_slot.to_uint() == rar_info.prach_slot and ra_rnti == r.ra_rnti) {
if (r.msg3_grant.size() >= sched_interface::MAX_RAR_LIST) { 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"); logger.warning("PRACH ignored, as the the maximum number of RAR grants per tti has been reached");
return SRSRAN_ERROR; return SRSRAN_ERROR;
@ -142,7 +142,7 @@ int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info)
// create new RAR // create new RAR
pending_rar_t p; pending_rar_t p;
p.ra_rnti = ra_rnti; p.ra_rnti = ra_rnti;
p.prach_tti = tti_point{rar_info.prach_tti}; p.prach_slot = slot_point{0, rar_info.prach_slot};
p.msg3_grant.push_back(rar_info); p.msg3_grant.push_back(rar_info);
pending_rars.push_back(p); pending_rars.push_back(p);

View File

@ -27,9 +27,9 @@ bool harq_proc::ack_info(uint32_t tb_idx, bool ack)
return true; return true;
} }
void harq_proc::new_tti(tti_point tti_rx) void harq_proc::new_slot(slot_point slot_rx)
{ {
if (has_pending_retx(tti_rx) and nof_retx() + 1 >= max_nof_retx()) { if (has_pending_retx(slot_rx) and nof_retx() + 1 >= max_nof_retx()) {
tb[0].active = false; tb[0].active = false;
} }
} }
@ -43,8 +43,8 @@ void harq_proc::reset()
tb[0].tbs = std::numeric_limits<uint32_t>::max(); tb[0].tbs = std::numeric_limits<uint32_t>::max();
} }
bool harq_proc::new_tx(tti_point tti_tx_, bool harq_proc::new_tx(slot_point slot_tx_,
tti_point tti_ack_, slot_point slot_ack_,
const prb_grant& grant, const prb_grant& grant,
uint32_t mcs, uint32_t mcs,
uint32_t tbs, uint32_t tbs,
@ -55,8 +55,8 @@ bool harq_proc::new_tx(tti_point tti_tx_,
} }
reset(); reset();
max_retx = max_retx_; max_retx = max_retx_;
tti_tx = tti_tx_; slot_tx = slot_tx_;
tti_ack = tti_ack_; slot_ack = slot_ack_;
prbs_ = grant; prbs_ = grant;
tb[0].ndi = !tb[0].ndi; tb[0].ndi = !tb[0].ndi;
tb[0].mcs = mcs; tb[0].mcs = mcs;
@ -74,27 +74,27 @@ bool harq_proc::set_tbs(uint32_t tbs)
return true; return true;
} }
bool harq_proc::new_retx(tti_point tti_tx_, tti_point tti_ack_, const prb_grant& grant) bool harq_proc::new_retx(slot_point slot_tx_, slot_point slot_ack_, const prb_grant& grant)
{ {
if (grant.is_alloc_type0() != prbs_.is_alloc_type0() or if (grant.is_alloc_type0() != prbs_.is_alloc_type0() or
(grant.is_alloc_type0() and grant.rbgs().count() != prbs_.rbgs().count()) or (grant.is_alloc_type0() and grant.rbgs().count() != prbs_.rbgs().count()) or
(grant.is_alloc_type1() and grant.prbs().length() == prbs_.prbs().length())) { (grant.is_alloc_type1() and grant.prbs().length() == prbs_.prbs().length())) {
return false; return false;
} }
if (new_retx(tti_tx_, tti_ack_)) { if (new_retx(slot_tx_, slot_ack_)) {
prbs_ = grant; prbs_ = grant;
return true; return true;
} }
return false; return false;
} }
bool harq_proc::new_retx(tti_point tti_tx_, tti_point tti_ack_) bool harq_proc::new_retx(slot_point slot_tx_, slot_point slot_ack_)
{ {
if (empty()) { if (empty()) {
return false; return false;
} }
tti_tx = tti_tx_; slot_tx = slot_tx_;
tti_ack = tti_ack_; slot_ack = slot_ack_;
tb[0].ack_state = false; tb[0].ack_state = false;
tb[0].n_rtx++; tb[0].n_rtx++;
return true; return true;
@ -111,14 +111,14 @@ harq_entity::harq_entity(uint32_t nprb, uint32_t nof_harq_procs)
} }
} }
void harq_entity::new_tti(tti_point tti_rx_) void harq_entity::new_slot(slot_point slot_rx_)
{ {
tti_rx = tti_rx_; slot_rx = slot_rx_;
for (harq_proc& dl_h : dl_harqs) { for (harq_proc& dl_h : dl_harqs) {
dl_h.new_tti(tti_rx); dl_h.new_slot(slot_rx);
} }
for (harq_proc& ul_h : ul_harqs) { for (harq_proc& ul_h : ul_harqs) {
ul_h.new_tti(tti_rx); ul_h.new_slot(slot_rx);
} }
} }

View File

@ -67,9 +67,9 @@ void fill_dl_dci_ue_fields(const slot_ue& ue,
fill_dci_common(ue, bwp_cfg, dci); fill_dci_common(ue, bwp_cfg, dci);
if (dci.ctx.format == srsran_dci_format_nr_1_0) { if (dci.ctx.format == srsran_dci_format_nr_1_0) {
dci.harq_feedback = ue.cfg->phy().harq_ack.dl_data_to_ul_ack[ue.pdsch_tti.sf_idx()] - 1; dci.harq_feedback = ue.cfg->phy().harq_ack.dl_data_to_ul_ack[ue.pdsch_slot.slot_idx()] - 1;
} else { } else {
dci.harq_feedback = ue.pdsch_tti.sf_idx(); dci.harq_feedback = ue.pdsch_slot.slot_idx();
} }
} }

View File

@ -72,9 +72,9 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint32_t
{ {
static const uint32_t msg3_nof_prbs = 3, m = 0; static const uint32_t msg3_nof_prbs = 3, m = 0;
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_tti]; bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot];
tti_point msg3_tti = pdcch_tti + cfg.pusch_ra_list[m].msg3_delay; slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay;
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_tti]; 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, nullptr);
if (ret != alloc_result::success) { if (ret != alloc_result::success) {
return ret; return ret;
@ -129,11 +129,11 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint32_t
const int mcs = 0, max_harq_msg3_retx = 4; const int mcs = 0, max_harq_msg3_retx = 4;
int dai = 0; int dai = 0;
srsran_slot_cfg_t slot_cfg; srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = msg3_tti.sf_idx(); slot_cfg.idx = msg3_slot.slot_idx();
for (const auto& grant : rar.msg3_grant) { for (const auto& grant : rar.msg3_grant) {
slot_ue& ue = ues[grant.temp_crnti]; slot_ue& ue = ues[grant.temp_crnti];
bool success = ue.h_ul->new_tx( 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); msg3_slot, msg3_slot, prb_interval{last_msg3, last_msg3 + msg3_nof_prbs}, mcs, 100, max_harq_msg3_retx);
srsran_assert(success, "Failed to allocate Msg3"); srsran_assert(success, "Failed to allocate Msg3");
last_msg3 += msg3_nof_prbs; last_msg3 += msg3_nof_prbs;
srsran_dci_ul_nr_t msg3_dci; // Create dummy Msg3 DCI srsran_dci_ul_nr_t msg3_dci; // Create dummy Msg3 DCI
@ -168,9 +168,9 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
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;
} }
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti]; bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_tti]; bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot];
bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_tti]; bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot];
if (not bwp_pdsch_slot.is_dl) { if (not bwp_pdsch_slot.is_dl) {
logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", bwp_pdsch_slot.slot_idx); logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", bwp_pdsch_slot.slot_idx);
return alloc_result::no_sch_space; return alloc_result::no_sch_space;
@ -200,10 +200,10 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
srsran_assert(ue.cfg->ue_cfg()->fixed_dl_mcs >= 0, "Dynamic MCS not yet supported"); srsran_assert(ue.cfg->ue_cfg()->fixed_dl_mcs >= 0, "Dynamic MCS not yet supported");
int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs; int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs;
int tbs = 100; int tbs = 100;
bool ret = ue.h_dl->new_tx(ue.pdsch_tti, ue.uci_tti, dl_grant, mcs, tbs, 4); bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, tbs, 4);
srsran_assert(ret, "Failed to allocate DL HARQ"); srsran_assert(ret, "Failed to allocate DL HARQ");
} else { } else {
bool ret = ue.h_dl->new_retx(ue.pdsch_tti, ue.uci_tti, dl_grant); bool ret = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant);
srsran_assert(ret, "Failed to allocate DL HARQ retx"); srsran_assert(ret, "Failed to allocate DL HARQ retx");
} }
@ -230,7 +230,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
bwp_pdsch_slot.pdschs.emplace_back(); bwp_pdsch_slot.pdschs.emplace_back();
pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back(); pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back();
srsran_slot_cfg_t slot_cfg; srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = ue.pdsch_tti.sf_idx(); slot_cfg.idx = ue.pdsch_slot.slot_idx();
bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
srsran_assert(ret, "Error converting DCI to grant"); srsran_assert(ret, "Error converting DCI to grant");
pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get();
@ -245,8 +245,8 @@ 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) 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_pdcch_slot = bwp_grid[ue.pdcch_slot];
auto& bwp_pusch_slot = bwp_grid[ue.pusch_tti]; 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, &bwp_pdcch_slot);
if (ret != alloc_result::success) { if (ret != alloc_result::success) {
return ret; return ret;
@ -272,10 +272,10 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m
srsran_assert(ue.cfg->ue_cfg()->fixed_ul_mcs >= 0, "Dynamic MCS not yet supported"); 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 mcs = ue.cfg->ue_cfg()->fixed_ul_mcs;
int tbs = 100; 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); bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx);
srsran_assert(success, "Failed to allocate UL HARQ"); srsran_assert(success, "Failed to allocate UL HARQ");
} else { } else {
srsran_assert(ue.h_ul->new_retx(ue.pusch_tti, ue.pusch_tti, ul_mask), "Failed to allocate UL HARQ retx"); srsran_assert(ue.h_ul->new_retx(ue.pusch_slot, ue.pusch_slot, ul_mask), "Failed to allocate UL HARQ retx");
} }
// Allocation Successful // Allocation Successful
@ -288,7 +288,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m
bwp_pusch_slot.puschs.emplace_back(); bwp_pusch_slot.puschs.emplace_back();
pusch_t& pusch = bwp_pusch_slot.puschs.back(); pusch_t& pusch = bwp_pusch_slot.puschs.back();
srsran_slot_cfg_t slot_cfg; srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = ue.pusch_tti.sf_idx(); slot_cfg.idx = ue.pusch_slot.to_uint();
bool success = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch); bool success = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch);
srsran_assert(success, "Error converting DCI to PUSCH grant"); srsran_assert(success, "Error converting DCI to PUSCH grant");
pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get();

View File

@ -16,7 +16,7 @@
namespace srsenb { namespace srsenb {
namespace sched_nr_impl { namespace sched_nr_impl {
slot_ue::slot_ue(uint16_t rnti_, tti_point tti_rx_, uint32_t cc_) : rnti(rnti_), tti_rx(tti_rx_), cc(cc_) {} slot_ue::slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc_) : rnti(rnti_), slot_rx(slot_rx_), cc(cc_) {}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -28,41 +28,42 @@ ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const sched_cell_
harq_ent(cell_params_.nof_prb()) harq_ent(cell_params_.nof_prb())
{} {}
void ue_carrier::new_tti(tti_point pdcch_tti, const ue_cfg_t& uecfg_) void ue_carrier::new_slot(slot_point pdcch_slot, const ue_cfg_t& uecfg_)
{ {
if (bwp_cfg.ue_cfg() != &uecfg_) { if (bwp_cfg.ue_cfg() != &uecfg_) {
bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], uecfg_); bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], uecfg_);
} }
harq_ent.new_tti(pdcch_tti - TX_ENB_DELAY); harq_ent.new_slot(pdcch_slot - TX_ENB_DELAY);
} }
slot_ue ue_carrier::try_reserve(tti_point pdcch_tti) slot_ue ue_carrier::try_reserve(slot_point pdcch_slot)
{ {
tti_point tti_rx = pdcch_tti - TX_ENB_DELAY; slot_point slot_rx = pdcch_slot - TX_ENB_DELAY;
// copy cc-specific parameters and find available HARQs // copy cc-specific parameters and find available HARQs
slot_ue sfu(rnti, tti_rx, cc); slot_ue sfu(rnti, slot_rx, cc);
sfu.cfg = &bwp_cfg; sfu.cfg = &bwp_cfg;
sfu.pdcch_tti = pdcch_tti; sfu.pdcch_slot = pdcch_slot;
const uint32_t k0 = 0; const uint32_t k0 = 0;
sfu.pdsch_tti = sfu.pdcch_tti + k0; sfu.pdsch_slot = sfu.pdcch_slot + k0;
uint32_t k1 = uint32_t k1 =
sfu.cfg->phy().harq_ack.dl_data_to_ul_ack[sfu.pdsch_tti.sf_idx() % sfu.cfg->phy().harq_ack.nof_dl_data_to_ul_ack]; sfu.cfg->phy()
sfu.uci_tti = sfu.pdsch_tti + k1; .harq_ack.dl_data_to_ul_ack[sfu.pdsch_slot.slot_idx() % sfu.cfg->phy().harq_ack.nof_dl_data_to_ul_ack];
sfu.uci_slot = sfu.pdsch_slot + k1;
uint32_t k2 = bwp_cfg.active_bwp().pusch_ra_list[0].K; uint32_t k2 = bwp_cfg.active_bwp().pusch_ra_list[0].K;
sfu.pusch_tti = sfu.pdcch_tti + k2; sfu.pusch_slot = sfu.pdcch_slot + k2;
sfu.dl_cqi = dl_cqi; sfu.dl_cqi = dl_cqi;
sfu.ul_cqi = ul_cqi; sfu.ul_cqi = ul_cqi;
const srsran_tdd_config_nr_t& tdd_cfg = cell_params.cell_cfg.tdd; const srsran_tdd_config_nr_t& tdd_cfg = cell_params.cell_cfg.tdd;
if (srsran_tdd_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_tti.sf_idx())) { if (srsran_tdd_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_slot.slot_idx())) {
// If DL enabled // If DL enabled
sfu.h_dl = harq_ent.find_pending_dl_retx(); sfu.h_dl = harq_ent.find_pending_dl_retx();
if (sfu.h_dl == nullptr) { if (sfu.h_dl == nullptr) {
sfu.h_dl = harq_ent.find_empty_dl_harq(); sfu.h_dl = harq_ent.find_empty_dl_harq();
} }
} }
if (srsran_tdd_nr_is_ul(&tdd_cfg, 0, sfu.pusch_tti.sf_idx())) { if (srsran_tdd_nr_is_ul(&tdd_cfg, 0, sfu.pusch_slot.slot_idx())) {
// If UL enabled // If UL enabled
sfu.h_ul = harq_ent.find_pending_ul_retx(); sfu.h_ul = harq_ent.find_pending_ul_retx();
if (sfu.h_ul == nullptr) { if (sfu.h_ul == nullptr) {
@ -95,12 +96,12 @@ void ue::set_cfg(const ue_cfg_t& cfg)
ue_cfg = cfg; ue_cfg = cfg;
} }
slot_ue ue::try_reserve(tti_point pdcch_tti, uint32_t cc) slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc)
{ {
if (carriers[cc] == nullptr) { if (carriers[cc] == nullptr) {
return slot_ue(); return slot_ue();
} }
slot_ue sfu = carriers[cc]->try_reserve(pdcch_tti); slot_ue sfu = carriers[cc]->try_reserve(pdcch_slot);
if (sfu.empty()) { if (sfu.empty()) {
return slot_ue(); return slot_ue();
} }

View File

@ -46,10 +46,10 @@ void slot_cc_worker::run_feedback(ue_map_t& ue_db)
} }
/// Called at the beginning of TTI in a locked context, to reserve available UE resources /// Called at the beginning of TTI in a locked context, to reserve available UE resources
void slot_cc_worker::start(tti_point pdcch_tti, ue_map_t& ue_db) void slot_cc_worker::start(slot_point pdcch_slot, ue_map_t& ue_db)
{ {
srsran_assert(not running(), "scheduler worker::start() called for active worker"); srsran_assert(not running(), "scheduler worker::start() called for active worker");
tti_rx = pdcch_tti - TX_ENB_DELAY; slot_rx = pdcch_slot - TX_ENB_DELAY;
// Run pending cell feedback // Run pending cell feedback
run_feedback(ue_db); run_feedback(ue_db);
@ -62,15 +62,15 @@ void slot_cc_worker::start(tti_point pdcch_tti, ue_map_t& ue_db)
continue; continue;
} }
u.carriers[cfg.cc]->new_tti(pdcch_tti, u.cfg()); u.carriers[cfg.cc]->new_slot(pdcch_slot, u.cfg());
slot_ues.insert(rnti, u.try_reserve(pdcch_tti, cfg.cc)); slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc));
if (slot_ues[rnti].empty()) { if (slot_ues[rnti].empty()) {
// Failed to generate slot UE because UE has no conditions for DL/UL tx // Failed to generate slot UE because UE has no conditions for DL/UL tx
slot_ues.erase(rnti); slot_ues.erase(rnti);
continue; continue;
} }
// UE acquired successfully for scheduling in this {tti, cc} // UE acquired successfully for scheduling in this {slot, cc}
} }
} }
@ -78,7 +78,7 @@ void slot_cc_worker::run()
{ {
srsran_assert(running(), "scheduler worker::run() called for non-active worker"); srsran_assert(running(), "scheduler worker::run() called for non-active worker");
bwp_alloc.new_slot(tti_rx + TX_ENB_DELAY); bwp_alloc.new_slot(slot_rx + TX_ENB_DELAY);
// Allocate pending RARs // Allocate pending RARs
cell.bwps[0].ra.run_slot(bwp_alloc, slot_ues); cell.bwps[0].ra.run_slot(bwp_alloc, slot_ues);
@ -92,7 +92,7 @@ void slot_cc_worker::run()
// releases UE resources // releases UE resources
slot_ues.clear(); slot_ues.clear();
tti_rx = {}; slot_rx = {};
} }
void slot_cc_worker::finish() void slot_cc_worker::finish()
@ -132,7 +132,7 @@ void slot_cc_worker::alloc_ul_ues()
void slot_cc_worker::log_result() const void slot_cc_worker::log_result() const
{ {
const bwp_slot_grid& bwp_slot = cell.bwps[0].grid[tti_rx + TX_ENB_DELAY]; const bwp_slot_grid& bwp_slot = cell.bwps[0].grid[slot_rx + TX_ENB_DELAY];
for (const pdcch_dl_t& pdcch : bwp_slot.dl_pdcchs) { for (const pdcch_dl_t& pdcch : bwp_slot.dl_pdcchs) {
fmt::memory_buffer fmtbuf; fmt::memory_buffer fmtbuf;
if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) {
@ -146,8 +146,8 @@ void slot_cc_worker::log_result() const
ue.h_dl->nof_retx(), ue.h_dl->nof_retx(),
srsran_dci_format_nr_string(pdcch.dci.ctx.format), srsran_dci_format_nr_string(pdcch.dci.ctx.format),
pdcch.dci.dai, pdcch.dci.dai,
ue.pdsch_tti, ue.pdsch_slot,
ue.uci_tti); ue.uci_slot);
} else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) { } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) {
fmt::format_to(fmtbuf, "SCHED: DL RAR, cc={}", cell.cfg.cc); fmt::format_to(fmtbuf, "SCHED: DL RAR, cc={}", cell.cfg.cc);
} else { } else {
@ -168,7 +168,7 @@ void slot_cc_worker::log_result() const
pdcch.dci.pid, pdcch.dci.pid,
ue.h_dl->nof_retx(), ue.h_dl->nof_retx(),
srsran_dci_format_nr_string(pdcch.dci.ctx.format), srsran_dci_format_nr_string(pdcch.dci.ctx.format),
ue.pusch_tti); ue.pusch_slot);
} else { } else {
fmt::format_to(fmtbuf, "SCHED: unknown rnti format"); fmt::format_to(fmtbuf, "SCHED: unknown rnti format");
} }
@ -198,18 +198,18 @@ void sched_worker_manager::enqueue_event(uint16_t rnti, srsran::move_callback<vo
next_slot_events.push_back(ue_event_t{rnti, std::move(ev)}); next_slot_events.push_back(ue_event_t{rnti, std::move(ev)});
} }
void sched_worker_manager::run_slot(tti_point tti_tx, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res) void sched_worker_manager::run_slot(slot_point slot_tx, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res)
{ {
srsran::bounded_vector<std::condition_variable*, SRSRAN_MAX_CARRIERS> waiting_cvars; srsran::bounded_vector<std::condition_variable*, SRSRAN_MAX_CARRIERS> waiting_cvars;
{ {
std::unique_lock<std::mutex> lock(slot_mutex); std::unique_lock<std::mutex> lock(slot_mutex);
while (current_tti.is_valid() and current_tti != tti_tx) { while (current_slot.valid() and current_slot != slot_tx) {
// Wait for previous slot to finish // Wait for previous slot to finish
cc_worker_list[cc]->waiting = true; cc_worker_list[cc]->waiting = true;
cc_worker_list[cc]->cvar.wait(lock); cc_worker_list[cc]->cvar.wait(lock);
cc_worker_list[cc]->waiting = false; cc_worker_list[cc]->waiting = false;
} }
if (not current_tti.is_valid()) { if (not current_slot.valid()) {
/* First Worker to start slot */ /* First Worker to start slot */
// process non-cc specific feedback if pending (e.g. SRs, buffer updates, UE config) for UEs with CA // process non-cc specific feedback if pending (e.g. SRs, buffer updates, UE config) for UEs with CA
@ -226,7 +226,7 @@ void sched_worker_manager::run_slot(tti_point tti_tx, uint32_t cc, dl_sched_t& d
} }
// mark the start of slot. awake remaining workers if locking on the mutex // mark the start of slot. awake remaining workers if locking on the mutex
current_tti = tti_tx; current_slot = slot_tx;
worker_count.store(static_cast<int>(cc_worker_list.size()), std::memory_order_relaxed); worker_count.store(static_cast<int>(cc_worker_list.size()), std::memory_order_relaxed);
for (auto& w : cc_worker_list) { for (auto& w : cc_worker_list) {
if (w->waiting) { if (w->waiting) {
@ -251,20 +251,20 @@ void sched_worker_manager::run_slot(tti_point tti_tx, uint32_t cc, dl_sched_t& d
} }
// process pending feedback and pre-cache UE state for slot decision // process pending feedback and pre-cache UE state for slot decision
cc_worker_list[cc]->worker.start(tti_tx, ue_db); cc_worker_list[cc]->worker.start(slot_tx, ue_db);
// Get {tti, cc} scheduling decision // Get {slot, cc} scheduling decision
cc_worker_list[cc]->worker.run(); cc_worker_list[cc]->worker.run();
// decrement the number of active workers // decrement the number of active workers
int rem_workers = worker_count.fetch_sub(1, std::memory_order_release) - 1; int rem_workers = worker_count.fetch_sub(1, std::memory_order_release) - 1;
srsran_assert(rem_workers >= 0, "invalid number of calls to run_tti(tti, cc)"); srsran_assert(rem_workers >= 0, "invalid number of calls to run_slot(slot, cc)");
if (rem_workers == 0) { if (rem_workers == 0) {
/* Last Worker to finish slot */ /* Last Worker to finish slot */
// Signal the release of slot if it is the last worker that finished its own generation // Signal the release of slot if it is the last worker that finished its own generation
std::unique_lock<std::mutex> lock(slot_mutex); std::unique_lock<std::mutex> lock(slot_mutex);
current_tti = {}; current_slot = {};
// All the workers of the same slot have finished. Synchronize scheduling decisions with UEs state // All the workers of the same slot have finished. Synchronize scheduling decisions with UEs state
for (auto& c : cc_worker_list) { for (auto& c : cc_worker_list) {
@ -282,13 +282,13 @@ void sched_worker_manager::run_slot(tti_point tti_tx, uint32_t cc, dl_sched_t& d
} }
// Copy results to intermediate buffer // Copy results to intermediate buffer
save_sched_result(tti_tx, cc, dl_res, ul_res); save_sched_result(slot_tx, cc, dl_res, ul_res);
} }
bool sched_worker_manager::save_sched_result(tti_point pdcch_tti, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res) bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, uint32_t cc, dl_sched_t& dl_res, ul_sched_t& ul_res)
{ {
// NOTE: Unlocked region // NOTE: Unlocked region
auto& bwp_slot = cells[cc]->bwps[0].grid[pdcch_tti]; auto& bwp_slot = cells[cc]->bwps[0].grid[pdcch_slot];
dl_res.pdcch_dl = bwp_slot.dl_pdcchs; dl_res.pdcch_dl = bwp_slot.dl_pdcchs;
dl_res.pdcch_ul = bwp_slot.ul_pdcchs; dl_res.pdcch_ul = bwp_slot.ul_pdcchs;
@ -309,7 +309,7 @@ bool sched_worker_manager::save_sched_result(tti_point pdcch_tti, uint32_t cc, d
if (phy_cfg != nullptr) { if (phy_cfg != nullptr) {
srsran_slot_cfg_t slot_cfg{}; srsran_slot_cfg_t slot_cfg{};
slot_cfg.idx = pdcch_tti.sf_idx(); slot_cfg.idx = pdcch_slot.slot_idx();
srsran_uci_cfg_nr_t uci_cfg = {}; srsran_uci_cfg_nr_t uci_cfg = {};
srsran_assert(phy_cfg->get_uci_cfg(slot_cfg, ack, uci_cfg), "Error getting UCI CFG"); srsran_assert(phy_cfg->get_uci_cfg(slot_cfg, ack, uci_cfg), "Error getting UCI CFG");

View File

@ -18,12 +18,12 @@ namespace srsenb {
sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_, sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_,
const sched_nr_interface::ue_cfg_t& ue_cfg_, const sched_nr_interface::ue_cfg_t& ue_cfg_,
tti_point prach_tti_rx, slot_point prach_slot_rx,
uint32_t preamble_idx) : uint32_t preamble_idx) :
logger(srslog::fetch_basic_logger("MAC")) logger(srslog::fetch_basic_logger("MAC"))
{ {
ctxt.rnti = rnti_; ctxt.rnti = rnti_;
ctxt.prach_tti_rx = prach_tti_rx; ctxt.prach_slot_rx = prach_slot_rx;
ctxt.preamble_idx = preamble_idx; ctxt.preamble_idx = preamble_idx;
ctxt.ue_cfg = ue_cfg_; ctxt.ue_cfg = ue_cfg_;
@ -45,16 +45,16 @@ int sched_nr_ue_sim::update(const sched_nr_cc_output_res_t& cc_out)
if (data.dci.ctx.rnti != ctxt.rnti) { if (data.dci.ctx.rnti != ctxt.rnti) {
continue; continue;
} }
tti_point pdcch_tti = cc_out.tti; slot_point pdcch_slot = cc_out.slot;
uint32_t k1 = ctxt.ue_cfg.phy_cfg.harq_ack uint32_t k1 = ctxt.ue_cfg.phy_cfg.harq_ack
.dl_data_to_ul_ack[pdcch_tti.sf_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; .dl_data_to_ul_ack[pdcch_slot.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack];
tti_point uci_tti = pdcch_tti + k1; slot_point uci_slot = pdcch_slot + k1;
ctxt.cc_list[cc_out.cc].pending_acks[uci_tti.to_uint()]++; ctxt.cc_list[cc_out.cc].pending_acks[uci_slot.to_uint()]++;
} }
// clear up old slots // clear up old slots
ctxt.cc_list[cc_out.cc].pending_acks[(cc_out.tti - 1).to_uint()] = 0; ctxt.cc_list[cc_out.cc].pending_acks[(cc_out.slot - 1).to_uint()] = 0;
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
@ -72,7 +72,7 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out)
// It is newtx // It is newtx
h.nof_retxs = 0; h.nof_retxs = 0;
h.ndi = data.dci.ndi; h.ndi = data.dci.ndi;
h.first_tti_tx = cc_out.tti; h.first_slot_tx = cc_out.slot;
h.dci_loc = data.dci.ctx.location; h.dci_loc = data.dci.ctx.location;
h.tbs = 100; // TODO h.tbs = 100; // TODO
} else { } else {
@ -80,11 +80,11 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out)
h.nof_retxs++; h.nof_retxs++;
} }
h.active = true; h.active = true;
h.last_tti_tx = cc_out.tti; h.last_slot_tx = cc_out.slot;
h.last_tti_ack = h.last_slot_ack =
h.last_tti_tx + h.last_slot_tx +
ctxt.ue_cfg.phy_cfg.harq_ack ctxt.ue_cfg.phy_cfg.harq_ack
.dl_data_to_ul_ack[h.last_tti_tx.sf_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; .dl_data_to_ul_ack[h.last_slot_tx.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack];
h.nof_txs++; h.nof_txs++;
} }
} }
@ -117,26 +117,26 @@ int sched_nr_sim_base::add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_
TESTASSERT(ue_db.count(rnti) == 0); TESTASSERT(ue_db.count(rnti) == 0);
sched_ptr->ue_cfg(rnti, ue_cfg_); sched_ptr->ue_cfg(rnti, ue_cfg_);
ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_tti_tx, preamble_idx))); ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_slot_tx, preamble_idx)));
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
void sched_nr_sim_base::new_slot(srsran::tti_point tti_tx) void sched_nr_sim_base::new_slot(slot_point slot_tx)
{ {
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
while (cc_finished > 0) { while (cc_finished > 0) {
cvar.wait(lock); cvar.wait(lock);
} }
logger.set_context(tti_tx.to_uint()); logger.set_context(slot_tx.to_uint());
mac_logger.set_context(tti_tx.to_uint()); mac_logger.set_context(slot_tx.to_uint());
logger.info("---------------- TTI=%d ---------------", tti_tx.to_uint()); logger.info("---------------- TTI=%d ---------------", slot_tx.to_uint());
current_tti_tx = tti_tx; current_slot_tx = slot_tx;
cc_finished = cell_params.size(); cc_finished = cell_params.size();
for (auto& ue : ue_db) { for (auto& ue : ue_db) {
ue_nr_tti_events events; ue_nr_slot_events events;
set_default_tti_events(ue.second.get_ctxt(), events); set_default_slot_events(ue.second.get_ctxt(), events);
set_external_tti_events(ue.second.get_ctxt(), events); set_external_slot_events(ue.second.get_ctxt(), events);
apply_tti_events(ue.second.get_ctxt(), events); apply_slot_events(ue.second.get_ctxt(), events);
} }
} }
@ -157,11 +157,11 @@ void sched_nr_sim_base::update(sched_nr_cc_output_res_t& cc_out)
} }
} }
int sched_nr_sim_base::set_default_tti_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_tti_events& pending_events) int sched_nr_sim_base::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events)
{ {
pending_events.cc_list.clear(); pending_events.cc_list.clear();
pending_events.cc_list.resize(cell_params.size()); pending_events.cc_list.resize(cell_params.size());
pending_events.tti_rx = current_tti_tx; pending_events.slot_rx = current_slot_tx;
for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_events.cc_list.size(); ++enb_cc_idx) { for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_events.cc_list.size(); ++enb_cc_idx) {
auto& cc_feedback = pending_events.cc_list[enb_cc_idx]; auto& cc_feedback = pending_events.cc_list[enb_cc_idx];
@ -172,13 +172,13 @@ int sched_nr_sim_base::set_default_tti_events(const sim_nr_ue_ctxt_t& ue_ctxt, u
auto& ul_h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[pid]; auto& ul_h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[pid];
// Set default DL ACK // Set default DL ACK
if (dl_h.active and (dl_h.last_tti_ack) == current_tti_tx) { if (dl_h.active and (dl_h.last_slot_ack) == current_slot_tx) {
cc_feedback.dl_acks.push_back(ue_nr_tti_events::ack_t{pid, true}); cc_feedback.dl_acks.push_back(ue_nr_slot_events::ack_t{pid, true});
} }
// Set default UL ACK // Set default UL ACK
if (ul_h.active and (ul_h.last_tti_tx + 8) == current_tti_tx) { if (ul_h.active and (ul_h.last_slot_tx + 8) == current_slot_tx) {
cc_feedback.ul_acks.emplace_back(ue_nr_tti_events::ack_t{pid, true}); cc_feedback.ul_acks.emplace_back(ue_nr_slot_events::ack_t{pid, true});
} }
// TODO: other CSI // TODO: other CSI
@ -188,7 +188,7 @@ int sched_nr_sim_base::set_default_tti_events(const sim_nr_ue_ctxt_t& ue_ctxt, u
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
int sched_nr_sim_base::apply_tti_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_tti_events& events) int sched_nr_sim_base::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events)
{ {
for (uint32_t enb_cc_idx = 0; enb_cc_idx < events.cc_list.size(); ++enb_cc_idx) { for (uint32_t enb_cc_idx = 0; enb_cc_idx < events.cc_list.size(); ++enb_cc_idx) {
const auto& cc_feedback = events.cc_list[enb_cc_idx]; const auto& cc_feedback = events.cc_list[enb_cc_idx];
@ -201,7 +201,7 @@ int sched_nr_sim_base::apply_tti_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_t
if (ack.ack) { if (ack.ack) {
logger.info( logger.info(
"DL ACK rnti=0x%x tti_dl_tx=%u cc=%d pid=%d", ue_ctxt.rnti, h.last_tti_tx.to_uint(), enb_cc_idx, ack.pid); "DL ACK rnti=0x%x slot_dl_tx=%u cc=%d pid=%d", ue_ctxt.rnti, h.last_slot_tx.to_uint(), enb_cc_idx, ack.pid);
} }
// update scheduler // update scheduler
@ -218,11 +218,11 @@ int sched_nr_sim_base::apply_tti_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_t
if (ack.ack) { if (ack.ack) {
logger.info( logger.info(
"UL ACK rnti=0x%x, tti_ul_tx=%u, cc=%d pid=%d", ue_ctxt.rnti, h.last_tti_tx.to_uint(), enb_cc_idx, h.pid); "UL ACK rnti=0x%x, slot_ul_tx=%u, cc=%d pid=%d", ue_ctxt.rnti, h.last_slot_tx.to_uint(), enb_cc_idx, h.pid);
} }
// // update scheduler // // update scheduler
// if (sched_ptr->ul_crc_info(events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) { // if (sched_ptr->ul_crc_info(events.slot_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) {
// logger.error("The ACKed UL Harq pid=%d does not exist.", cc_feedback.ul_pid); // logger.error("The ACKed UL Harq pid=%d does not exist.", cc_feedback.ul_pid);
// error_counter++; // error_counter++;
// } // }

View File

@ -31,10 +31,10 @@ struct ue_nr_harq_ctxt_t {
uint32_t riv = 0; uint32_t riv = 0;
srsran_dci_location_t dci_loc = {}; srsran_dci_location_t dci_loc = {};
uint32_t tbs = 0; uint32_t tbs = 0;
tti_point last_tti_tx, first_tti_tx, last_tti_ack; slot_point last_slot_tx, first_slot_tx, last_slot_ack;
}; };
struct sched_nr_cc_output_res_t { struct sched_nr_cc_output_res_t {
tti_point tti; slot_point slot;
uint32_t cc; uint32_t cc;
const sched_nr_interface::dl_sched_t* dl_cc_result; const sched_nr_interface::dl_sched_t* dl_cc_result;
const sched_nr_interface::ul_sched_t* ul_cc_result; const sched_nr_interface::ul_sched_t* ul_cc_result;
@ -46,7 +46,7 @@ struct ue_nr_cc_ctxt_t {
srsran::circular_array<uint32_t, TTIMOD_SZ> pending_acks; srsran::circular_array<uint32_t, TTIMOD_SZ> pending_acks;
}; };
struct ue_nr_tti_events { struct ue_nr_slot_events {
struct ack_t { struct ack_t {
uint32_t pid; uint32_t pid;
bool ack; bool ack;
@ -56,14 +56,14 @@ struct ue_nr_tti_events {
srsran::bounded_vector<ack_t, MAX_GRANTS> dl_acks; srsran::bounded_vector<ack_t, MAX_GRANTS> dl_acks;
srsran::bounded_vector<ack_t, MAX_GRANTS> ul_acks; srsran::bounded_vector<ack_t, MAX_GRANTS> ul_acks;
}; };
srsran::tti_point tti_rx; slot_point slot_rx;
std::vector<cc_data> cc_list; std::vector<cc_data> cc_list;
}; };
struct sim_nr_ue_ctxt_t { struct sim_nr_ue_ctxt_t {
uint16_t rnti; uint16_t rnti;
uint32_t preamble_idx; uint32_t preamble_idx;
srsran::tti_point prach_tti_rx; slot_point prach_slot_rx;
sched_nr_interface::ue_cfg_t ue_cfg; sched_nr_interface::ue_cfg_t ue_cfg;
std::vector<ue_nr_cc_ctxt_t> cc_list; std::vector<ue_nr_cc_ctxt_t> cc_list;
@ -83,7 +83,7 @@ class sched_nr_ue_sim
public: public:
sched_nr_ue_sim(uint16_t rnti_, sched_nr_ue_sim(uint16_t rnti_,
const sched_nr_interface::ue_cfg_t& ue_cfg_, const sched_nr_interface::ue_cfg_t& ue_cfg_,
tti_point prach_tti_rx, slot_point prach_slot_rx,
uint32_t preamble_idx); uint32_t preamble_idx);
int update(const sched_nr_cc_output_res_t& cc_out); int update(const sched_nr_cc_output_res_t& cc_out);
@ -108,7 +108,7 @@ public:
int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, uint32_t preamble_idx); int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, uint32_t preamble_idx);
void new_slot(srsran::tti_point tti_tx); void new_slot(slot_point slot_tx);
void update(sched_nr_cc_output_res_t& cc_out); void update(sched_nr_cc_output_res_t& cc_out);
sched_nr_ue_sim& at(uint16_t rnti) { return ue_db.at(rnti); } sched_nr_ue_sim& at(uint16_t rnti) { return ue_db.at(rnti); }
@ -131,10 +131,10 @@ public:
} }
sched_nr* get_sched() { return sched_ptr.get(); } sched_nr* get_sched() { return sched_ptr.get(); }
srsran::const_span<sched_nr_impl::sched_cell_params> get_cell_params() { return cell_params; } srsran::const_span<sched_nr_impl::sched_cell_params> get_cell_params() { return cell_params; }
tti_point get_tti_rx() const slot_point get_slot_rx() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
return current_tti_tx; return current_slot_tx;
} }
sim_nr_enb_ctxt_t get_enb_ctxt() const; sim_nr_enb_ctxt_t get_enb_ctxt() const;
@ -143,11 +143,11 @@ public:
std::map<uint16_t, sched_nr_ue_sim>::iterator end() { return ue_db.end(); } std::map<uint16_t, sched_nr_ue_sim>::iterator end() { return ue_db.end(); }
// configurable by simulator concrete implementation // configurable by simulator concrete implementation
virtual void set_external_tti_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_tti_events& pending_events) {} virtual void set_external_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) {}
private: private:
int set_default_tti_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_tti_events& pending_events); int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events);
int apply_tti_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_tti_events& events); int apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events);
std::string test_name; std::string test_name;
srslog::basic_logger& logger; srslog::basic_logger& logger;
@ -155,7 +155,7 @@ private:
std::unique_ptr<sched_nr> sched_ptr; std::unique_ptr<sched_nr> sched_ptr;
std::vector<sched_nr_impl::sched_cell_params> cell_params; std::vector<sched_nr_impl::sched_cell_params> cell_params;
srsran::tti_point current_tti_tx; slot_point current_slot_tx;
int cc_finished = 0; int cc_finished = 0;
std::map<uint16_t, sched_nr_ue_sim> ue_db; std::map<uint16_t, sched_nr_ue_sim> ue_db;

View File

@ -38,22 +38,22 @@ struct task_job_manager {
explicit task_job_manager(int max_concurrent_slots = 4) : slot_counter(max_concurrent_slots) {} explicit task_job_manager(int max_concurrent_slots = 4) : slot_counter(max_concurrent_slots) {}
void start_slot(tti_point tti, int nof_sectors) void start_slot(slot_point slot, int nof_sectors)
{ {
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
auto& sl = slot_counter[tti.to_uint() % slot_counter.size()]; auto& sl = slot_counter[slot.to_uint() % slot_counter.size()];
while (sl.count > 0) { while (sl.count > 0) {
sl.cvar.wait(lock); sl.cvar.wait(lock);
} }
sl.count = nof_sectors; sl.count = nof_sectors;
} }
void finish_cc(tti_point tti, const dl_sched_t& dl_res, const sched_nr_interface::ul_sched_t& ul_res) void finish_cc(slot_point slot, const dl_sched_t& dl_res, const sched_nr_interface::ul_sched_t& ul_res)
{ {
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
TESTASSERT(dl_res.pdcch_dl.size() <= 1); TESTASSERT(dl_res.pdcch_dl.size() <= 1);
res_count++; res_count++;
pdsch_count += dl_res.pdcch_dl.size(); pdsch_count += dl_res.pdcch_dl.size();
auto& sl = slot_counter[tti.to_uint() % slot_counter.size()]; auto& sl = slot_counter[slot.to_uint() % slot_counter.size()];
if (--sl.count == 0) { if (--sl.count == 0) {
sl.cvar.notify_one(); sl.cvar.notify_one();
} }
@ -91,23 +91,23 @@ void sched_nr_cfg_serialized_test()
sched_tester.add_user(0x46, uecfg, 0); sched_tester.add_user(0x46, uecfg, 0);
std::vector<long> count_per_cc(nof_sectors, 0); std::vector<long> count_per_cc(nof_sectors, 0);
for (uint32_t nof_ttis = 0; nof_ttis < max_nof_ttis; ++nof_ttis) { for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) {
tti_point tti_rx(nof_ttis % 10240); slot_point slot_rx(0, nof_slots % 10240);
tti_point tti_tx = tti_rx + TX_ENB_DELAY; slot_point slot_tx = slot_rx + TX_ENB_DELAY;
tasks.start_slot(tti_rx, nof_sectors); tasks.start_slot(slot_rx, nof_sectors);
sched_tester.new_slot(tti_tx); sched_tester.new_slot(slot_tx);
for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) { for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) {
sched_nr_interface::dl_sched_t dl_res; sched_nr_interface::dl_sched_t dl_res;
sched_nr_interface::ul_sched_t ul_res; sched_nr_interface::ul_sched_t ul_res;
auto tp1 = std::chrono::steady_clock::now(); auto tp1 = std::chrono::steady_clock::now();
TESTASSERT(sched_tester.get_sched()->get_dl_sched(tti_tx, cc, dl_res) == SRSRAN_SUCCESS); TESTASSERT(sched_tester.get_sched()->get_dl_sched(slot_tx, cc, dl_res) == SRSRAN_SUCCESS);
TESTASSERT(sched_tester.get_sched()->get_ul_sched(tti_tx, cc, ul_res) == SRSRAN_SUCCESS); TESTASSERT(sched_tester.get_sched()->get_ul_sched(slot_tx, cc, ul_res) == SRSRAN_SUCCESS);
auto tp2 = std::chrono::steady_clock::now(); auto tp2 = std::chrono::steady_clock::now();
count_per_cc[cc] += std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp1).count(); count_per_cc[cc] += std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp1).count();
sched_nr_cc_output_res_t out{tti_tx, cc, &dl_res, &ul_res}; sched_nr_cc_output_res_t out{slot_tx, cc, &dl_res, &ul_res};
sched_tester.update(out); sched_tester.update(out);
tasks.finish_cc(tti_rx, dl_res, ul_res); tasks.finish_cc(slot_rx, dl_res, ul_res);
TESTASSERT(not srsran_tdd_nr_is_dl(&cells_cfg[cc].tdd, 0, (tti_tx).sf_idx()) or dl_res.pdcch_dl.size() == 1); TESTASSERT(not srsran_tdd_nr_is_dl(&cells_cfg[cc].tdd, 0, (slot_tx).slot_idx()) or dl_res.pdcch_dl.size() == 1);
} }
} }
@ -139,24 +139,24 @@ void sched_nr_cfg_parallel_cc_test()
sched_tester.add_user(0x46, uecfg, 0); sched_tester.add_user(0x46, uecfg, 0);
std::array<std::atomic<long>, SRSRAN_MAX_CARRIERS> nano_count{}; std::array<std::atomic<long>, SRSRAN_MAX_CARRIERS> nano_count{};
for (uint32_t nof_ttis = 0; nof_ttis < max_nof_ttis; ++nof_ttis) { for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) {
tti_point tti_rx(nof_ttis % 10240); slot_point slot_rx(0, nof_slots % 10240);
tti_point tti_tx = tti_rx + TX_ENB_DELAY; slot_point slot_tx = slot_rx + TX_ENB_DELAY;
tasks.start_slot(tti_tx, nof_sectors); tasks.start_slot(slot_tx, nof_sectors);
sched_tester.new_slot(tti_tx); sched_tester.new_slot(slot_tx);
for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) { for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) {
srsran::get_background_workers().push_task([cc, tti_tx, &tasks, &sched_tester, &nano_count]() { srsran::get_background_workers().push_task([cc, slot_tx, &tasks, &sched_tester, &nano_count]() {
sched_nr_interface::dl_sched_t dl_res; sched_nr_interface::dl_sched_t dl_res;
sched_nr_interface::ul_sched_t ul_res; sched_nr_interface::ul_sched_t ul_res;
auto tp1 = std::chrono::steady_clock::now(); auto tp1 = std::chrono::steady_clock::now();
TESTASSERT(sched_tester.get_sched()->get_dl_sched(tti_tx, cc, dl_res) == SRSRAN_SUCCESS); TESTASSERT(sched_tester.get_sched()->get_dl_sched(slot_tx, cc, dl_res) == SRSRAN_SUCCESS);
TESTASSERT(sched_tester.get_sched()->get_ul_sched(tti_tx, cc, ul_res) == SRSRAN_SUCCESS); TESTASSERT(sched_tester.get_sched()->get_ul_sched(slot_tx, cc, ul_res) == SRSRAN_SUCCESS);
auto tp2 = std::chrono::steady_clock::now(); auto tp2 = std::chrono::steady_clock::now();
nano_count[cc].fetch_add(std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp1).count(), nano_count[cc].fetch_add(std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp1).count(),
std::memory_order_relaxed); std::memory_order_relaxed);
sched_nr_cc_output_res_t out{tti_tx, cc, &dl_res, &ul_res}; sched_nr_cc_output_res_t out{slot_tx, cc, &dl_res, &ul_res};
sched_tester.update(out); sched_tester.update(out);
tasks.finish_cc(tti_tx, dl_res, ul_res); tasks.finish_cc(slot_tx, dl_res, ul_res);
}); });
} }
} }

View File

@ -20,7 +20,7 @@ using namespace srsenb::sched_nr_impl;
void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_output_res_t& cc_out) void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_output_res_t& cc_out)
{ {
tti_point pdcch_tti = cc_out.tti; slot_point pdcch_slot = cc_out.slot;
const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result->pdcch_dl; const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result->pdcch_dl;
const pdsch_list_t& pdschs = cc_out.dl_cc_result->pdsch; const pdsch_list_t& pdschs = cc_out.dl_cc_result->pdsch;
@ -31,7 +31,7 @@ void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_o
} }
const sim_nr_ue_ctxt_t& ue = *enb_ctxt.ue_db.at(pdcch.dci.ctx.rnti); const sim_nr_ue_ctxt_t& ue = *enb_ctxt.ue_db.at(pdcch.dci.ctx.rnti);
uint32_t k1 = ue.ue_cfg.phy_cfg.harq_ack uint32_t k1 = ue.ue_cfg.phy_cfg.harq_ack
.dl_data_to_ul_ack[pdcch_tti.sf_idx() % ue.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; .dl_data_to_ul_ack[pdcch_slot.slot_idx() % ue.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack];
// CHECK: Carrier activation // CHECK: Carrier activation
TESTASSERT(ue.ue_cfg.carriers[cc_out.cc].active); TESTASSERT(ue.ue_cfg.carriers[cc_out.cc].active);
@ -46,9 +46,9 @@ void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_o
if (pdcch.dci.ctx.format == srsran_dci_format_nr_1_0) { if (pdcch.dci.ctx.format == srsran_dci_format_nr_1_0) {
TESTASSERT(pdcch.dci.harq_feedback == k1 - 1); TESTASSERT(pdcch.dci.harq_feedback == k1 - 1);
} else { } else {
TESTASSERT(pdcch.dci.harq_feedback == pdcch_tti.sf_idx()); TESTASSERT(pdcch.dci.harq_feedback == pdcch_slot.slot_idx());
} }
TESTASSERT(ue.cc_list[cc_out.cc].pending_acks[(pdcch_tti + k1).to_uint()] % 4 == pdcch.dci.dai); TESTASSERT(ue.cc_list[cc_out.cc].pending_acks[(pdcch_slot + k1).to_uint()] % 4 == pdcch.dci.dai);
} }
for (const pdsch_t& pdsch : pdschs) { for (const pdsch_t& pdsch : pdschs) {

View File

@ -28,6 +28,8 @@
class gnb_dummy_stack : public srsenb::stack_interface_phy_nr class gnb_dummy_stack : public srsenb::stack_interface_phy_nr
{ {
const static uint32_t NUMEROLOGY_IDX = 0;
public: public:
struct prach_metrics_t { struct prach_metrics_t {
uint32_t count; uint32_t count;
@ -72,7 +74,7 @@ private:
bool valid = false; bool valid = false;
srsenb::sched_nr sched; srsenb::sched_nr sched;
srsran::tti_point pdsch_tti, pusch_tti; srsran::slot_point pdsch_slot, pusch_slot;
srslog::basic_logger& sched_logger; srslog::basic_logger& sched_logger;
std::mutex metrics_mutex; std::mutex metrics_mutex;
@ -406,14 +408,14 @@ public:
{ {
logger.set_context(slot_cfg.idx); logger.set_context(slot_cfg.idx);
sched_logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx);
if (not pdsch_tti.is_valid()) { if (not pdsch_slot.valid()) {
pdsch_tti = srsran::tti_point{slot_cfg.idx}; pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx};
} else { } else {
pdsch_tti++; pdsch_slot++;
} }
if (not use_dummy_sched) { if (not use_dummy_sched) {
int ret = sched.get_dl_sched(pdsch_tti, 0, dl_sched); int ret = sched.get_dl_sched(pdsch_slot, 0, dl_sched);
for (pdsch_t& pdsch : dl_sched.pdsch) { for (pdsch_t& pdsch : dl_sched.pdsch) {
// Set TBS // Set TBS
@ -452,14 +454,14 @@ public:
{ {
logger.set_context(slot_cfg.idx); logger.set_context(slot_cfg.idx);
sched_logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx);
if (not pusch_tti.is_valid()) { if (not pusch_slot.valid()) {
pusch_tti = srsran::tti_point{slot_cfg.idx}; pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx};
} else { } else {
pusch_tti++; pusch_slot++;
} }
if (not use_dummy_sched) { if (not use_dummy_sched) {
int ret = sched.get_ul_sched(pusch_tti, 0, ul_sched); int ret = sched.get_ul_sched(pusch_slot, 0, ul_sched);
for (pusch_t& pusch : ul_sched.pusch) { for (pusch_t& pusch : ul_sched.pusch) {
pusch.data[0] = rx_harq_proc[pusch.pid].get_tb(pusch.sch.grant.tb[0].tbs).data(); pusch.data[0] = rx_harq_proc[pusch.pid].get_tb(pusch.sch.grant.tb[0].tbs).data();