diff --git a/srsgnb/hdr/stack/mac/sched_nr_cfg.h b/srsgnb/hdr/stack/mac/sched_nr_cfg.h index 85ab43212..6c70e24b6 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_cfg.h +++ b/srsgnb/hdr/stack/mac/sched_nr_cfg.h @@ -13,7 +13,7 @@ #ifndef SRSRAN_SCHED_NR_CFG_H #define SRSRAN_SCHED_NR_CFG_H -#include "sched_nr_interface.h" +#include "sched_nr_interface_utils.h" #include "sched_nr_rb.h" #include "srsenb/hdr/common/common_enb.h" #include "srsran/adt/optional_array.h" @@ -148,12 +148,11 @@ public: } const srsran_search_space_t* find_ss_with_dci_format(srsran_dci_format_nr_t valid_format) const { - for (uint32_t ss_id = 0; ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++ss_id) { - if (phy().pdcch.search_space_present[ss_id]) { - for (uint32_t i = 0; i < phy().pdcch.search_space[ss_id].nof_formats; ++i) { - if (phy().pdcch.search_space[ss_id].formats[i] == valid_format) { - return &phy().pdcch.search_space[ss_id]; - } + auto active_ss_lst = view_active_search_spaces(phy().pdcch); + for (const srsran_search_space_t& ss : active_ss_lst) { + for (uint32_t i = 0; i < ss.nof_formats; ++i) { + if (ss.formats[i] == valid_format) { + return &ss; } } } @@ -192,7 +191,6 @@ private: }; } // namespace sched_nr_impl - } // namespace srsenb #endif // SRSRAN_SCHED_NR_CFG_H diff --git a/srsgnb/hdr/stack/mac/sched_nr_helpers.h b/srsgnb/hdr/stack/mac/sched_nr_helpers.h index c6aaa9d0d..47be2e462 100644 --- a/srsgnb/hdr/stack/mac/sched_nr_helpers.h +++ b/srsgnb/hdr/stack/mac/sched_nr_helpers.h @@ -15,6 +15,7 @@ #include "sched_nr_cfg.h" #include "sched_nr_ue.h" +#include "srsran/adt/optional_array.h" namespace srsenb { namespace sched_nr_impl { @@ -23,8 +24,6 @@ class slot_ue; class ul_harq_proc; struct bwp_res_grid; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - bool fill_dci_sib(prb_interval interv, uint32_t sib_idx, uint32_t si_ntx, diff --git a/srsgnb/hdr/stack/mac/sched_nr_interface_utils.h b/srsgnb/hdr/stack/mac/sched_nr_interface_utils.h new file mode 100644 index 000000000..40aafbc56 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_interface_utils.h @@ -0,0 +1,36 @@ +/** + * + * \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_INTERFACE_HELPERS_H +#define SRSRAN_SCHED_NR_INTERFACE_HELPERS_H + +#include "sched_nr_interface.h" +#include "srsran/adt/optional_array.h" + +namespace srsenb { + +// Helpers to handle PHY struct types + +/// Get a range of active search spaces in a PDCCH configuration +inline srsran::split_optional_span view_active_search_spaces(srsran_pdcch_cfg_nr_t& pdcch) +{ + return srsran::split_optional_span{pdcch.search_space, pdcch.search_space_present}; +} +inline srsran::split_optional_span +view_active_search_spaces(const srsran_pdcch_cfg_nr_t& pdcch) +{ + return srsran::split_optional_span{pdcch.search_space, pdcch.search_space_present}; +} + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_INTERFACE_HELPERS_H diff --git a/srsgnb/src/stack/mac/sched_nr.cc b/srsgnb/src/stack/mac/sched_nr.cc index c99121abc..c2f13d360 100644 --- a/srsgnb/src/stack/mac/sched_nr.cc +++ b/srsgnb/src/stack/mac/sched_nr.cc @@ -419,7 +419,6 @@ int sched_nr::dl_rach_info(const rar_info_t& rar_info, const ue_cfg_t& uecfg) auto add_ue = [this, uecfg, rar_info](event_manager::logger& ev_logger) { // create user // Note: UEs being created in sched main thread, which has higher priority - logger->info("SCHED: New user rnti=0x%x, cc=%d", rar_info.temp_crnti, uecfg.carriers[0].cc); std::unique_ptr u{new ue{rar_info.temp_crnti, uecfg, cfg}}; uint16_t rnti = rar_info.temp_crnti; diff --git a/srsgnb/src/stack/mac/sched_nr_ue.cc b/srsgnb/src/stack/mac/sched_nr_ue.cc index a8389b08d..e77636acb 100644 --- a/srsgnb/src/stack/mac/sched_nr_ue.cc +++ b/srsgnb/src/stack/mac/sched_nr_ue.cc @@ -110,7 +110,7 @@ ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params_t& sched_cfg_) : void ue::set_cfg(const ue_cfg_t& cfg) { - bool conres_needed = cfg.is_temp_crnti != ue_cfg.is_temp_crnti; + bool conres_needed = not cfg.is_temp_crnti and ue_cfg.is_temp_crnti; ue_cfg = cfg; for (auto& ue_cc_cfg : cfg.carriers) { diff --git a/srsgnb/src/stack/mac/test/CMakeLists.txt b/srsgnb/src/stack/mac/test/CMakeLists.txt index eab5855b1..212ed4693 100644 --- a/srsgnb/src/stack/mac/test/CMakeLists.txt +++ b/srsgnb/src/stack/mac/test/CMakeLists.txt @@ -6,16 +6,17 @@ # the distribution. # -add_library(sched_nr_test_suite sched_nr_common_test.cc sched_nr_ue_ded_test_suite.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) -add_executable(sched_nr_test sched_nr_test.cc sched_nr_sim_ue.cc) -target_link_libraries(sched_nr_test +add_executable(sched_nr_parallel_test sched_nr_parallel_test.cc) +target_link_libraries(sched_nr_parallel_test srsgnb_mac sched_nr_test_suite srsran_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -add_nr_test(sched_nr_test sched_nr_test) +add_nr_test(sched_nr_parallel_test sched_nr_parallel_test) add_executable(sched_nr_prb_test sched_nr_prb_test.cc) target_link_libraries(sched_nr_prb_test @@ -27,4 +28,12 @@ add_nr_test(sched_nr_prb_test sched_nr_prb_test) add_executable(sched_nr_rar_test sched_nr_rar_test.cc) target_link_libraries(sched_nr_rar_test srsgnb_mac sched_nr_test_suite srsran_common) -add_nr_test(sched_nr_rar_test sched_nr_rar_test) \ No newline at end of file +add_nr_test(sched_nr_rar_test sched_nr_rar_test) + +add_executable(sched_nr_test sched_nr_test.cc) +target_link_libraries(sched_nr_test + srsgnb_mac + sched_nr_test_suite + srsran_common ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES}) +add_nr_test(sched_nr_test sched_nr_test) \ No newline at end of file diff --git a/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h b/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h index 1ed5b0ca4..51091a0c9 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h +++ b/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h @@ -13,7 +13,7 @@ #ifndef SRSRAN_SCHED_NR_CFG_GENERATORS_H #define SRSRAN_SCHED_NR_CFG_GENERATORS_H -#include "srsgnb/hdr/stack/mac/sched_nr_interface.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface_utils.h" #include "srsran/common/phy_cfg_nr_default.h" namespace srsenb { @@ -62,11 +62,14 @@ inline std::vector get_default_cells_cfg( return cells; } -inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t cc) +inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t 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.is_temp_crnti = true; - // set Pcell + // set PCell uecfg.carriers.resize(1); uecfg.carriers[0].active = true; uecfg.carriers[0].cc = cc; @@ -77,6 +80,12 @@ inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t cc) // set basic PHY config uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; uecfg.phy_cfg.csi = {}; + for (srsran_search_space_t& ss : view_active_search_spaces(uecfg.phy_cfg.pdcch)) { + // disable UE-specific search spaces + if (ss.type == srsran_search_space_type_ue) { + uecfg.phy_cfg.pdcch.search_space_present[ss.id] = false; + } + } return uecfg; } diff --git a/srsgnb/src/stack/mac/test/sched_nr_common_test.cc b/srsgnb/src/stack/mac/test/sched_nr_common_test.cc index 0ab6f9a35..5c7c007f5 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_common_test.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_common_test.cc @@ -16,13 +16,23 @@ namespace srsenb { -void test_dl_pdcch_consistency(srsran::const_span dl_pdcchs) +void test_dl_pdcch_consistency(const sched_nr_interface::cell_cfg_t& cell_cfg, + srsran::const_span dl_pdcchs) { for (const auto& pdcch : dl_pdcchs) { + TESTASSERT(pdcch.dci.bwp_id < cell_cfg.bwps.size()); + const srsran_pdcch_cfg_nr_t& pdcch_cfg = cell_cfg.bwps[pdcch.dci.bwp_id].pdcch; + TESTASSERT(pdcch_cfg.coreset_present[pdcch.dci.ctx.coreset_id]); + if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) { TESTASSERT_EQ(pdcch.dci.ctx.format, srsran_dci_format_nr_1_0); TESTASSERT_EQ(pdcch.dci.ctx.ss_type, srsran_search_space_type_common_1); - TESTASSERT(pdcch.dci.ctx.location.L > 0); + TESTASSERT(pdcch.dci.ctx.location.L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR); + + // check consistency with cell_cfg + TESTASSERT(pdcch_cfg.ra_search_space_present); + TESTASSERT_EQ(pdcch_cfg.ra_search_space.coreset_id, pdcch.dci.ctx.coreset_id); + TESTASSERT(pdcch_cfg.ra_search_space.nof_candidates[pdcch.dci.ctx.location.L] > 0); } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { TESTASSERT(pdcch.dci.ctx.format == srsran_dci_format_nr_1_0 or pdcch.dci.ctx.format == srsran_dci_format_nr_1_1); } diff --git a/srsgnb/src/stack/mac/test/sched_nr_common_test.h b/srsgnb/src/stack/mac/test/sched_nr_common_test.h index a835ba8f9..ec1514d67 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_common_test.h +++ b/srsgnb/src/stack/mac/test/sched_nr_common_test.h @@ -18,7 +18,8 @@ namespace srsenb { -void test_dl_pdcch_consistency(srsran::const_span dl_pdcch); +void test_dl_pdcch_consistency(const sched_nr_interface::cell_cfg_t& cell_cfg, + srsran::const_span dl_pdcch); void test_pdsch_consistency(srsran::const_span dl_pdcch); /// @brief Test whether the SSB grant gets scheduled with the correct periodicity. void test_ssb_scheduled_grant( diff --git a/srsgnb/src/stack/mac/test/sched_nr_rar_test.cc b/srsgnb/src/stack/mac/test/sched_nr_rar_test.cc index dbd0870c4..526b494ff 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_rar_test.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_rar_test.cc @@ -74,7 +74,7 @@ void test_single_prach() log_sched_bwp_result(mac_logger, alloc.get_pdcch_tti(), alloc.res_grid(), slot_ues); const bwp_slot_grid* result = &alloc.res_grid()[alloc.get_pdcch_tti()]; - test_dl_pdcch_consistency(result->dl.phy.pdcch_dl); + test_dl_pdcch_consistency(res_grid->cfg->cell_cfg, result->dl.phy.pdcch_dl); ++pdcch_slot; return result; }; diff --git a/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc index 70fdc707b..686b14489 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc @@ -64,6 +64,8 @@ int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out) void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) { uint32_t cc = cc_out.cc; + + // Update DL Harqs for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_dl.size(); ++i) { const auto& data = cc_out.dl->phy.pdcch_dl[i]; if (data.dci.ctx.rnti != ctxt.rnti) { @@ -89,6 +91,61 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) .dl_data_to_ul_ack[h.last_slot_tx.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; h.nof_txs++; } + + // Update UL harqs + for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_ul.size(); ++i) { + const auto& data = cc_out.dl->phy.pdcch_ul[i]; + if (data.dci.ctx.rnti != ctxt.rnti) { + continue; + } + auto& h = ctxt.cc_list[cc].ul_harqs[data.dci.pid]; + if (h.nof_txs == 0 or h.ndi != data.dci.ndi) { + // It is newtx + h.nof_retxs = 0; + h.ndi = data.dci.ndi; + h.first_slot_tx = cc_out.slot + 4; // TODO + h.dci_loc = data.dci.ctx.location; + h.tbs = 100; // TODO + } else { + // it is retx + h.nof_retxs++; + } + h.active = true; + h.last_slot_tx = cc_out.slot + 4; // TODO + h.last_slot_ack = h.last_slot_tx; + h.nof_txs++; + } + + uint32_t rar_count = 0; + for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_dl.size(); ++i) { + const auto& rar_pdcch = cc_out.dl->phy.pdcch_dl[i]; + if (rar_pdcch.dci.ctx.rnti_type != srsran_rnti_type_ra) { + continue; + } + const auto& rar_data = cc_out.dl->rar[rar_count++]; + for (uint32_t j = 0; j < rar_data.grants.size(); ++j) { + auto& msg3_grant = rar_data.grants[j]; + if (msg3_grant.msg3_dci.ctx.rnti != ctxt.rnti) { + continue; + } + auto& h = ctxt.cc_list[cc].ul_harqs[msg3_grant.msg3_dci.pid]; + if (h.nof_txs == 0) { + // It is newtx + h.nof_retxs = 0; + h.ndi = msg3_grant.msg3_dci.ndi; + h.first_slot_tx = cc_out.slot + 4 + MSG3_DELAY_MS; // TODO + h.dci_loc = msg3_grant.msg3_dci.ctx.location; + h.tbs = 100; // TODO + } else { + // it is retx + h.nof_retxs++; + } + h.active = true; + h.last_slot_tx = cc_out.slot + 4 + MSG3_DELAY_MS; // TODO + h.last_slot_ack = h.last_slot_tx; + h.nof_txs++; + } + } } sched_nr_base_tester::sched_nr_base_tester(const sched_nr_interface::sched_args_t& sched_args, @@ -98,11 +155,10 @@ sched_nr_base_tester::sched_nr_base_tester(const sched_nr_interface::sched_args_ logger(srslog::fetch_basic_logger("TEST")), mac_logger(srslog::fetch_basic_logger("MAC-NR")), sched_ptr(new sched_nr()), - test_name(std::move(test_name_)) + test_delimiter(new srsran::test_delimit_logger{test_name_.c_str()}) { sem_init(&slot_sem, 0, 1); - printf("\n=========== Start %s ===========\n", test_name.c_str()); cell_params.reserve(cell_cfg_list.size()); for (uint32_t cc = 0; cc < cell_cfg_list.size(); ++cc) { cell_params.emplace_back(cc, cell_cfg_list[cc], sched_args); @@ -136,7 +192,7 @@ void sched_nr_base_tester::stop() worker->stop(); } sem_destroy(&slot_sem); - printf("============ End %s ===========\n", test_name.c_str()); + test_delimiter.reset(); } } @@ -163,6 +219,14 @@ int sched_nr_base_tester::add_user(uint16_t rnti, return SRSRAN_SUCCESS; } +void sched_nr_base_tester::user_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_) +{ + TESTASSERT(ue_db.count(rnti) > 0); + + ue_db.at(rnti).get_ctxt().ue_cfg = ue_cfg_; + sched_ptr->ue_cfg(rnti, ue_cfg_); +} + void sched_nr_base_tester::run_slot(slot_point slot_tx) { srsran_assert(not stopped.load(std::memory_order_relaxed), "Running scheduler when it has already been stopped"); @@ -236,7 +300,7 @@ void sched_nr_base_tester::process_results() sched_nr_cc_result_view cc_out = cc_results[cc].res; // Run common tests - test_dl_pdcch_consistency(cc_out.dl->phy.pdcch_dl); + test_dl_pdcch_consistency(cell_params[cc].cfg, cc_out.dl->phy.pdcch_dl); test_pdsch_consistency(cc_out.dl->phy.pdsch); test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc].cfg, cc_out.dl->phy.ssb); @@ -265,12 +329,12 @@ int sched_nr_base_tester::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctx auto& ul_h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[pid]; // Set default DL ACK - if (dl_h.active and (dl_h.last_slot_ack) == current_slot_tx) { + if (dl_h.active and dl_h.last_slot_ack == current_slot_tx) { cc_feedback.dl_acks.push_back(ue_nr_slot_events::ack_t{pid, true}); } // Set default UL ACK - if (ul_h.active and (ul_h.last_slot_tx + 8) == current_slot_tx) { + if (ul_h.active and ul_h.last_slot_ack == current_slot_tx) { cc_feedback.ul_acks.emplace_back(ue_nr_slot_events::ack_t{pid, true}); } @@ -314,11 +378,8 @@ int sched_nr_base_tester::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_ "UL ACK rnti=0x%x, slot_ul_tx=%u, cc=%d pid=%d", ue_ctxt.rnti, h.last_slot_tx.to_uint(), enb_cc_idx, h.pid); } - // // update scheduler - // if (sched_ptr->ul_crc_info(events.slot_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) { - // logger.error("The ACKed UL Harq pid=%d does not exist.", cc_feedback.ul_pid); - // error_counter++; - // } + // update scheduler + sched_ptr->ul_crc_info(ue_ctxt.rnti, enb_cc_idx, ack.pid, ack.ack); } } diff --git a/srsgnb/src/stack/mac/test/sched_nr_sim_ue.h b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.h index 6ed98e4bc..b8f17ec20 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_sim_ue.h +++ b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.h @@ -16,6 +16,7 @@ #include "srsenb/test/mac/sched_sim_ue.h" #include "srsgnb/hdr/stack/mac/sched_nr.h" #include "srsran/adt/circular_array.h" +#include "srsran/common/test_common.h" #include #include @@ -103,7 +104,7 @@ private: sim_nr_ue_ctxt_t ctxt; }; -/// Implementation of features common to sched_nr_sim_parallel and sched_nr_sim +/// Implementation of features common to parallel and sequential sched nr testers class sched_nr_base_tester { public: @@ -121,8 +122,12 @@ public: void run_slot(slot_point slot_tx); void stop(); + slot_point get_slot_tx() const { return current_slot_tx; } + int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx); + void user_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_); + srsran::const_span get_cell_params() { return cell_params; } // configurable by simulator concrete implementation @@ -141,11 +146,11 @@ protected: /// Runs general tests to verify result consistency, and updates UE state void process_results(); - std::string test_name; - srslog::basic_logger& logger; - srslog::basic_logger& mac_logger; - std::unique_ptr sched_ptr; - std::vector cell_params; + std::unique_ptr test_delimiter; + srslog::basic_logger& logger; + srslog::basic_logger& mac_logger; + std::unique_ptr sched_ptr; + std::vector cell_params; std::vector > cc_workers; diff --git a/srsgnb/src/stack/mac/test/sched_nr_test.cc b/srsgnb/src/stack/mac/test/sched_nr_test.cc index 58cf370ab..1a9cb2baa 100644 --- a/srsgnb/src/stack/mac/test/sched_nr_test.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_test.cc @@ -25,7 +25,7 @@ struct sched_event_t { sched_event_t add_user(uint32_t slot_count, uint16_t rnti, uint32_t preamble_idx) { auto task = [rnti, preamble_idx](sched_nr_base_tester& tester) { - tester.add_user(rnti, get_rach_ue_cfg(1), tester.get_slot_tx() - TX_ENB_DELAY, preamble_idx); + tester.add_user(rnti, get_rach_ue_cfg(0), tester.get_slot_tx() - TX_ENB_DELAY, preamble_idx); }; return sched_event_t{slot_count, task}; } @@ -76,7 +76,7 @@ int main() auto& test_logger = srslog::fetch_basic_logger("TEST"); test_logger.set_level(srslog::basic_levels::warning); auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR"); - mac_nr_logger.set_level(srslog::basic_levels::warning); + mac_nr_logger.set_level(srslog::basic_levels::debug); auto& pool_logger = srslog::fetch_basic_logger("POOL"); pool_logger.set_level(srslog::basic_levels::debug);