sched,nr: add option to run phy nr test with real NR scheduler

master
Francisco Paisana 3 years ago
parent bc072f07d6
commit 660b66dbe3

@ -71,7 +71,9 @@ public:
};
struct ue_cfg_t {
uint32_t maxharq_tx = 4;
uint32_t maxharq_tx = 4;
int fixed_dl_mcs = -1;
int fixed_ul_mcs = -1;
srsran::bounded_vector<ue_cc_cfg_t, SCHED_NR_MAX_CARRIERS> carriers;
srsran::phy_cfg_nr_t phy_cfg = {};
};

@ -151,7 +151,8 @@ int sched_nr::get_dl_sched(tti_point tti_tx, uint32_t cc, dl_sched_t& result)
int sched_nr::get_ul_sched(tti_point tti_rx, uint32_t cc, ul_sched_t& result)
{
if (not pending_results->has_ul_result(tti_rx, cc)) {
return SRSRAN_ERROR;
// sched result hasn't been generated
return SRSRAN_SUCCESS;
}
result = pending_results->pop_ul_result(tti_rx, cc);

@ -29,8 +29,8 @@ sched_cell_params::sched_cell_params(uint32_t cc_, const cell_cfg_t& cell, const
cc(cc_), cell_cfg(cell), sched_cfg(sched_cfg_)
{
bwps.reserve(cell.bwps.size());
for (uint32_t i = 0; i < cell.bwps.size(); ++i) {
bwps.emplace_back(cell, sched_cfg_, cc, i);
for (uint32_t i = 0; i < cell_cfg.bwps.size(); ++i) {
bwps.emplace_back(cell_cfg, sched_cfg_, cc, i);
}
srsran_assert(not bwps.empty(), "No BWPs were configured");
}

@ -75,7 +75,7 @@ void fill_ul_dci_ue_fields(const slot_ue& ue,
srsran_dci_location_t dci_pos,
srsran_dci_ul_nr_t& dci)
{
bool ret = ue.cfg->phy().get_dci_ctx_pdsch_rnti_c(ss_id, dci_pos, ue.rnti, dci.ctx);
bool ret = ue.cfg->phy().get_dci_ctx_pusch_rnti_c(ss_id, dci_pos, ue.rnti, dci.ctx);
srsran_assert(ret, "Invalid DL DCI format");
fill_dci_common(ue, bwp_cfg, dci);

@ -45,6 +45,8 @@ void bwp_slot_grid::reset()
ul_prbs.reset();
dl_pdcchs.clear();
ul_pdcchs.clear();
pdschs.clear();
puschs.clear();
pending_acks.clear();
}
@ -157,7 +159,8 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
// Allocate HARQ
if (ue.h_dl->empty()) {
int mcs = 20;
srsran_assert(ue.cfg->ue_cfg()->fixed_dl_mcs >= 0, "Dynamic MCS not yet supported");
int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs;
int tbs = 100;
bool ret = ue.h_dl->new_tx(ue.pdsch_tti, ue.uci_tti, dl_grant, mcs, tbs, 4);
srsran_assert(ret, "Failed to allocate DL HARQ");
@ -176,6 +179,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
bwp_uci_slot.pending_acks.end(),
[&ue](const harq_ack_t& p) { return p.res.rnti == ue.rnti; });
pdcch.dci.dai %= 4;
pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg();
// Generate PUCCH
bwp_uci_slot.pending_acks.emplace_back();
@ -230,7 +234,8 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m
}
if (ue.h_ul->empty()) {
int mcs = 20;
srsran_assert(ue.cfg->ue_cfg()->fixed_ul_mcs >= 0, "Dynamic MCS not yet supported");
int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs;
int tbs = 100;
bool ret = ue.h_ul->new_tx(ue.pusch_tti, ue.pusch_tti, ul_mask, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx);
srsran_assert(ret, "Failed to allocate UL HARQ");
@ -242,6 +247,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const rbg_bitmap& ul_m
// Generate PDCCH
pdcch_ul_t& pdcch = pdcchs.back();
fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci);
pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg();
// Generate PUSCH
bwp_pusch_slot.ul_prbs.add(ul_mask);

@ -138,12 +138,13 @@ void slot_cc_worker::log_result() const
if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) {
const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti];
fmt::format_to(fmtbuf,
"SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, nrtx={}, dai={}, tti_pdsch={}, tti_ack={}",
"SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, nrtx={}, f={}, dai={}, tti_pdsch={}, tti_ack={}",
ue.h_dl->nof_retx() == 0 ? "tx" : "retx",
cell.cfg.cc,
ue.rnti,
ue.h_dl->pid,
pdcch.dci.pid,
ue.h_dl->nof_retx(),
srsran_dci_format_nr_string(pdcch.dci.ctx.format),
pdcch.dci.dai,
ue.pdsch_tti,
ue.uci_tti);
@ -153,6 +154,26 @@ void slot_cc_worker::log_result() const
fmt::format_to(fmtbuf, "SCHED: unknown format");
}
logger.info("%s", srsran::to_c_str(fmtbuf));
}
for (const pdcch_ul_t& pdcch : bwp_slot.ul_pdcchs) {
fmt::memory_buffer fmtbuf;
if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) {
const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti];
fmt::format_to(fmtbuf,
"SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, nrtx={}, f={}, tti_pusch={}, tti_ack={}",
ue.h_dl->nof_retx() == 0 ? "tx" : "retx",
cell.cfg.cc,
ue.rnti,
pdcch.dci.pid,
ue.h_dl->nof_retx(),
srsran_dci_format_nr_string(pdcch.dci.ctx.format),
ue.pusch_tti,
ue.uci_tti);
} else {
fmt::format_to(fmtbuf, "SCHED: unknown rnti format");
}
logger.info("%s", srsran::to_c_str(fmtbuf));
}
}

@ -0,0 +1,95 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSRAN_SCHED_NR_CFG_GENERATORS_H
#define SRSRAN_SCHED_NR_CFG_GENERATORS_H
#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h"
#include "srsran/common/phy_cfg_nr_default.h"
namespace srsenb {
srsran_coreset_t get_default_coreset0()
{
srsran_coreset_t coreset{};
coreset.id = 0;
coreset.duration = 1;
coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle;
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; ++i) {
coreset.freq_resources[i] = i < 8;
}
return coreset;
}
sched_nr_interface::cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t& phy_cfg)
{
sched_nr_interface::cell_cfg_t cell_cfg{};
cell_cfg.carrier = phy_cfg.carrier;
cell_cfg.tdd = phy_cfg.tdd;
cell_cfg.bwps.resize(1);
cell_cfg.bwps[0].pdcch = phy_cfg.pdcch;
cell_cfg.bwps[0].pdsch = phy_cfg.pdsch;
cell_cfg.bwps[0].rb_width = phy_cfg.carrier.nof_prb;
cell_cfg.bwps[0].pdcch.coreset_present[0] = true;
cell_cfg.bwps[0].pdcch.coreset[0] = get_default_coreset0();
cell_cfg.bwps[0].pdcch.search_space_present[0] = true;
auto& ss = cell_cfg.bwps[0].pdcch.search_space[0];
ss.id = 0;
ss.coreset_id = 0;
ss.duration = 1;
ss.type = srsran_search_space_type_common_0;
ss.nof_candidates[0] = 1;
ss.nof_candidates[1] = 1;
ss.nof_candidates[2] = 1;
ss.nof_candidates[3] = 0;
ss.nof_candidates[4] = 0;
ss.nof_formats = 1;
ss.formats[0] = srsran_dci_format_nr_1_0;
cell_cfg.bwps[0].pdcch.ra_search_space_present = true;
cell_cfg.bwps[0].pdcch.ra_search_space = cell_cfg.bwps[0].pdcch.search_space[1];
return cell_cfg;
}
std::vector<sched_nr_interface::cell_cfg_t> get_default_cells_cfg(
uint32_t nof_sectors,
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
{
std::vector<sched_nr_interface::cell_cfg_t> cells;
cells.reserve(nof_sectors);
for (uint32_t i = 0; i < nof_sectors; ++i) {
cells.push_back(get_default_cell_cfg(phy_cfg));
}
return cells;
}
sched_nr_interface::ue_cfg_t get_default_ue_cfg(uint32_t nof_cc,
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{
srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
{
sched_nr_interface::ue_cfg_t uecfg{};
uecfg.carriers.resize(nof_cc);
for (uint32_t cc = 0; cc < nof_cc; ++cc) {
uecfg.carriers[cc].cc = cc;
uecfg.carriers[cc].active = true;
}
uecfg.phy_cfg = phy_cfg;
return uecfg;
}
} // namespace srsenb
#endif // SRSRAN_SCHED_NR_CFG_GENERATORS_H

@ -10,6 +10,7 @@
*
*/
#include "sched_nr_cfg_generators.h"
#include "sched_nr_sim_ue.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr.h"
#include "srsran/common/phy_cfg_nr_default.h"
@ -24,72 +25,6 @@ using dl_sched_t = sched_nr_interface::dl_sched_t;
static const srsran::phy_cfg_nr_t default_phy_cfg =
srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}};
srsran_coreset_t get_default_coreset0()
{
srsran_coreset_t coreset{};
coreset.id = 0;
coreset.duration = 1;
coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle;
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; ++i) {
coreset.freq_resources[i] = i < 8;
}
return coreset;
}
sched_nr_interface::cell_cfg_t get_default_cell_cfg()
{
sched_nr_interface::cell_cfg_t cell_cfg{};
cell_cfg.carrier = default_phy_cfg.carrier;
cell_cfg.tdd = default_phy_cfg.tdd;
cell_cfg.bwps.resize(1);
cell_cfg.bwps[0].pdcch = default_phy_cfg.pdcch;
cell_cfg.bwps[0].pdsch = default_phy_cfg.pdsch;
cell_cfg.bwps[0].rb_width = default_phy_cfg.carrier.nof_prb;
cell_cfg.bwps[0].pdcch.coreset_present[0] = true;
cell_cfg.bwps[0].pdcch.coreset[0] = get_default_coreset0();
cell_cfg.bwps[0].pdcch.search_space_present[0] = true;
auto& ss = cell_cfg.bwps[0].pdcch.search_space[0];
ss.id = 0;
ss.coreset_id = 0;
ss.duration = 1;
ss.type = srsran_search_space_type_common_0;
ss.nof_candidates[0] = 1;
ss.nof_candidates[1] = 1;
ss.nof_candidates[2] = 1;
ss.nof_candidates[3] = 0;
ss.nof_candidates[4] = 0;
ss.nof_formats = 1;
ss.formats[0] = srsran_dci_format_nr_1_0;
cell_cfg.bwps[0].pdcch.ra_search_space_present = true;
cell_cfg.bwps[0].pdcch.ra_search_space = cell_cfg.bwps[0].pdcch.search_space[1];
return cell_cfg;
}
std::vector<sched_nr_interface::cell_cfg_t> get_default_cells_cfg(uint32_t nof_sectors)
{
std::vector<sched_nr_interface::cell_cfg_t> cells;
cells.reserve(nof_sectors);
for (uint32_t i = 0; i < nof_sectors; ++i) {
cells.push_back(get_default_cell_cfg());
}
return cells;
}
sched_nr_interface::ue_cfg_t get_default_ue_cfg(uint32_t nof_cc)
{
sched_nr_interface::ue_cfg_t uecfg{};
uecfg.carriers.resize(nof_cc);
for (uint32_t cc = 0; cc < nof_cc; ++cc) {
uecfg.carriers[cc].active = true;
}
uecfg.phy_cfg = default_phy_cfg;
return uecfg;
}
struct task_job_manager {
std::mutex mutex;
int res_count = 0;
@ -151,7 +86,8 @@ void sched_nr_cfg_serialized_test()
sched_nr_sim_base sched_tester(cfg, cells_cfg, "Serialized Test");
sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors);
uecfg.fixed_dl_mcs = 15;
uecfg.fixed_ul_mcs = 15;
sched_tester.add_user(0x46, uecfg, 0);
std::vector<long> count_per_cc(nof_sectors, 0);
@ -198,6 +134,8 @@ void sched_nr_cfg_parallel_cc_test()
sched_nr_sim_base sched_tester(cfg, cells_cfg, "Parallel CC Test");
sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(cells_cfg.size());
uecfg.fixed_dl_mcs = 15;
uecfg.fixed_ul_mcs = 15;
sched_tester.add_user(0x46, uecfg, 0);
std::array<std::atomic<long>, SRSRAN_MAX_CARRIERS> nano_count{};

@ -17,6 +17,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
srsran_phy
srsran_radio
srsenb_phy
srsgnb_mac
${CMAKE_THREAD_LIBS_INIT}
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}

@ -15,6 +15,8 @@
#include "dummy_rx_harq_proc.h"
#include "dummy_tx_harq_proc.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr.h"
#include "srsenb/test/mac/nr/sched_nr_cfg_generators.h"
#include <mutex>
#include <set>
#include <srsenb/hdr/stack/mac/common/mac_metrics.h>
@ -38,8 +40,9 @@ public:
};
private:
srslog::basic_logger& logger = srslog::fetch_basic_logger("GNB STK");
const uint16_t rnti = 0x1234;
srslog::basic_logger& logger = srslog::fetch_basic_logger("GNB STK");
bool use_dummy_sched = true;
const uint16_t rnti = 0x1234;
struct {
srsran::circular_array<srsran_dci_location_t, SRSRAN_NOF_SF_X_FRAME> dci_location;
uint32_t mcs;
@ -51,6 +54,9 @@ private:
srsran::phy_cfg_nr_t phy_cfg = {};
bool valid = false;
srsenb::sched_nr sched;
srsran::tti_point pdsch_tti, pusch_tti;
std::mutex metrics_mutex;
metrics_t metrics = {};
@ -271,6 +277,7 @@ private:
public:
struct args_t {
srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration
bool use_dummy_sched = false; ///< Use dummy or real NR scheduler
uint16_t rnti = 0x1234; ///< C-RNTI
uint32_t ss_id = 1; ///< Search Space identifier
uint32_t pdcch_aggregation_level = 0; ///< PDCCH aggregation level
@ -285,10 +292,21 @@ public:
std::string log_level = "warning";
};
gnb_dummy_stack(const args_t& args) : rnti(args.rnti), phy_cfg(args.phy_cfg), ss_id(args.ss_id)
gnb_dummy_stack(const args_t& args) :
rnti(args.rnti), phy_cfg(args.phy_cfg), ss_id(args.ss_id), sched(srsenb::sched_nr_interface::sched_cfg_t{})
{
logger.set_level(srslog::str_to_basic_level(args.log_level));
// create sched object
std::vector<srsenb::sched_nr_interface::cell_cfg_t> cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg);
sched.cell_cfg(cells_cfg);
// add UE to scheduler
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg);
ue_cfg.fixed_dl_mcs = args.pdsch.mcs;
ue_cfg.fixed_ul_mcs = args.pusch.mcs;
sched.ue_cfg(args.rnti, ue_cfg);
dl.mcs = args.pdsch.mcs;
ul.mcs = args.pusch.mcs;
@ -351,6 +369,26 @@ public:
int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override
{
logger.set_context(slot_cfg.idx);
if (not pdsch_tti.is_valid()) {
pdsch_tti = srsran::tti_point{slot_cfg.idx};
} else {
pdsch_tti++;
}
if (not use_dummy_sched) {
int ret = sched.get_dl_sched(pdsch_tti, 0, dl_sched);
for (pdsch_t& pdsch : dl_sched.pdsch) {
// Set TBS
// Select grant and set data
pdsch.data[0] = tx_harq_proc[slot_cfg.idx].get_tb(pdsch.sch.grant.tb[0].tbs).data();
// Generate random data
srsran_random_byte_vector(random_gen, pdsch.data[0], pdsch.sch.grant.tb[0].tbs / 8);
}
return ret;
}
// Check if it is TDD DL slot and PDSCH mask, if no PDSCH shall be scheduled, do not set any grant and skip
if (not srsran_tdd_nr_is_dl(&phy_cfg.tdd, phy_cfg.carrier.scs, slot_cfg.idx)) {
@ -378,6 +416,15 @@ public:
int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override
{
logger.set_context(slot_cfg.idx);
if (not pusch_tti.is_valid()) {
pusch_tti = srsran::tti_point{slot_cfg.idx};
} else {
pusch_tti++;
}
if (not use_dummy_sched) {
return sched.get_ul_sched(pusch_tti, 0, ul_sched);
}
// Get ACK information
srsran_pdsch_ack_nr_t ack = pending_ack[slot_cfg.idx % pending_ack.size()].get_ack();

@ -54,6 +54,7 @@ test_bench::args_t::args_t(int argc, char** argv)
("gnb.stack.pusch.slots", bpo::value<std::string>(&gnb_stack.pusch.slots)->default_value(gnb_stack.pusch.slots), "Slots enabled for PUSCH")
("gnb.stack.pusch.mcs", bpo::value<uint32_t>(&gnb_stack.pusch.mcs)->default_value(gnb_stack.pusch.mcs), "PUSCH scheduling modulation code scheme")
("gnb.stack.log.level", bpo::value<std::string>(&gnb_stack.log_level)->default_value(gnb_stack.log_level), "Stack log level")
("gnb.stack.use_dummy_sched", bpo::value<bool>(&gnb_stack.use_dummy_sched)->default_value(true), "Use dummy or real NR scheduler")
;
options_gnb_phy.add_options()

Loading…
Cancel
Save