diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index 44ff4271f..e7323b33f 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -67,7 +67,6 @@ bool slot_worker::init(const args_t& args) return false; } - // Prepare UL arguments srsran_gnb_ul_args_t ul_args = {}; ul_args.pusch.measure_time = true; diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 1a071a115..5f797acb9 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -7,6 +7,9 @@ # if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) + set(NR_PHY_TEST_GNB_NOF_THREADS 3) + set(NR_PHY_TEST_UE_NOF_THREADS 3) + add_executable(nr_phy_test nr_phy_test.cc) target_link_libraries(nr_phy_test srsue_phy @@ -23,7 +26,10 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) add_nr_test(nr_phy_test_10MHz_dl_only nr_phy_test --duration=100 --gnb.stack.pdsch.slots=\"0,1,2,3,4,5\" - --gnb.stack.pusch.slots=\"\") + --gnb.stack.pusch.slots=\"\" + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} + ) add_nr_test(nr_phy_test_10MHz_ul_only nr_phy_test --duration=100 # 100 slots @@ -32,6 +38,8 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pusch.start=0 # Start at RB 0 --gnb.stack.pusch.length=52 # Full 10 MHz BW --gnb.stack.pusch.mcs=28 # Maximum MCS + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} ) add_nr_test(nr_phy_test_10MHz_bidir nr_phy_test @@ -44,13 +52,17 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pusch.start=0 # Start at RB 0 --gnb.stack.pusch.length=52 # Full 10 MHz BW --gnb.stack.pusch.mcs=28 # Maximum MCS + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} ) add_nr_test(nr_phy_test_10MHz_prach nr_phy_test --duration=1000 # 100 slots --gnb.stack.pdsch.slots=6 # No PDSCH --gnb.stack.pusch.slots=0 # No PUSCH + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} --ue.stack.prach.period=30 # Transmit PRACH every 30 radio frames --ue.stack.prach.preamble=10 # Use preamble 10 + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} ) endif () diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index e7568ab4d..9d6258ffc 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -47,10 +47,9 @@ private: std::set slots; } dl, ul; srsran::circular_array dl_data_to_ul_ack; - uint32_t ss_id = 0; - srsran_random_t random_gen = nullptr; - srsran::phy_cfg_nr_t phy_cfg = {}; - bool valid = false; + uint32_t ss_id = 0; + srsran::phy_cfg_nr_t phy_cfg = {}; + bool valid = false; std::mutex metrics_mutex; metrics_t metrics = {}; @@ -124,9 +123,8 @@ private: }; std::array pending_pusch = {}; - srsran::circular_array tx_harq_proc; - - srsran::circular_array rx_harq_proc; + dummy_tx_harq_entity tx_harq_proc; + dummy_rx_harq_entity rx_harq_proc; bool schedule_pdsch(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) { @@ -180,9 +178,6 @@ private: // 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); - // Set softbuffer pdsch.sch.grant.tb[0].softbuffer.tx = &tx_harq_proc[slot_cfg.idx].get_softbuffer(dci.ndi); @@ -292,7 +287,6 @@ public: gnb_dummy_stack(const args_t& args) : rnti(args.rnti), phy_cfg(args.phy_cfg), ss_id(args.ss_id) { - random_gen = srsran_random_init(0x1234); logger.set_level(srslog::str_to_basic_level(args.log_level)); dl.mcs = args.pdsch.mcs; @@ -347,7 +341,7 @@ public: valid = true; } - ~gnb_dummy_stack() { srsran_random_free(random_gen); } + ~gnb_dummy_stack() {} bool is_valid() const { return valid; } int rx_data_indication(rx_data_ind_t& grant) override { return 0; } @@ -411,7 +405,6 @@ public: // Generate data pusch.data[0] = rx_harq_proc[pusch.pid].get_tb(pusch.sch.grant.tb[0].tbs).data(); pusch.data[1] = nullptr; - srsran_random_byte_vector(random_gen, pusch.data[0], pusch.sch.grant.tb[0].tbs / 8); // Put UCI configuration in PUSCH config if (not phy_cfg.get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { @@ -462,6 +455,8 @@ public: return SRSRAN_ERROR; } + // Handle UL-SCH metrics + std::unique_lock lock(metrics_mutex); if (not pusch_info.pusch_data.tb[0].crc) { metrics.mac.rx_errors++; } diff --git a/test/phy/dummy_rx_harq_proc.h b/test/phy/dummy_rx_harq_proc.h index 77ca5c6fa..300553547 100644 --- a/test/phy/dummy_rx_harq_proc.h +++ b/test/phy/dummy_rx_harq_proc.h @@ -61,4 +61,7 @@ public: uint32_t get_tbs() const { return tbs; } }; +class dummy_rx_harq_entity : public srsran::circular_array +{}; + #endif // SRSRAN_DUMMY_RX_HARQ_PROC_H diff --git a/test/phy/dummy_tx_harq_proc.h b/test/phy/dummy_tx_harq_proc.h index 6ae47d873..d3a1631d2 100644 --- a/test/phy/dummy_tx_harq_proc.h +++ b/test/phy/dummy_tx_harq_proc.h @@ -23,9 +23,11 @@ class dummy_tx_harq_proc { private: + mutable std::mutex mutex; + srsran_random_t random_gen = nullptr; srsran::byte_buffer_t data; srsran_softbuffer_tx_t softbuffer = {}; - std::atomic tbs = {0}; + uint32_t tbs = 0; bool first = true; uint32_t ndi = 0; @@ -39,16 +41,26 @@ public: } } - ~dummy_tx_harq_proc() { srsran_softbuffer_tx_free(&softbuffer); } + void init(uint32_t pid) { random_gen = srsran_random_init(pid * 1234); } + + ~dummy_tx_harq_proc() + { + srsran_softbuffer_tx_free(&softbuffer); + srsran_random_free(random_gen); + } srsran::byte_buffer_t& get_tb(uint32_t tbs_) { + std::unique_lock lock(mutex); tbs = tbs_; + srsran_random_byte_vector(random_gen, data.msg, tbs / 8); return data; } srsran_softbuffer_tx_t& get_softbuffer(uint32_t ndi_) { + std::unique_lock lock(mutex); + if (ndi_ != ndi || first) { srsran_softbuffer_tx_reset(&softbuffer); ndi = ndi_; @@ -58,7 +70,23 @@ public: return softbuffer; } - uint32_t get_tbs() const { return tbs; } + uint32_t get_tbs() const + { + std::unique_lock lock(mutex); + return tbs; + } +}; + +class dummy_tx_harq_entity : public srsran::circular_array +{ +public: + dummy_tx_harq_entity() : srsran::circular_array() + { + uint32_t pid = 0; + for (dummy_tx_harq_proc& proc : *this) { + proc.init(pid++); + } + } }; #endif // SRSRAN_TX_DUMMY_HARQ_PROC_H diff --git a/test/phy/dummy_ue_stack.h b/test/phy/dummy_ue_stack.h index 286960c3d..51580aba8 100644 --- a/test/phy/dummy_ue_stack.h +++ b/test/phy/dummy_ue_stack.h @@ -27,7 +27,6 @@ public: }; private: - srsran_random_t random_gen = srsran_random_init(0x4567); uint16_t rnti = 0; bool valid = false; uint32_t sr_period = 0; @@ -37,8 +36,8 @@ private: metrics_t metrics = {}; srsue::phy_interface_stack_nr& phy; - srsran::circular_array tx_harq_proc; - srsran::circular_array rx_harq_proc; + dummy_tx_harq_entity tx_harq_proc; + dummy_rx_harq_entity rx_harq_proc; public: struct args_t { @@ -56,7 +55,7 @@ public: { valid = true; } - ~ue_dummy_stack() { srsran_random_free(random_gen); } + ~ue_dummy_stack() = default; void in_sync() override {} void out_of_sync() override {} void run_tti(const uint32_t tti) override @@ -88,7 +87,6 @@ public: action->tb.enabled = true; action->tb.payload = &tx_harq_proc[grant.pid].get_tb(grant.tbs); action->tb.softbuffer = &tx_harq_proc[grant.pid].get_softbuffer(grant.ndi); - srsran_random_byte_vector(random_gen, action->tb.payload->msg, grant.tbs); } void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) override {} bool sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, bool ul_sch_tx) override