mirror of https://github.com/PentHertz/srsLTE.git
sched,nr: add slot_point to sched nr
This commit is contained in:
parent
a0a1af9d0f
commit
12e33483e1
|
@ -31,6 +31,11 @@ class slot_point
|
|||
|
||||
public:
|
||||
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) :
|
||||
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; }
|
||||
|
||||
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 numerology_idx() const { return numerology_; }
|
||||
uint32_t to_uint() const { return count_; }
|
||||
|
@ -56,11 +61,7 @@ public:
|
|||
void clear() { numerology_ = NOF_NUMEROLOGIES; }
|
||||
|
||||
// operators
|
||||
bool operator==(const slot_point& other) const
|
||||
{
|
||||
srsran_assert(numerology_idx() == other.numerology_idx(), "Comparing slots of different numerologies");
|
||||
return other.count_ == count_;
|
||||
}
|
||||
bool operator==(const slot_point& other) const { return other.count_ == count_ and other.numerology_ == numerology_; }
|
||||
bool operator!=(const slot_point& other) const { return not(*this == other); }
|
||||
bool operator<(const slot_point& other) const
|
||||
{
|
||||
|
@ -163,8 +164,9 @@ struct formatter<srsran::slot_point> {
|
|||
|
||||
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
|
||||
|
|
|
@ -73,7 +73,7 @@ void test_nr_slot_type()
|
|||
srsran::slot_point slot1;
|
||||
TESTASSERT(not slot1.valid());
|
||||
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);
|
||||
srsran::slot_point slot3{slot2};
|
||||
TESTASSERT(slot3 == slot2);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "sched_nr_interface.h"
|
||||
#include "sched_nr_ue.h"
|
||||
#include "srsran/adt/pool/cached_alloc.h"
|
||||
#include "srsran/common/tti_point.h"
|
||||
#include "srsran/common/slot_point.h"
|
||||
#include <array>
|
||||
extern "C" {
|
||||
#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 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_ul_sched(tti_point pusch_tti, uint32_t cc, ul_sched_t& result) override;
|
||||
int get_dl_sched(slot_point pdsch_tti, uint32_t cc, dl_sched_t& result) override;
|
||||
int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_sched_t& result) override;
|
||||
|
||||
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);
|
||||
|
||||
// args
|
||||
|
|
|
@ -24,7 +24,7 @@ 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;
|
||||
slot_point prach_slot;
|
||||
srsran::bounded_vector<dl_sched_rar_info_t, sched_interface::MAX_RAR_LIST> msg3_grant;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "sched_nr_cfg.h"
|
||||
#include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h"
|
||||
#include "srsran/common/tti_point.h"
|
||||
#include "srsran/common/slot_point.h"
|
||||
#include <array>
|
||||
|
||||
namespace srsenb {
|
||||
|
@ -31,23 +31,30 @@ public:
|
|||
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 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 max_nof_retx() const { return max_retx; }
|
||||
uint32_t tbs() const { return tb[0].tbs; }
|
||||
uint32_t ndi() const { return tb[0].ndi; }
|
||||
uint32_t mcs() const { return tb[0].mcs; }
|
||||
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);
|
||||
|
||||
void new_tti(tti_point tti_rx);
|
||||
void new_slot(slot_point slot_rx);
|
||||
void reset();
|
||||
bool
|
||||
new_tx(tti_point tti_tx, tti_point tti_ack, const prb_grant& grant, uint32_t mcs, uint32_t tbs, uint32_t max_retx);
|
||||
bool new_retx(tti_point tti_tx, tti_point tti_ack, const prb_grant& grant);
|
||||
bool new_retx(tti_point tti_tx, tti_point tti_ack);
|
||||
bool new_tx(slot_point slot_tx,
|
||||
slot_point slot_ack,
|
||||
const prb_grant& grant,
|
||||
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
|
||||
bool set_tbs(uint32_t tbs);
|
||||
|
@ -65,8 +72,8 @@ private:
|
|||
};
|
||||
|
||||
uint32_t max_retx = 1;
|
||||
tti_point tti_tx;
|
||||
tti_point tti_ack;
|
||||
slot_point slot_tx;
|
||||
slot_point slot_ack;
|
||||
prb_grant prbs_;
|
||||
std::array<tb_t, SCHED_NR_MAX_TB> tb;
|
||||
};
|
||||
|
@ -113,18 +120,18 @@ class harq_entity
|
|||
{
|
||||
public:
|
||||
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 ul_crc_info(uint32_t pid, bool ack) { ul_harqs[pid].ack_info(0, ack); }
|
||||
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -149,7 +156,7 @@ private:
|
|||
return (it == ul_harqs.end()) ? nullptr : &(*it);
|
||||
}
|
||||
|
||||
tti_point tti_rx;
|
||||
slot_point slot_rx;
|
||||
std::vector<dl_harq_proc> dl_harqs;
|
||||
std::vector<ul_harq_proc> ul_harqs;
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "srsran/adt/optional.h"
|
||||
#include "srsran/adt/span.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/phy/phch/dci_nr.h"
|
||||
|
||||
|
@ -85,7 +85,7 @@ public:
|
|||
uint32_t ta_cmd;
|
||||
uint16_t temp_crnti;
|
||||
uint32_t msg3_size;
|
||||
uint32_t prach_tti;
|
||||
uint32_t prach_slot;
|
||||
};
|
||||
|
||||
///// Sched Result /////
|
||||
|
@ -96,12 +96,12 @@ public:
|
|||
virtual ~sched_nr_interface() = default;
|
||||
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 int get_dl_sched(tti_point tti_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_dl_sched(slot_point slot_rx, uint32_t cc, dl_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 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
|
||||
|
|
|
@ -61,8 +61,8 @@ struct bwp_slot_grid {
|
|||
struct bwp_res_grid {
|
||||
bwp_res_grid(const bwp_params& bwp_cfg_);
|
||||
|
||||
bwp_slot_grid& operator[](tti_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()]; };
|
||||
bwp_slot_grid& operator[](slot_point tti) { 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 nof_prbs() const { return cfg->cfg.rb_width; }
|
||||
|
||||
|
@ -81,7 +81,7 @@ class bwp_slot_allocator
|
|||
public:
|
||||
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,
|
||||
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_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_params& cfg;
|
||||
|
@ -102,7 +102,7 @@ private:
|
|||
srslog::basic_logger& logger;
|
||||
bwp_res_grid& bwp_grid;
|
||||
|
||||
tti_point pdcch_tti;
|
||||
slot_point pdcch_slot;
|
||||
};
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
|
|
|
@ -30,25 +30,25 @@ class slot_ue
|
|||
{
|
||||
public:
|
||||
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& operator=(slot_ue&&) noexcept = default;
|
||||
bool empty() const { return rnti == SCHED_NR_INVALID_RNTI; }
|
||||
void release() { rnti = SCHED_NR_INVALID_RNTI; }
|
||||
|
||||
uint16_t rnti = SCHED_NR_INVALID_RNTI;
|
||||
tti_point tti_rx;
|
||||
uint32_t cc = SCHED_NR_MAX_CARRIERS;
|
||||
uint16_t rnti = SCHED_NR_INVALID_RNTI;
|
||||
slot_point slot_rx;
|
||||
uint32_t cc = SCHED_NR_MAX_CARRIERS;
|
||||
|
||||
// UE parameters common to all sectors
|
||||
bool pending_sr;
|
||||
|
||||
// UE parameters that are sector specific
|
||||
const bwp_ue_cfg* cfg = nullptr;
|
||||
tti_point pdcch_tti;
|
||||
tti_point pdsch_tti;
|
||||
tti_point pusch_tti;
|
||||
tti_point uci_tti;
|
||||
slot_point pdcch_slot;
|
||||
slot_point pdsch_slot;
|
||||
slot_point pusch_slot;
|
||||
slot_point uci_slot;
|
||||
uint32_t dl_cqi;
|
||||
uint32_t ul_cqi;
|
||||
dl_harq_proc* h_dl = nullptr;
|
||||
|
@ -59,8 +59,8 @@ class ue_carrier
|
|||
{
|
||||
public:
|
||||
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_);
|
||||
slot_ue try_reserve(tti_point pdcch_tti);
|
||||
void new_slot(slot_point pdcch_slot, const ue_cfg_t& uecfg_);
|
||||
slot_ue try_reserve(slot_point pdcch_slot);
|
||||
|
||||
const uint16_t rnti;
|
||||
const uint32_t cc;
|
||||
|
@ -81,12 +81,12 @@ class ue
|
|||
public:
|
||||
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);
|
||||
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; }
|
||||
uint32_t pcell_cc() const { return ue_cfg.carriers[0].cc; }
|
||||
|
|
|
@ -37,10 +37,10 @@ public:
|
|||
|
||||
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 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
|
||||
void enqueue_cc_feedback(uint16_t rnti, feedback_callback_t fdbk);
|
||||
|
@ -57,7 +57,7 @@ private:
|
|||
serv_cell_manager& cell;
|
||||
srslog::basic_logger& logger;
|
||||
|
||||
tti_point tti_rx;
|
||||
slot_point slot_rx;
|
||||
bwp_slot_allocator bwp_alloc;
|
||||
|
||||
// Process of UE cell-specific feedback
|
||||
|
@ -76,7 +76,7 @@ class sched_worker_manager
|
|||
struct slot_worker_ctxt {
|
||||
std::mutex slot_mutex; // lock of all workers of the same slot.
|
||||
std::condition_variable cvar;
|
||||
tti_point tti_rx;
|
||||
slot_point slot_rx;
|
||||
int nof_workers_waiting = 0;
|
||||
std::atomic<int> worker_count{0}; // variable shared across slot_cc_workers
|
||||
std::vector<slot_cc_worker> workers;
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
sched_worker_manager(sched_worker_manager&&) = delete;
|
||||
~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_cc_feedback(uint16_t rnti, uint32_t cc, slot_cc_worker::feedback_callback_t fdbk)
|
||||
|
@ -99,7 +99,7 @@ public:
|
|||
}
|
||||
|
||||
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;
|
||||
ue_map_t& ue_db;
|
||||
|
@ -124,7 +124,7 @@ private:
|
|||
|
||||
std::mutex slot_mutex;
|
||||
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::vector<std::unique_ptr<cc_context> > cc_worker_list;
|
||||
};
|
||||
|
|
|
@ -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)) {
|
||||
results[tti.to_uint()][cc].tti_dl = tti;
|
||||
results[tti.to_uint()][cc].dl_res = {};
|
||||
results[tti.to_uint()][cc].slot_dl = tti;
|
||||
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)) {
|
||||
results[tti.to_uint()][cc].tti_ul = tti;
|
||||
results[tti.to_uint()][cc].ul_res = {};
|
||||
results[tti.to_uint()][cc].slot_ul = tti;
|
||||
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)) {
|
||||
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 {};
|
||||
}
|
||||
|
||||
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)) {
|
||||
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 {};
|
||||
|
@ -75,8 +75,8 @@ public:
|
|||
|
||||
private:
|
||||
struct slot_result_t {
|
||||
tti_point tti_dl;
|
||||
tti_point tti_ul;
|
||||
slot_point slot_dl;
|
||||
slot_point slot_ul;
|
||||
dl_sched_t dl_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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
generate_slot_result(tti_tx, cc);
|
||||
if (not pending_results->has_dl_result(slot_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;
|
||||
}
|
||||
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)) {
|
||||
// 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); });
|
||||
}
|
||||
|
||||
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, ...) \
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
static const uint32_t PRACH_RAR_OFFSET = 3;
|
||||
tti_point pdcch_tti = slot_grid.get_pdcch_tti();
|
||||
tti_point msg3_tti = pdcch_tti + bwp_cfg->pusch_ra_list[0].msg3_delay;
|
||||
if (not slot_grid.res_grid()[msg3_tti].is_ul) {
|
||||
slot_point pdcch_slot = slot_grid.get_pdcch_tti();
|
||||
slot_point msg3_slot = pdcch_slot + bwp_cfg->pusch_ra_list[0].msg3_delay;
|
||||
if (not slot_grid.res_grid()[msg3_slot].is_ul) {
|
||||
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:
|
||||
// - 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 + bwp_cfg->cfg.rar_window_size};
|
||||
if (not rar_window.contains(pdcch_tti)) {
|
||||
if (pdcch_tti >= rar_window.stop()) {
|
||||
slot_interval rar_window{rar.prach_slot + PRACH_RAR_OFFSET,
|
||||
rar.prach_slot + PRACH_RAR_OFFSET + bwp_cfg->cfg.rar_window_size};
|
||||
if (not rar_window.contains(pdcch_slot)) {
|
||||
if (pdcch_slot >= 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.prach_slot,
|
||||
rar_window,
|
||||
pdcch_tti);
|
||||
pdcch_slot);
|
||||
srsran::console("%s\n", srsran::to_c_str(str_buffer));
|
||||
logger.warning("%s", srsran::to_c_str(str_buffer));
|
||||
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)
|
||||
{
|
||||
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.temp_crnti,
|
||||
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
|
||||
// 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);
|
||||
uint16_t ra_rnti = 1 + (uint16_t)(rar_info.prach_slot % 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.prach_slot.to_uint() == rar_info.prach_slot 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;
|
||||
|
@ -141,8 +141,8 @@ int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info)
|
|||
|
||||
// create new RAR
|
||||
pending_rar_t p;
|
||||
p.ra_rnti = ra_rnti;
|
||||
p.prach_tti = tti_point{rar_info.prach_tti};
|
||||
p.ra_rnti = ra_rnti;
|
||||
p.prach_slot = slot_point{0, rar_info.prach_slot};
|
||||
p.msg3_grant.push_back(rar_info);
|
||||
pending_rars.push_back(p);
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ bool harq_proc::ack_info(uint32_t tb_idx, bool ack)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ void harq_proc::reset()
|
|||
tb[0].tbs = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
bool harq_proc::new_tx(tti_point tti_tx_,
|
||||
tti_point tti_ack_,
|
||||
bool harq_proc::new_tx(slot_point slot_tx_,
|
||||
slot_point slot_ack_,
|
||||
const prb_grant& grant,
|
||||
uint32_t mcs,
|
||||
uint32_t tbs,
|
||||
|
@ -55,8 +55,8 @@ bool harq_proc::new_tx(tti_point tti_tx_,
|
|||
}
|
||||
reset();
|
||||
max_retx = max_retx_;
|
||||
tti_tx = tti_tx_;
|
||||
tti_ack = tti_ack_;
|
||||
slot_tx = slot_tx_;
|
||||
slot_ack = slot_ack_;
|
||||
prbs_ = grant;
|
||||
tb[0].ndi = !tb[0].ndi;
|
||||
tb[0].mcs = mcs;
|
||||
|
@ -74,27 +74,27 @@ bool harq_proc::set_tbs(uint32_t tbs)
|
|||
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
|
||||
(grant.is_alloc_type0() and grant.rbgs().count() != prbs_.rbgs().count()) or
|
||||
(grant.is_alloc_type1() and grant.prbs().length() == prbs_.prbs().length())) {
|
||||
return false;
|
||||
}
|
||||
if (new_retx(tti_tx_, tti_ack_)) {
|
||||
if (new_retx(slot_tx_, slot_ack_)) {
|
||||
prbs_ = grant;
|
||||
return true;
|
||||
}
|
||||
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()) {
|
||||
return false;
|
||||
}
|
||||
tti_tx = tti_tx_;
|
||||
tti_ack = tti_ack_;
|
||||
slot_tx = slot_tx_;
|
||||
slot_ack = slot_ack_;
|
||||
tb[0].ack_state = false;
|
||||
tb[0].n_rtx++;
|
||||
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) {
|
||||
dl_h.new_tti(tti_rx);
|
||||
dl_h.new_slot(slot_rx);
|
||||
}
|
||||
for (harq_proc& ul_h : ul_harqs) {
|
||||
ul_h.new_tti(tti_rx);
|
||||
ul_h.new_slot(slot_rx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,9 +67,9 @@ void fill_dl_dci_ue_fields(const slot_ue& ue,
|
|||
|
||||
fill_dci_common(ue, bwp_cfg, dci);
|
||||
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 {
|
||||
dci.harq_feedback = ue.pdsch_tti.sf_idx();
|
||||
dci.harq_feedback = ue.pdsch_slot.slot_idx();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_tti];
|
||||
tti_point msg3_tti = pdcch_tti + cfg.pusch_ra_list[m].msg3_delay;
|
||||
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_tti];
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot];
|
||||
slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay;
|
||||
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot];
|
||||
alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr);
|
||||
if (ret != alloc_result::success) {
|
||||
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;
|
||||
int dai = 0;
|
||||
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) {
|
||||
slot_ue& ue = ues[grant.temp_crnti];
|
||||
bool success = ue.h_ul->new_tx(
|
||||
msg3_tti, msg3_tti, prb_interval{last_msg3, last_msg3 + msg3_nof_prbs}, mcs, 100, max_harq_msg3_retx);
|
||||
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");
|
||||
last_msg3 += msg3_nof_prbs;
|
||||
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);
|
||||
return alloc_result::no_rnti_opportunity;
|
||||
}
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti];
|
||||
bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_tti];
|
||||
bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_tti];
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
|
||||
bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot];
|
||||
bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot];
|
||||
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);
|
||||
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");
|
||||
int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs;
|
||||
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");
|
||||
} 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");
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back();
|
||||
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);
|
||||
srsran_assert(ret, "Error converting DCI to grant");
|
||||
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)
|
||||
{
|
||||
auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_tti];
|
||||
auto& bwp_pusch_slot = bwp_grid[ue.pusch_tti];
|
||||
auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
|
||||
auto& bwp_pusch_slot = bwp_grid[ue.pusch_slot];
|
||||
alloc_result ret = verify_pusch_space(bwp_pusch_slot, &bwp_pdcch_slot);
|
||||
if (ret != alloc_result::success) {
|
||||
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");
|
||||
int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs;
|
||||
int tbs = 100;
|
||||
bool success = ue.h_ul->new_tx(ue.pusch_tti, ue.pusch_tti, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx);
|
||||
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");
|
||||
} 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
|
||||
|
@ -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();
|
||||
pusch_t& pusch = bwp_pusch_slot.puschs.back();
|
||||
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);
|
||||
srsran_assert(success, "Error converting DCI to PUSCH grant");
|
||||
pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get();
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
namespace srsenb {
|
||||
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())
|
||||
{}
|
||||
|
||||
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_) {
|
||||
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
|
||||
slot_ue sfu(rnti, tti_rx, cc);
|
||||
slot_ue sfu(rnti, slot_rx, cc);
|
||||
sfu.cfg = &bwp_cfg;
|
||||
sfu.pdcch_tti = pdcch_tti;
|
||||
sfu.pdcch_slot = pdcch_slot;
|
||||
const uint32_t k0 = 0;
|
||||
sfu.pdsch_tti = sfu.pdcch_tti + k0;
|
||||
sfu.pdsch_slot = sfu.pdcch_slot + k0;
|
||||
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.uci_tti = sfu.pdsch_tti + k1;
|
||||
uint32_t k2 = bwp_cfg.active_bwp().pusch_ra_list[0].K;
|
||||
sfu.pusch_tti = sfu.pdcch_tti + k2;
|
||||
sfu.dl_cqi = dl_cqi;
|
||||
sfu.ul_cqi = ul_cqi;
|
||||
sfu.cfg->phy()
|
||||
.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;
|
||||
sfu.pusch_slot = sfu.pdcch_slot + k2;
|
||||
sfu.dl_cqi = dl_cqi;
|
||||
sfu.ul_cqi = ul_cqi;
|
||||
|
||||
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
|
||||
sfu.h_dl = harq_ent.find_pending_dl_retx();
|
||||
if (sfu.h_dl == nullptr) {
|
||||
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
|
||||
sfu.h_ul = harq_ent.find_pending_ul_retx();
|
||||
if (sfu.h_ul == nullptr) {
|
||||
|
@ -95,12 +96,12 @@ void ue::set_cfg(const ue_cfg_t& 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) {
|
||||
return slot_ue();
|
||||
}
|
||||
slot_ue sfu = carriers[cc]->try_reserve(pdcch_tti);
|
||||
slot_ue sfu = carriers[cc]->try_reserve(pdcch_slot);
|
||||
if (sfu.empty()) {
|
||||
return slot_ue();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
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");
|
||||
tti_rx = pdcch_tti - TX_ENB_DELAY;
|
||||
slot_rx = pdcch_slot - TX_ENB_DELAY;
|
||||
|
||||
// Run pending cell feedback
|
||||
run_feedback(ue_db);
|
||||
|
@ -62,15 +62,15 @@ void slot_cc_worker::start(tti_point pdcch_tti, ue_map_t& ue_db)
|
|||
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()) {
|
||||
// Failed to generate slot UE because UE has no conditions for DL/UL tx
|
||||
slot_ues.erase(rnti);
|
||||
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");
|
||||
|
||||
bwp_alloc.new_slot(tti_rx + TX_ENB_DELAY);
|
||||
bwp_alloc.new_slot(slot_rx + TX_ENB_DELAY);
|
||||
|
||||
// Allocate pending RARs
|
||||
cell.bwps[0].ra.run_slot(bwp_alloc, slot_ues);
|
||||
|
@ -92,7 +92,7 @@ void slot_cc_worker::run()
|
|||
|
||||
// releases UE resources
|
||||
slot_ues.clear();
|
||||
tti_rx = {};
|
||||
slot_rx = {};
|
||||
}
|
||||
|
||||
void slot_cc_worker::finish()
|
||||
|
@ -132,7 +132,7 @@ void slot_cc_worker::alloc_ul_ues()
|
|||
|
||||
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) {
|
||||
fmt::memory_buffer fmtbuf;
|
||||
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(),
|
||||
srsran_dci_format_nr_string(pdcch.dci.ctx.format),
|
||||
pdcch.dci.dai,
|
||||
ue.pdsch_tti,
|
||||
ue.uci_tti);
|
||||
ue.pdsch_slot,
|
||||
ue.uci_slot);
|
||||
} else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) {
|
||||
fmt::format_to(fmtbuf, "SCHED: DL RAR, cc={}", cell.cfg.cc);
|
||||
} else {
|
||||
|
@ -168,7 +168,7 @@ void slot_cc_worker::log_result() const
|
|||
pdcch.dci.pid,
|
||||
ue.h_dl->nof_retx(),
|
||||
srsran_dci_format_nr_string(pdcch.dci.ctx.format),
|
||||
ue.pusch_tti);
|
||||
ue.pusch_slot);
|
||||
} else {
|
||||
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)});
|
||||
}
|
||||
|
||||
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;
|
||||
{
|
||||
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
|
||||
cc_worker_list[cc]->waiting = true;
|
||||
cc_worker_list[cc]->cvar.wait(lock);
|
||||
cc_worker_list[cc]->waiting = false;
|
||||
}
|
||||
if (not current_tti.is_valid()) {
|
||||
if (not current_slot.valid()) {
|
||||
/* First Worker to start slot */
|
||||
|
||||
// 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
|
||||
current_tti = tti_tx;
|
||||
current_slot = slot_tx;
|
||||
worker_count.store(static_cast<int>(cc_worker_list.size()), std::memory_order_relaxed);
|
||||
for (auto& w : cc_worker_list) {
|
||||
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
|
||||
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();
|
||||
|
||||
// decrement the number of active workers
|
||||
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) {
|
||||
/* Last Worker to finish slot */
|
||||
|
||||
// Signal the release of slot if it is the last worker that finished its own generation
|
||||
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
|
||||
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
|
||||
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
|
||||
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_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) {
|
||||
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_assert(phy_cfg->get_uci_cfg(slot_cfg, ack, uci_cfg), "Error getting UCI CFG");
|
||||
|
||||
|
|
|
@ -18,14 +18,14 @@ namespace srsenb {
|
|||
|
||||
sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_,
|
||||
const sched_nr_interface::ue_cfg_t& ue_cfg_,
|
||||
tti_point prach_tti_rx,
|
||||
slot_point prach_slot_rx,
|
||||
uint32_t preamble_idx) :
|
||||
logger(srslog::fetch_basic_logger("MAC"))
|
||||
{
|
||||
ctxt.rnti = rnti_;
|
||||
ctxt.prach_tti_rx = prach_tti_rx;
|
||||
ctxt.preamble_idx = preamble_idx;
|
||||
ctxt.ue_cfg = ue_cfg_;
|
||||
ctxt.rnti = rnti_;
|
||||
ctxt.prach_slot_rx = prach_slot_rx;
|
||||
ctxt.preamble_idx = preamble_idx;
|
||||
ctxt.ue_cfg = ue_cfg_;
|
||||
|
||||
ctxt.cc_list.resize(ue_cfg_.carriers.size());
|
||||
for (auto& cc : ctxt.cc_list) {
|
||||
|
@ -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) {
|
||||
continue;
|
||||
}
|
||||
tti_point pdcch_tti = cc_out.tti;
|
||||
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];
|
||||
tti_point uci_tti = pdcch_tti + k1;
|
||||
slot_point pdcch_slot = cc_out.slot;
|
||||
uint32_t k1 = ctxt.ue_cfg.phy_cfg.harq_ack
|
||||
.dl_data_to_ul_ack[pdcch_slot.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack];
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
@ -70,21 +70,21 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out)
|
|||
auto& h = ctxt.cc_list[cc].dl_harqs[data.dci.pid];
|
||||
if (h.nof_txs == 0 or h.ndi != data.dci.ndi) {
|
||||
// It is newtx
|
||||
h.nof_retxs = 0;
|
||||
h.ndi = data.dci.ndi;
|
||||
h.first_tti_tx = cc_out.tti;
|
||||
h.dci_loc = data.dci.ctx.location;
|
||||
h.tbs = 100; // TODO
|
||||
h.nof_retxs = 0;
|
||||
h.ndi = data.dci.ndi;
|
||||
h.first_slot_tx = cc_out.slot;
|
||||
h.dci_loc = data.dci.ctx.location;
|
||||
h.tbs = 100; // TODO
|
||||
} else {
|
||||
// it is retx
|
||||
h.nof_retxs++;
|
||||
}
|
||||
h.active = true;
|
||||
h.last_tti_tx = cc_out.tti;
|
||||
h.last_tti_ack =
|
||||
h.last_tti_tx +
|
||||
h.active = true;
|
||||
h.last_slot_tx = cc_out.slot;
|
||||
h.last_slot_ack =
|
||||
h.last_slot_tx +
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
while (cc_finished > 0) {
|
||||
cvar.wait(lock);
|
||||
}
|
||||
logger.set_context(tti_tx.to_uint());
|
||||
mac_logger.set_context(tti_tx.to_uint());
|
||||
logger.info("---------------- TTI=%d ---------------", tti_tx.to_uint());
|
||||
current_tti_tx = tti_tx;
|
||||
cc_finished = cell_params.size();
|
||||
logger.set_context(slot_tx.to_uint());
|
||||
mac_logger.set_context(slot_tx.to_uint());
|
||||
logger.info("---------------- TTI=%d ---------------", slot_tx.to_uint());
|
||||
current_slot_tx = slot_tx;
|
||||
cc_finished = cell_params.size();
|
||||
for (auto& ue : ue_db) {
|
||||
ue_nr_tti_events events;
|
||||
set_default_tti_events(ue.second.get_ctxt(), events);
|
||||
set_external_tti_events(ue.second.get_ctxt(), events);
|
||||
apply_tti_events(ue.second.get_ctxt(), events);
|
||||
ue_nr_slot_events events;
|
||||
set_default_slot_events(ue.second.get_ctxt(), events);
|
||||
set_external_slot_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.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) {
|
||||
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];
|
||||
|
||||
// Set default DL ACK
|
||||
if (dl_h.active and (dl_h.last_tti_ack) == current_tti_tx) {
|
||||
cc_feedback.dl_acks.push_back(ue_nr_tti_events::ack_t{pid, true});
|
||||
if (dl_h.active and (dl_h.last_slot_ack) == current_slot_tx) {
|
||||
cc_feedback.dl_acks.push_back(ue_nr_slot_events::ack_t{pid, true});
|
||||
}
|
||||
|
||||
// Set default UL ACK
|
||||
if (ul_h.active and (ul_h.last_tti_tx + 8) == current_tti_tx) {
|
||||
cc_feedback.ul_acks.emplace_back(ue_nr_tti_events::ack_t{pid, true});
|
||||
if (ul_h.active and (ul_h.last_slot_tx + 8) == current_slot_tx) {
|
||||
cc_feedback.ul_acks.emplace_back(ue_nr_slot_events::ack_t{pid, true});
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
|
@ -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) {
|
||||
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
|
||||
// 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);
|
||||
// error_counter++;
|
||||
// }
|
||||
|
|
|
@ -31,10 +31,10 @@ struct ue_nr_harq_ctxt_t {
|
|||
uint32_t riv = 0;
|
||||
srsran_dci_location_t dci_loc = {};
|
||||
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 {
|
||||
tti_point tti;
|
||||
slot_point slot;
|
||||
uint32_t cc;
|
||||
const sched_nr_interface::dl_sched_t* dl_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;
|
||||
};
|
||||
|
||||
struct ue_nr_tti_events {
|
||||
struct ue_nr_slot_events {
|
||||
struct ack_t {
|
||||
uint32_t pid;
|
||||
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> ul_acks;
|
||||
};
|
||||
srsran::tti_point tti_rx;
|
||||
slot_point slot_rx;
|
||||
std::vector<cc_data> cc_list;
|
||||
};
|
||||
|
||||
struct sim_nr_ue_ctxt_t {
|
||||
uint16_t rnti;
|
||||
uint32_t preamble_idx;
|
||||
srsran::tti_point prach_tti_rx;
|
||||
slot_point prach_slot_rx;
|
||||
sched_nr_interface::ue_cfg_t ue_cfg;
|
||||
std::vector<ue_nr_cc_ctxt_t> cc_list;
|
||||
|
||||
|
@ -83,7 +83,7 @@ class sched_nr_ue_sim
|
|||
public:
|
||||
sched_nr_ue_sim(uint16_t rnti_,
|
||||
const sched_nr_interface::ue_cfg_t& ue_cfg_,
|
||||
tti_point prach_tti_rx,
|
||||
slot_point prach_slot_rx,
|
||||
uint32_t preamble_idx);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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(); }
|
||||
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);
|
||||
return current_tti_tx;
|
||||
return current_slot_tx;
|
||||
}
|
||||
|
||||
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(); }
|
||||
|
||||
// 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:
|
||||
int set_default_tti_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_tti_events& pending_events);
|
||||
int apply_tti_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_tti_events& events);
|
||||
int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events);
|
||||
int apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events);
|
||||
|
||||
std::string test_name;
|
||||
srslog::basic_logger& logger;
|
||||
|
@ -155,8 +155,8 @@ private:
|
|||
std::unique_ptr<sched_nr> sched_ptr;
|
||||
std::vector<sched_nr_impl::sched_cell_params> cell_params;
|
||||
|
||||
srsran::tti_point current_tti_tx;
|
||||
int cc_finished = 0;
|
||||
slot_point current_slot_tx;
|
||||
int cc_finished = 0;
|
||||
|
||||
std::map<uint16_t, sched_nr_ue_sim> ue_db;
|
||||
|
||||
|
|
|
@ -38,22 +38,22 @@ struct task_job_manager {
|
|||
|
||||
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);
|
||||
auto& sl = slot_counter[tti.to_uint() % slot_counter.size()];
|
||||
auto& sl = slot_counter[slot.to_uint() % slot_counter.size()];
|
||||
while (sl.count > 0) {
|
||||
sl.cvar.wait(lock);
|
||||
}
|
||||
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);
|
||||
TESTASSERT(dl_res.pdcch_dl.size() <= 1);
|
||||
res_count++;
|
||||
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) {
|
||||
sl.cvar.notify_one();
|
||||
}
|
||||
|
@ -91,23 +91,23 @@ void sched_nr_cfg_serialized_test()
|
|||
sched_tester.add_user(0x46, uecfg, 0);
|
||||
|
||||
std::vector<long> count_per_cc(nof_sectors, 0);
|
||||
for (uint32_t nof_ttis = 0; nof_ttis < max_nof_ttis; ++nof_ttis) {
|
||||
tti_point tti_rx(nof_ttis % 10240);
|
||||
tti_point tti_tx = tti_rx + TX_ENB_DELAY;
|
||||
tasks.start_slot(tti_rx, nof_sectors);
|
||||
sched_tester.new_slot(tti_tx);
|
||||
for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) {
|
||||
slot_point slot_rx(0, nof_slots % 10240);
|
||||
slot_point slot_tx = slot_rx + TX_ENB_DELAY;
|
||||
tasks.start_slot(slot_rx, nof_sectors);
|
||||
sched_tester.new_slot(slot_tx);
|
||||
for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) {
|
||||
sched_nr_interface::dl_sched_t dl_res;
|
||||
sched_nr_interface::ul_sched_t ul_res;
|
||||
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_ul_sched(tti_tx, cc, ul_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(slot_tx, cc, ul_res) == SRSRAN_SUCCESS);
|
||||
auto tp2 = std::chrono::steady_clock::now();
|
||||
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);
|
||||
tasks.finish_cc(tti_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);
|
||||
tasks.finish_cc(slot_rx, dl_res, ul_res);
|
||||
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);
|
||||
|
||||
std::array<std::atomic<long>, SRSRAN_MAX_CARRIERS> nano_count{};
|
||||
for (uint32_t nof_ttis = 0; nof_ttis < max_nof_ttis; ++nof_ttis) {
|
||||
tti_point tti_rx(nof_ttis % 10240);
|
||||
tti_point tti_tx = tti_rx + TX_ENB_DELAY;
|
||||
tasks.start_slot(tti_tx, nof_sectors);
|
||||
sched_tester.new_slot(tti_tx);
|
||||
for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) {
|
||||
slot_point slot_rx(0, nof_slots % 10240);
|
||||
slot_point slot_tx = slot_rx + TX_ENB_DELAY;
|
||||
tasks.start_slot(slot_tx, nof_sectors);
|
||||
sched_tester.new_slot(slot_tx);
|
||||
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::ul_sched_t ul_res;
|
||||
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_ul_sched(tti_tx, cc, ul_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(slot_tx, cc, ul_res) == SRSRAN_SUCCESS);
|
||||
auto tp2 = std::chrono::steady_clock::now();
|
||||
nano_count[cc].fetch_add(std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp1).count(),
|
||||
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);
|
||||
tasks.finish_cc(tti_tx, dl_res, ul_res);
|
||||
tasks.finish_cc(slot_tx, dl_res, ul_res);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ 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)
|
||||
{
|
||||
tti_point pdcch_tti = cc_out.tti;
|
||||
const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result->pdcch_dl;
|
||||
const pdsch_list_t& pdschs = cc_out.dl_cc_result->pdsch;
|
||||
slot_point pdcch_slot = cc_out.slot;
|
||||
const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result->pdcch_dl;
|
||||
const pdsch_list_t& pdschs = cc_out.dl_cc_result->pdsch;
|
||||
|
||||
// Iterate over UE PDCCH allocations
|
||||
for (const pdcch_dl_t& pdcch : pdcchs) {
|
||||
|
@ -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);
|
||||
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
|
||||
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) {
|
||||
TESTASSERT(pdcch.dci.harq_feedback == k1 - 1);
|
||||
} 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) {
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
class gnb_dummy_stack : public srsenb::stack_interface_phy_nr
|
||||
{
|
||||
const static uint32_t NUMEROLOGY_IDX = 0;
|
||||
|
||||
public:
|
||||
struct prach_metrics_t {
|
||||
uint32_t count;
|
||||
|
@ -72,7 +74,7 @@ private:
|
|||
bool valid = false;
|
||||
|
||||
srsenb::sched_nr sched;
|
||||
srsran::tti_point pdsch_tti, pusch_tti;
|
||||
srsran::slot_point pdsch_slot, pusch_slot;
|
||||
srslog::basic_logger& sched_logger;
|
||||
|
||||
std::mutex metrics_mutex;
|
||||
|
@ -406,14 +408,14 @@ public:
|
|||
{
|
||||
logger.set_context(slot_cfg.idx);
|
||||
sched_logger.set_context(slot_cfg.idx);
|
||||
if (not pdsch_tti.is_valid()) {
|
||||
pdsch_tti = srsran::tti_point{slot_cfg.idx};
|
||||
if (not pdsch_slot.valid()) {
|
||||
pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx};
|
||||
} else {
|
||||
pdsch_tti++;
|
||||
pdsch_slot++;
|
||||
}
|
||||
|
||||
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) {
|
||||
// Set TBS
|
||||
|
@ -452,14 +454,14 @@ public:
|
|||
{
|
||||
logger.set_context(slot_cfg.idx);
|
||||
sched_logger.set_context(slot_cfg.idx);
|
||||
if (not pusch_tti.is_valid()) {
|
||||
pusch_tti = srsran::tti_point{slot_cfg.idx};
|
||||
if (not pusch_slot.valid()) {
|
||||
pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx};
|
||||
} else {
|
||||
pusch_tti++;
|
||||
pusch_slot++;
|
||||
}
|
||||
|
||||
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) {
|
||||
pusch.data[0] = rx_harq_proc[pusch.pid].get_tb(pusch.sch.grant.tb[0].tbs).data();
|
||||
|
|
Loading…
Reference in New Issue