started to implement separate SIB scheduler, and its tests. This is particualrly important for CA

master
Francisco Paisana 5 years ago
parent 84ac16826f
commit 837c16557f

@ -153,6 +153,7 @@ protected:
uint32_t window_start;
uint32_t n_tx;
} sched_sib_t;
class bc_sched_t;
class tti_sched_t : public dl_tti_sched_t, public ul_tti_sched_t
{

@ -0,0 +1,60 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_SCHEDULER_CTRL_H
#define SRSLTE_SCHEDULER_CTRL_H
#include "scheduler.h"
namespace srsenb {
class sched::bc_sched_t
{
public:
bc_sched_t(cell_cfg_t* cfg_);
void dl_sched(tti_sched_t* tti_sched);
void reset();
private:
struct sched_sib_t {
bool is_in_window = false;
uint32_t window_start = 0;
uint32_t n_tx = 0;
};
void update_si_windows(tti_sched_t* tti_sched);
void alloc_sibs(tti_sched_t* tti_sched);
// args
cell_cfg_t* cfg;
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;
};
} // namespace srsenb
#endif // SRSLTE_SCHEDULER_CTRL_H

@ -100,7 +100,7 @@ private:
size_t nof_dci_allocs = 0;
};
//! manages a full TTI grid, namely CCE and RB allocations
//! manages a full TTI grid resources, namely CCE and DL/UL RB allocations
class tti_grid_t
{
public:

@ -0,0 +1,109 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srsenb/hdr/stack/mac/scheduler_ctrl.h"
namespace srsenb {
sched::bc_sched_t::bc_sched_t(cell_cfg_t* cfg_) : cfg(cfg_) {}
void sched::bc_sched_t::dl_sched(sched::tti_sched_t* 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;
/* Activate/deactivate SI windows */
update_si_windows(tti_sched);
/* Allocate DCIs and RBGs for each SIB */
alloc_sibs(tti_sched);
}
void sched::bc_sched_t::update_si_windows(tti_sched_t* tti_sched)
{
uint32_t tti_tx_dl = tti_sched->get_tti_tx_dl();
for (uint32_t i = 0; i < pending_sibs.size(); ++i) {
// There is SIB data
if (cfg->sibs[i].len == 0) {
continue;
}
if (not pending_sibs[i].is_in_window) {
uint32_t sf = 5;
uint32_t x = 0;
if (i > 0) {
x = (i - 1) * cfg->si_window_ms;
sf = x % 10;
}
if ((current_sfn % (cfg->sibs[i].period_rf)) == x / 10 && current_sf_idx == sf) {
pending_sibs[i].is_in_window = true;
pending_sibs[i].window_start = tti_tx_dl;
pending_sibs[i].n_tx = 0;
}
} else {
if (i > 0) {
if (srslte_tti_interval(tti_tx_dl, pending_sibs[i].window_start) > cfg->si_window_ms) {
// the si window has passed
pending_sibs[i] = {};
}
} else {
// SIB1 is always in window
if (pending_sibs[0].n_tx == 4) {
pending_sibs[0].n_tx = 0;
}
}
}
}
}
void sched::bc_sched_t::alloc_sibs(tti_sched_t* tti_sched)
{
for (uint32_t i = 0; i < pending_sibs.size(); i++) {
if (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(cfg->si_window_ms, 10), 4) : 4;
uint32_t n_sf = (tti_sched->get_tti_tx_dl() - pending_sibs[i].window_start);
// Check if there is any SIB to tx
bool sib1_flag = (i == 0) and (current_sfn % 2) == 0 and current_sf_idx == 5;
bool other_sibs_flag =
(i > 0) and (n_sf >= (cfg->si_window_ms / nof_tx) * pending_sibs[i].n_tx) and current_sf_idx == 9;
if (not sib1_flag and not other_sibs_flag) {
continue;
}
// Schedule SIB
tti_sched->alloc_bc(bc_aggr_level, i, pending_sibs[i].n_tx);
pending_sibs[i].n_tx++;
}
}
}
void sched::bc_sched_t::reset()
{
for (auto& sib : pending_sibs) {
sib = {};
}
}
} // namespace srsenb

@ -89,7 +89,7 @@ const sched_ue::sched_dci_cce_t* pdcch_grid_t::get_cce_loc_table(alloc_type_t al
case alloc_type_t::UL_DATA:
return user->get_locations(current_cfix + 1, sf_idx);
}
return NULL;
return nullptr;
}
bool pdcch_grid_t::alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user)
@ -98,7 +98,7 @@ bool pdcch_grid_t::alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_u
/* Get DCI Location Table */
const sched_ue::sched_dci_cce_t* dci_locs = get_cce_loc_table(alloc_type, user);
if (!dci_locs) {
if (dci_locs == nullptr) {
return false;
}
@ -199,16 +199,17 @@ void pdcch_grid_t::get_allocs(alloc_result_t* vec, pdcch_mask_t* tot_mask, size_
{
// if alloc tree is empty
if (prev_start == prev_end) {
if (vec)
if (vec != nullptr) {
vec->clear();
if (tot_mask) {
}
if (tot_mask != nullptr) {
tot_mask->reset();
}
return;
}
// set vector of allocations
if (vec) {
if (vec != nullptr) {
vec->clear();
size_t i = prev_start + idx;
while (dci_alloc_tree[i].first >= 0) {
@ -220,7 +221,7 @@ void pdcch_grid_t::get_allocs(alloc_result_t* vec, pdcch_mask_t* tot_mask, size_
}
// set final cce mask
if (tot_mask) {
if (tot_mask != nullptr) {
*tot_mask = dci_alloc_tree[prev_start + idx].second.total_mask;
}
}
@ -293,6 +294,7 @@ void tti_grid_t::new_tti(uint32_t tti_rx_, uint32_t start_cfi)
pdcch_alloc.new_tti(tti_rx, start_cfi);
}
//! Allocates CCEs and RBs for the given mask and allocation type (e.g. data, BC, RAR, paging)
alloc_outcome_t tti_grid_t::alloc_dl(uint32_t aggr_lvl, alloc_type_t alloc_type, rbgmask_t alloc_mask, sched_ue* user)
{
// Check RBG collision
@ -312,6 +314,7 @@ alloc_outcome_t tti_grid_t::alloc_dl(uint32_t aggr_lvl, alloc_type_t alloc_type,
return alloc_outcome_t::SUCCESS;
}
//! Allocates CCEs and RBs for control allocs. It allocates RBs in a contiguous manner.
tti_grid_t::ctrl_alloc_t tti_grid_t::alloc_dl_ctrl(uint32_t aggr_lvl, alloc_type_t alloc_type)
{
rbg_range_t range;
@ -334,10 +337,11 @@ tti_grid_t::ctrl_alloc_t tti_grid_t::alloc_dl_ctrl(uint32_t aggr_lvl, alloc_type
return {alloc_dl(aggr_lvl, alloc_type, new_mask), range};
}
//! Allocates CCEs and RBs for a user DL data alloc.
alloc_outcome_t tti_grid_t::alloc_dl_data(sched_ue* user, const rbgmask_t& user_mask)
{
srslte_dci_format_t dci_format = user->get_dci_format();
uint32_t aggr_level = user->get_aggr_level(srslte_dci_format_sizeof(&cell_cfg->cell, NULL, NULL, dci_format));
uint32_t aggr_level = user->get_aggr_level(srslte_dci_format_sizeof(&cell_cfg->cell, nullptr, nullptr, dci_format));
return alloc_dl(aggr_level, alloc_type_t::DL_DATA, user_mask, user);
}
@ -355,7 +359,8 @@ alloc_outcome_t tti_grid_t::alloc_ul_data(sched_ue* user, ul_harq_proc::ul_alloc
// Generate PDCCH except for RAR and non-adaptive retx
if (needs_pdcch) {
uint32_t aggr_idx = user->get_aggr_level(srslte_dci_format_sizeof(&cell_cfg->cell, NULL, NULL, SRSLTE_DCI_FORMAT0));
uint32_t aggr_idx =
user->get_aggr_level(srslte_dci_format_sizeof(&cell_cfg->cell, nullptr, nullptr, SRSLTE_DCI_FORMAT0));
if (not pdcch_alloc.alloc_dci(alloc_type_t::UL_DATA, aggr_idx, user)) {
return alloc_outcome_t::DCI_COLLISION;
}

@ -127,15 +127,15 @@ int main(int argc, char *argv[])
srsenb::sched_interface::ue_bearer_cfg_t bearer_cfg;
bzero(&bearer_cfg, sizeof(srsenb::sched_interface::ue_bearer_cfg_t));
bearer_cfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH;
bearer_cfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH;
my_sched.ue_cfg(rnti, &ue_cfg);
my_sched.bearer_ue_cfg(rnti, 0, &bearer_cfg);
//my_sched.dl_rlc_buffer_state(rnti, 0, 1e6, 0);
my_sched.ul_bsr(rnti, 0, 1e6);
// my_sched.dl_rlc_buffer_state(rnti, 0, 1e6, 0);
my_sched.ul_bsr(rnti, 0, 1e6, true);
bool running = true;
uint32_t tti = 0;
bool running = true;
uint32_t tti = 0;
while(running) {
log_out.step(tti);
if (tti > 50) {

@ -226,6 +226,7 @@ struct sched_tester : public srsenb::sched {
void assert_no_empty_allocs();
void test_collisions();
void test_harqs();
void test_sibs();
void run_tti(uint32_t tti_rx);
private:
@ -381,6 +382,7 @@ void sched_tester::process_results()
test_collisions();
assert_no_empty_allocs();
test_harqs();
test_sibs();
}
void sched_tester::run_tti(uint32_t tti_rx)
@ -712,6 +714,40 @@ void sched_tester::test_harqs()
// }
}
void sched_tester::test_sibs()
{
uint32_t sfn = tti_data.tti_tx_dl / 10;
uint32_t sf_idx = TTI_TX(tti_data.tti_rx) % 10;
bool sib1_present = ((sfn % 2) == 0) and sf_idx == 5;
using bc_elem = sched_interface::dl_sched_bc_t;
bc_elem* bc_begin = &tti_data.sched_result_dl.bc[0];
bc_elem* bc_end = &tti_data.sched_result_dl.bc[tti_data.sched_result_dl.nof_bc_elems];
/* Test if SIB1 was correctly scheduled */
if (sib1_present) {
auto it = std::find_if(bc_begin, bc_end, [](bc_elem& elem) { return elem.index == 0; });
CondError(it == bc_end, "Failed to allocate SIB1 in even sfn, sf_idx==5\n");
}
/* Test if any SIB was scheduled outside of its window */
for (bc_elem* bc = bc_begin; bc != bc_end; ++bc) {
if (bc->index == 0) {
continue;
}
uint32_t x = (bc->index - 1) * cfg.si_window_ms;
uint32_t sf = x % 10;
uint32_t sfn_start = sfn;
while ((sfn_start % cfg.sibs[bc->index].period_rf) != x / 10) {
sfn_start--;
}
uint32_t win_start = sfn_start * 10 + sf;
uint32_t win_end = win_start + cfg.si_window_ms;
CondError(tti_data.tti_tx_dl < win_start or tti_data.tti_tx_dl > win_end,
"Scheduled SIB is outside of its SIB window\n");
}
}
void sched_tester::test_collisions()
{
tti_sched_t* tti_sched = get_tti_sched(tti_data.tti_rx);

Loading…
Cancel
Save