nr,gnb,sched: expose cqi in slot_ue object

master
Francisco 3 years ago committed by Francisco Paisana
parent 2a933ed8ad
commit ffca2f7684

@ -65,10 +65,12 @@ public:
uint32_t cc = SRSRAN_MAX_CARRIERS; uint32_t cc = SRSRAN_MAX_CARRIERS;
ue_buffer_manager* parent = nullptr; ue_buffer_manager* parent = nullptr;
}; };
};
private: /// Class containing context of UE that is common to all carriers
/// Update of buffers is mutexed when carrier aggreg. is in place struct ue_context_common {
std::mutex mutex; uint32_t pending_dl_bytes = 0;
uint32_t pending_ul_bytes = 0;
}; };
class slot_ue; class slot_ue;
@ -79,6 +81,7 @@ public:
ue_carrier(uint16_t rnti, ue_carrier(uint16_t rnti,
const ue_cfg_t& cfg, const ue_cfg_t& cfg,
const cell_params_t& cell_params_, const cell_params_t& cell_params_,
const ue_context_common& ctxt,
const ue_buffer_manager::pdu_builder& pdu_builder_); const ue_buffer_manager::pdu_builder& pdu_builder_);
void set_cfg(const ue_cfg_t& ue_cfg); void set_cfg(const ue_cfg_t& ue_cfg);
@ -102,6 +105,9 @@ public:
// metrics // metrics
mac_ue_metrics_t metrics = {}; mac_ue_metrics_t metrics = {};
// common context
const ue_context_common& common_ctxt;
private: private:
friend class slot_ue; friend class slot_ue;
@ -127,7 +133,7 @@ public:
/// UE state feedback /// UE state feedback
void ul_bsr(uint32_t lcg, uint32_t bsr_val) { buffers.ul_bsr(lcg, bsr_val); } void ul_bsr(uint32_t lcg, uint32_t bsr_val) { buffers.ul_bsr(lcg, bsr_val); }
void ul_sr_info() { last_sr_slot = last_pdcch_slot - TX_ENB_DELAY; } void ul_sr_info() { last_sr_slot = last_tx_slot - TX_ENB_DELAY; }
bool has_ca() const bool has_ca() const
{ {
@ -146,9 +152,9 @@ private:
ue_cfg_t ue_cfg; ue_cfg_t ue_cfg;
slot_point last_pdcch_slot; slot_point last_tx_slot;
slot_point last_sr_slot; slot_point last_sr_slot;
int ul_pending_bytes = 0, dl_pending_bytes = 0; ue_context_common common_ctxt;
ue_buffer_manager buffers; ue_buffer_manager buffers;
}; };
@ -157,25 +163,29 @@ class slot_ue
{ {
public: public:
slot_ue() = default; slot_ue() = default;
explicit slot_ue(ue_carrier& ue, slot_point slot_tx_, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes); explicit slot_ue(ue_carrier& ue, slot_point slot_tx_);
slot_ue(slot_ue&&) noexcept = default; slot_ue(slot_ue&&) noexcept = default;
slot_ue& operator=(slot_ue&&) noexcept = default; slot_ue& operator=(slot_ue&&) noexcept = default;
bool empty() const { return ue == nullptr; } bool empty() const { return ue == nullptr; }
void release() { ue = nullptr; } void release() { ue = nullptr; }
const ue_carrier_params_t& cfg() const { return ue->bwp_cfg; } const ue_carrier_params_t& cfg() const { return ue->bwp_cfg; }
const ue_carrier_params_t& operator*() const { return ue->bwp_cfg; }
const ue_carrier_params_t* operator->() const { return &ue->bwp_cfg; } const ue_carrier_params_t* operator->() const { return &ue->bwp_cfg; }
// mutable interface to ue_carrier state /// Find available HARQs
dl_harq_proc* find_empty_dl_harq() { return ue->harq_ent.find_empty_dl_harq(); } dl_harq_proc* find_empty_dl_harq() { return ue->harq_ent.find_empty_dl_harq(); }
ul_harq_proc* find_empty_ul_harq() { return ue->harq_ent.find_empty_ul_harq(); } ul_harq_proc* find_empty_ul_harq() { return ue->harq_ent.find_empty_ul_harq(); }
/// Build PDU with MAC CEs and MAC SDUs
void build_pdu(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu) void build_pdu(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu)
{ {
ue->pdu_builder.alloc_subpdus(rem_bytes, pdu); ue->pdu_builder.alloc_subpdus(rem_bytes, pdu);
} }
/// Channel Information Getters
uint32_t dl_cqi() const { return ue->dl_cqi; }
uint32_t ul_cqi() const { return ue->ul_cqi; }
// UE parameters common to all sectors // UE parameters common to all sectors
uint32_t dl_bytes = 0, ul_bytes = 0; uint32_t dl_bytes = 0, ul_bytes = 0;

@ -34,7 +34,14 @@ void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uin
for (const auto& ue_pair : slot_ues) { for (const auto& ue_pair : slot_ues) {
auto& ue = ue_pair->second; auto& ue = ue_pair->second;
fmt::format_to(fmtbuf, "{}{{rnti=0x{:x}, dl_bs={}, ul_bs={}}}", use_comma, ue->rnti, ue.dl_bytes, ue.ul_bytes); fmt::format_to(fmtbuf, "{}{{rnti=0x{:x}", use_comma, ue->rnti);
if (ue.dl_active) {
fmt::format_to(fmtbuf, ", dl_bs={}", ue.dl_bytes);
}
if (ue.ul_active) {
fmt::format_to(fmtbuf, ", ul_bs={}", ue.ul_bytes);
}
fmt::format_to(fmtbuf, "}}");
use_comma = ", "; use_comma = ", ";
} }

@ -121,9 +121,9 @@ alloc_result pdsch_allocator::is_ue_grant_valid(const ue_carrier_params_t& ue,
log_alloc_failure(bwp_cfg.logger.error, "rnti=0x%x,SearchSpaceId={} has not been configured.", ue.rnti, ss_id); log_alloc_failure(bwp_cfg.logger.error, "rnti=0x%x,SearchSpaceId={} has not been configured.", ue.rnti, ss_id);
return alloc_result::invalid_grant_params; return alloc_result::invalid_grant_params;
} }
alloc_result alloc_result = is_grant_valid_common(ss->type, dci_fmt, ss->coreset_id, grant); alloc_result ret = is_grant_valid_common(ss->type, dci_fmt, ss->coreset_id, grant);
if (alloc_result != alloc_result::success) { if (ret != alloc_result::success) {
return alloc_result; return ret;
} }
// TS 38.214, 5.1.2.2 - "the UE shall use the downlink frequency resource allocation type as defined by the higher // TS 38.214, 5.1.2.2 - "the UE shall use the downlink frequency resource allocation type as defined by the higher

@ -53,8 +53,7 @@ void ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes, sched_nr_
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) : slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_) : ue(&ue_), pdcch_slot(slot_tx_)
ue(&ue_), pdcch_slot(slot_tx_)
{ {
const uint32_t k0 = 0; const uint32_t k0 = 0;
pdsch_slot = pdcch_slot + k0; pdsch_slot = pdcch_slot + k0;
@ -65,17 +64,17 @@ slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_, uint32_t dl_pending_bytes
const srsran_duplex_config_nr_t& tdd_cfg = ue->cell_params.cfg.duplex; const srsran_duplex_config_nr_t& tdd_cfg = ue->cell_params.cfg.duplex;
dl_active = srsran_duplex_nr_is_dl(&tdd_cfg, 0, pdsch_slot.slot_idx()); dl_active = ue->cell_params.bwps[0].slots[pdsch_slot.slot_idx()].is_dl;
if (dl_active) { if (dl_active) {
dl_bytes = dl_pending_bytes; dl_bytes = ue->common_ctxt.pending_dl_bytes;
h_dl = ue->harq_ent.find_pending_dl_retx(); h_dl = ue->harq_ent.find_pending_dl_retx();
if (h_dl == nullptr) { if (h_dl == nullptr) {
h_dl = ue->harq_ent.find_empty_dl_harq(); h_dl = ue->harq_ent.find_empty_dl_harq();
} }
} }
ul_active = srsran_duplex_nr_is_ul(&tdd_cfg, 0, pusch_slot.slot_idx()); ul_active = ue->cell_params.bwps[0].slots[pusch_slot.slot_idx()].is_ul;
if (ul_active) { if (ul_active) {
ul_bytes = ul_pending_bytes; ul_bytes = ue->common_ctxt.pending_ul_bytes;
h_ul = ue->harq_ent.find_pending_ul_retx(); h_ul = ue->harq_ent.find_pending_ul_retx();
if (h_ul == nullptr) { if (h_ul == nullptr) {
h_ul = ue->harq_ent.find_empty_ul_harq(); h_ul = ue->harq_ent.find_empty_ul_harq();
@ -88,6 +87,7 @@ slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_, uint32_t dl_pending_bytes
ue_carrier::ue_carrier(uint16_t rnti_, ue_carrier::ue_carrier(uint16_t rnti_,
const ue_cfg_t& uecfg_, const ue_cfg_t& uecfg_,
const cell_params_t& cell_params_, const cell_params_t& cell_params_,
const ue_context_common& ctxt,
const ue_buffer_manager::pdu_builder& pdu_builder_) : const ue_buffer_manager::pdu_builder& pdu_builder_) :
rnti(rnti_), rnti(rnti_),
cc(cell_params_.cc), cc(cell_params_.cc),
@ -95,6 +95,7 @@ ue_carrier::ue_carrier(uint16_t rnti_,
bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_), bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_),
cell_params(cell_params_), cell_params(cell_params_),
pdu_builder(pdu_builder_), pdu_builder(pdu_builder_),
common_ctxt(ctxt),
harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger) harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger)
{} {}
@ -142,8 +143,11 @@ void ue::set_cfg(const ue_cfg_t& cfg)
for (auto& ue_cc_cfg : cfg.carriers) { for (auto& ue_cc_cfg : cfg.carriers) {
if (ue_cc_cfg.active) { if (ue_cc_cfg.active) {
if (carriers[ue_cc_cfg.cc] == nullptr) { if (carriers[ue_cc_cfg.cc] == nullptr) {
carriers[ue_cc_cfg.cc].reset(new ue_carrier( carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti,
rnti, ue_cfg, sched_cfg.cells[ue_cc_cfg.cc], ue_buffer_manager::pdu_builder{ue_cc_cfg.cc, buffers})); ue_cfg,
sched_cfg.cells[ue_cc_cfg.cc],
common_ctxt,
ue_buffer_manager::pdu_builder{ue_cc_cfg.cc, buffers}));
} else { } else {
carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg); carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg);
} }
@ -175,7 +179,7 @@ void ue::rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t priotx)
void ue::new_slot(slot_point pdcch_slot) void ue::new_slot(slot_point pdcch_slot)
{ {
last_pdcch_slot = pdcch_slot; last_tx_slot = pdcch_slot;
for (std::unique_ptr<ue_carrier>& cc : carriers) { for (std::unique_ptr<ue_carrier>& cc : carriers) {
if (cc != nullptr) { if (cc != nullptr) {
@ -185,18 +189,18 @@ void ue::new_slot(slot_point pdcch_slot)
// Compute pending DL/UL bytes for {rnti, pdcch_slot} // Compute pending DL/UL bytes for {rnti, pdcch_slot}
if (sched_cfg.sched_cfg.auto_refill_buffer) { if (sched_cfg.sched_cfg.auto_refill_buffer) {
dl_pending_bytes = 1000000; common_ctxt.pending_dl_bytes = 1000000;
ul_pending_bytes = 1000000; common_ctxt.pending_ul_bytes = 1000000;
} else { } else {
dl_pending_bytes = buffers.get_dl_tx_total(); common_ctxt.pending_dl_bytes = buffers.get_dl_tx_total();
ul_pending_bytes = buffers.get_bsr(); common_ctxt.pending_ul_bytes = buffers.get_bsr();
for (auto& ue_cc_cfg : ue_cfg.carriers) { for (auto& ue_cc_cfg : ue_cfg.carriers) {
auto& cc = carriers[ue_cc_cfg.cc]; auto& cc = carriers[ue_cc_cfg.cc];
if (cc != nullptr) { if (cc != nullptr) {
// Discount UL HARQ pending bytes to BSR // Discount UL HARQ pending bytes to BSR
for (uint32_t pid = 0; pid < cc->harq_ent.nof_ul_harqs(); ++pid) { for (uint32_t pid = 0; pid < cc->harq_ent.nof_ul_harqs(); ++pid) {
if (not cc->harq_ent.ul_harq(pid).empty()) { if (not cc->harq_ent.ul_harq(pid).empty()) {
ul_pending_bytes -= cc->harq_ent.ul_harq(pid).tbs(); common_ctxt.pending_ul_bytes -= std::min(cc->harq_ent.ul_harq(pid).tbs(), common_ctxt.pending_ul_bytes);
if (last_sr_slot.valid() and cc->harq_ent.ul_harq(pid).harq_slot_tx() > last_sr_slot) { if (last_sr_slot.valid() and cc->harq_ent.ul_harq(pid).harq_slot_tx() > last_sr_slot) {
last_sr_slot.clear(); last_sr_slot.clear();
} }
@ -204,10 +208,9 @@ void ue::new_slot(slot_point pdcch_slot)
} }
} }
} }
ul_pending_bytes = std::max(0, ul_pending_bytes); if (common_ctxt.pending_ul_bytes == 0 and last_sr_slot.valid()) {
if (ul_pending_bytes == 0 and last_sr_slot.valid()) {
// If unanswered SR is pending // If unanswered SR is pending
ul_pending_bytes = 512; common_ctxt.pending_ul_bytes = 512;
} }
} }
} }
@ -215,7 +218,7 @@ void ue::new_slot(slot_point pdcch_slot)
slot_ue ue::make_slot_ue(slot_point pdcch_slot, uint32_t cc) slot_ue ue::make_slot_ue(slot_point pdcch_slot, uint32_t cc)
{ {
srsran_assert(carriers[cc] != nullptr, "make_slot_ue() called for inexistent rnti=0x%x,cc=%d", rnti, cc); srsran_assert(carriers[cc] != nullptr, "make_slot_ue() called for inexistent rnti=0x%x,cc=%d", rnti, cc);
return slot_ue(*carriers[cc], pdcch_slot, dl_pending_bytes, ul_pending_bytes); return slot_ue(*carriers[cc], pdcch_slot);
} }
} // namespace sched_nr_impl } // namespace sched_nr_impl

@ -6,6 +6,8 @@
# the distribution. # the distribution.
# #
set_directory_properties(PROPERTIES LABELS "sched;nr")
add_library(sched_nr_test_suite sched_nr_common_test.cc sched_nr_ue_ded_test_suite.cc sched_nr_sim_ue.cc) add_library(sched_nr_test_suite sched_nr_common_test.cc sched_nr_ue_ded_test_suite.cc sched_nr_sim_ue.cc)
target_link_libraries(sched_nr_test_suite srsgnb_mac srsran_common) target_link_libraries(sched_nr_test_suite srsgnb_mac srsran_common)

@ -130,7 +130,7 @@ void test_sched_nr_data()
{ {
uint32_t max_nof_ttis = 1000, nof_sectors = 1; uint32_t max_nof_ttis = 1000, nof_sectors = 1;
uint16_t rnti = 0x4601; uint16_t rnti = 0x4601;
uint32_t nof_dl_bytes_to_tx = 1e6; uint32_t nof_dl_bytes_to_tx = 2e6;
sched_nr_interface::sched_args_t cfg; sched_nr_interface::sched_args_t cfg;
cfg.auto_refill_buffer = false; cfg.auto_refill_buffer = false;

Loading…
Cancel
Save