The struct tti_point is now used ubiquitously in the scheduler

master
Francisco 4 years ago committed by Andre Puschmann
parent 49bcffcdf8
commit 86ab1864f7

@ -14,6 +14,7 @@
#define SRSLTE_INTERVAL_H #define SRSLTE_INTERVAL_H
#include "adt_utils.h" #include "adt_utils.h"
#include "srslte/srslog/bundled/fmt/format.h"
#include <cassert> #include <cassert>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
@ -76,11 +77,7 @@ public:
bool contains(T point) const { return start_ <= point and point < stop_; } bool contains(T point) const { return start_ <= point and point < stop_; }
std::string to_string() const std::string to_string() const { return fmt::format("[{},{})", start_, stop_); }
{
std::string s = "[" + std::to_string(start_) + "," + std::to_string(stop_) + ")";
return s;
}
private: private:
T start_; T start_;

@ -113,8 +113,20 @@ using tti_interval = srslte::interval<srslte::tti_point>;
} // namespace srslte } // namespace srslte
template <>
struct fmt::formatter<srslte::tti_point> : public fmt::formatter<uint32_t> {
// parse is inherited from formatter<int>.
template <typename FormatContext>
auto format(srslte::tti_point tti, FormatContext& ctx) -> decltype(format_to(ctx.out(), ""))
{
return format_to(ctx.out(), "{}", tti.to_uint());
}
};
namespace srsenb { namespace srsenb {
using tti_point = srslte::tti_point;
inline srslte::tti_point to_tx_dl(srslte::tti_point t) inline srslte::tti_point to_tx_dl(srslte::tti_point t)
{ {
return t + TX_ENB_DELAY; return t + TX_ENB_DELAY;

@ -68,9 +68,9 @@ public:
{ {
return mac.cqi_info(tti, rnti, cc_idx, cqi_value); return mac.cqi_info(tti, rnti, cc_idx, cqi_value);
} }
int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr_db) final int snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t cc_idx, float snr_db) final
{ {
return mac.snr_info(tti, rnti, cc_idx, snr_db); return mac.snr_info(tti_rx, rnti, cc_idx, snr_db);
} }
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override { return mac.ta_info(tti, rnti, ta_us); } int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override { return mac.ta_info(tti, rnti, ta_us); }
int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) final int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) final

@ -38,7 +38,7 @@ public:
// getters // getters
const ra_sched* get_ra_sched() const { return ra_sched_ptr.get(); } const ra_sched* get_ra_sched() const { return ra_sched_ptr.get(); }
//! Get a subframe result for a given tti //! Get a subframe result for a given tti
const sf_sched_result* get_sf_result(uint32_t tti_rx) const; const sf_sched_result* get_sf_result(tti_point tti_rx) const;
private: private:
//! Compute DL scheduler result for given TTI //! Compute DL scheduler result for given TTI
@ -78,9 +78,9 @@ public:
private: private:
struct sched_sib_t { struct sched_sib_t {
bool is_in_window = false; bool is_in_window = false;
uint32_t window_start = 0; tti_point window_start{};
uint32_t n_tx = 0; uint32_t n_tx = 0;
}; };
void update_si_windows(sf_sched* tti_sched); void update_si_windows(sf_sched* tti_sched);
@ -94,8 +94,8 @@ private:
std::array<sched_sib_t, sched_interface::MAX_SIBS> pending_sibs; std::array<sched_sib_t, sched_interface::MAX_SIBS> pending_sibs;
// TTI specific // TTI specific
uint32_t current_tti = 0; tti_point current_tti{};
uint32_t bc_aggr_level = 2; uint32_t bc_aggr_level = 2;
}; };
//! RAR/Msg3 scheduler //! RAR/Msg3 scheduler

@ -35,17 +35,6 @@ struct sched_dci_cce_t {
uint32_t nof_loc[4]; ///< Number of possible CCE locations for each aggregation level index uint32_t nof_loc[4]; ///< Number of possible CCE locations for each aggregation level index
}; };
//! Params relative to a single TTI
struct tti_params_t {
uint32_t tti_rx;
uint32_t tti_tx_dl;
uint32_t tti_tx_ul;
uint32_t sf_idx_tx_dl;
uint32_t sfn_tx_dl;
explicit tti_params_t(uint32_t tti_rx_);
uint32_t tti_rx_ack_dl() const { return tti_tx_ul; }
};
//! structs to bundle together all the sched arguments, and share them with all the sched sub-components //! structs to bundle together all the sched arguments, and share them with all the sched sub-components
class sched_cell_params_t class sched_cell_params_t
{ {

@ -38,14 +38,14 @@ struct alloc_outcome_t {
//! Result of a Subframe sched computation //! Result of a Subframe sched computation
struct cc_sched_result { struct cc_sched_result {
tti_params_t tti_params{10241}; tti_point tti_rx;
sched_interface::dl_sched_res_t dl_sched_result = {}; sched_interface::dl_sched_res_t dl_sched_result = {};
sched_interface::ul_sched_res_t ul_sched_result = {}; sched_interface::ul_sched_res_t ul_sched_result = {};
rbgmask_t dl_mask = {}; ///< Accumulation of all DL RBG allocations rbgmask_t dl_mask = {}; ///< Accumulation of all DL RBG allocations
prbmask_t ul_mask = {}; ///< Accumulation of all UL PRB allocations prbmask_t ul_mask = {}; ///< Accumulation of all UL PRB allocations
pdcch_mask_t pdcch_mask = {}; ///< Accumulation of all CCE allocations pdcch_mask_t pdcch_mask = {}; ///< Accumulation of all CCE allocations
bool is_generated(srslte::tti_point tti_rx) const { return srslte::tti_point{tti_params.tti_rx} == tti_rx; } bool is_generated(tti_point tti_rx_) const { return tti_rx == tti_rx_; }
}; };
struct sf_sched_result { struct sf_sched_result {
@ -91,7 +91,7 @@ public:
using alloc_result_t = std::vector<const alloc_t*>; using alloc_result_t = std::vector<const alloc_t*>;
void init(const sched_cell_params_t& cell_params_); void init(const sched_cell_params_t& cell_params_);
void new_tti(const tti_params_t& tti_params_); void new_tti(tti_point tti_rx_);
bool alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user = nullptr); bool alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user = nullptr);
bool set_cfi(uint32_t cfi); bool set_cfi(uint32_t cfi);
@ -134,14 +134,14 @@ private:
int node_idx, int node_idx,
const alloc_record_t& dci_record, const alloc_record_t& dci_record,
const sched_dci_cce_t& dci_locs, const sched_dci_cce_t& dci_locs,
uint32_t tti_tx_dl); tti_point tti_tx_dl);
// consts // consts
const sched_cell_params_t* cc_cfg = nullptr; const sched_cell_params_t* cc_cfg = nullptr;
srslte::log_ref log_h; srslte::log_ref log_h;
// tti vars // tti vars
const tti_params_t* tti_params = nullptr; tti_point tti_rx;
uint32_t current_cfix = 0; uint32_t current_cfix = 0;
std::vector<alloc_tree_t> alloc_trees; ///< List of PDCCH alloc trees, where index is the cfi index std::vector<alloc_tree_t> alloc_trees; ///< List of PDCCH alloc trees, where index is the cfi index
std::vector<alloc_record_t> dci_record_list; ///< Keeps a record of all the PDCCH allocations done so far std::vector<alloc_record_t> dci_record_list; ///< Keeps a record of all the PDCCH allocations done so far
@ -157,7 +157,7 @@ public:
}; };
void init(const sched_cell_params_t& cell_params_); void init(const sched_cell_params_t& cell_params_);
void new_tti(const tti_params_t& tti_params_); void new_tti(tti_point tti_rx);
dl_ctrl_alloc_t alloc_dl_ctrl(uint32_t aggr_lvl, alloc_type_t alloc_type); dl_ctrl_alloc_t alloc_dl_ctrl(uint32_t aggr_lvl, alloc_type_t alloc_type);
alloc_outcome_t alloc_dl_data(sched_ue* user, const rbgmask_t& user_mask); alloc_outcome_t alloc_dl_data(sched_ue* user, const rbgmask_t& user_mask);
bool reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg); bool reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg);
@ -180,12 +180,11 @@ private:
uint32_t nof_rbgs = 0; uint32_t nof_rbgs = 0;
uint32_t si_n_rbg = 0, rar_n_rbg = 0; uint32_t si_n_rbg = 0, rar_n_rbg = 0;
// tti const
const tti_params_t* tti_params = nullptr;
// derived // derived
pdcch_grid_t pdcch_alloc = {}; pdcch_grid_t pdcch_alloc = {};
// internal state // internal state
tti_point tti_rx;
uint32_t avail_rbg = 0; uint32_t avail_rbg = 0;
rbgmask_t dl_mask = {}; rbgmask_t dl_mask = {};
prbmask_t ul_mask = {}; prbmask_t ul_mask = {};
@ -241,8 +240,8 @@ public:
uint32_t mcs = 0; uint32_t mcs = 0;
}; };
struct pending_rar_t { struct pending_rar_t {
uint16_t ra_rnti = 0; uint16_t ra_rnti = 0;
uint32_t prach_tti = 0; tti_point prach_tti{};
uint32_t nof_grants = 0; uint32_t nof_grants = 0;
sched_interface::dl_sched_rar_info_t msg3_grant[sched_interface::MAX_RAR_LIST] = {}; sched_interface::dl_sched_rar_info_t msg3_grant[sched_interface::MAX_RAR_LIST] = {};
}; };
@ -270,19 +269,18 @@ public:
void generate_sched_results(sched_ue_list& ue_db); void generate_sched_results(sched_ue_list& ue_db);
alloc_outcome_t alloc_dl_user(sched_ue* user, const rbgmask_t& user_mask, uint32_t pid); alloc_outcome_t alloc_dl_user(sched_ue* user, const rbgmask_t& user_mask, uint32_t pid);
uint32_t get_tti_tx_dl() const { return tti_params.tti_tx_dl; } tti_point get_tti_tx_dl() const { return to_tx_dl(tti_rx); }
uint32_t get_nof_ctrl_symbols() const; uint32_t get_nof_ctrl_symbols() const;
const rbgmask_t& get_dl_mask() const { return tti_alloc.get_dl_mask(); } const rbgmask_t& get_dl_mask() const { return tti_alloc.get_dl_mask(); }
alloc_outcome_t alloc_ul_user(sched_ue* user, prb_interval alloc); alloc_outcome_t alloc_ul_user(sched_ue* user, prb_interval alloc);
const prbmask_t& get_ul_mask() const { return tti_alloc.get_ul_mask(); } const prbmask_t& get_ul_mask() const { return tti_alloc.get_ul_mask(); }
uint32_t get_tti_tx_ul() const { return tti_params.tti_tx_ul; } tti_point get_tti_tx_ul() const { return to_tx_ul(tti_rx); }
// getters // getters
uint32_t get_tti_rx() const { return tti_params.tti_rx; } tti_point get_tti_rx() const { return tti_rx; }
const tti_params_t& get_tti_params() const { return tti_params; } bool is_dl_alloc(uint16_t rnti) const;
bool is_dl_alloc(uint16_t rnti) const; bool is_ul_alloc(uint16_t rnti) const;
bool is_ul_alloc(uint16_t rnti) const; uint32_t get_enb_cc_idx() const { return cc_cfg->enb_cc_idx; }
uint32_t get_enb_cc_idx() const { return cc_cfg->enb_cc_idx; }
private: private:
ctrl_code_t alloc_dl_ctrl(uint32_t aggr_lvl, uint32_t tbs_bytes, uint16_t rnti); ctrl_code_t alloc_dl_ctrl(uint32_t aggr_lvl, uint32_t tbs_bytes, uint16_t rnti);
@ -311,7 +309,7 @@ private:
uint32_t last_msg3_prb = 0, max_msg3_prb = 0; uint32_t last_msg3_prb = 0, max_msg3_prb = 0;
// Next TTI state // Next TTI state
tti_params_t tti_params{10241}; tti_point tti_rx;
}; };
} // namespace srsenb } // namespace srsenb

@ -62,17 +62,17 @@ class dl_harq_proc : public harq_proc
{ {
public: public:
dl_harq_proc(); dl_harq_proc();
void new_tx(const rbgmask_t& new_mask, void new_tx(const rbgmask_t& new_mask,
uint32_t tb_idx, uint32_t tb_idx,
uint32_t tti, tti_point tti_tx_dl,
int mcs, int mcs,
int tbs, int tbs,
uint32_t n_cce_, uint32_t n_cce_,
uint32_t max_retx); uint32_t max_retx);
void new_retx(const rbgmask_t& new_mask, uint32_t tb_idx, uint32_t tti_, int* mcs, int* tbs, uint32_t n_cce_); void new_retx(const rbgmask_t& new_mask, uint32_t tb_idx, tti_point tti_tx_dl, int* mcs, int* tbs, uint32_t n_cce_);
int set_ack(uint32_t tb_idx, bool ack); int set_ack(uint32_t tb_idx, bool ack);
rbgmask_t get_rbgmask() const; rbgmask_t get_rbgmask() const;
bool has_pending_retx(uint32_t tb_idx, uint32_t tti) const; bool has_pending_retx(uint32_t tb_idx, tti_point tti_tx_dl) const;
int get_tbs(uint32_t tb_idx) const; int get_tbs(uint32_t tb_idx) const;
uint32_t get_n_cce() const; uint32_t get_n_cce() const;
void reset_pending_data(); void reset_pending_data();
@ -123,13 +123,13 @@ public:
* @param tti_tx_dl assumed to always be equal or ahead in time in comparison to current harqs * @param tti_tx_dl assumed to always be equal or ahead in time in comparison to current harqs
* @return pointer to found dl_harq * @return pointer to found dl_harq
*/ */
dl_harq_proc* get_pending_dl_harq(uint32_t tti_tx_dl); dl_harq_proc* get_pending_dl_harq(tti_point tti_tx_dl);
/** /**
* Get empty DL Harq * Get empty DL Harq
* @param tti_tx_dl only used in case of sync dl sched * @param tti_tx_dl only used in case of sync dl sched
* @return pointer to found dl_harq * @return pointer to found dl_harq
*/ */
dl_harq_proc* get_empty_dl_harq(uint32_t tti_tx_dl); dl_harq_proc* get_empty_dl_harq(tti_point tti_tx_dl);
/** /**
* Set ACK state for DL Harq Proc * Set ACK state for DL Harq Proc
@ -138,10 +138,10 @@ public:
* @param ack true for ACK and false for NACK * @param ack true for ACK and false for NACK
* @return pair with pid and size of TB of the DL harq that was ACKed * @return pair with pid and size of TB of the DL harq that was ACKed
*/ */
std::pair<uint32_t, int> set_ack_info(uint32_t tti_rx, uint32_t tb_idx, bool ack); std::pair<uint32_t, int> set_ack_info(tti_point tti_rx, uint32_t tb_idx, bool ack);
//! Get UL Harq for a given tti_tx_ul //! Get UL Harq for a given tti_tx_ul
ul_harq_proc* get_ul_harq(uint32_t tti_tx_ul); ul_harq_proc* get_ul_harq(tti_point tti_tx_ul);
/** /**
* Set ACK state for UL Harq Proc * Set ACK state for UL Harq Proc
@ -152,7 +152,7 @@ public:
void reset_pending_data(srslte::tti_point tti_rx); void reset_pending_data(srslte::tti_point tti_rx);
private: private:
dl_harq_proc* get_oldest_dl_harq(uint32_t tti_tx_dl); dl_harq_proc* get_oldest_dl_harq(tti_point tti_tx_dl);
srslte::log_ref log_h; srslte::log_ref log_h;

@ -48,21 +48,21 @@ struct cc_sched_ue {
uint32_t get_required_prb_ul(uint32_t req_bytes); uint32_t get_required_prb_ul(uint32_t req_bytes);
const sched_cell_params_t* get_cell_cfg() const { return cell_params; } const sched_cell_params_t* get_cell_cfg() const { return cell_params; }
uint32_t get_ue_cc_idx() const { return ue_cc_idx; } uint32_t get_ue_cc_idx() const { return ue_cc_idx; }
void set_dl_cqi(uint32_t tti_tx_dl, uint32_t dl_cqi); void set_dl_cqi(tti_point tti_rx, uint32_t dl_cqi);
int cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint32_t* mcs); int cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint32_t* mcs);
cc_st cc_state() const { return cc_state_; } cc_st cc_state() const { return cc_state_; }
harq_entity harq_ent; harq_entity harq_ent;
uint32_t dl_ri = 0; uint32_t dl_ri = 0;
uint32_t dl_ri_tti = 0; tti_point dl_ri_tti_rx{};
uint32_t dl_pmi = 0; uint32_t dl_pmi = 0;
uint32_t dl_pmi_tti = 0; tti_point dl_pmi_tti_rx{};
uint32_t dl_cqi = 1; uint32_t dl_cqi = 1;
uint32_t dl_cqi_tti = 0; tti_point dl_cqi_tti_rx{0};
uint32_t ul_cqi = 1; uint32_t ul_cqi = 1;
uint32_t ul_cqi_tti = 0; tti_point ul_cqi_tti_rx{};
bool dl_cqi_rx = false; bool dl_cqi_rx = false;
uint32_t max_mcs_dl = 28, max_mcs_ul = 28; uint32_t max_mcs_dl = 28, max_mcs_ul = 28;
uint32_t max_aggr_level = 3; uint32_t max_aggr_level = 3;
@ -92,21 +92,25 @@ const char* to_string(sched_interface::ue_bearer_cfg_t::direction_t dir);
*/ */
class sched_ue class sched_ue
{ {
using ue_cfg_t = sched_interface::ue_cfg_t;
using bearer_cfg_t = sched_interface::ue_bearer_cfg_t;
public: public:
sched_ue(); sched_ue();
void reset(); void reset();
void init(uint16_t rnti, const std::vector<sched_cell_params_t>& cell_list_params_); void init(uint16_t rnti, const std::vector<sched_cell_params_t>& cell_list_params_);
void new_tti(srslte::tti_point new_tti); void new_subframe(tti_point tti_rx, uint32_t enb_cc_idx);
/************************************************************* /*************************************************************
* *
* FAPI-like Interface * FAPI-like Interface
* *
************************************************************/ ************************************************************/
void phy_config_enabled(uint32_t tti, bool enabled);
void set_cfg(const sched_interface::ue_cfg_t& cfg);
void set_bearer_cfg(uint32_t lc_id, srsenb::sched_interface::ue_bearer_cfg_t* cfg); void phy_config_enabled(tti_point tti_rx, bool enabled);
void set_cfg(const ue_cfg_t& cfg);
void set_bearer_cfg(uint32_t lc_id, const bearer_cfg_t& cfg);
void rem_bearer(uint32_t lc_id); void rem_bearer(uint32_t lc_id);
void dl_buffer_state(uint8_t lc_id, uint32_t tx_queue, uint32_t retx_queue); void dl_buffer_state(uint8_t lc_id, uint32_t tx_queue, uint32_t retx_queue);
@ -114,12 +118,12 @@ public:
void ul_phr(int phr); void ul_phr(int phr);
void mac_buffer_state(uint32_t ce_code, uint32_t nof_cmds); void mac_buffer_state(uint32_t ce_code, uint32_t nof_cmds);
void set_ul_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code); void set_ul_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code);
void set_dl_ri(uint32_t tti, uint32_t enb_cc_idx, uint32_t ri); void set_dl_ri(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t ri);
void set_dl_pmi(uint32_t tti, uint32_t enb_cc_idx, uint32_t ri); void set_dl_pmi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t ri);
void set_dl_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi); void set_dl_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi);
int set_ack_info(uint32_t tti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack); int set_ack_info(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack);
void set_ul_crc(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool crc_res); void set_ul_crc(tti_point tti_rx, uint32_t enb_cc_idx, bool crc_res);
/******************************************************* /*******************************************************
* Custom functions * Custom functions
@ -128,12 +132,12 @@ public:
void tpc_inc(); void tpc_inc();
void tpc_dec(); void tpc_dec();
const dl_harq_proc& get_dl_harq(uint32_t idx, uint32_t cc_idx) const; const dl_harq_proc& get_dl_harq(uint32_t idx, uint32_t cc_idx) const;
uint16_t get_rnti() const { return rnti; } uint16_t get_rnti() const { return rnti; }
std::pair<bool, uint32_t> get_active_cell_index(uint32_t enb_cc_idx) const; std::pair<bool, uint32_t> get_active_cell_index(uint32_t enb_cc_idx) const;
const sched_interface::ue_cfg_t& get_ue_cfg() const { return cfg; } const ue_cfg_t& get_ue_cfg() const { return cfg; }
uint32_t get_aggr_level(uint32_t ue_cc_idx, uint32_t nof_bits); uint32_t get_aggr_level(uint32_t ue_cc_idx, uint32_t nof_bits);
void ul_buffer_add(uint8_t lcid, uint32_t bytes); void ul_buffer_add(uint8_t lcid, uint32_t bytes);
/******************************************************* /*******************************************************
* Functions used by scheduler metric objects * Functions used by scheduler metric objects
@ -146,21 +150,21 @@ public:
uint32_t get_pending_dl_rlc_data() const; uint32_t get_pending_dl_rlc_data() const;
uint32_t get_expected_dl_bitrate(uint32_t ue_cc_idx) const; uint32_t get_expected_dl_bitrate(uint32_t ue_cc_idx) const;
uint32_t get_pending_ul_data_total(uint32_t tti, int this_ue_cc_idx); uint32_t get_pending_ul_data_total(tti_point tti_tx_ul, int this_ue_cc_idx);
uint32_t get_pending_ul_new_data(uint32_t tti, int this_ue_cc_idx); uint32_t get_pending_ul_new_data(tti_point tti_tx_ul, int this_ue_cc_idx);
uint32_t get_pending_ul_old_data(); uint32_t get_pending_ul_old_data();
uint32_t get_pending_ul_old_data(uint32_t cc_idx); uint32_t get_pending_ul_old_data(uint32_t cc_idx);
uint32_t get_expected_ul_bitrate(uint32_t ue_cc_idx) const; uint32_t get_expected_ul_bitrate(uint32_t ue_cc_idx) const;
dl_harq_proc* get_pending_dl_harq(uint32_t tti_tx_dl, uint32_t cc_idx); dl_harq_proc* get_pending_dl_harq(tti_point tti_tx_dl, uint32_t cc_idx);
dl_harq_proc* get_empty_dl_harq(uint32_t tti_tx_dl, uint32_t cc_idx); dl_harq_proc* get_empty_dl_harq(tti_point tti_tx_dl, uint32_t cc_idx);
ul_harq_proc* get_ul_harq(uint32_t tti, uint32_t ue_cc_idx); ul_harq_proc* get_ul_harq(tti_point tti_tx_ul, uint32_t ue_cc_idx);
/******************************************************* /*******************************************************
* Functions used by the scheduler carrier object * Functions used by the scheduler carrier object
*******************************************************/ *******************************************************/
void finish_tti(const tti_params_t& tti_params, uint32_t enb_cc_idx); void finish_tti(tti_point tti_rx, uint32_t enb_cc_idx);
/******************************************************* /*******************************************************
* Functions used by the scheduler object * Functions used by the scheduler object
@ -171,12 +175,12 @@ public:
int generate_dl_dci_format(uint32_t pid, int generate_dl_dci_format(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti, tti_point tti_tx_dl,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask); const rbgmask_t& user_mask);
int generate_format0(sched_interface::ul_sched_data_t* data, int generate_format0(sched_interface::ul_sched_data_t* data,
uint32_t tti, tti_point tti_tx_ul,
uint32_t cc_idx, uint32_t cc_idx,
prb_interval alloc, prb_interval alloc,
bool needs_pdcch, bool needs_pdcch,
@ -192,12 +196,11 @@ public:
std::bitset<SRSLTE_MAX_CARRIERS> scell_activation_mask() const; std::bitset<SRSLTE_MAX_CARRIERS> scell_activation_mask() const;
int enb_to_ue_cc_idx(uint32_t enb_cc_idx) const; int enb_to_ue_cc_idx(uint32_t enb_cc_idx) const;
bool needs_cqi(uint32_t tti, uint32_t cc_idx, bool will_send = false);
uint32_t get_max_retx(); uint32_t get_max_retx();
bool pucch_sr_collision(uint32_t tti, uint32_t n_cce); bool pucch_sr_collision(tti_point tti_tx_dl, uint32_t n_cce);
bool pdsch_enabled(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const; bool pdsch_enabled(tti_point tti_rx, uint32_t enb_cc_idx) const;
bool pusch_enabled(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool needs_pdcch) const; bool pusch_enabled(tti_point tti_rx, uint32_t enb_cc_idx, bool needs_pdcch) const;
private: private:
void check_ue_cfg_correctness() const; void check_ue_cfg_correctness() const;
@ -206,40 +209,40 @@ private:
std::pair<int, int> allocate_new_dl_mac_pdu(sched_interface::dl_sched_data_t* data, std::pair<int, int> allocate_new_dl_mac_pdu(sched_interface::dl_sched_data_t* data,
dl_harq_proc* h, dl_harq_proc* h,
const rbgmask_t& user_mask, const rbgmask_t& user_mask,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
uint32_t tb); uint32_t tb);
std::pair<int, int> compute_mcs_and_tbs(uint32_t ue_cc_idx, std::pair<int, int> compute_mcs_and_tbs(uint32_t ue_cc_idx,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t nof_alloc_prbs, uint32_t nof_alloc_prbs,
uint32_t cfi, uint32_t cfi,
const srslte_dci_dl_t& dci); const srslte_dci_dl_t& dci);
bool needs_cqi_unlocked(uint32_t tti, uint32_t cc_idx, bool will_send = false); bool needs_cqi(uint32_t tti, uint32_t cc_idx, bool will_send = false);
int generate_format1(uint32_t pid, int generate_format1(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti, tti_point tti_tx_dl,
uint32_t cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask); const rbgmask_t& user_mask);
int generate_format2a(uint32_t pid, int generate_format2a(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti, tti_point tti_tx_dl,
uint32_t cc_idx, uint32_t cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask); const rbgmask_t& user_mask);
int generate_format2(uint32_t pid, int generate_format2(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti, tti_point tti_tx_dl,
uint32_t cc_idx, uint32_t cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask); const rbgmask_t& user_mask);
/* Args */ /* Args */
sched_interface::ue_cfg_t cfg = {}; ue_cfg_t cfg = {};
srslte_cell_t cell = {}; srslte_cell_t cell = {};
srslte::log_ref log_h; srslte::log_ref log_h;
const std::vector<sched_cell_params_t>* cell_params_list = nullptr; const std::vector<sched_cell_params_t>* cell_params_list = nullptr;
@ -260,8 +263,9 @@ private:
bool phy_config_dedicated_enabled = false; bool phy_config_dedicated_enabled = false;
srslte::tti_point current_tti; tti_point current_tti;
std::vector<cc_sched_ue> carriers; ///< map of UE CellIndex to carrier configuration std::vector<cc_sched_ue> carriers; ///< map of UE CellIndex to carrier configuration
std::vector<int> enb_ue_cc_idx_map;
}; };
using sched_ue_list = std::map<uint16_t, sched_ue>; using sched_ue_list = std::map<uint16_t, sched_ue>;

@ -284,16 +284,16 @@ void mac::get_metrics(std::vector<mac_metrics_t>& metrics)
* *
*******************************************************/ *******************************************************/
int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) int mac::ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack)
{ {
log_h->step(tti); log_h->step(tti_rx);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (not check_ue_exists(rnti)) { if (not check_ue_exists(rnti)) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
uint32_t nof_bytes = scheduler.dl_ack_info(tti, rnti, enb_cc_idx, tb_idx, ack); uint32_t nof_bytes = scheduler.dl_ack_info(tti_rx, rnti, enb_cc_idx, tb_idx, ack);
ue_db[rnti]->metrics_tx(ack, nof_bytes); ue_db[rnti]->metrics_tx(ack, nof_bytes);
if (ack) { if (ack) {
@ -382,9 +382,9 @@ int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int mac::snr_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, float snr) int mac::snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, float snr)
{ {
log_h->step(tti); log_h->step(tti_rx);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (not check_ue_exists(rnti)) { if (not check_ue_exists(rnti)) {
@ -392,7 +392,7 @@ int mac::snr_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, float snr)
} }
uint32_t cqi = srslte_cqi_from_snr(snr); uint32_t cqi = srslte_cqi_from_snr(snr);
return scheduler.ul_cqi_info(tti, rnti, enb_cc_idx, cqi, 0); return scheduler.ul_cqi_info(tti_rx, rnti, enb_cc_idx, cqi, 0);
} }
int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us) int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us)

@ -231,12 +231,12 @@ void sched::phy_config_enabled(uint16_t rnti, bool enabled)
{ {
// TODO: Check if correct use of last_tti // TODO: Check if correct use of last_tti
ue_db_access( ue_db_access(
rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(last_tti.to_uint(), enabled); }, __PRETTY_FUNCTION__); rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(last_tti, enabled); }, __PRETTY_FUNCTION__);
} }
int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg_) int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg_)
{ {
return ue_db_access(rnti, [lc_id, cfg_](sched_ue& ue) { ue.set_bearer_cfg(lc_id, cfg_); }); return ue_db_access(rnti, [lc_id, cfg_](sched_ue& ue) { ue.set_bearer_cfg(lc_id, *cfg_); });
} }
int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id)
@ -258,7 +258,7 @@ uint32_t sched::get_ul_buffer(uint16_t rnti)
uint32_t ret = SRSLTE_ERROR; uint32_t ret = SRSLTE_ERROR;
ue_db_access( ue_db_access(
rnti, rnti,
[this, &ret](sched_ue& ue) { ret = ue.get_pending_ul_new_data(last_tti.to_uint(), -1); }, [this, &ret](sched_ue& ue) { ret = ue.get_pending_ul_new_data(to_tx_ul(last_tti), -1); },
__PRETTY_FUNCTION__); __PRETTY_FUNCTION__);
return ret; return ret;
} }
@ -273,33 +273,38 @@ int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code, uint32_t nof_cmd
return ue_db_access(rnti, [ce_code, nof_cmds](sched_ue& ue) { ue.mac_buffer_state(ce_code, nof_cmds); }); return ue_db_access(rnti, [ce_code, nof_cmds](sched_ue& ue) { ue.mac_buffer_state(ce_code, nof_cmds); });
} }
int sched::dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) int sched::dl_ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack)
{ {
int ret = -1; int ret = -1;
ue_db_access( ue_db_access(
rnti, [&](sched_ue& ue) { ret = ue.set_ack_info(tti, enb_cc_idx, tb_idx, ack); }, __PRETTY_FUNCTION__); rnti,
[&](sched_ue& ue) { ret = ue.set_ack_info(tti_point{tti_rx}, enb_cc_idx, tb_idx, ack); },
__PRETTY_FUNCTION__);
return ret; return ret;
} }
int sched::ul_crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, bool crc) int sched::ul_crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, bool crc)
{ {
return ue_db_access( return ue_db_access(rnti,
rnti, [tti_rx, enb_cc_idx, crc](sched_ue& ue) { ue.set_ul_crc(srslte::tti_point{tti_rx}, enb_cc_idx, crc); }); [tti_rx, enb_cc_idx, crc](sched_ue& ue) { ue.set_ul_crc(tti_point{tti_rx}, enb_cc_idx, crc); });
} }
int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value)
{ {
return ue_db_access(rnti, [tti, enb_cc_idx, ri_value](sched_ue& ue) { ue.set_dl_ri(tti, enb_cc_idx, ri_value); }); return ue_db_access(
rnti, [tti, enb_cc_idx, ri_value](sched_ue& ue) { ue.set_dl_ri(tti_point{tti}, enb_cc_idx, ri_value); });
} }
int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value)
{ {
return ue_db_access(rnti, [tti, enb_cc_idx, pmi_value](sched_ue& ue) { ue.set_dl_pmi(tti, enb_cc_idx, pmi_value); }); return ue_db_access(
rnti, [tti, enb_cc_idx, pmi_value](sched_ue& ue) { ue.set_dl_pmi(tti_point{tti}, enb_cc_idx, pmi_value); });
} }
int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value)
{ {
return ue_db_access(rnti, [tti, enb_cc_idx, cqi_value](sched_ue& ue) { ue.set_dl_cqi(tti, enb_cc_idx, cqi_value); }); return ue_db_access(
rnti, [tti, enb_cc_idx, cqi_value](sched_ue& ue) { ue.set_dl_cqi(tti_point{tti}, enb_cc_idx, cqi_value); });
} }
int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info) int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info)
@ -308,9 +313,9 @@ int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info)
return carrier_schedulers[enb_cc_idx]->dl_rach_info(rar_info); return carrier_schedulers[enb_cc_idx]->dl_rach_info(rar_info);
} }
int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) int sched::ul_cqi_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code)
{ {
return ue_db_access(rnti, [&](sched_ue& ue) { ue.set_ul_cqi(tti, enb_cc_idx, cqi, ul_ch_code); }); return ue_db_access(rnti, [&](sched_ue& ue) { ue.set_ul_cqi(tti_point{tti_rx}, enb_cc_idx, cqi, ul_ch_code); });
} }
int sched::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) int sched::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr)
@ -444,11 +449,6 @@ void sched::new_tti(tti_point tti_rx)
// Generate sched results for all CCs, if not yet generated // Generate sched results for all CCs, if not yet generated
for (size_t cc_idx = 0; cc_idx < carrier_schedulers.size(); ++cc_idx) { for (size_t cc_idx = 0; cc_idx < carrier_schedulers.size(); ++cc_idx) {
if (not is_generated(tti_rx, cc_idx)) { if (not is_generated(tti_rx, cc_idx)) {
// Setup tti-specific vars of the UE
for (auto& user : ue_db) {
user.second.new_tti(tti_rx);
}
// Generate carrier scheduling result // Generate carrier scheduling result
carrier_schedulers[cc_idx]->generate_tti_result(tti_rx); carrier_schedulers[cc_idx]->generate_tti_result(tti_rx);
} }

@ -44,9 +44,9 @@ void bc_sched::dl_sched(sf_sched* tti_sched)
void bc_sched::update_si_windows(sf_sched* tti_sched) void bc_sched::update_si_windows(sf_sched* tti_sched)
{ {
uint32_t tti_tx_dl = tti_sched->get_tti_tx_dl(); tti_point tti_tx_dl = tti_sched->get_tti_tx_dl();
uint32_t current_sf_idx = tti_sched->get_tti_params().sf_idx_tx_dl; uint32_t current_sf_idx = tti_sched->get_tti_tx_dl().sf_idx();
uint32_t current_sfn = tti_sched->get_tti_params().sfn_tx_dl; uint32_t current_sfn = tti_sched->get_tti_tx_dl().sfn();
for (uint32_t i = 0; i < pending_sibs.size(); ++i) { for (uint32_t i = 0; i < pending_sibs.size(); ++i) {
// There is SIB data // There is SIB data
@ -68,7 +68,7 @@ void bc_sched::update_si_windows(sf_sched* tti_sched)
} }
} else { } else {
if (i > 0) { if (i > 0) {
if (srslte_tti_interval(tti_tx_dl, pending_sibs[i].window_start) > cc_cfg->cfg.si_window_ms) { if (pending_sibs[i].window_start + cc_cfg->cfg.si_window_ms < tti_tx_dl) {
// the si window has passed // the si window has passed
pending_sibs[i] = {}; pending_sibs[i] = {};
} }
@ -84,8 +84,8 @@ void bc_sched::update_si_windows(sf_sched* tti_sched)
void bc_sched::alloc_sibs(sf_sched* tti_sched) void bc_sched::alloc_sibs(sf_sched* tti_sched)
{ {
uint32_t current_sf_idx = tti_sched->get_tti_params().sf_idx_tx_dl; uint32_t current_sf_idx = tti_sched->get_tti_tx_dl().sf_idx();
uint32_t current_sfn = tti_sched->get_tti_params().sfn_tx_dl; uint32_t current_sfn = tti_sched->get_tti_tx_dl().sfn();
for (uint32_t i = 0; i < pending_sibs.size(); i++) { for (uint32_t i = 0; i < pending_sibs.size(); i++) {
if (cc_cfg->cfg.sibs[i].len > 0 and pending_sibs[i].is_in_window and pending_sibs[i].n_tx < 4) { if (cc_cfg->cfg.sibs[i].len > 0 and pending_sibs[i].is_in_window and pending_sibs[i].n_tx < 4) {
@ -112,7 +112,7 @@ void bc_sched::alloc_paging(sf_sched* tti_sched)
/* Allocate DCIs and RBGs for paging */ /* Allocate DCIs and RBGs for paging */
if (rrc != nullptr) { if (rrc != nullptr) {
uint32_t paging_payload = 0; uint32_t paging_payload = 0;
if (rrc->is_paging_opportunity(current_tti, &paging_payload) and paging_payload > 0) { if (rrc->is_paging_opportunity(current_tti.to_uint(), &paging_payload) and paging_payload > 0) {
tti_sched->alloc_paging(bc_aggr_level, paging_payload); tti_sched->alloc_paging(bc_aggr_level, paging_payload);
} }
} }
@ -138,25 +138,24 @@ ra_sched::ra_sched(const sched_cell_params_t& cfg_, std::map<uint16_t, sched_ue>
// discard it. // discard it.
void ra_sched::dl_sched(sf_sched* tti_sched) void ra_sched::dl_sched(sf_sched* tti_sched)
{ {
uint32_t tti_tx_dl = tti_sched->get_tti_tx_dl(); tti_point tti_tx_dl = tti_sched->get_tti_tx_dl();
rar_aggr_level = 2; rar_aggr_level = 2;
while (not pending_rars.empty()) { while (not pending_rars.empty()) {
sf_sched::pending_rar_t& rar = pending_rars.front(); sf_sched::pending_rar_t& rar = pending_rars.front();
uint32_t prach_tti = rar.prach_tti;
// Discard all RARs out of the window. The first one inside the window is scheduled, if we can't we exit // Discard all RARs out of the window. The first one inside the window is scheduled, if we can't we exit
if (not sched_utils::is_in_tti_interval( srslte::tti_interval rar_window{rar.prach_tti + PRACH_RAR_OFFSET,
tti_tx_dl, prach_tti + PRACH_RAR_OFFSET, prach_tti + PRACH_RAR_OFFSET + cc_cfg->cfg.prach_rar_window)) { rar.prach_tti + PRACH_RAR_OFFSET + cc_cfg->cfg.prach_rar_window};
if (tti_tx_dl >= prach_tti + PRACH_RAR_OFFSET + cc_cfg->cfg.prach_rar_window) { if (not rar_window.contains(tti_tx_dl)) {
if (tti_tx_dl >= rar_window.stop()) {
char error_msg[128]; char error_msg[128];
int len = snprintf(error_msg, int len = snprintf(error_msg,
sizeof(error_msg), sizeof(error_msg),
"SCHED: Could not transmit RAR within the window (RA=%d, Window=[%d..%d], RAR=%d)\n", "SCHED: Could not transmit RAR within the window (RA=%d, Window=%s, RAR=%d)\n",
prach_tti, rar.prach_tti.to_uint(),
prach_tti + PRACH_RAR_OFFSET, rar_window.to_string().c_str(),
prach_tti + PRACH_RAR_OFFSET + cc_cfg->cfg.prach_rar_window, tti_tx_dl.to_uint());
tti_tx_dl);
error_msg[len] = '\0'; error_msg[len] = '\0';
srslte::console("%s", error_msg); srslte::console("%s", error_msg);
log_h->error("%s", error_msg); log_h->error("%s", error_msg);
@ -206,7 +205,7 @@ int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info)
// find pending rar with same RA-RNTI // find pending rar with same RA-RNTI
for (sf_sched::pending_rar_t& r : pending_rars) { for (sf_sched::pending_rar_t& r : pending_rars) {
if (r.prach_tti == rar_info.prach_tti and ra_rnti == r.ra_rnti) { if (r.prach_tti.to_uint() == rar_info.prach_tti and ra_rnti == r.ra_rnti) {
if (r.nof_grants >= sched_interface::MAX_RAR_LIST) { if (r.nof_grants >= sched_interface::MAX_RAR_LIST) {
log_h->warning("PRACH ignored, as the the maximum number of RAR grants per tti has been reached\n"); log_h->warning("PRACH ignored, as the the maximum number of RAR grants per tti has been reached\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -220,7 +219,7 @@ int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info)
// create new RAR // create new RAR
sf_sched::pending_rar_t p; sf_sched::pending_rar_t p;
p.ra_rnti = ra_rnti; p.ra_rnti = ra_rnti;
p.prach_tti = rar_info.prach_tti; p.prach_tti = tti_point{rar_info.prach_tti};
p.nof_grants = 1; p.nof_grants = 1;
p.msg3_grant[0] = rar_info; p.msg3_grant[0] = rar_info;
pending_rars.push_back(p); pending_rars.push_back(p);
@ -240,9 +239,11 @@ void ra_sched::ul_sched(sf_sched* sf_dl_sched, sf_sched* sf_msg3_sched)
uint16_t crnti = msg3grant.data.temp_crnti; uint16_t crnti = msg3grant.data.temp_crnti;
auto user_it = ue_db->find(crnti); auto user_it = ue_db->find(crnti);
if (user_it != ue_db->end() and sf_msg3_sched->alloc_msg3(&user_it->second, msg3grant)) { if (user_it != ue_db->end() and sf_msg3_sched->alloc_msg3(&user_it->second, msg3grant)) {
log_h->debug("SCHED: Queueing Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul()); log_h->debug("SCHED: Queueing Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul().to_uint());
} else { } else {
log_h->error("SCHED: Failed to allocate Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul()); log_h->error("SCHED: Failed to allocate Msg3 for rnti=0x%x at tti=%d\n",
crnti,
sf_msg3_sched->get_tti_tx_ul().to_uint());
} }
} }
} }
@ -313,7 +314,12 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r
sf_sched_result* sf_result = prev_sched_results->get_sf(tti_rx); sf_sched_result* sf_result = prev_sched_results->get_sf(tti_rx);
cc_sched_result* cc_result = sf_result->new_cc(enb_cc_idx); cc_sched_result* cc_result = sf_result->new_cc(enb_cc_idx);
bool dl_active = sf_dl_mask[tti_sched->get_tti_tx_dl() % sf_dl_mask.size()] == 0; bool dl_active = sf_dl_mask[tti_sched->get_tti_tx_dl().to_uint() % sf_dl_mask.size()] == 0;
/* Refresh UE internal buffers and subframe vars */
for (auto& user : *ue_db) {
user.second.new_subframe(tti_rx, enb_cc_idx);
}
/* Schedule PHICH */ /* Schedule PHICH */
for (auto& ue_pair : *ue_db) { for (auto& ue_pair : *ue_db) {
@ -350,7 +356,7 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r
/* Reset ue harq pending ack state, clean-up blocked pids */ /* Reset ue harq pending ack state, clean-up blocked pids */
for (auto& user : *ue_db) { for (auto& user : *ue_db) {
user.second.finish_tti(cc_result->tti_params, enb_cc_idx); user.second.finish_tti(tti_rx, enb_cc_idx);
} }
log_dl_cc_results(log_h, enb_cc_idx, cc_result->dl_sched_result); log_dl_cc_results(log_h, enb_cc_idx, cc_result->dl_sched_result);
@ -360,14 +366,14 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r
void sched::carrier_sched::alloc_dl_users(sf_sched* tti_result) void sched::carrier_sched::alloc_dl_users(sf_sched* tti_result)
{ {
if (sf_dl_mask[tti_result->get_tti_tx_dl() % sf_dl_mask.size()] != 0) { if (sf_dl_mask[tti_result->get_tti_tx_dl().to_uint() % sf_dl_mask.size()] != 0) {
return; return;
} }
// NOTE: In case of 6 PRBs, do not transmit if there is going to be a PRACH in the UL to avoid collisions // NOTE: In case of 6 PRBs, do not transmit if there is going to be a PRACH in the UL to avoid collisions
if (cc_cfg->nof_prb() == 6) { if (cc_cfg->nof_prb() == 6) {
uint32_t tti_rx_ack = tti_result->get_tti_params().tti_rx_ack_dl(); tti_point tti_rx_ack = to_tx_dl_ack(tti_result->get_tti_rx());
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_rx_ack, -1)) { if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_rx_ack.to_uint(), -1)) {
tti_result->reserve_dl_rbgs(0, cc_cfg->nof_rbgs); tti_result->reserve_dl_rbgs(0, cc_cfg->nof_rbgs);
} }
} }
@ -387,11 +393,11 @@ int sched::carrier_sched::alloc_ul_users(sf_sched* tti_sched)
sf_sched* sched::carrier_sched::get_sf_sched(tti_point tti_rx) sf_sched* sched::carrier_sched::get_sf_sched(tti_point tti_rx)
{ {
sf_sched* ret = &sf_scheds[tti_rx.to_uint() % sf_scheds.size()]; sf_sched* ret = &sf_scheds[tti_rx.to_uint() % sf_scheds.size()];
if (ret->get_tti_rx() != tti_rx.to_uint()) { if (ret->get_tti_rx() != tti_rx) {
sf_sched_result* sf_res = prev_sched_results->get_sf(srslte::tti_point{tti_rx}); sf_sched_result* sf_res = prev_sched_results->get_sf(tti_rx);
if (sf_res == nullptr) { if (sf_res == nullptr) {
// Reset if tti_rx has not been yet set in the sched results // Reset if tti_rx has not been yet set in the sched results
sf_res = prev_sched_results->new_tti(srslte::tti_point{tti_rx}); sf_res = prev_sched_results->new_tti(tti_rx);
} }
// start new TTI for the given CC. // start new TTI for the given CC.
ret->new_tti(tti_rx, sf_res); ret->new_tti(tti_rx, sf_res);
@ -399,9 +405,9 @@ sf_sched* sched::carrier_sched::get_sf_sched(tti_point tti_rx)
return ret; return ret;
} }
const sf_sched_result* sched::carrier_sched::get_sf_result(uint32_t tti_rx) const const sf_sched_result* sched::carrier_sched::get_sf_result(tti_point tti_rx) const
{ {
return prev_sched_results->get_sf(srslte::tti_point{tti_rx}); return prev_sched_results->get_sf(tti_rx);
} }
int sched::carrier_sched::dl_rach_info(dl_sched_rar_info_t rar_info) int sched::carrier_sched::dl_rach_info(dl_sched_rar_info_t rar_info)

@ -41,14 +41,6 @@ const char* alloc_outcome_t::to_string() const
return "unknown error"; return "unknown error";
} }
tti_params_t::tti_params_t(uint32_t tti_rx_) :
tti_rx(tti_rx_),
sf_idx_tx_dl(TTI_ADD(tti_rx, FDD_HARQ_DELAY_UL_MS) % 10),
tti_tx_dl(TTI_ADD(tti_rx, FDD_HARQ_DELAY_UL_MS)),
tti_tx_ul(TTI_ADD(tti_rx, (FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS))),
sfn_tx_dl(TTI_ADD(tti_rx, FDD_HARQ_DELAY_UL_MS) / 10)
{}
cc_sched_result* sf_sched_result::new_cc(uint32_t enb_cc_idx) cc_sched_result* sf_sched_result::new_cc(uint32_t enb_cc_idx)
{ {
if (enb_cc_idx >= enb_cc_list.size()) { if (enb_cc_idx >= enb_cc_list.size()) {
@ -135,9 +127,9 @@ void pdcch_grid_t::init(const sched_cell_params_t& cell_params_)
} }
} }
void pdcch_grid_t::new_tti(const tti_params_t& tti_params_) void pdcch_grid_t::new_tti(tti_point tti_rx_)
{ {
tti_params = &tti_params_; tti_rx = tti_rx_;
// Reset back all CFIs // Reset back all CFIs
for (auto& t : alloc_trees) { for (auto& t : alloc_trees) {
@ -155,11 +147,11 @@ const sched_dci_cce_t* pdcch_grid_t::get_cce_loc_table(alloc_type_t alloc_type,
case alloc_type_t::DL_PCCH: case alloc_type_t::DL_PCCH:
return &cc_cfg->common_locations[cfix]; return &cc_cfg->common_locations[cfix];
case alloc_type_t::DL_RAR: case alloc_type_t::DL_RAR:
return &cc_cfg->rar_locations[cfix][tti_params->sf_idx_tx_dl]; return &cc_cfg->rar_locations[cfix][to_tx_dl(tti_rx).sf_idx()];
case alloc_type_t::DL_DATA: case alloc_type_t::DL_DATA:
return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, tti_params->sf_idx_tx_dl); return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx());
case alloc_type_t::UL_DATA: case alloc_type_t::UL_DATA:
return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, tti_params->sf_idx_tx_dl); return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx());
default: default:
break; break;
} }
@ -204,10 +196,10 @@ bool pdcch_grid_t::alloc_dci_record(const alloc_record_t& record, uint32_t cfix)
if (tree.prev_end > 0) { if (tree.prev_end > 0) {
for (size_t j = tree.prev_start; j < tree.prev_end; ++j) { for (size_t j = tree.prev_start; j < tree.prev_end; ++j) {
ret |= add_tree_node_leaves(tree, (int)j, record, *dci_locs, tti_params->tti_tx_dl); ret |= add_tree_node_leaves(tree, (int)j, record, *dci_locs, to_tx_dl(tti_rx));
} }
} else { } else {
ret = add_tree_node_leaves(tree, -1, record, *dci_locs, tti_params->tti_tx_dl); ret = add_tree_node_leaves(tree, -1, record, *dci_locs, to_tx_dl(tti_rx));
} }
if (ret) { if (ret) {
@ -223,7 +215,7 @@ bool pdcch_grid_t::add_tree_node_leaves(alloc_tree_t& tree,
int parent_node_idx, int parent_node_idx,
const alloc_record_t& dci_record, const alloc_record_t& dci_record,
const sched_dci_cce_t& dci_locs, const sched_dci_cce_t& dci_locs,
uint32_t tti_tx_dl) tti_point tti_tx_dl)
{ {
bool ret = false; bool ret = false;
@ -397,16 +389,16 @@ void sf_grid_t::init(const sched_cell_params_t& cell_params_)
pdcch_alloc.init(*cc_cfg); pdcch_alloc.init(*cc_cfg);
} }
void sf_grid_t::new_tti(const tti_params_t& tti_params_) void sf_grid_t::new_tti(tti_point tti_rx_)
{ {
tti_params = &tti_params_; tti_rx = tti_rx_;
dl_mask.reset(); dl_mask.reset();
ul_mask.reset(); ul_mask.reset();
avail_rbg = nof_rbgs; avail_rbg = nof_rbgs;
// internal state // internal state
pdcch_alloc.new_tti(*tti_params); pdcch_alloc.new_tti(tti_rx);
} }
//! Allocates CCEs and RBs for the given mask and allocation type (e.g. data, BC, RAR, paging) //! Allocates CCEs and RBs for the given mask and allocation type (e.g. data, BC, RAR, paging)
@ -581,26 +573,27 @@ void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_)
data_allocs.clear(); data_allocs.clear();
ul_data_allocs.clear(); ul_data_allocs.clear();
tti_params = tti_params_t{tti_rx_.to_uint()}; tti_rx = tti_rx_;
tti_alloc.new_tti(tti_params); tti_alloc.new_tti(tti_rx_);
cc_results = cc_results_; cc_results = cc_results_;
// Reserve PRBs for PUCCH // Reserve PRBs for PUCCH
reserve_ul_prbs(pucch_mask, true); reserve_ul_prbs(pucch_mask, true);
// Reserve PRBs for PRACH // Reserve PRBs for PRACH
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_params.tti_tx_ul, -1)) { if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, to_tx_ul(tti_rx).to_uint(), -1)) {
prbmask_t prach_mask{cc_cfg->nof_prb()}; prbmask_t prach_mask{cc_cfg->nof_prb()};
prach_mask.fill(cc_cfg->cfg.prach_freq_offset, cc_cfg->cfg.prach_freq_offset + 6); prach_mask.fill(cc_cfg->cfg.prach_freq_offset, cc_cfg->cfg.prach_freq_offset + 6);
reserve_ul_prbs(prach_mask, cc_cfg->nof_prb() != 6); reserve_ul_prbs(prach_mask, cc_cfg->nof_prb() != 6);
log_h->debug( log_h->debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s\n",
"SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s\n", tti_params.tti_tx_ul, prach_mask.to_hex().c_str()); to_tx_ul(tti_rx).to_uint(),
prach_mask.to_hex().c_str());
} }
// setup first prb to be used for msg3 alloc. Account for potential PRACH alloc // setup first prb to be used for msg3 alloc. Account for potential PRACH alloc
last_msg3_prb = cc_cfg->cfg.nrb_pucch; last_msg3_prb = cc_cfg->cfg.nrb_pucch;
uint32_t tti_msg3_alloc = TTI_ADD(tti_params.tti_tx_ul, MSG3_DELAY_MS); tti_point tti_msg3_alloc = to_tx_ul(tti_rx) + MSG3_DELAY_MS;
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_msg3_alloc, -1)) { if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_msg3_alloc.to_uint(), -1)) {
last_msg3_prb = std::max(last_msg3_prb, cc_cfg->cfg.prach_freq_offset + 6); last_msg3_prb = std::max(last_msg3_prb, cc_cfg->cfg.prach_freq_offset + 6);
} }
} }
@ -744,11 +737,11 @@ std::pair<alloc_outcome_t, uint32_t> sf_sched::alloc_rar(uint32_t aggr_lvl, cons
return ret; return ret;
} }
bool is_periodic_cqi_expected(const sched_interface::ue_cfg_t& ue_cfg, uint32_t tti_tx_ul) bool is_periodic_cqi_expected(const sched_interface::ue_cfg_t& ue_cfg, tti_point tti_tx_ul)
{ {
for (const sched_interface::ue_cfg_t::cc_cfg_t& cc : ue_cfg.supported_cc_list) { for (const sched_interface::ue_cfg_t::cc_cfg_t& cc : ue_cfg.supported_cc_list) {
if (cc.dl_cfg.cqi_report.periodic_configured) { if (cc.dl_cfg.cqi_report.periodic_configured) {
if (srslte_cqi_periodic_send(&cc.dl_cfg.cqi_report, tti_tx_ul, SRSLTE_FDD)) { if (srslte_cqi_periodic_send(&cc.dl_cfg.cqi_report, tti_tx_ul.to_uint(), SRSLTE_FDD)) {
return true; return true;
} }
} }
@ -880,7 +873,7 @@ bool sf_sched::alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_s
} }
uint32_t cell_index = p.second; uint32_t cell_index = p.second;
ul_harq_proc* h = user->get_ul_harq(tti_params.tti_tx_ul, cell_index); ul_harq_proc* h = user->get_ul_harq(get_tti_tx_ul(), cell_index);
/* Indicate PHICH acknowledgment if needed */ /* Indicate PHICH acknowledgment if needed */
if (h->has_pending_phich()) { if (h->has_pending_phich()) {
@ -1085,7 +1078,7 @@ uci_pusch_t is_uci_included(const sf_sched* sf_sched,
// Check if CQI is pending for this CC // Check if CQI is pending for this CC
const srslte_cqi_report_cfg_t& cqi_report = ue_cfg.supported_cc_list[ueccidx].dl_cfg.cqi_report; const srslte_cqi_report_cfg_t& cqi_report = ue_cfg.supported_cc_list[ueccidx].dl_cfg.cqi_report;
if (srslte_cqi_periodic_send(&cqi_report, sf_sched->get_tti_tx_ul(), SRSLTE_FDD)) { if (srslte_cqi_periodic_send(&cqi_report, sf_sched->get_tti_tx_ul().to_uint(), SRSLTE_FDD)) {
if (uci_alloc == UCI_PUSCH_ACK) { if (uci_alloc == UCI_PUSCH_ACK) {
uci_alloc = UCI_PUSCH_ACK_CQI; uci_alloc = UCI_PUSCH_ACK_CQI;
} else { } else {
@ -1271,9 +1264,9 @@ void sf_sched::generate_sched_results(sched_ue_list& ue_db)
set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db); set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db);
/* Store remaining sf_sched results for this TTI */ /* Store remaining sf_sched results for this TTI */
cc_result->dl_mask = tti_alloc.get_dl_mask(); cc_result->dl_mask = tti_alloc.get_dl_mask();
cc_result->ul_mask = tti_alloc.get_ul_mask(); cc_result->ul_mask = tti_alloc.get_ul_mask();
cc_result->tti_params = tti_params; cc_result->tti_rx = get_tti_rx();
} }
uint32_t sf_sched::get_nof_ctrl_symbols() const uint32_t sf_sched::get_nof_ctrl_symbols() const

@ -163,7 +163,7 @@ dl_harq_proc::dl_harq_proc() : harq_proc()
void dl_harq_proc::new_tx(const rbgmask_t& new_mask, void dl_harq_proc::new_tx(const rbgmask_t& new_mask,
uint32_t tb_idx, uint32_t tb_idx,
uint32_t tti, tti_point tti_tx_dl,
int mcs, int mcs,
int tbs, int tbs,
uint32_t n_cce_, uint32_t n_cce_,
@ -171,19 +171,19 @@ void dl_harq_proc::new_tx(const rbgmask_t& new_mask,
{ {
n_cce = n_cce_; n_cce = n_cce_;
rbgmask = new_mask; rbgmask = new_mask;
new_tx_common(tb_idx, tti_point{tti}, mcs, tbs, max_retx_); new_tx_common(tb_idx, tti_tx_dl, mcs, tbs, max_retx_);
} }
void dl_harq_proc::new_retx(const rbgmask_t& new_mask, void dl_harq_proc::new_retx(const rbgmask_t& new_mask,
uint32_t tb_idx, uint32_t tb_idx,
uint32_t tti_, tti_point tti_tx_dl,
int* mcs, int* mcs,
int* tbs, int* tbs,
uint32_t n_cce_) uint32_t n_cce_)
{ {
n_cce = n_cce_; n_cce = n_cce_;
rbgmask = new_mask; rbgmask = new_mask;
new_retx_common(tb_idx, tti_point{tti_}, mcs, tbs); new_retx_common(tb_idx, tti_tx_dl, mcs, tbs);
} }
int dl_harq_proc::set_ack(uint32_t tb_idx, bool ack) int dl_harq_proc::set_ack(uint32_t tb_idx, bool ack)
@ -201,9 +201,9 @@ rbgmask_t dl_harq_proc::get_rbgmask() const
return rbgmask; return rbgmask;
} }
bool dl_harq_proc::has_pending_retx(uint32_t tb_idx, uint32_t tti_tx_dl) const bool dl_harq_proc::has_pending_retx(uint32_t tb_idx, tti_point tti_tx_dl) const
{ {
return (tti_point{tti_tx_dl} >= to_tx_dl_ack(tti)) and has_pending_retx_common(tb_idx); return (tti_tx_dl >= to_tx_dl_ack(tti)) and has_pending_retx_common(tb_idx);
} }
int dl_harq_proc::get_tbs(uint32_t tb_idx) const int dl_harq_proc::get_tbs(uint32_t tb_idx) const
@ -314,10 +314,10 @@ void harq_entity::reset()
} }
} }
dl_harq_proc* harq_entity::get_empty_dl_harq(uint32_t tti_tx_dl) dl_harq_proc* harq_entity::get_empty_dl_harq(tti_point tti_tx_dl)
{ {
if (not is_async) { if (not is_async) {
dl_harq_proc* h = &dl_harqs[tti_tx_dl % nof_dl_harqs()]; dl_harq_proc* h = &dl_harqs[tti_tx_dl.to_uint() % nof_dl_harqs()];
return h->is_empty() ? h : nullptr; return h->is_empty() ? h : nullptr;
} }
@ -325,19 +325,19 @@ dl_harq_proc* harq_entity::get_empty_dl_harq(uint32_t tti_tx_dl)
return it != dl_harqs.end() ? &(*it) : nullptr; return it != dl_harqs.end() ? &(*it) : nullptr;
} }
dl_harq_proc* harq_entity::get_pending_dl_harq(uint32_t tti_tx_dl) dl_harq_proc* harq_entity::get_pending_dl_harq(tti_point tti_tx_dl)
{ {
if (not is_async) { if (not is_async) {
dl_harq_proc* h = &dl_harqs[tti_tx_dl % nof_dl_harqs()]; dl_harq_proc* h = &dl_harqs[tti_tx_dl.to_uint() % nof_dl_harqs()];
return (h->has_pending_retx(0, tti_tx_dl) or h->has_pending_retx(1, tti_tx_dl)) ? h : nullptr; return (h->has_pending_retx(0, tti_tx_dl) or h->has_pending_retx(1, tti_tx_dl)) ? h : nullptr;
} }
return get_oldest_dl_harq(tti_tx_dl); return get_oldest_dl_harq(tti_tx_dl);
} }
std::pair<uint32_t, int> harq_entity::set_ack_info(uint32_t tti_rx, uint32_t tb_idx, bool ack) std::pair<uint32_t, int> harq_entity::set_ack_info(tti_point tti_rx, uint32_t tb_idx, bool ack)
{ {
for (auto& h : dl_harqs) { for (auto& h : dl_harqs) {
if (h.get_tti() + FDD_HARQ_DELAY_DL_MS == tti_point{tti_rx}) { if (h.get_tti() + FDD_HARQ_DELAY_DL_MS == tti_rx) {
if (h.set_ack(tb_idx, ack) == SRSLTE_SUCCESS) { if (h.set_ack(tb_idx, ack) == SRSLTE_SUCCESS) {
return {h.get_id(), h.get_tbs(tb_idx)}; return {h.get_id(), h.get_tbs(tb_idx)};
} }
@ -347,25 +347,24 @@ std::pair<uint32_t, int> harq_entity::set_ack_info(uint32_t tti_rx, uint32_t tb_
return {dl_harqs.size(), -1}; return {dl_harqs.size(), -1};
} }
ul_harq_proc* harq_entity::get_ul_harq(uint32_t tti_tx_ul) ul_harq_proc* harq_entity::get_ul_harq(tti_point tti_tx_ul)
{ {
return &ul_harqs[tti_tx_ul % ul_harqs.size()]; return &ul_harqs[tti_tx_ul.to_uint() % ul_harqs.size()];
} }
int harq_entity::set_ul_crc(srslte::tti_point tti_rx, uint32_t tb_idx, bool ack_) int harq_entity::set_ul_crc(tti_point tti_rx, uint32_t tb_idx, bool ack_)
{ {
ul_harq_proc* h = get_ul_harq(tti_rx.to_uint()); ul_harq_proc* h = get_ul_harq(tti_rx);
uint32_t pid = h->get_id(); uint32_t pid = h->get_id();
return h->set_ack(tb_idx, ack_) ? pid : -1; return h->set_ack(tb_idx, ack_) ? pid : -1;
} }
void harq_entity::reset_pending_data(srslte::tti_point tti_rx) void harq_entity::reset_pending_data(tti_point tti_rx)
{ {
tti_point tti_tx_ul = to_tx_ul(tti_rx); tti_point tti_tx_ul = to_tx_ul(tti_rx);
tti_point tti_tx_dl = to_tx_dl(tti_rx);
// Reset ACK state of UL Harq // Reset ACK state of UL Harq
get_ul_harq(tti_tx_ul.to_uint())->reset_pending_data(); get_ul_harq(tti_tx_ul)->reset_pending_data();
// Reset any DL harq which has 0 retxs // Reset any DL harq which has 0 retxs
for (auto& h : dl_harqs) { for (auto& h : dl_harqs) {
@ -378,14 +377,13 @@ void harq_entity::reset_pending_data(srslte::tti_point tti_rx)
* @param tti_tx_dl assumed to always be equal or ahead in time in comparison to current harqs * @param tti_tx_dl assumed to always be equal or ahead in time in comparison to current harqs
* @return pointer to found dl_harq * @return pointer to found dl_harq
*/ */
dl_harq_proc* harq_entity::get_oldest_dl_harq(uint32_t tti_tx_dl) dl_harq_proc* harq_entity::get_oldest_dl_harq(tti_point tti_tx_dl)
{ {
tti_point t_tx_dl{tti_tx_dl}; int oldest_idx = -1;
int oldest_idx = -1; uint32_t oldest_tti = 0;
uint32_t oldest_tti = 0;
for (const dl_harq_proc& h : dl_harqs) { for (const dl_harq_proc& h : dl_harqs) {
if (h.has_pending_retx(0, tti_tx_dl) or h.has_pending_retx(1, tti_tx_dl)) { if (h.has_pending_retx(0, tti_tx_dl) or h.has_pending_retx(1, tti_tx_dl)) {
uint32_t x = t_tx_dl - h.get_tti(); uint32_t x = tti_tx_dl - h.get_tti();
if (x > oldest_tti) { if (x > oldest_tti) {
oldest_idx = h.get_id(); oldest_idx = h.get_id();
oldest_tti = x; oldest_tti = x;

@ -47,16 +47,6 @@ uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool use_tbs_index_
return (uint32_t)tbs / 8U; return (uint32_t)tbs / 8U;
} }
//! TS 36.321 sec 7.1.2 - MAC PDU subheader is 2 bytes if L<=128 and 3 otherwise
uint32_t get_mac_subheader_size(uint32_t sdu_bytes)
{
return sdu_bytes == 0 ? 0 : (sdu_bytes > 128 ? 3 : 2);
}
uint32_t get_mac_sdu_and_subheader_size(uint32_t sdu_bytes)
{
return sdu_bytes + get_mac_subheader_size(sdu_bytes);
}
/** /**
* Count number of PRBs present in a DL RBG mask * Count number of PRBs present in a DL RBG mask
* @param bitmask DL RBG mask * @param bitmask DL RBG mask
@ -145,7 +135,7 @@ std::tuple<int, YType, int, YType> false_position_method(int x1, int x2, YType y
* *
*******************************************************/ *******************************************************/
sched_ue::sched_ue() : log_h(srslte::logmap::get("MAC ")) sched_ue::sched_ue() : log_h(srslte::logmap::get("MAC"))
{ {
reset(); reset();
} }
@ -157,7 +147,7 @@ void sched_ue::init(uint16_t rnti_, const std::vector<sched_cell_params_t>& cell
Info("SCHED: Added user rnti=0x%x\n", rnti); Info("SCHED: Added user rnti=0x%x\n", rnti);
} }
void sched_ue::set_cfg(const sched_interface::ue_cfg_t& cfg_) void sched_ue::set_cfg(const ue_cfg_t& cfg_)
{ {
// for the first configured cc, set it as primary cc // for the first configured cc, set it as primary cc
if (cfg.supported_cc_list.empty()) { if (cfg.supported_cc_list.empty()) {
@ -187,8 +177,11 @@ void sched_ue::set_cfg(const sched_interface::ue_cfg_t& cfg_)
} }
// in case carriers have been added or modified // in case carriers have been added or modified
bool scell_activation_state_changed = false; bool scell_activation_state_changed = false;
enb_ue_cc_idx_map.clear();
enb_ue_cc_idx_map.resize(cell_params_list->size(), -1);
for (uint32_t ue_idx = 0; ue_idx < cfg.supported_cc_list.size(); ++ue_idx) { for (uint32_t ue_idx = 0; ue_idx < cfg.supported_cc_list.size(); ++ue_idx) {
auto& cc_cfg = cfg.supported_cc_list[ue_idx]; auto& cc_cfg = cfg.supported_cc_list[ue_idx];
enb_ue_cc_idx_map[cc_cfg.enb_cc_idx] = ue_idx;
if (ue_idx >= prev_supported_cc_list.size()) { if (ue_idx >= prev_supported_cc_list.size()) {
// New carrier needs to be added // New carrier needs to be added
@ -230,11 +223,12 @@ void sched_ue::reset()
} }
} }
void sched_ue::new_tti(srslte::tti_point new_tti) void sched_ue::new_subframe(tti_point tti_rx, uint32_t enb_cc_idx)
{ {
current_tti = new_tti; if (current_tti != tti_rx) {
current_tti = tti_rx;
lch_handler.new_tti(); lch_handler.new_tti();
}
} }
/// sanity check the UE CC configuration /// sanity check the UE CC configuration
@ -272,10 +266,10 @@ void sched_ue::check_ue_cfg_correctness() const
* *
*******************************************************/ *******************************************************/
void sched_ue::set_bearer_cfg(uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg_) void sched_ue::set_bearer_cfg(uint32_t lc_id, const bearer_cfg_t& cfg_)
{ {
cfg.ue_bearers[lc_id] = *cfg_; cfg.ue_bearers[lc_id] = cfg_;
lch_handler.config_lcid(lc_id, *cfg_); lch_handler.config_lcid(lc_id, cfg_);
} }
void sched_ue::rem_bearer(uint32_t lc_id) void sched_ue::rem_bearer(uint32_t lc_id)
@ -284,10 +278,10 @@ void sched_ue::rem_bearer(uint32_t lc_id)
lch_handler.config_lcid(lc_id, sched_interface::ue_bearer_cfg_t{}); lch_handler.config_lcid(lc_id, sched_interface::ue_bearer_cfg_t{});
} }
void sched_ue::phy_config_enabled(uint32_t tti, bool enabled) void sched_ue::phy_config_enabled(tti_point tti_rx, bool enabled)
{ {
for (cc_sched_ue& c : carriers) { for (cc_sched_ue& c : carriers) {
c.dl_cqi_tti = tti; c.dl_cqi_tti_rx = tti_rx;
} }
phy_config_dedicated_enabled = enabled; phy_config_dedicated_enabled = enabled;
} }
@ -335,12 +329,12 @@ void sched_ue::unset_sr()
sr = false; sr = false;
} }
bool sched_ue::pucch_sr_collision(uint32_t tti, uint32_t n_cce) bool sched_ue::pucch_sr_collision(tti_point tti_tx_dl, uint32_t n_cce)
{ {
if (!phy_config_dedicated_enabled) { if (!phy_config_dedicated_enabled) {
return false; return false;
} }
if (cfg.pucch_cfg.sr_configured && srslte_ue_ul_sr_send_tti(&cfg.pucch_cfg, tti)) { if (cfg.pucch_cfg.sr_configured && srslte_ue_ul_sr_send_tti(&cfg.pucch_cfg, tti_tx_dl.to_uint())) {
return (n_cce + cfg.pucch_cfg.N_pucch_1) == cfg.pucch_cfg.n_pucch_sr; return (n_cce + cfg.pucch_cfg.N_pucch_1) == cfg.pucch_cfg.n_pucch_sr;
} }
return false; return false;
@ -383,7 +377,7 @@ bool sched_ue::pdsch_enabled(srslte::tti_point tti_rx, uint32_t enb_cc_idx) cons
return true; return true;
} }
bool sched_ue::pusch_enabled(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool needs_pdcch) const bool sched_ue::pusch_enabled(tti_point tti_rx, uint32_t enb_cc_idx, bool needs_pdcch) const
{ {
if (carriers[0].get_cell_cfg()->enb_cc_idx != enb_cc_idx) { if (carriers[0].get_cell_cfg()->enb_cc_idx != enb_cc_idx) {
return true; return true;
@ -407,7 +401,7 @@ bool sched_ue::pusch_enabled(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool
return true; return true;
} }
int sched_ue::set_ack_info(uint32_t tti_rx, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) int sched_ue::set_ack_info(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack)
{ {
int tbs_acked = -1; int tbs_acked = -1;
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
@ -415,9 +409,10 @@ int sched_ue::set_ack_info(uint32_t tti_rx, uint32_t enb_cc_idx, uint32_t tb_idx
std::pair<uint32_t, int> p2 = c->harq_ent.set_ack_info(tti_rx, tb_idx, ack); std::pair<uint32_t, int> p2 = c->harq_ent.set_ack_info(tti_rx, tb_idx, ack);
tbs_acked = p2.second; tbs_acked = p2.second;
if (tbs_acked > 0) { if (tbs_acked > 0) {
Debug("SCHED: Set DL ACK=%d for rnti=0x%x, pid=%d, tb=%d, tti=%d\n", ack, rnti, p2.first, tb_idx, tti_rx); Debug(
"SCHED: Set DL ACK=%d for rnti=0x%x, pid=%d, tb=%d, tti=%d\n", ack, rnti, p2.first, tb_idx, tti_rx.to_uint());
} else { } else {
Warning("SCHED: Received ACK info for unknown TTI=%d\n", tti_rx); Warning("SCHED: Received ACK info for unknown TTI=%d\n", tti_rx.to_uint());
} }
} else { } else {
log_h->warning("Received DL ACK for invalid cell index %d\n", enb_cc_idx); log_h->warning("Received DL ACK for invalid cell index %d\n", enb_cc_idx);
@ -425,7 +420,7 @@ int sched_ue::set_ack_info(uint32_t tti_rx, uint32_t enb_cc_idx, uint32_t tb_idx
return tbs_acked; return tbs_acked;
} }
void sched_ue::set_ul_crc(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool crc_res) void sched_ue::set_ul_crc(tti_point tti_rx, uint32_t enb_cc_idx, bool crc_res)
{ {
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
if (c != nullptr and c->cc_state() != cc_st::idle) { if (c != nullptr and c->cc_state() != cc_st::idle) {
@ -438,44 +433,44 @@ void sched_ue::set_ul_crc(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool cr
} }
} }
void sched_ue::set_dl_ri(uint32_t tti, uint32_t enb_cc_idx, uint32_t ri) void sched_ue::set_dl_ri(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t ri)
{ {
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
if (c != nullptr and c->cc_state() != cc_st::idle) { if (c != nullptr and c->cc_state() != cc_st::idle) {
c->dl_ri = ri; c->dl_ri = ri;
c->dl_ri_tti = tti; c->dl_ri_tti_rx = tti_rx;
} else { } else {
log_h->warning("Received DL RI for invalid cell index %d\n", enb_cc_idx); log_h->warning("Received DL RI for invalid cell index %d\n", enb_cc_idx);
} }
} }
void sched_ue::set_dl_pmi(uint32_t tti, uint32_t enb_cc_idx, uint32_t pmi) void sched_ue::set_dl_pmi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t pmi)
{ {
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
if (c != nullptr and c->cc_state() != cc_st::idle) { if (c != nullptr and c->cc_state() != cc_st::idle) {
c->dl_pmi = pmi; c->dl_pmi = pmi;
c->dl_pmi_tti = tti; c->dl_pmi_tti_rx = tti_rx;
} else { } else {
log_h->warning("Received DL PMI for invalid cell index %d\n", enb_cc_idx); log_h->warning("Received DL PMI for invalid cell index %d\n", enb_cc_idx);
} }
} }
void sched_ue::set_dl_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi) void sched_ue::set_dl_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi)
{ {
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
if (c != nullptr and c->cc_state() != cc_st::idle) { if (c != nullptr and c->cc_state() != cc_st::idle) {
c->set_dl_cqi(tti, cqi); c->set_dl_cqi(tti_rx, cqi);
} else { } else {
log_h->warning("Received DL CQI for invalid enb cell index %d\n", enb_cc_idx); log_h->warning("Received DL CQI for invalid enb cell index %d\n", enb_cc_idx);
} }
} }
void sched_ue::set_ul_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) void sched_ue::set_ul_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code)
{ {
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
if (c != nullptr and c->cc_state() != cc_st::idle) { if (c != nullptr and c->cc_state() != cc_st::idle) {
c->ul_cqi = cqi; c->ul_cqi = cqi;
c->ul_cqi_tti = tti; c->ul_cqi_tti_rx = tti_rx;
} else { } else {
log_h->warning("Received SNR info for invalid cell index %d\n", enb_cc_idx); log_h->warning("Received SNR info for invalid cell index %d\n", enb_cc_idx);
} }
@ -513,7 +508,7 @@ void sched_ue::tpc_dec()
std::pair<int, int> sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* data, std::pair<int, int> sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* data,
dl_harq_proc* h, dl_harq_proc* h,
const rbgmask_t& user_mask, const rbgmask_t& user_mask,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
uint32_t tb) uint32_t tb)
@ -541,7 +536,7 @@ std::pair<int, int> sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* da
int sched_ue::generate_dl_dci_format(uint32_t pid, int sched_ue::generate_dl_dci_format(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask) const rbgmask_t& user_mask)
@ -569,7 +564,7 @@ int sched_ue::generate_dl_dci_format(uint32_t pid,
// > return 0 if allocation is invalid // > return 0 if allocation is invalid
int sched_ue::generate_format1(uint32_t pid, int sched_ue::generate_format1(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask) const rbgmask_t& user_mask)
@ -636,7 +631,7 @@ int sched_ue::generate_format1(uint32_t pid,
* @return pair with MCS and TBS (in bytes) * @return pair with MCS and TBS (in bytes)
*/ */
std::pair<int, int> sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_idx, std::pair<int, int> sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_idx,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t nof_alloc_prbs, uint32_t nof_alloc_prbs,
uint32_t cfi, uint32_t cfi,
const srslte_dci_dl_t& dci) const srslte_dci_dl_t& dci)
@ -648,7 +643,7 @@ std::pair<int, int> sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_i
srslte_pdsch_grant_t grant = {}; srslte_pdsch_grant_t grant = {};
srslte_dl_sf_cfg_t dl_sf = {}; srslte_dl_sf_cfg_t dl_sf = {};
dl_sf.cfi = cfi; dl_sf.cfi = cfi;
dl_sf.tti = tti_tx_dl; dl_sf.tti = tti_tx_dl.to_uint();
srslte_ra_dl_grant_to_grant_prb_allocation(&dci, &grant, carriers[ue_cc_idx].get_cell_cfg()->nof_prb()); srslte_ra_dl_grant_to_grant_prb_allocation(&dci, &grant, carriers[ue_cc_idx].get_cell_cfg()->nof_prb());
uint32_t nof_re = srslte_ra_dl_grant_nof_re(&carriers[ue_cc_idx].get_cell_cfg()->cfg.cell, &dl_sf, &grant); uint32_t nof_re = srslte_ra_dl_grant_nof_re(&carriers[ue_cc_idx].get_cell_cfg()->cfg.cell, &dl_sf, &grant);
@ -677,7 +672,7 @@ std::pair<int, int> sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_i
// Generates a Format2a dci // Generates a Format2a dci
int sched_ue::generate_format2a(uint32_t pid, int sched_ue::generate_format2a(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti_tx_dl, tti_point tti_tx_dl,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask) const rbgmask_t& user_mask)
@ -757,13 +752,13 @@ int sched_ue::generate_format2a(uint32_t pid,
// Generates a Format2 dci // Generates a Format2 dci
int sched_ue::generate_format2(uint32_t pid, int sched_ue::generate_format2(uint32_t pid,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti, tti_point tti_tx_dl,
uint32_t cc_idx, uint32_t cc_idx,
uint32_t cfi, uint32_t cfi,
const rbgmask_t& user_mask) const rbgmask_t& user_mask)
{ {
/* Call Format 2a (common) */ /* Call Format 2a (common) */
int ret = generate_format2a(pid, data, tti, cc_idx, cfi, user_mask); int ret = generate_format2a(pid, data, tti_tx_dl, cc_idx, cfi, user_mask);
/* Compute precoding information */ /* Compute precoding information */
data->dci.format = SRSLTE_DCI_FORMAT2; data->dci.format = SRSLTE_DCI_FORMAT2;
@ -777,7 +772,7 @@ int sched_ue::generate_format2(uint32_t pid,
} }
int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data, int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
uint32_t tti, tti_point tti_tx_ul,
uint32_t ue_cc_idx, uint32_t ue_cc_idx,
prb_interval alloc, prb_interval alloc,
bool needs_pdcch, bool needs_pdcch,
@ -785,10 +780,10 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
int explicit_mcs, int explicit_mcs,
uci_pusch_t uci_type) uci_pusch_t uci_type)
{ {
ul_harq_proc* h = get_ul_harq(tti, ue_cc_idx); ul_harq_proc* h = get_ul_harq(tti_tx_ul, ue_cc_idx);
srslte_dci_ul_t* dci = &data->dci; srslte_dci_ul_t* dci = &data->dci;
bool cqi_request = needs_cqi_unlocked(tti, true); bool cqi_request = needs_cqi(tti_tx_ul.to_uint(), true);
// Set DCI position // Set DCI position
data->needs_pdcch = needs_pdcch; data->needs_pdcch = needs_pdcch;
@ -808,7 +803,7 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs, false, true), alloc.length()) / 8; tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs, false, true), alloc.length()) / 8;
} else { } else {
// dynamic mcs // dynamic mcs
uint32_t req_bytes = get_pending_ul_new_data(tti, ue_cc_idx); uint32_t req_bytes = get_pending_ul_new_data(tti_tx_ul, ue_cc_idx);
uint32_t N_srs = 0; uint32_t N_srs = 0;
uint32_t nof_symb = 2 * (SRSLTE_CP_NSYMB(cell.cp) - 1) - N_srs; uint32_t nof_symb = 2 * (SRSLTE_CP_NSYMB(cell.cp) - 1) - N_srs;
uint32_t nof_re = nof_symb * alloc.length() * SRSLTE_NRE; uint32_t nof_re = nof_symb * alloc.length() * SRSLTE_NRE;
@ -835,14 +830,14 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
// NOTE: if (nof_re < nof_uci_re) we should set TBS=0 // NOTE: if (nof_re < nof_uci_re) we should set TBS=0
} }
} }
h->new_tx(tti_point{tti}, mcs, tbs, alloc, nof_retx); h->new_tx(tti_tx_ul, mcs, tbs, alloc, nof_retx);
// Un-trigger the SR if data is allocated // Un-trigger the SR if data is allocated
if (tbs > 0) { if (tbs > 0) {
unset_sr(); unset_sr();
} }
} else { } else {
// retx // retx
h->new_retx(tti_point{tti}, &mcs, nullptr, alloc); h->new_retx(tti_tx_ul, &mcs, nullptr, alloc);
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs, false, true), alloc.length()) / 8; tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs, false, true), alloc.length()) / 8;
} }
@ -901,26 +896,20 @@ uint32_t sched_ue::get_max_retx()
return cfg.maxharq_tx; return cfg.maxharq_tx;
} }
bool sched_ue::needs_cqi(uint32_t tti, uint32_t cc_idx, bool will_be_sent) bool sched_ue::needs_cqi(uint32_t tti, uint32_t cc_idx, bool will_send)
{
return needs_cqi_unlocked(tti, cc_idx, will_be_sent);
}
// Private lock-free implemenentation
bool sched_ue::needs_cqi_unlocked(uint32_t tti, uint32_t cc_idx, bool will_be_sent)
{ {
bool ret = false; bool ret = false;
if (phy_config_dedicated_enabled && cfg.supported_cc_list[0].aperiodic_cqi_period && if (phy_config_dedicated_enabled && cfg.supported_cc_list[0].aperiodic_cqi_period &&
lch_handler.has_pending_dl_txs()) { lch_handler.has_pending_dl_txs()) {
uint32_t interval = srslte_tti_interval(tti, carriers[cc_idx].dl_cqi_tti); uint32_t interval = srslte_tti_interval(tti, carriers[cc_idx].dl_cqi_tti_rx.to_uint());
bool needscqi = interval >= cfg.supported_cc_list[0].aperiodic_cqi_period; bool needscqi = interval >= cfg.supported_cc_list[0].aperiodic_cqi_period;
if (needscqi) { if (needscqi) {
uint32_t interval_sent = srslte_tti_interval(tti, cqi_request_tti); uint32_t interval_sent = srslte_tti_interval(tti, cqi_request_tti);
if (interval_sent >= 16) { if (interval_sent >= 16) {
if (will_be_sent) { if (will_send) {
cqi_request_tti = tti; cqi_request_tti = tti;
} }
Debug("SCHED: Needs_cqi, last_sent=%d, will_be_sent=%d\n", cqi_request_tti, will_be_sent); Debug("SCHED: Needs_cqi, last_sent=%d, will_be_sent=%d\n", cqi_request_tti, will_send);
ret = true; ret = true;
} }
} }
@ -1084,7 +1073,7 @@ uint32_t sched_ue::get_pending_ul_old_data()
return pending_ul_data; return pending_ul_data;
} }
uint32_t sched_ue::get_pending_ul_data_total(uint32_t tti, int this_ue_cc_idx) uint32_t sched_ue::get_pending_ul_data_total(tti_point tti_tx_ul, int this_ue_cc_idx)
{ {
static constexpr uint32_t lbsr_size = 4, sbsr_size = 2; static constexpr uint32_t lbsr_size = 4, sbsr_size = 2;
@ -1119,7 +1108,7 @@ uint32_t sched_ue::get_pending_ul_data_total(uint32_t tti, int this_ue_cc_idx)
} }
} }
for (uint32_t cc_idx = 0; cc_idx < carriers.size(); ++cc_idx) { for (uint32_t cc_idx = 0; cc_idx < carriers.size(); ++cc_idx) {
if (needs_cqi_unlocked(tti, cc_idx)) { if (needs_cqi(tti_tx_ul.to_uint(), cc_idx)) {
return 128; return 128;
} }
} }
@ -1128,9 +1117,9 @@ uint32_t sched_ue::get_pending_ul_data_total(uint32_t tti, int this_ue_cc_idx)
return pending_data; return pending_data;
} }
uint32_t sched_ue::get_pending_ul_new_data(uint32_t tti, int this_ue_cc_idx) uint32_t sched_ue::get_pending_ul_new_data(tti_point tti_tx_ul, int this_ue_cc_idx)
{ {
uint32_t pending_data = get_pending_ul_data_total(tti, this_ue_cc_idx); uint32_t pending_data = get_pending_ul_data_total(tti_tx_ul, this_ue_cc_idx);
// Subtract all the UL data already allocated in the UL harqs // Subtract all the UL data already allocated in the UL harqs
uint32_t pending_ul_data = get_pending_ul_old_data(); uint32_t pending_ul_data = get_pending_ul_old_data();
@ -1156,7 +1145,7 @@ bool sched_ue::is_sr_triggered()
} }
/* Gets HARQ process with oldest pending retx */ /* Gets HARQ process with oldest pending retx */
dl_harq_proc* sched_ue::get_pending_dl_harq(uint32_t tti_tx_dl, uint32_t ue_cc_idx) dl_harq_proc* sched_ue::get_pending_dl_harq(tti_point tti_tx_dl, uint32_t ue_cc_idx)
{ {
if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].cc_state() == cc_st::active) { if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].cc_state() == cc_st::active) {
return carriers[ue_cc_idx].harq_ent.get_pending_dl_harq(tti_tx_dl); return carriers[ue_cc_idx].harq_ent.get_pending_dl_harq(tti_tx_dl);
@ -1164,7 +1153,7 @@ dl_harq_proc* sched_ue::get_pending_dl_harq(uint32_t tti_tx_dl, uint32_t ue_cc_i
return nullptr; return nullptr;
} }
dl_harq_proc* sched_ue::get_empty_dl_harq(uint32_t tti_tx_dl, uint32_t ue_cc_idx) dl_harq_proc* sched_ue::get_empty_dl_harq(tti_point tti_tx_dl, uint32_t ue_cc_idx)
{ {
if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].cc_state() == cc_st::active) { if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].cc_state() == cc_st::active) {
return carriers[ue_cc_idx].harq_ent.get_empty_dl_harq(tti_tx_dl); return carriers[ue_cc_idx].harq_ent.get_empty_dl_harq(tti_tx_dl);
@ -1172,7 +1161,7 @@ dl_harq_proc* sched_ue::get_empty_dl_harq(uint32_t tti_tx_dl, uint32_t ue_cc_idx
return nullptr; return nullptr;
} }
ul_harq_proc* sched_ue::get_ul_harq(uint32_t tti_tx_ul, uint32_t ue_cc_idx) ul_harq_proc* sched_ue::get_ul_harq(tti_point tti_tx_ul, uint32_t ue_cc_idx)
{ {
if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].cc_state() == cc_st::active) { if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].cc_state() == cc_st::active) {
return carriers[ue_cc_idx].harq_ent.get_ul_harq(tti_tx_ul); return carriers[ue_cc_idx].harq_ent.get_ul_harq(tti_tx_ul);
@ -1203,13 +1192,13 @@ uint32_t sched_ue::get_aggr_level(uint32_t ue_cc_idx, uint32_t nof_bits)
return carriers[ue_cc_idx].get_aggr_level(nof_bits); return carriers[ue_cc_idx].get_aggr_level(nof_bits);
} }
void sched_ue::finish_tti(const tti_params_t& tti_params, uint32_t enb_cc_idx) void sched_ue::finish_tti(tti_point tti_rx, uint32_t enb_cc_idx)
{ {
cc_sched_ue* c = find_ue_carrier(enb_cc_idx); cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
if (c != nullptr) { if (c != nullptr) {
// Check that scell state needs to change // Check that scell state needs to change
c->finish_tti(current_tti); c->finish_tti(tti_rx);
} }
} }
@ -1271,10 +1260,7 @@ std::bitset<SRSLTE_MAX_CARRIERS> sched_ue::scell_activation_mask() const
int sched_ue::enb_to_ue_cc_idx(uint32_t enb_cc_idx) const int sched_ue::enb_to_ue_cc_idx(uint32_t enb_cc_idx) const
{ {
auto it = std::find_if(carriers.begin(), carriers.end(), [enb_cc_idx](const cc_sched_ue& c) { return enb_ue_cc_idx_map[enb_cc_idx];
return c.get_cell_cfg()->enb_cc_idx == enb_cc_idx;
});
return it != carriers.end() ? std::distance(carriers.begin(), it) : -1;
} }
int cc_sched_ue::cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint32_t* mcs) int cc_sched_ue::cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool is_ul, uint32_t* mcs)
@ -1364,14 +1350,14 @@ cc_sched_ue::cc_sched_ue(const sched_interface::ue_cfg_t& cfg_,
void cc_sched_ue::reset() void cc_sched_ue::reset()
{ {
dl_ri = 0; dl_ri = 0;
dl_ri_tti = 0; dl_ri_tti_rx = tti_point{};
dl_pmi = 0; dl_pmi = 0;
dl_pmi_tti = 0; dl_pmi_tti_rx = tti_point{};
dl_cqi = 1; dl_cqi = 1;
dl_cqi_tti = 0; dl_cqi_tti_rx = tti_point{};
ul_cqi = 1; ul_cqi = 1;
ul_cqi_tti = 0; ul_cqi_tti_rx = tti_point{};
harq_ent.reset(); harq_ent.reset();
} }
@ -1418,7 +1404,7 @@ void cc_sched_ue::set_cfg(const sched_interface::ue_cfg_t& cfg_)
} }
} }
void cc_sched_ue::finish_tti(srslte::tti_point tti_rx) void cc_sched_ue::finish_tti(tti_point tti_rx)
{ {
last_tti = tti_point{tti_rx}; last_tti = tti_point{tti_rx};
@ -1553,11 +1539,11 @@ uint32_t cc_sched_ue::get_required_prb_ul(uint32_t req_bytes)
return req_prbs; return req_prbs;
} }
void cc_sched_ue::set_dl_cqi(uint32_t tti_tx_dl, uint32_t dl_cqi_) void cc_sched_ue::set_dl_cqi(tti_point tti_rx, uint32_t dl_cqi_)
{ {
dl_cqi = dl_cqi_; dl_cqi = dl_cqi_;
dl_cqi_tti = tti_tx_dl; dl_cqi_tti_rx = tti_rx;
dl_cqi_rx = dl_cqi_rx or dl_cqi > 0; dl_cqi_rx = dl_cqi_rx or dl_cqi > 0;
if (ue_cc_idx > 0 and cc_state_ == cc_st::activating and dl_cqi_rx) { if (ue_cc_idx > 0 and cc_state_ == cc_st::activating and dl_cqi_rx) {
// Wait for SCell to receive a positive CQI before activating it // Wait for SCell to receive a positive CQI before activating it
cc_state_ = cc_st::active; cc_state_ = cc_st::active;

@ -31,7 +31,7 @@ void sched_time_rr::sched_dl_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched
} }
// give priority in a time-domain RR basis. // give priority in a time-domain RR basis.
uint32_t priority_idx = tti_sched->get_tti_tx_dl() % (uint32_t)ue_db.size(); uint32_t priority_idx = tti_sched->get_tti_tx_dl().to_uint() % (uint32_t)ue_db.size();
sched_dl_retxs(ue_db, tti_sched, priority_idx); sched_dl_retxs(ue_db, tti_sched, priority_idx);
sched_dl_newtxs(ue_db, tti_sched, priority_idx); sched_dl_newtxs(ue_db, tti_sched, priority_idx);
} }
@ -94,7 +94,7 @@ void sched_time_rr::sched_ul_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched
return; return;
} }
// give priority in a time-domain RR basis. // give priority in a time-domain RR basis.
uint32_t priority_idx = tti_sched->get_tti_tx_ul() % (uint32_t)ue_db.size(); uint32_t priority_idx = tti_sched->get_tti_tx_ul().to_uint() % (uint32_t)ue_db.size();
sched_ul_retxs(ue_db, tti_sched, priority_idx); sched_ul_retxs(ue_db, tti_sched, priority_idx);
sched_ul_newtxs(ue_db, tti_sched, priority_idx); sched_ul_newtxs(ue_db, tti_sched, priority_idx);
} }

@ -56,21 +56,21 @@ int test_pdcch_one_ue()
uint32_t tti_counter = 0; uint32_t tti_counter = 0;
for (; tti_counter < nof_ttis; ++tti_counter) { for (; tti_counter < nof_ttis; ++tti_counter) {
tti_params_t tti_params{(start_tti + tti_counter).to_uint()}; tti_point tti_rx = start_tti + tti_counter;
pdcch.new_tti(tti_params); pdcch.new_tti(tti_rx);
TESTASSERT(pdcch.nof_cces() == cell_params[ENB_CC_IDX].nof_cce_table[0]); TESTASSERT(pdcch.nof_cces() == cell_params[ENB_CC_IDX].nof_cce_table[0]);
TESTASSERT(pdcch.get_cfi() == 1); // Start at CFI=1 TESTASSERT(pdcch.get_cfi() == 1); // Start at CFI=1
// Set DL CQI - it should affect aggregation level // Set DL CQI - it should affect aggregation level
uint32_t dl_cqi = std::uniform_int_distribution<uint32_t>{1, 25}(srsenb::get_rand_gen()); uint32_t dl_cqi = std::uniform_int_distribution<uint32_t>{1, 25}(srsenb::get_rand_gen());
sched_ue.set_dl_cqi(tti_params.tti_tx_dl, ENB_CC_IDX, dl_cqi); sched_ue.set_dl_cqi(to_tx_dl(tti_rx), ENB_CC_IDX, dl_cqi);
uint32_t aggr_idx = get_aggr_level(sched_ue, PCell_IDX, cell_params); uint32_t aggr_idx = get_aggr_level(sched_ue, PCell_IDX, cell_params);
uint32_t max_nof_cce_locs = uint32_t max_nof_cce_locs =
sched_ue.get_locations(ENB_CC_IDX, pdcch_grid_t::MAX_CFI, tti_params.sf_idx_tx_dl)->nof_loc[aggr_idx]; sched_ue.get_locations(ENB_CC_IDX, pdcch_grid_t::MAX_CFI, to_tx_dl(tti_rx).sf_idx())->nof_loc[aggr_idx];
// allocate DL user // allocate DL user
uint32_t prev_cfi = pdcch.get_cfi(); uint32_t prev_cfi = pdcch.get_cfi();
srsenb::sched_dci_cce_t* dci_cce = sched_ue.get_locations(ENB_CC_IDX, prev_cfi, tti_params.sf_idx_tx_dl); srsenb::sched_dci_cce_t* dci_cce = sched_ue.get_locations(ENB_CC_IDX, prev_cfi, to_tx_dl(tti_rx).sf_idx());
uint32_t prev_nof_cce_locs = dci_cce->nof_loc[aggr_idx]; uint32_t prev_nof_cce_locs = dci_cce->nof_loc[aggr_idx];
TESTASSERT(pdcch.alloc_dci(alloc_type_t::DL_DATA, aggr_idx, &sched_ue)); TESTASSERT(pdcch.alloc_dci(alloc_type_t::DL_DATA, aggr_idx, &sched_ue));
@ -83,7 +83,7 @@ int test_pdcch_one_ue()
TESTASSERT(pdcch.get_cfi() == prev_cfi); TESTASSERT(pdcch.get_cfi() == prev_cfi);
} }
dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), tti_params.sf_idx_tx_dl); dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx());
uint32_t nof_dci_locs = dci_cce->nof_loc[aggr_idx]; uint32_t nof_dci_locs = dci_cce->nof_loc[aggr_idx];
const uint32_t* dci_locs = dci_cce->cce_start[aggr_idx]; const uint32_t* dci_locs = dci_cce->cce_start[aggr_idx];
@ -115,7 +115,7 @@ int test_pdcch_one_ue()
TESTASSERT(pdcch.get_cfi() == prev_cfi); TESTASSERT(pdcch.get_cfi() == prev_cfi);
} }
dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), tti_params.sf_idx_tx_dl); dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx());
nof_dci_locs = dci_cce->nof_loc[aggr_idx]; nof_dci_locs = dci_cce->nof_loc[aggr_idx];
dci_locs = dci_cce->cce_start[aggr_idx]; dci_locs = dci_cce->cce_start[aggr_idx];

@ -238,11 +238,11 @@ int ue_ctxt_test::schedule_acks(cc_result result)
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
void user_state_sched_tester::new_tti(sched* sched_ptr, uint32_t tti_rx) void user_state_sched_tester::new_tti(sched* sched_ptr, tti_point tti_rx)
{ {
tic++; tic++;
for (auto& u : users) { for (auto& u : users) {
u.second.new_tti(sched_ptr, srslte::tti_point{tti_rx}); u.second.new_tti(sched_ptr, tti_rx);
} }
} }
@ -315,7 +315,7 @@ int user_state_sched_tester::test_all(const sf_output_res_t& sf_out)
* Sim Stats Storage * Sim Stats Storage
**********************/ **********************/
void sched_result_stats::process_results(const tti_params_t& tti_params, void sched_result_stats::process_results(tti_point tti_rx,
const std::vector<sched_interface::dl_sched_res_t>& dl_result, const std::vector<sched_interface::dl_sched_res_t>& dl_result,
const std::vector<sched_interface::ul_sched_res_t>& ul_result) const std::vector<sched_interface::ul_sched_res_t>& ul_result)
{ {
@ -377,7 +377,7 @@ int common_sched_tester::add_user(uint16_t rnti, const ue_ctxt_test_cfg& ue_cfg_
// "New user added in a non-PRACH TTI\n"); // "New user added in a non-PRACH TTI\n");
dl_sched_rar_info_t rar_info = {}; dl_sched_rar_info_t rar_info = {};
rar_info.prach_tti = tti_info.tti_params.tti_rx; rar_info.prach_tti = tti_rx.to_uint();
rar_info.temp_crnti = rnti; rar_info.temp_crnti = rnti;
rar_info.msg3_size = 7; rar_info.msg3_size = 7;
rar_info.preamble_idx = tti_info.nof_prachs++; rar_info.preamble_idx = tti_info.nof_prachs++;
@ -407,34 +407,30 @@ void common_sched_tester::rem_user(uint16_t rnti)
void common_sched_tester::new_test_tti() void common_sched_tester::new_test_tti()
{ {
if (not tic.is_valid()) { if (not tti_rx.is_valid()) {
tic = srslte::tti_point{sim_args0.start_tti}; tti_rx = srslte::tti_point{sim_args0.start_tti};
} else { } else {
tic++; tti_rx++;
} }
tti_info.tti_params = tti_params_t{tic.to_uint()};
tti_info.nof_prachs = 0; tti_info.nof_prachs = 0;
tti_info.dl_sched_result.clear(); tti_info.dl_sched_result.clear();
tti_info.ul_sched_result.clear(); tti_info.ul_sched_result.clear();
tti_info.dl_sched_result.resize(sched_cell_params.size()); tti_info.dl_sched_result.resize(sched_cell_params.size());
tti_info.ul_sched_result.resize(sched_cell_params.size()); tti_info.ul_sched_result.resize(sched_cell_params.size());
tester_log->step(tti_info.tti_params.tti_rx); tester_log->step(tti_rx.to_uint());
} }
int common_sched_tester::process_results() int common_sched_tester::process_results()
{ {
// Perform common eNB result tests // Perform common eNB result tests
sf_output_res_t sf_out{sched_cell_params, sf_output_res_t sf_out{sched_cell_params, tti_rx, tti_info.ul_sched_result, tti_info.dl_sched_result};
srslte::tti_point{tti_info.tti_params.tti_rx},
tti_info.ul_sched_result,
tti_info.dl_sched_result};
TESTASSERT(test_all_common(sf_out) == SRSLTE_SUCCESS); TESTASSERT(test_all_common(sf_out) == SRSLTE_SUCCESS);
TESTASSERT(ue_tester->test_all(sf_out) == SRSLTE_SUCCESS); TESTASSERT(ue_tester->test_all(sf_out) == SRSLTE_SUCCESS);
sched_stats->process_results(tti_info.tti_params, tti_info.dl_sched_result, tti_info.ul_sched_result); sched_stats->process_results(tti_rx, tti_info.dl_sched_result, tti_info.ul_sched_result);
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -470,7 +466,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
if (user != nullptr) { if (user != nullptr) {
const auto& ue_sim_ctxt = user->ue_ctxt->get_ctxt(); const auto& ue_sim_ctxt = user->ue_ctxt->get_ctxt();
if (not ue_sim_ctxt.msg4_tti_rx.is_valid() and ue_sim_ctxt.msg3_tti_rx.is_valid() and if (not ue_sim_ctxt.msg4_tti_rx.is_valid() and ue_sim_ctxt.msg3_tti_rx.is_valid() and
to_tx_ul(ue_sim_ctxt.msg3_tti_rx) <= tic) { to_tx_ul(ue_sim_ctxt.msg3_tti_rx) <= tti_rx) {
// Msg3 has been received but Msg4 has not been yet transmitted // Msg3 has been received but Msg4 has not been yet transmitted
// Setup default UE config // Setup default UE config
reconf_user(user->rnti, generate_setup_ue_cfg(sim_args0.default_ue_sim_cfg.ue_cfg)); reconf_user(user->rnti, generate_setup_ue_cfg(sim_args0.default_ue_sim_cfg.ue_cfg));
@ -516,7 +512,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
if (ue_ev.buffer_ev->sr_data > 0 and user->drb_cfg_flag) { if (ue_ev.buffer_ev->sr_data > 0 and user->drb_cfg_flag) {
uint32_t tot_ul_data = uint32_t tot_ul_data =
ue_db[ue_ev.rnti].get_pending_ul_new_data(tti_info.tti_params.tti_tx_ul, -1) + ue_ev.buffer_ev->sr_data; ue_db[ue_ev.rnti].get_pending_ul_new_data(to_tx_ul(tti_rx), -1) + ue_ev.buffer_ev->sr_data;
uint32_t lcg = 1; uint32_t lcg = 1;
ul_bsr(ue_ev.rnti, lcg, tot_ul_data); ul_bsr(ue_ev.rnti, lcg, tot_ul_data);
} }
@ -528,20 +524,20 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
int common_sched_tester::run_tti(const tti_ev& tti_events) int common_sched_tester::run_tti(const tti_ev& tti_events)
{ {
new_test_tti(); new_test_tti();
tester_log->info("---- tti=%u | nof_ues=%zd ----\n", tic.to_uint(), ue_db.size()); tester_log->info("---- tti=%u | nof_ues=%zd ----\n", tti_rx.to_uint(), ue_db.size());
ue_tester->new_tti(this, tti_info.tti_params.tti_rx); ue_tester->new_tti(this, tti_rx);
process_tti_events(tti_events); process_tti_events(tti_events);
before_sched(); before_sched();
// Call scheduler for all carriers // Call scheduler for all carriers
tti_info.dl_sched_result.resize(sched_cell_params.size()); tti_info.dl_sched_result.resize(sched_cell_params.size());
for (uint32_t i = 0; i < sched_cell_params.size(); ++i) { for (uint32_t i = 0; i < sched_cell_params.size(); ++i) {
dl_sched(tti_info.tti_params.tti_tx_dl, i, tti_info.dl_sched_result[i]); dl_sched(to_tx_dl(tti_rx).to_uint(), i, tti_info.dl_sched_result[i]);
} }
tti_info.ul_sched_result.resize(sched_cell_params.size()); tti_info.ul_sched_result.resize(sched_cell_params.size());
for (uint32_t i = 0; i < sched_cell_params.size(); ++i) { for (uint32_t i = 0; i < sched_cell_params.size(); ++i) {
ul_sched(tti_info.tti_params.tti_tx_ul, i, tti_info.ul_sched_result[i]); ul_sched(to_tx_ul(tti_rx).to_uint(), i, tti_info.ul_sched_result[i]);
} }
process_results(); process_results();

@ -94,7 +94,7 @@ public:
cell_params(cell_params_) cell_params(cell_params_)
{} {}
void new_tti(sched* sched_ptr, uint32_t tti_rx); void new_tti(sched* sched_ptr, tti_point tti_rx);
bool user_exists(uint16_t rnti) const { return users.find(rnti) != users.end(); } bool user_exists(uint16_t rnti) const { return users.find(rnti) != users.end(); }
const ue_ctxt_test* get_user_ctxt(uint16_t rnti) const const ue_ctxt_test* get_user_ctxt(uint16_t rnti) const
{ {
@ -128,7 +128,7 @@ public:
cell_params(std::move(cell_params_)) cell_params(std::move(cell_params_))
{} {}
void process_results(const tti_params_t& tti_params, void process_results(tti_point tti_rx,
const std::vector<sched_interface::dl_sched_res_t>& dl_result, const std::vector<sched_interface::dl_sched_res_t>& dl_result,
const std::vector<sched_interface::ul_sched_res_t>& ul_result); const std::vector<sched_interface::ul_sched_res_t>& ul_result);
@ -151,7 +151,6 @@ class common_sched_tester : public sched
{ {
public: public:
struct tti_info_t { struct tti_info_t {
tti_params_t tti_params{10241};
uint32_t nof_prachs = 0; uint32_t nof_prachs = 0;
std::vector<sched_interface::dl_sched_res_t> dl_sched_result; std::vector<sched_interface::dl_sched_res_t> dl_sched_result;
std::vector<sched_interface::ul_sched_res_t> ul_sched_result; std::vector<sched_interface::ul_sched_res_t> ul_sched_result;
@ -176,9 +175,9 @@ public:
srslte::log* tester_log = nullptr; srslte::log* tester_log = nullptr;
// tti specific params // tti specific params
tti_info_t tti_info; tti_info_t tti_info;
srslte::tti_point tic; tti_point tti_rx;
uint32_t tti_count = 0; uint32_t tti_count = 0;
// testers // testers
std::unique_ptr<user_state_sched_tester> ue_tester; std::unique_ptr<user_state_sched_tester> ue_tester;

@ -160,17 +160,16 @@ void sched_tester::before_sched()
uint16_t rnti = it.first; uint16_t rnti = it.first;
srsenb::sched_ue* user = &it.second; srsenb::sched_ue* user = &it.second;
tester_user_results d; tester_user_results d;
srsenb::ul_harq_proc* hul = user->get_ul_harq(tti_info.tti_params.tti_tx_ul, CARRIER_IDX); srsenb::ul_harq_proc* hul = user->get_ul_harq(srsenb::to_tx_ul(tti_rx), CARRIER_IDX);
d.ul_pending_data = get_ul_buffer(rnti); d.ul_pending_data = get_ul_buffer(rnti);
// user->get_pending_ul_new_data(tti_info.tti_params.tti_tx_ul) or hul->has_pending_retx(); // // user->get_pending_ul_new_data(tti_info.tti_params.tti_tx_ul) or hul->has_pending_retx(); //
// get_ul_buffer(rnti); // get_ul_buffer(rnti);
d.dl_pending_data = get_dl_buffer(rnti); d.dl_pending_data = get_dl_buffer(rnti);
d.has_ul_retx = hul->has_pending_retx(); d.has_ul_retx = hul->has_pending_retx();
d.has_ul_tx = d.has_ul_retx or d.ul_pending_data > 0; d.has_ul_tx = d.has_ul_retx or d.ul_pending_data > 0;
srsenb::dl_harq_proc* hdl = user->get_pending_dl_harq(tti_info.tti_params.tti_tx_dl, CARRIER_IDX); srsenb::dl_harq_proc* hdl = user->get_pending_dl_harq(srsenb::to_tx_dl(tti_rx), CARRIER_IDX);
d.has_dl_tx = d.has_dl_tx = (hdl != nullptr) or (it.second.get_empty_dl_harq(srsenb::to_tx_dl(tti_rx), CARRIER_IDX) != nullptr and
(hdl != nullptr) or d.dl_pending_data > 0);
(it.second.get_empty_dl_harq(tti_info.tti_params.tti_tx_dl, CARRIER_IDX) != nullptr and d.dl_pending_data > 0);
d.has_ul_newtx = not d.has_ul_retx and d.ul_pending_data > 0; d.has_ul_newtx = not d.has_ul_retx and d.ul_pending_data > 0;
tti_data.ue_data.insert(std::make_pair(rnti, d)); tti_data.ue_data.insert(std::make_pair(rnti, d));
tti_data.total_ues.dl_pending_data += d.dl_pending_data; tti_data.total_ues.dl_pending_data += d.dl_pending_data;
@ -184,7 +183,7 @@ void sched_tester::before_sched()
tti_data.ue_data[rnti].dl_harqs[i] = h; tti_data.ue_data[rnti].dl_harqs[i] = h;
} }
// NOTE: ACK might have just cleared the harq for tti_info.tti_params.tti_tx_ul // NOTE: ACK might have just cleared the harq for tti_info.tti_params.tti_tx_ul
tti_data.ue_data[rnti].ul_harq = *user->get_ul_harq(tti_info.tti_params.tti_tx_ul, CARRIER_IDX); tti_data.ue_data[rnti].ul_harq = *user->get_ul_harq(srsenb::to_tx_ul(tti_rx), CARRIER_IDX);
} }
// TODO: Check whether pending pending_rar.rar_tti correspond to a prach_tti // TODO: Check whether pending pending_rar.rar_tti correspond to a prach_tti
@ -192,11 +191,9 @@ void sched_tester::before_sched()
int sched_tester::process_results() int sched_tester::process_results()
{ {
const srsenb::cc_sched_result* cc_result = const srsenb::cc_sched_result* cc_result = sched_results.get_cc(tti_rx, CARRIER_IDX);
sched_results.get_cc(srslte::tti_point{tti_info.tti_params.tti_rx}, CARRIER_IDX); srsenb::sf_output_res_t sf_out{sched_cell_params, tti_rx, tti_info.ul_sched_result, tti_info.dl_sched_result};
srsenb::sf_output_res_t sf_out{ TESTASSERT(tti_rx == cc_result->tti_rx);
sched_cell_params, tti_point{tti_info.tti_params.tti_rx}, tti_info.ul_sched_result, tti_info.dl_sched_result};
TESTASSERT(tti_info.tti_params.tti_rx == cc_result->tti_params.tti_rx);
// Common tests // Common tests
TESTASSERT(test_pdcch_collisions(sf_out, CARRIER_IDX, &cc_result->pdcch_mask) == SRSLTE_SUCCESS); TESTASSERT(test_pdcch_collisions(sf_out, CARRIER_IDX, &cc_result->pdcch_mask) == SRSLTE_SUCCESS);
@ -248,10 +245,10 @@ int sched_tester::test_harqs()
uint32_t h_id = data.dci.pid; uint32_t h_id = data.dci.pid;
uint16_t rnti = data.dci.rnti; uint16_t rnti = data.dci.rnti;
const srsenb::dl_harq_proc& h = ue_db[rnti].get_dl_harq(h_id, CARRIER_IDX); const srsenb::dl_harq_proc& h = ue_db[rnti].get_dl_harq(h_id, CARRIER_IDX);
CONDERROR(h.get_tti() != tti_point{tti_info.tti_params.tti_tx_dl}, CONDERROR(h.get_tti() != srsenb::to_tx_dl(tti_rx),
"The scheduled DL harq pid=%d does not a valid tti=%u\n", "The scheduled DL harq pid=%d does not a valid tti=%u\n",
h_id, h_id,
tti_info.tti_params.tti_tx_dl); srsenb::to_tx_dl(tti_rx).to_uint());
CONDERROR(h.get_n_cce() != data.dci.location.ncce, "Harq DCI location does not match with result\n"); CONDERROR(h.get_n_cce() != data.dci.location.ncce, "Harq DCI location does not match with result\n");
} }
@ -259,7 +256,7 @@ int sched_tester::test_harqs()
for (uint32_t i = 0; i < tti_info.ul_sched_result[CARRIER_IDX].nof_phich_elems; ++i) { for (uint32_t i = 0; i < tti_info.ul_sched_result[CARRIER_IDX].nof_phich_elems; ++i) {
const auto& phich = tti_info.ul_sched_result[CARRIER_IDX].phich[i]; const auto& phich = tti_info.ul_sched_result[CARRIER_IDX].phich[i];
const auto& hprev = tti_data.ue_data[phich.rnti].ul_harq; const auto& hprev = tti_data.ue_data[phich.rnti].ul_harq;
const auto* h = ue_db[phich.rnti].get_ul_harq(tti_info.tti_params.tti_tx_ul, CARRIER_IDX); const auto* h = ue_db[phich.rnti].get_ul_harq(srsenb::to_tx_ul(tti_rx), CARRIER_IDX);
CONDERROR(not hprev.has_pending_phich(), "Alloc PHICH did not have any pending ack\n"); CONDERROR(not hprev.has_pending_phich(), "Alloc PHICH did not have any pending ack\n");
bool maxretx_flag = hprev.nof_retx(0) + 1 >= hprev.max_nof_retx(); bool maxretx_flag = hprev.nof_retx(0) + 1 >= hprev.max_nof_retx();
if (phich.phich == sched_interface::ul_sched_phich_t::ACK) { if (phich.phich == sched_interface::ul_sched_phich_t::ACK) {

Loading…
Cancel
Save