From daf471be1f203a80b9ab071c83d7f249b7a44c10 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 29 Jan 2020 11:01:58 +0000 Subject: [PATCH] moved test of pdsch collisions for separate test file --- srsenb/test/mac/scheduler_test_common.cc | 90 +++++++++++++++++++++++- srsenb/test/mac/scheduler_test_common.h | 13 +++- srsenb/test/mac/scheduler_test_rand.cc | 67 +++++------------- 3 files changed, 116 insertions(+), 54 deletions(-) diff --git a/srsenb/test/mac/scheduler_test_common.cc b/srsenb/test/mac/scheduler_test_common.cc index 11574f6e1..ff272136d 100644 --- a/srsenb/test/mac/scheduler_test_common.cc +++ b/srsenb/test/mac/scheduler_test_common.cc @@ -26,7 +26,7 @@ using namespace srsenb; -int output_sched_tester::test_ul_rb_collisions(const tti_params_t& tti_params, +int output_sched_tester::test_pusch_collisions(const tti_params_t& tti_params, const sched_interface::ul_sched_res_t& ul_result, prbmask_t& ul_allocs) const { @@ -74,7 +74,7 @@ int output_sched_tester::test_ul_rb_collisions(const tti_params_t& return SRSLTE_SUCCESS; } -int output_sched_tester::test_dl_rb_collisions(const tti_params_t& tti_params, +int output_sched_tester::test_pdsch_collisions(const tti_params_t& tti_params, const sched_interface::dl_sched_res_t& dl_result, rbgmask_t& rbgmask) const { @@ -150,11 +150,16 @@ int output_sched_tester::test_sib_scheduling(const tti_params_t& 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 */ + /* Test if any SIB was scheduled with wrong index, tbs, or outside of its window */ for (bc_elem* bc = bc_begin; bc != bc_end; ++bc) { if (bc->index == 0) { continue; } + CONDERROR(bc->index >= sched_interface::MAX_SIBS, "Invalid SIB idx=%d\n", bc->index + 1); + CONDERROR(bc->tbs < params.cfg->sibs[bc->index].len, + "Allocated BC process with TBS=%d < sib_len=%d\n", + bc->tbs, + params.cfg->sibs[bc->index].len); uint32_t x = (bc->index - 1) * params.cfg->si_window_ms; uint32_t sf = x % 10; uint32_t sfn_start = sfn; @@ -169,6 +174,85 @@ int output_sched_tester::test_sib_scheduling(const tti_params_t& return SRSLTE_SUCCESS; } +int output_sched_tester::test_pdcch_collisions(const sched_interface::dl_sched_res_t& dl_result, + const sched_interface::ul_sched_res_t& ul_result, + srslte::bounded_bitset<128, true>* used_cce) const +{ + used_cce->resize(srslte_regs_pdcch_ncce(params.regs, dl_result.cfi)); + used_cce->reset(); + + // Helper Function: checks if there is any collision. If not, fills the PDCCH mask + auto try_cce_fill = [&](const srslte_dci_location_t& dci_loc, const char* ch) { + uint32_t cce_start = dci_loc.ncce, cce_stop = dci_loc.ncce + (1u << dci_loc.L); + if (used_cce->any(cce_start, cce_stop)) { + TESTERROR("[TESTER] %s DCI collision between CCE positions (%u, %u)\n", ch, cce_start, cce_stop); + } + used_cce->fill(cce_start, cce_stop); + return SRSLTE_SUCCESS; + }; + + /* TEST: verify there are no dci collisions for UL, DL data, BC, RAR */ + for (uint32_t i = 0; i < ul_result.nof_dci_elems; ++i) { + const auto& pusch = ul_result.pusch[i]; + if (not pusch.needs_pdcch) { + // In case of non-adaptive retx or Msg3 + continue; + } + try_cce_fill(pusch.dci.location, "UL"); + } + for (uint32_t i = 0; i < dl_result.nof_data_elems; ++i) { + try_cce_fill(dl_result.data[i].dci.location, "DL data"); + } + for (uint32_t i = 0; i < dl_result.nof_bc_elems; ++i) { + try_cce_fill(dl_result.bc[i].dci.location, "DL BC"); + } + for (uint32_t i = 0; i < dl_result.nof_rar_elems; ++i) { + try_cce_fill(dl_result.rar[i].dci.location, "DL RAR"); + } + + return SRSLTE_SUCCESS; +} + +int output_sched_tester::test_dci_values_consistency(const sched_interface::dl_sched_res_t& dl_result, + const sched_interface::ul_sched_res_t& ul_result) const +{ + for (uint32_t i = 0; i < ul_result.nof_dci_elems; ++i) { + const auto& pusch = ul_result.pusch[i]; + CONDERROR(pusch.tbs == 0, "Allocated RAR process with invalid TBS=%d\n", pusch.tbs); + // CONDERROR(ue_db.count(pusch.dci.rnti) == 0, "The allocated rnti=0x%x does not exist\n", pusch.dci.rnti); + if (not pusch.needs_pdcch) { + // In case of non-adaptive retx or Msg3 + continue; + } + CONDERROR(pusch.dci.location.L == 0, + "[TESTER] Invalid aggregation level %d\n", + pusch.dci.location.L); // TODO: Extend this test + } + for (uint32_t i = 0; i < dl_result.nof_data_elems; ++i) { + auto& data = dl_result.data[i]; + CONDERROR(data.tbs[0] == 0, "Allocated DL data has empty TBS\n"); + } + for (uint32_t i = 0; i < dl_result.nof_bc_elems; ++i) { + auto& bc = dl_result.bc[i]; + if (bc.type == sched_interface::dl_sched_bc_t::BCCH) { + CONDERROR(bc.tbs < params.cfg->sibs[bc.index].len, + "Allocated BC process with TBS=%d < sib_len=%d\n", + bc.tbs, + params.cfg->sibs[bc.index].len); + } else if (bc.type == sched_interface::dl_sched_bc_t::PCCH) { + CONDERROR(bc.tbs == 0, "Allocated paging process with invalid TBS=%d\n", bc.tbs); + } else { + TESTERROR("Invalid broadcast process id=%d\n", (int)bc.type); + } + } + for (uint32_t i = 0; i < dl_result.nof_rar_elems; ++i) { + const auto& rar = dl_result.rar[i]; + CONDERROR(rar.tbs == 0, "Allocated RAR process with invalid TBS=%d\n", rar.tbs); + } + + return SRSLTE_SUCCESS; +} + int srsenb::extract_dl_prbmask(const srslte_cell_t& cell, const srslte_dci_dl_t& dci, srslte::bounded_bitset<100, true>* alloc_mask) diff --git a/srsenb/test/mac/scheduler_test_common.h b/srsenb/test/mac/scheduler_test_common.h index 17f0bd2af..3f3d7e627 100644 --- a/srsenb/test/mac/scheduler_test_common.h +++ b/srsenb/test/mac/scheduler_test_common.h @@ -37,18 +37,27 @@ public: explicit output_sched_tester(const sched_params_t& params_) : params(params_) {} /* Check for collisions between RB allocations in the PUSCH and PUCCH */ - int test_ul_rb_collisions(const tti_params_t& tti_params, + int test_pusch_collisions(const tti_params_t& tti_params, const sched_interface::ul_sched_res_t& ul_result, prbmask_t& ul_allocs) const; /* Check for collision between RB allocations in the PDSCH */ - int test_dl_rb_collisions(const tti_params_t& tti_params, + int test_pdsch_collisions(const tti_params_t& tti_params, const sched_interface::dl_sched_res_t& dl_result, rbgmask_t& dl_mask) const; /* Check if SIBs are scheduled within their window */ int test_sib_scheduling(const tti_params_t& tti_params, const sched_interface::dl_sched_res_t& dl_result) const; + /* Check for collisions in the PDCCH */ + int test_pdcch_collisions(const sched_interface::dl_sched_res_t& dl_result, + const sched_interface::ul_sched_res_t& ul_result, + srslte::bounded_bitset<128, true>* used_cce) const; + + /* Check DCI params correctness */ + int test_dci_values_consistency(const sched_interface::dl_sched_res_t& dl_result, + const sched_interface::ul_sched_res_t& ul_result) const; + private: const sched_params_t& params; }; diff --git a/srsenb/test/mac/scheduler_test_rand.cc b/srsenb/test/mac/scheduler_test_rand.cc index d69f5735e..48dfa93f1 100644 --- a/srsenb/test/mac/scheduler_test_rand.cc +++ b/srsenb/test/mac/scheduler_test_rand.cc @@ -166,15 +166,14 @@ struct sched_tester : public srsenb::sched { srsenb::ul_harq_proc ul_harq; }; struct sched_tti_data { - uint32_t tti_rx; - uint32_t tti_tx_dl; - uint32_t tti_tx_ul; - uint32_t current_cfi; - uint32_t nof_prachs = 0; - bool ul_pending_msg3_present = false; - srsenb::sf_sched::pending_msg3_t ul_pending_msg3; - srslte::bounded_bitset<128, true> used_cce; - // std::vector used_cce; + uint32_t tti_rx; + uint32_t tti_tx_dl; + uint32_t tti_tx_ul; + uint32_t current_cfi; + uint32_t nof_prachs = 0; + bool ul_pending_msg3_present = false; + srsenb::sf_sched::pending_msg3_t ul_pending_msg3; + srslte::bounded_bitset<128, true> used_cce; std::map ue_data; ///< stores buffer state of each user tester_user_results total_ues; ///< stores combined UL/DL buffer state srsenb::sched_interface::ul_sched_res_t sched_result_ul; @@ -551,56 +550,26 @@ int sched_tester::assert_no_empty_allocs() */ int sched_tester::test_tti_result() { - const srsenb::sf_sched* tti_sched = carrier_schedulers[0]->get_sf_sched_ptr(tti_data.tti_rx); + /* TEST: Check if there are collisions in the PDCCH */ + TESTASSERT(output_tester->test_pdcch_collisions( + tti_data.sched_result_dl, tti_data.sched_result_ul, &tti_data.used_cce) == SRSLTE_SUCCESS); - // Helper Function: checks if there is any collision. If not, fills the mask - auto try_cce_fill = [&](const srslte_dci_location_t& dci_loc, const char* ch) { - uint32_t cce_start = dci_loc.ncce, cce_stop = dci_loc.ncce + (1u << dci_loc.L); - if (tti_data.used_cce.any(cce_start, cce_stop)) { - TESTERROR("[TESTER] %s DCI collision between CCE positions (%u, %u)\n", ch, cce_start, cce_stop); - } - tti_data.used_cce.fill(cce_start, cce_stop); - return SRSLTE_SUCCESS; - }; + /* TEST: Check whether dci values are correct */ + TESTASSERT(output_tester->test_dci_values_consistency(tti_data.sched_result_dl, tti_data.sched_result_ul) == + SRSLTE_SUCCESS); + + const srsenb::sf_sched* tti_sched = carrier_schedulers[0]->get_sf_sched_ptr(tti_data.tti_rx); - /* verify there are no dci collisions for UL, DL data, BC, RAR */ for (uint32_t i = 0; i < tti_data.sched_result_ul.nof_dci_elems; ++i) { const auto& pusch = tti_data.sched_result_ul.pusch[i]; - CONDERROR(pusch.tbs == 0, "Allocated RAR process with invalid TBS=%d\n", pusch.tbs); CONDERROR(ue_db.count(pusch.dci.rnti) == 0, "The allocated rnti=0x%x does not exist\n", pusch.dci.rnti); - if (not pusch.needs_pdcch) { - // In case of non-adaptive retx or Msg3 - continue; - } - CONDERROR(pusch.dci.location.L == 0, - "[TESTER] Invalid aggregation level %d\n", - pusch.dci.location.L); // TODO: Extend this test - try_cce_fill(pusch.dci.location, "UL"); } for (uint32_t i = 0; i < tti_data.sched_result_dl.nof_data_elems; ++i) { auto& data = tti_data.sched_result_dl.data[i]; - try_cce_fill(data.dci.location, "DL data"); CONDERROR(ue_db.count(data.dci.rnti) == 0, "Allocated rnti=0x%x that does not exist\n", data.dci.rnti); } - for (uint32_t i = 0; i < tti_data.sched_result_dl.nof_bc_elems; ++i) { - auto& bc = tti_data.sched_result_dl.bc[i]; - try_cce_fill(bc.dci.location, "DL BC"); - if (bc.type == sched_interface::dl_sched_bc_t::BCCH) { - CONDERROR(bc.index >= MAX_SIBS, "Invalid SIB idx=%d\n", bc.index + 1); - CONDERROR(bc.tbs < cfg.sibs[bc.index].len, - "Allocated BC process with TBS=%d < sib_len=%d\n", - bc.tbs, - cfg.sibs[bc.index].len); - } else if (bc.type == sched_interface::dl_sched_bc_t::PCCH) { - CONDERROR(bc.tbs == 0, "Allocated paging process with invalid TBS=%d\n", bc.tbs); - } else { - TESTERROR("Invalid broadcast process id=%d\n", (int)bc.type); - } - } for (uint32_t i = 0; i < tti_data.sched_result_dl.nof_rar_elems; ++i) { const auto& rar = tti_data.sched_result_dl.rar[i]; - try_cce_fill(rar.dci.location, "DL RAR"); - CONDERROR(rar.tbs == 0, "Allocated RAR process with invalid TBS=%d\n", rar.tbs); for (uint32_t j = 0; j < rar.nof_grants; ++j) { const auto& msg3_grant = rar.msg3_grant[j]; const auto& msg3_list = @@ -792,7 +761,7 @@ int sched_tester::test_collisions() srsenb::prbmask_t ul_allocs(cfg.cell.nof_prb); /* TEST: any collision in PUCCH and PUSCH */ - TESTASSERT(output_tester->test_ul_rb_collisions(tti_params, tti_data.sched_result_ul, ul_allocs) == SRSLTE_SUCCESS); + TESTASSERT(output_tester->test_pusch_collisions(tti_params, tti_data.sched_result_ul, ul_allocs) == SRSLTE_SUCCESS); /* TEST: check whether cumulative UL PRB masks coincide */ if (ul_allocs != tti_sched->get_ul_mask()) { @@ -828,7 +797,7 @@ int sched_tester::test_collisions() /* TEST: check any collision in PDSCH */ srsenb::rbgmask_t rbgmask(cfg.cell.nof_prb); - TESTASSERT(output_tester->test_dl_rb_collisions(tti_params, tti_data.sched_result_dl, rbgmask) == SRSLTE_SUCCESS); + TESTASSERT(output_tester->test_pdsch_collisions(tti_params, tti_data.sched_result_dl, rbgmask) == SRSLTE_SUCCESS); // update ue stats with number of DL RB allocations srslte::bounded_bitset<100, true> alloc_mask(cfg.cell.nof_prb);