store mask results in separate variables for testing, and reset sf_sched state at the end of the tti

This commit is contained in:
Francisco Paisana 2020-03-04 15:44:19 +00:00
parent afc209711c
commit 8f7890c60a
5 changed files with 112 additions and 71 deletions

View File

@ -98,7 +98,6 @@ private:
std::array<sched_sib_t, sched_interface::MAX_SIBS> pending_sibs;
// TTI specific
uint32_t current_sfn = 0, current_sf_idx = 0;
uint32_t current_tti = 0;
uint32_t bc_aggr_level = 2;
};

View File

@ -69,6 +69,7 @@ public:
void init(const sched_cell_params_t& cell_params_);
void new_tti(const tti_params_t& tti_params_, uint32_t start_cfi);
void reset();
bool alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user = nullptr);
bool set_cfi(uint32_t cfi);
@ -84,7 +85,6 @@ private:
const static uint32_t nof_cfis = 3;
using tree_node_t = std::pair<int, alloc_t>; ///< First represents the parent node idx, and second the alloc tree node
void reset();
const sched_dci_cce_t* get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user) const;
void update_alloc_tree(int node_idx,
uint32_t aggr_idx,
@ -104,7 +104,7 @@ private:
size_t nof_dci_allocs = 0;
};
//! manages a full TTI grid resources, namely CCE and DL/UL RB allocations
//! manages a subframe grid resources, namely CCE and DL/UL RB allocations
class sf_grid_t
{
public:
@ -113,16 +113,17 @@ public:
rbg_range_t rbg_range;
};
void init(const sched_cell_params_t& cell_params_, uint32_t enb_cc_idx_);
void init(const sched_cell_params_t& cell_params_);
void new_tti(const tti_params_t& tti_params_, uint32_t start_cfi);
void reset();
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);
bool reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg);
alloc_outcome_t alloc_ul_data(sched_ue* user, ul_harq_proc::ul_alloc_t alloc, bool needs_pdcch);
bool reserve_ul_prbs(const prbmask_t& prbmask, bool strict);
// getters
rbgmask_t& get_dl_mask() { return dl_mask; }
const rbgmask_t& get_dl_mask() const { return dl_mask; }
prbmask_t& get_ul_mask() { return ul_mask; }
const prbmask_t& get_ul_mask() const { return ul_mask; }
uint32_t get_cfi() const { return pdcch_alloc.get_cfi(); }
const pdcch_grid_t& get_pdcch_grid() const { return pdcch_alloc; }
@ -168,8 +169,8 @@ public:
virtual bool is_ul_alloc(sched_ue* user) const = 0;
};
/** Description: Stores the RAR, broadcast, paging, DL data, UL data allocations for the given TTI
* Converts the stored allocations' metadata to the scheduler UL/DL result
/** Description: Stores the RAR, broadcast, paging, DL data, UL data allocations for the given subframe
* Converts the stored allocations' metadata to the scheduler DL/UL result
* Handles the generation of DCI formats
*/
class sf_sched : public dl_sf_sched_itf, public ul_sf_sched_itf
@ -219,32 +220,36 @@ public:
uint32_t mcs = 0;
};
struct pending_rar_t {
uint16_t ra_rnti = 0;
uint32_t prach_tti = 0;
uint32_t nof_grants = 0;
sched_interface::dl_sched_rar_info_t msg3_grant[sched_interface::MAX_RAR_LIST];
uint16_t ra_rnti = 0;
uint32_t prach_tti = 0;
uint32_t nof_grants = 0;
sched_interface::dl_sched_rar_info_t msg3_grant[sched_interface::MAX_RAR_LIST] = {};
};
typedef std::pair<alloc_outcome_t, const ctrl_alloc_t> ctrl_code_t;
// TTI scheduler result
pdcch_mask_t pdcch_mask;
sched_interface::dl_sched_res_t dl_sched_result;
sched_interface::ul_sched_res_t ul_sched_result;
// Control/Configuration Methods
void init(const sched_cell_params_t& cell_params_);
void new_tti(uint32_t tti_rx_, uint32_t start_cfi);
void reset();
// DL alloc
// DL alloc methods
alloc_outcome_t alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx);
alloc_outcome_t alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload);
std::pair<alloc_outcome_t, uint32_t> alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar_grant);
bool reserve_dl_rbgs(uint32_t rbg_start, uint32_t rbg_end) { return tti_alloc.reserve_dl_rbgs(rbg_start, rbg_end); }
// UL alloc
// UL alloc methods
alloc_outcome_t alloc_msg3(const pending_msg3_t& msg3);
alloc_outcome_t
alloc_ul(sched_ue* user, ul_harq_proc::ul_alloc_t alloc, sf_sched::ul_alloc_t::type_t alloc_type, uint32_t mcs = 0);
alloc_ul(sched_ue* user, ul_harq_proc::ul_alloc_t alloc, sf_sched::ul_alloc_t::type_t alloc_type, uint32_t mcs = 0);
bool reserve_ul_prbs(const prbmask_t& ulmask, bool strict) { return tti_alloc.reserve_ul_prbs(ulmask, strict); }
void generate_dcis();
// compute DCIs and generate dl_sched_result/ul_sched_result for a given TTI
void generate_sched_results();
// dl_tti_sched itf
alloc_outcome_t alloc_dl_user(sched_ue* user, const rbgmask_t& user_mask, uint32_t pid) final;
@ -257,18 +262,13 @@ public:
uint32_t get_tti_tx_ul() const final { return tti_params.tti_tx_ul; }
// getters
const pdcch_mask_t& get_pdcch_mask() const { return pdcch_mask; }
rbgmask_t& get_dl_mask() { return tti_alloc.get_dl_mask(); }
prbmask_t& get_ul_mask() { return tti_alloc.get_ul_mask(); }
const std::vector<ul_alloc_t>& get_ul_allocs() const { return ul_data_allocs; }
uint32_t get_cfi() const { return tti_alloc.get_cfi(); }
uint32_t get_tti_rx() const { return tti_params.tti_rx; }
uint32_t get_sfn() const { return tti_params.sfn; }
uint32_t get_sf_idx() const { return tti_params.sf_idx; }
const tti_params_t& get_tti_params() const { return tti_params; }
std::deque<pending_msg3_t>& get_pending_msg3() { return pending_msg3s; }
const std::deque<pending_msg3_t>& get_pending_msg3() const { return pending_msg3s; }
const std::tuple<pdcch_mask_t, rbgmask_t, prbmask_t> last_sched_result_masks() const;
private:
bool is_dl_alloc(sched_ue* user) const final;
bool is_ul_alloc(sched_ue* user) const final;
@ -297,6 +297,11 @@ private:
std::vector<ul_alloc_t> ul_data_allocs;
std::deque<pending_msg3_t> pending_msg3s;
uint32_t last_msg3_prb = 0, max_msg3_prb = 0;
// Store last decisions
rbgmask_t last_dl_mask;
prbmask_t last_ul_mask;
pdcch_mask_t last_pdcch_mask;
};
} // namespace srsenb

View File

@ -38,10 +38,8 @@ bc_sched::bc_sched(const sched_cell_params_t& cfg_, srsenb::rrc_interface_mac* r
void bc_sched::dl_sched(sf_sched* tti_sched)
{
current_sf_idx = tti_sched->get_sf_idx();
current_sfn = tti_sched->get_sfn();
current_tti = tti_sched->get_tti_tx_dl();
bc_aggr_level = 2;
current_tti = tti_sched->get_tti_tx_dl();
bc_aggr_level = 2;
/* Activate/deactivate SI windows */
update_si_windows(tti_sched);
@ -56,7 +54,9 @@ void bc_sched::dl_sched(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();
uint32_t tti_tx_dl = tti_sched->get_tti_tx_dl();
uint32_t current_sf_idx = tti_sched->get_tti_params().sf_idx;
uint32_t current_sfn = tti_sched->get_tti_params().sfn;
for (uint32_t i = 0; i < pending_sibs.size(); ++i) {
// There is SIB data
@ -94,6 +94,9 @@ void bc_sched::update_si_windows(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;
uint32_t current_sfn = tti_sched->get_tti_params().sfn;
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) {
uint32_t nof_tx = (i > 0) ? SRSLTE_MIN(srslte::ceil_div(cc_cfg->cfg.si_window_ms, 10), 4) : 4;
@ -371,7 +374,7 @@ sf_sched* sched::carrier_sched::generate_tti_result(uint32_t tti_rx)
}
/* Select the winner DCI allocation combination */
tti_sched->generate_dcis();
tti_sched->generate_sched_results();
/* Enqueue Msg3s derived from allocated RARs */
if (dl_active) {
@ -430,7 +433,7 @@ void sched::carrier_sched::alloc_dl_users(sf_sched* tti_result)
if (cc_cfg->nof_prb() == 6) {
uint32_t tti_rx_ack = TTI_RX_ACK(tti_result->get_tti_rx());
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_rx_ack, -1)) {
tti_result->get_dl_mask().fill(0, tti_result->get_dl_mask().size());
tti_result->reserve_dl_rbgs(0, cc_cfg->nof_rbgs);
}
}
@ -440,12 +443,11 @@ void sched::carrier_sched::alloc_dl_users(sf_sched* tti_result)
int sched::carrier_sched::alloc_ul_users(sf_sched* tti_sched)
{
uint32_t tti_tx_ul = tti_sched->get_tti_tx_ul();
prbmask_t& ul_mask = tti_sched->get_ul_mask();
uint32_t tti_tx_ul = tti_sched->get_tti_tx_ul();
/* reserve PRBs for PRACH */
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_tx_ul, -1)) {
ul_mask = prach_mask;
tti_sched->reserve_ul_prbs(prach_mask, false);
log_h->debug("SCHED: Allocated PRACH RBs. Mask: 0x%s\n", prach_mask.to_hex().c_str());
}
@ -453,12 +455,7 @@ int sched::carrier_sched::alloc_ul_users(sf_sched* tti_sched)
ra_sched_ptr->ul_sched(tti_sched);
/* reserve PRBs for PUCCH */
if (cc_cfg->nof_prb() != 6 and (ul_mask & pucch_mask).any()) {
log_h->error("There was a collision with the PUCCH. current mask=0x%s, pucch_mask=0x%s\n",
ul_mask.to_hex().c_str(),
pucch_mask.to_hex().c_str());
}
ul_mask |= pucch_mask;
tti_sched->reserve_ul_prbs(pucch_mask, true);
/* Call scheduler for UL data */
ul_metric->sched_users(*ue_db, tti_sched);

View File

@ -70,7 +70,6 @@ void pdcch_grid_t::new_tti(const tti_params_t& tti_params_, uint32_t start_cfi)
{
tti_params = &tti_params_;
current_cfix = start_cfi - 1;
reset();
}
const sched_dci_cce_t* pdcch_grid_t::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user) const
@ -208,6 +207,7 @@ void pdcch_grid_t::get_allocs(alloc_result_t* vec, pdcch_mask_t* tot_mask, size_
vec->clear();
}
if (tot_mask != nullptr) {
tot_mask->resize(nof_cces());
tot_mask->reset();
}
return;
@ -265,7 +265,7 @@ std::string pdcch_grid_t::result_to_string(bool verbose) const
* TTI resource Scheduling Methods
*******************************************************/
void sf_grid_t::init(const sched_cell_params_t& cell_params_, uint32_t enb_cc_idx_)
void sf_grid_t::init(const sched_cell_params_t& cell_params_)
{
cc_cfg = &cell_params_;
log_h = srslte::logmap::get("MAC ");
@ -274,6 +274,7 @@ void sf_grid_t::init(const sched_cell_params_t& cell_params_, uint32_t enb_cc_id
rar_n_rbg = srslte::ceil_div(3, cc_cfg->P);
pdcch_alloc.init(*cc_cfg);
reset();
}
void sf_grid_t::new_tti(const tti_params_t& tti_params_, uint32_t start_cfi)
@ -282,13 +283,18 @@ void sf_grid_t::new_tti(const tti_params_t& tti_params_, uint32_t start_cfi)
// internal state
avail_rbg = nof_rbgs;
dl_mask.reset();
dl_mask.resize(nof_rbgs);
ul_mask.reset();
ul_mask.resize(cc_cfg->nof_prb());
pdcch_alloc.new_tti(*tti_params, start_cfi);
}
void sf_grid_t::reset()
{
dl_mask.reset();
ul_mask.reset();
pdcch_alloc.reset();
}
//! Allocates CCEs and RBs for the given mask and allocation type (e.g. data, BC, RAR, paging)
alloc_outcome_t sf_grid_t::alloc_dl(uint32_t aggr_lvl, alloc_type_t alloc_type, rbgmask_t alloc_mask, sched_ue* user)
{
@ -381,6 +387,25 @@ alloc_outcome_t sf_grid_t::alloc_ul_data(sched_ue* user, ul_harq_proc::ul_alloc_
return alloc_outcome_t::SUCCESS;
}
bool sf_grid_t::reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg)
{
dl_mask.fill(start_rbg, end_rbg);
return true;
}
bool sf_grid_t::reserve_ul_prbs(const prbmask_t& prbmask, bool strict)
{
bool ret = true;
if (strict and (ul_mask & prbmask).any()) {
log_h->error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s\n",
ul_mask.to_hex().c_str(),
prbmask.to_hex().c_str());
ret = false;
}
ul_mask |= prbmask;
return ret;
}
/*******************************************************
* TTI resource Scheduling Methods
*******************************************************/
@ -389,8 +414,9 @@ void sf_sched::init(const sched_cell_params_t& cell_params_)
{
cc_cfg = &cell_params_;
log_h = srslte::logmap::get("MAC ");
tti_alloc.init(*cc_cfg, 0);
tti_alloc.init(*cc_cfg);
max_msg3_prb = std::max(6u, cc_cfg->cfg.cell.nof_prb - (uint32_t)cc_cfg->cfg.nrb_pucch);
reset();
}
void sf_sched::new_tti(uint32_t tti_rx_, uint32_t start_cfi)
@ -399,17 +425,9 @@ void sf_sched::new_tti(uint32_t tti_rx_, uint32_t start_cfi)
tti_alloc.new_tti(tti_params, start_cfi);
// reset sf result
pdcch_mask.reset();
pdcch_mask.resize(tti_alloc.get_pdcch_grid().nof_cces());
dl_sched_result = {};
ul_sched_result = {};
// reset internal state
bc_allocs.clear();
rar_allocs.clear();
data_allocs.clear();
ul_data_allocs.clear();
// setup first prb to be used for msg3 alloc
last_msg3_prb = cc_cfg->cfg.nrb_pucch;
uint32_t tti_msg3_alloc = TTI_ADD(tti_params.tti_tx_ul, MSG3_DELAY_MS);
@ -418,6 +436,17 @@ void sf_sched::new_tti(uint32_t tti_rx_, uint32_t start_cfi)
}
}
void sf_sched::reset()
{
// reset internal state
bc_allocs.clear();
rar_allocs.clear();
data_allocs.clear();
ul_data_allocs.clear();
tti_alloc.reset();
}
bool sf_sched::is_dl_alloc(sched_ue* user) const
{
for (const auto& a : data_allocs) {
@ -630,6 +659,11 @@ alloc_outcome_t sf_sched::alloc_ul_user(sched_ue* user, ul_harq_proc::ul_alloc_t
return alloc_ul(user, alloc, alloc_type);
}
const std::tuple<pdcch_mask_t, rbgmask_t, prbmask_t> sf_sched::last_sched_result_masks() const
{
return {last_pdcch_mask, last_dl_mask, last_ul_mask};
}
void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_result)
{
for (const auto& bc_alloc : bc_allocs) {
@ -769,13 +803,13 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_
int tbs = 0;
switch (dci_format) {
case SRSLTE_DCI_FORMAT1:
tbs = user->generate_format1(h, data, get_tti_tx_dl(), cell_index, get_cfi(), data_alloc.user_mask);
tbs = user->generate_format1(h, data, get_tti_tx_dl(), cell_index, tti_alloc.get_cfi(), data_alloc.user_mask);
break;
case SRSLTE_DCI_FORMAT2:
tbs = user->generate_format2(h, data, get_tti_tx_dl(), cell_index, get_cfi(), data_alloc.user_mask);
tbs = user->generate_format2(h, data, get_tti_tx_dl(), cell_index, tti_alloc.get_cfi(), data_alloc.user_mask);
break;
case SRSLTE_DCI_FORMAT2A:
tbs = user->generate_format2a(h, data, get_tti_tx_dl(), cell_index, get_cfi(), data_alloc.user_mask);
tbs = user->generate_format2a(h, data, get_tti_tx_dl(), cell_index, tti_alloc.get_cfi(), data_alloc.user_mask);
break;
default:
Error("DCI format (%d) not implemented\n", dci_format);
@ -874,12 +908,12 @@ alloc_outcome_t sf_sched::alloc_msg3(const pending_msg3_t& msg3)
return alloc_outcome_t::SUCCESS;
}
void sf_sched::generate_dcis()
void sf_sched::generate_sched_results()
{
/* Pick one of the possible DCI masks */
pdcch_grid_t::alloc_result_t dci_result;
// tti_alloc.get_pdcch_grid().result_to_string();
tti_alloc.get_pdcch_grid().get_allocs(&dci_result, &pdcch_mask);
tti_alloc.get_pdcch_grid().get_allocs(&dci_result, &last_pdcch_mask);
/* Register final CFI */
dl_sched_result.cfi = tti_alloc.get_pdcch_grid().get_cfi();
@ -892,6 +926,13 @@ void sf_sched::generate_dcis()
set_dl_data_sched_result(dci_result);
set_ul_sched_result(dci_result);
/* Store last results */
last_dl_mask = tti_alloc.get_dl_mask();
last_ul_mask = tti_alloc.get_ul_mask();
/* Reset all resources */
reset();
}
uint32_t sf_sched::get_nof_ctrl_symbols() const

View File

@ -252,9 +252,10 @@ int sched_tester::test_pdcch_collisions()
tti_info.dl_sched_result[CARRIER_IDX], tti_info.ul_sched_result[CARRIER_IDX]) == SRSLTE_SUCCESS);
/* verify if sched_result "used_cce" coincide with sched "used_cce" */
auto* tti_alloc = carrier_schedulers[0]->get_sf_sched_ptr(tti_info.tti_params.tti_rx);
if (used_cce != tti_alloc->get_pdcch_mask()) {
std::string mask_str = tti_alloc->get_pdcch_mask().to_string();
auto* tti_alloc = carrier_schedulers[0]->get_sf_sched_ptr(tti_info.tti_params.tti_rx);
srsenb::pdcch_mask_t mask = std::get<0>(tti_alloc->last_sched_result_masks());
if (used_cce != mask) {
std::string mask_str = mask.to_string();
TESTERROR("The used_cce do not match: (%s!=%s)\n", mask_str.c_str(), used_cce.to_string().c_str());
}
@ -375,15 +376,17 @@ int sched_tester::test_harqs()
int sched_tester::test_sch_collisions()
{
const srsenb::sf_sched* tti_sched = carrier_schedulers[0]->get_sf_sched_ptr(tti_info.tti_params.tti_rx);
srsenb::prbmask_t ul_allocs(sched_cell_params[CARRIER_IDX].cfg.cell.nof_prb);
const srsenb::sf_sched* tti_sched = carrier_schedulers[CARRIER_IDX]->get_sf_sched_ptr(tti_info.tti_params.tti_rx);
const auto& combined_sched_result = tti_sched->last_sched_result_masks();
srsenb::prbmask_t ul_allocs(sched_cell_params[CARRIER_IDX].cfg.cell.nof_prb);
/* TEST: any collision in PUCCH and PUSCH */
TESTASSERT(output_tester[CARRIER_IDX].test_pusch_collisions(
tti_info.tti_params, tti_info.ul_sched_result[CARRIER_IDX], ul_allocs) == SRSLTE_SUCCESS);
/* TEST: check whether cumulative UL PRB masks coincide */
if (ul_allocs != tti_sched->get_ul_mask()) {
if (ul_allocs != std::get<2>(combined_sched_result)) {
TESTERROR("The UL PRB mask and the scheduler result UL mask are not consistent\n");
}
@ -413,14 +416,10 @@ int sched_tester::test_sch_collisions()
}
// TEST: check if resulting DL mask is equal to scheduler internal DL mask
if (rbgmask != carrier_schedulers[0]->get_sf_sched_ptr(tti_info.tti_params.tti_rx)->get_dl_mask()) {
TESTERROR("The UL PRB mask and the scheduler result UL mask are not consistent (%s!=%s)\n",
if (rbgmask != std::get<1>(combined_sched_result)) {
TESTERROR("The DL PRB mask and the scheduler result DL mask are not consistent (%s!=%s)\n",
rbgmask.to_string().c_str(),
carrier_schedulers[CARRIER_IDX]
->get_sf_sched_ptr(tti_info.tti_params.tti_rx)
->get_dl_mask()
.to_string()
.c_str());
std::get<1>(combined_sched_result).to_string().c_str());
}
return SRSLTE_SUCCESS;
}