From 027201d457b48b30b63f267c8fc62914ecac0e20 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 17 Jun 2021 18:24:02 +0200 Subject: [PATCH] SRSUE/SRSENB: Refactor NR workers to generalise lower PHY --- .../srsran/interfaces/phy_common_interface.h | 29 +++++ srsenb/hdr/phy/nr/cc_worker.h | 19 +-- srsenb/hdr/phy/nr/sf_worker.h | 16 +-- srsenb/hdr/phy/nr/worker_pool.h | 13 +- srsenb/hdr/phy/phy_common.h | 17 +-- srsenb/src/phy/nr/cc_worker.cc | 16 +-- srsenb/src/phy/nr/sf_worker.cc | 16 +-- srsenb/src/phy/nr/worker_pool.cc | 13 +- srsenb/src/phy/phy.cc | 2 +- srsue/hdr/phy/nr/cc_worker.h | 10 +- srsue/hdr/phy/nr/sf_worker.h | 10 +- srsue/hdr/phy/nr/worker_pool.h | 2 +- srsue/hdr/phy/phy_common.h | 5 +- srsue/src/phy/lte/sf_worker.cc | 10 +- srsue/src/phy/nr/cc_worker.cc | 110 ++++++++--------- srsue/src/phy/nr/sf_worker.cc | 24 ++-- srsue/src/phy/nr/worker_pool.cc | 7 +- srsue/src/phy/phy.cc | 2 +- srsue/src/phy/phy_common.cc | 8 +- test/CMakeLists.txt | 2 + test/phy/CMakeLists.txt | 23 ++++ test/phy/nr_phy_test.cc | 111 ++++++++++++++++++ 22 files changed, 323 insertions(+), 142 deletions(-) create mode 100644 lib/include/srsran/interfaces/phy_common_interface.h create mode 100644 test/phy/CMakeLists.txt create mode 100644 test/phy/nr_phy_test.cc diff --git a/lib/include/srsran/interfaces/phy_common_interface.h b/lib/include/srsran/interfaces/phy_common_interface.h new file mode 100644 index 000000000..a0df2e6e5 --- /dev/null +++ b/lib/include/srsran/interfaces/phy_common_interface.h @@ -0,0 +1,29 @@ +/** + * + * \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_PHY_COMMON_INTERFACE_H +#define SRSRAN_PHY_COMMON_INTERFACE_H + +#include "../radio/rf_buffer.h" +#include "../radio/rf_timestamp.h" + +namespace srsran { + +class phy_common_interface +{ +public: + virtual void worker_end(void* h, srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& tx_time, bool is_nr) = 0; +}; + +} // namespace srsran + +#endif // SRSRAN_PHY_COMMON_INTERFACE_H diff --git a/srsenb/hdr/phy/nr/cc_worker.h b/srsenb/hdr/phy/nr/cc_worker.h index 2226c83b8..26667f1f4 100644 --- a/srsenb/hdr/phy/nr/cc_worker.h +++ b/srsenb/hdr/phy/nr/cc_worker.h @@ -13,6 +13,7 @@ #ifndef SRSENB_NR_CC_WORKER_H #define SRSENB_NR_CC_WORKER_H +#include "srsenb/hdr/phy/phy_interfaces.h" #include "srsran/interfaces/gnb_interfaces.h" #include "srsran/interfaces/rrc_nr_interface_types.h" #include "srsran/phy/enb/enb_dl_nr.h" @@ -24,16 +25,18 @@ namespace srsenb { namespace nr { -typedef struct { - uint32_t nof_carriers; - srsran_enb_dl_nr_args_t dl; -} phy_nr_args_t; +struct phy_nr_args_t { + uint32_t nof_carriers = 1; + uint32_t nof_ports = 1; + srsran_enb_dl_nr_args_t dl = {}; +}; class phy_nr_state { public: - phy_nr_args_t args = {}; - srsran::phy_cfg_nr_t cfg = {}; + phy_cell_cfg_list_nr_t cell_list = {}; + phy_nr_args_t args; + srsran::phy_cfg_nr_t cfg; phy_nr_state() { @@ -49,7 +52,7 @@ public: class cc_worker { public: - cc_worker(uint32_t cc_idx, srslog::basic_logger& logger, phy_nr_state* phy_state_); + cc_worker(uint32_t cc_idx, srslog::basic_logger& logger, phy_nr_state& phy_state_); ~cc_worker(); bool set_carrier(const srsran_carrier_nr_t* carrier); @@ -70,7 +73,7 @@ private: std::array tx_buffer = {}; std::array rx_buffer = {}; uint32_t buffer_sz = 0; - phy_nr_state* phy_state; + phy_nr_state& phy_state; srsran_enb_dl_nr_t enb_dl = {}; srslog::basic_logger& logger; }; diff --git a/srsenb/hdr/phy/nr/sf_worker.h b/srsenb/hdr/phy/nr/sf_worker.h index bf15ccc1d..2c41a6eb6 100644 --- a/srsenb/hdr/phy/nr/sf_worker.h +++ b/srsenb/hdr/phy/nr/sf_worker.h @@ -10,12 +10,12 @@ * */ -#ifndef SRSUE_NR_PHCH_WORKER_H -#define SRSUE_NR_PHCH_WORKER_H +#ifndef SRSENB_NR_PHCH_WORKER_H +#define SRSENB_NR_PHCH_WORKER_H #include "cc_worker.h" -#include "srsenb/hdr/phy/phy_common.h" #include "srsran/common/thread_pool.h" +#include "srsran/interfaces/phy_common_interface.h" #include "srsran/srslog/srslog.h" namespace srsenb { @@ -32,7 +32,7 @@ namespace nr { class sf_worker final : public srsran::thread_pool::worker { public: - sf_worker(phy_common* phy_, phy_nr_state* phy_state_, srslog::basic_logger& logger); + sf_worker(srsran::phy_common_interface& common_, phy_nr_state& phy_state_, srslog::basic_logger& logger); ~sf_worker(); bool set_carrier_unlocked(uint32_t cc_idx, const srsran_carrier_nr_t* carrier_); @@ -49,9 +49,9 @@ private: std::vector > cc_workers; - phy_common* phy = nullptr; - phy_nr_state* phy_state = nullptr; - srslog::basic_logger& logger; + srsran::phy_common_interface& common; + phy_nr_state& phy_state; + srslog::basic_logger& logger; // Temporal attributes srsran_softbuffer_tx_t softbuffer_tx = {}; @@ -61,4 +61,4 @@ private: } // namespace nr } // namespace srsenb -#endif // SRSUE_NR_PHCH_WORKER_H +#endif // SRSENB_NR_PHCH_WORKER_H diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index ebe00b378..37df6bb33 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -10,10 +10,11 @@ * */ -#ifndef SRSUE_NR_WORKER_POOL_H -#define SRSUE_NR_WORKER_POOL_H +#ifndef SRSENB_NR_WORKER_POOL_H +#define SRSENB_NR_WORKER_POOL_H #include "sf_worker.h" +#include "srsenb/hdr/phy/phy_interfaces.h" #include "srsran/common/thread_pool.h" namespace srsenb { @@ -29,7 +30,11 @@ public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } worker_pool(uint32_t max_workers); - bool init(const phy_args_t& args, phy_common* common, srslog::sink& log_sink, int prio); + bool init(const phy_cell_cfg_list_nr_t& cell_list, + const phy_args_t& args, + srsran::phy_common_interface& common, + srslog::sink& log_sink, + int prio); sf_worker* wait_worker(uint32_t tti); sf_worker* wait_worker_id(uint32_t id); void start_worker(sf_worker* w); @@ -39,4 +44,4 @@ public: } // namespace nr } // namespace srsenb -#endif // SRSUE_NR_WORKER_POOL_H +#endif // SRSENB_NR_WORKER_POOL_H diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 7ff216ca1..f8fbc2546 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -21,6 +21,7 @@ #include "srsran/common/thread_pool.h" #include "srsran/common/threads.h" #include "srsran/interfaces/enb_metrics_interface.h" +#include "srsran/interfaces/phy_common_interface.h" #include "srsran/interfaces/radio_interfaces.h" #include "srsran/phy/channel/channel.h" #include "srsran/radio/radio.h" @@ -31,7 +32,7 @@ namespace srsenb { -class phy_common +class phy_common : public srsran::phy_common_interface { public: phy_common() = default; @@ -56,7 +57,10 @@ public: * @param tx_time timestamp to transmit samples * @param is_nr flag is true if it is called from NR */ - void worker_end(void* tx_sem_id, srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& tx_time, bool is_nr = false); + void worker_end(void* tx_sem_id, + srsran::rf_buffer_t& buffer, + srsran::rf_timestamp_t& tx_time, + bool is_nr = false) override; // Common objects phy_args_t params = {}; @@ -151,15 +155,6 @@ public: } return c; }; - srsran_carrier_nr_t get_cell_nr(uint32_t cc_idx) - { - srsran_carrier_nr_t c = {}; - if (cc_idx < cell_list_nr.size()) { - c = cell_list_nr[cc_idx].carrier; - } - - return c; - }; void set_cell_gain(uint32_t cell_id, float gain_db) { diff --git a/srsenb/src/phy/nr/cc_worker.cc b/srsenb/src/phy/nr/cc_worker.cc index d6e182be0..66f686800 100644 --- a/srsenb/src/phy/nr/cc_worker.cc +++ b/srsenb/src/phy/nr/cc_worker.cc @@ -15,20 +15,20 @@ namespace srsenb { namespace nr { -cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, phy_nr_state* phy_state_) : +cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, phy_nr_state& phy_state_) : cc_idx(cc_idx_), phy_state(phy_state_), logger(log) { cf_t* buffer_c[SRSRAN_MAX_PORTS] = {}; // Allocate buffers - buffer_sz = SRSRAN_SF_LEN_PRB(phy_state->args.dl.nof_max_prb); - for (uint32_t i = 0; i < phy_state_->args.dl.nof_tx_antennas; i++) { + buffer_sz = SRSRAN_SF_LEN_PRB(phy_state.args.dl.nof_max_prb); + for (uint32_t i = 0; i < phy_state.args.dl.nof_tx_antennas; i++) { tx_buffer[i] = srsran_vec_cf_malloc(buffer_sz); rx_buffer[i] = srsran_vec_cf_malloc(buffer_sz); buffer_c[i] = tx_buffer[i]; } - if (srsran_enb_dl_nr_init(&enb_dl, buffer_c, &phy_state_->args.dl)) { + if (srsran_enb_dl_nr_init(&enb_dl, buffer_c, &phy_state.args.dl)) { ERROR("Error initiating UE DL NR"); return; } @@ -60,8 +60,8 @@ bool cc_worker::set_carrier(const srsran_carrier_nr_t* carrier) coreset.freq_resources[0] = true; // Enable the bottom 6 PRB for PDCCH coreset.duration = 2; - srsran_dci_cfg_nr_t dci_cfg = phy_state->cfg.get_dci_cfg(); - if (srsran_enb_dl_nr_set_pdcch_config(&enb_dl, &phy_state->cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) { + srsran_dci_cfg_nr_t dci_cfg = phy_state.cfg.get_dci_cfg(); + if (srsran_enb_dl_nr_set_pdcch_config(&enb_dl, &phy_state.cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) { ERROR("Error setting coreset"); return false; } @@ -76,7 +76,7 @@ void cc_worker::set_tti(uint32_t tti) cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx) { - if (antenna_idx >= phy_state->args.dl.nof_tx_antennas) { + if (antenna_idx >= phy_state.args.dl.nof_tx_antennas) { return nullptr; } @@ -85,7 +85,7 @@ cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx) cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx) { - if (antenna_idx >= phy_state->args.dl.nof_tx_antennas) { + if (antenna_idx >= phy_state.args.dl.nof_tx_antennas) { return nullptr; } diff --git a/srsenb/src/phy/nr/sf_worker.cc b/srsenb/src/phy/nr/sf_worker.cc index fb134852a..be1b300fa 100644 --- a/srsenb/src/phy/nr/sf_worker.cc +++ b/srsenb/src/phy/nr/sf_worker.cc @@ -14,10 +14,10 @@ namespace srsenb { namespace nr { -sf_worker::sf_worker(phy_common* phy_, phy_nr_state* phy_state_, srslog::basic_logger& logger) : - phy(phy_), phy_state(phy_state_), logger(logger) +sf_worker::sf_worker(srsran::phy_common_interface& common_, phy_nr_state& phy_state_, srslog::basic_logger& logger) : + common(common_), phy_state(phy_state_), logger(logger) { - for (uint32_t i = 0; i < phy_state->args.nof_carriers; i++) { + for (uint32_t i = 0; i < phy_state.args.nof_carriers; i++) { cc_worker* w = new cc_worker(i, logger, phy_state); cc_workers.push_back(std::unique_ptr(w)); } @@ -82,14 +82,14 @@ void sf_worker::work_imp() // Get Transmission buffers srsran::rf_buffer_t tx_buffer = {}; srsran::rf_timestamp_t dummy_ts = {}; - for (uint32_t cc = 0; cc < phy->get_nof_carriers_nr(); cc++) { - for (uint32_t ant = 0; ant < phy->get_nof_ports(0); ant++) { - tx_buffer.set(cc, ant, phy->get_nof_ports(0), cc_workers[cc]->get_tx_buffer(ant)); + for (uint32_t cc = 0; cc < phy_state.args.nof_carriers; cc++) { + for (uint32_t ant = 0; ant < phy_state.args.nof_ports; ant++) { + tx_buffer.set(cc, ant, phy_state.args.nof_ports, cc_workers[cc]->get_tx_buffer(ant)); } } // Configure user - phy_state->cfg.pdsch.rbg_size_cfg_1 = false; + phy_state.cfg.pdsch.rbg_size_cfg_1 = false; // Fill grant (this comes from the scheduler) srsran_slot_cfg_t dl_cfg = {}; @@ -116,7 +116,7 @@ void sf_worker::work_imp() w->work_dl(dl_cfg, grants); } - phy->worker_end(this, tx_buffer, dummy_ts, true); + common.worker_end(this, tx_buffer, dummy_ts, true); } } // namespace nr diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index eed75af45..30eddcdcb 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -16,8 +16,15 @@ namespace nr { worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {} -bool worker_pool::init(const phy_args_t& args, phy_common* common, srslog::sink& log_sink, int prio) +bool worker_pool::init(const phy_cell_cfg_list_nr_t& cell_list, + const phy_args_t& args, + srsran::phy_common_interface& common, + srslog::sink& log_sink, + int prio) { + // Save cell list + phy_state.cell_list = cell_list; + // Add workers to workers pool and start threads srslog::basic_levels log_level = srslog::str_to_basic_level(args.log.phy_level); for (uint32_t i = 0; i < args.nof_phy_threads; i++) { @@ -25,11 +32,11 @@ bool worker_pool::init(const phy_args_t& args, phy_common* common, srslog::sink& log.set_level(log_level); log.set_hex_dump_max_size(args.log.phy_hex_limit); - auto w = new sf_worker(common, &phy_state, log); + auto w = new sf_worker(common, phy_state, log); pool.init_worker(i, w, prio); workers.push_back(std::unique_ptr(w)); - srsran_carrier_nr_t c = common->get_cell_nr(0); + srsran_carrier_nr_t c = phy_state.cell_list[0].carrier; w->set_carrier_unlocked(0, &c); } diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index 1db96641c..8243b5e53 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -132,7 +132,7 @@ int phy::init(const phy_args_t& args, lte_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO); } if (not cfg.phy_cell_cfg_nr.empty()) { - nr_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO); + nr_workers.init(cfg.phy_cell_cfg_nr, args, workers_common, log_sink, WORKERS_THREAD_PRIO); } // For each carrier, initialise PRACH worker diff --git a/srsue/hdr/phy/nr/cc_worker.h b/srsue/hdr/phy/nr/cc_worker.h index 1d0687435..90e1f5d7f 100644 --- a/srsue/hdr/phy/nr/cc_worker.h +++ b/srsue/hdr/phy/nr/cc_worker.h @@ -22,7 +22,7 @@ namespace nr { class cc_worker { public: - cc_worker(uint32_t cc_idx, srslog::basic_logger& log, state* phy_state_); + cc_worker(uint32_t cc_idx, srslog::basic_logger& log, state& phy_state_); ~cc_worker(); bool update_cfg(); @@ -49,10 +49,10 @@ private: std::array rx_buffer = {}; std::array tx_buffer = {}; uint32_t buffer_sz = 0; - state* phy = nullptr; - srsran_ssb_t ssb = {}; - srsran_ue_dl_nr_t ue_dl = {}; - srsran_ue_ul_nr_t ue_ul = {}; + state& phy; + srsran_ssb_t ssb = {}; + srsran_ue_dl_nr_t ue_dl = {}; + srsran_ue_ul_nr_t ue_ul = {}; srslog::basic_logger& logger; // Methods for DCI blind search diff --git a/srsue/hdr/phy/nr/sf_worker.h b/srsue/hdr/phy/nr/sf_worker.h index 61eee0535..e2dc1637f 100644 --- a/srsue/hdr/phy/nr/sf_worker.h +++ b/srsue/hdr/phy/nr/sf_worker.h @@ -13,9 +13,9 @@ #ifndef SRSUE_NR_PHCH_WORKER_H #define SRSUE_NR_PHCH_WORKER_H -#include "../phy_common.h" #include "cc_worker.h" #include "srsran/common/thread_pool.h" +#include "srsran/interfaces/phy_common_interface.h" namespace srsue { namespace nr { @@ -31,7 +31,7 @@ namespace nr { class sf_worker final : public srsran::thread_pool::worker { public: - sf_worker(phy_common* phy, state* phy_state_, srslog::basic_logger& logger); + sf_worker(srsran::phy_common_interface& common_, state& phy_state_, srslog::basic_logger& logger); ~sf_worker() = default; bool update_cfg(uint32_t cc_idx); @@ -51,9 +51,9 @@ private: std::vector > cc_workers; - phy_common* phy = nullptr; - state* phy_state = nullptr; - srslog::basic_logger& logger; + srsran::phy_common_interface& common; + state& phy_state; + srslog::basic_logger& logger; uint32_t tti_rx = 0; cf_t* prach_ptr = nullptr; diff --git a/srsue/hdr/phy/nr/worker_pool.h b/srsue/hdr/phy/nr/worker_pool.h index adc42609d..286bf8bc1 100644 --- a/srsue/hdr/phy/nr/worker_pool.h +++ b/srsue/hdr/phy/nr/worker_pool.h @@ -33,7 +33,7 @@ public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } worker_pool(uint32_t max_workers); - bool init(const phy_args_nr_t& args_, phy_common* common, stack_interface_phy_nr* stack_, int prio); + bool init(const phy_args_nr_t& args_, srsran::phy_common_interface& common, stack_interface_phy_nr* stack_, int prio); sf_worker* wait_worker(uint32_t tti); void start_worker(sf_worker* w); void stop(); diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index d283ddf7d..10d26aa1e 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -17,6 +17,7 @@ #include "srsran/adt/circular_array.h" #include "srsran/common/gen_mch_tables.h" #include "srsran/common/tti_sempahore.h" +#include "srsran/interfaces/phy_common_interface.h" #include "srsran/interfaces/phy_interface_types.h" #include "srsran/interfaces/radio_interfaces.h" #include "srsran/interfaces/rrc_interface_types.h" @@ -46,7 +47,7 @@ public: }; /* Subclass that manages variables common to all workers */ -class phy_common +class phy_common : public srsran::phy_common_interface { public: /* Common variables used by all phy workers */ @@ -129,7 +130,7 @@ public: srsran_pdsch_ack_resource_t resource); bool get_dl_pending_ack(srsran_ul_sf_cfg_t* sf, uint32_t cc_idx, srsran_pdsch_ack_cc_t* ack); - void worker_end(void* h, bool tx_enable, srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& tx_time, bool is_nr); + void worker_end(void* h, srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& tx_time, bool is_nr) override; void set_cell(const srsran_cell_t& c); diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index 2ff948e9e..ea7b6a58c 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -155,7 +155,7 @@ void sf_worker::work_imp() { srsran::rf_buffer_t tx_signal_ptr = {}; if (!cell_initiated) { - phy->worker_end(this, false, tx_signal_ptr, tx_time, false); + phy->worker_end(this, tx_signal_ptr, tx_time, false); return; } @@ -216,7 +216,6 @@ void sf_worker::work_imp() } } } - tx_signal_ptr.set_nof_samples(nof_samples); // Set PRACH buffer signal pointer if (prach_ptr) { @@ -225,8 +224,13 @@ void sf_worker::work_imp() prach_ptr = nullptr; } + // Indicates worker there is a transmission by setting the number of samples + if (tx_signal_ready) { + tx_signal_ptr.set_nof_samples(nof_samples); + } + // Call worker_end to transmit the signal - phy->worker_end(this, tx_signal_ready, tx_signal_ptr, tx_time, false); + phy->worker_end(this, tx_signal_ptr, tx_time, false); if (rx_signal_ok) { update_measurements(); diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index ba818bdfe..1b2269a61 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -17,25 +17,25 @@ namespace srsue { namespace nr { -cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state* phy_state_) : +cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state& phy_state_) : cc_idx(cc_idx_), phy(phy_state_), logger(log) { cf_t* rx_buffer_c[SRSRAN_MAX_PORTS] = {}; // Allocate buffers - buffer_sz = SRSRAN_SF_LEN_PRB(phy->args.dl.nof_max_prb) * 5; - for (uint32_t i = 0; i < phy_state_->args.dl.nof_rx_antennas; i++) { + buffer_sz = SRSRAN_SF_LEN_PRB(phy.args.dl.nof_max_prb) * 5; + for (uint32_t i = 0; i < phy.args.dl.nof_rx_antennas; i++) { rx_buffer[i] = srsran_vec_cf_malloc(buffer_sz); rx_buffer_c[i] = rx_buffer[i]; tx_buffer[i] = srsran_vec_cf_malloc(buffer_sz); } - if (srsran_ue_dl_nr_init(&ue_dl, rx_buffer.data(), &phy_state_->args.dl) < SRSRAN_SUCCESS) { + if (srsran_ue_dl_nr_init(&ue_dl, rx_buffer.data(), &phy.args.dl) < SRSRAN_SUCCESS) { ERROR("Error initiating UE DL NR"); return; } - if (srsran_ue_ul_nr_init(&ue_ul, tx_buffer[0], &phy_state_->args.ul) < SRSRAN_SUCCESS) { + if (srsran_ue_ul_nr_init(&ue_ul, tx_buffer[0], &phy.args.ul) < SRSRAN_SUCCESS) { ERROR("Error initiating UE DL NR"); return; } @@ -67,38 +67,38 @@ cc_worker::~cc_worker() bool cc_worker::update_cfg() { - if (srsran_ue_dl_nr_set_carrier(&ue_dl, &phy->cfg.carrier) < SRSRAN_SUCCESS) { + if (srsran_ue_dl_nr_set_carrier(&ue_dl, &phy.cfg.carrier) < SRSRAN_SUCCESS) { ERROR("Error setting carrier"); return false; } - if (srsran_ue_ul_nr_set_carrier(&ue_ul, &phy->cfg.carrier) < SRSRAN_SUCCESS) { + if (srsran_ue_ul_nr_set_carrier(&ue_ul, &phy.cfg.carrier) < SRSRAN_SUCCESS) { ERROR("Error setting carrier"); return false; } - srsran_dci_cfg_nr_t dci_cfg = phy->cfg.get_dci_cfg(); - if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &phy->cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) { + srsran_dci_cfg_nr_t dci_cfg = phy.cfg.get_dci_cfg(); + if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &phy.cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) { logger.error("Error setting NR PDCCH configuration"); return false; } double abs_freq_point_a_freq = - srsran::srsran_band_helper().nr_arfcn_to_freq(phy->cfg.carrier.absolute_frequency_point_a); - double abs_freq_ssb_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(phy->cfg.carrier.absolute_frequency_ssb); + srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_point_a); + double abs_freq_ssb_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_ssb); - double carrier_center_freq = abs_freq_point_a_freq + (phy->cfg.carrier.nof_prb / 2 * - SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs) * SRSRAN_NRE); - uint16_t band = srsran::srsran_band_helper().get_band_from_dl_freq_Hz(carrier_center_freq); + double carrier_center_freq = + abs_freq_point_a_freq + (phy.cfg.carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs) * SRSRAN_NRE); + uint16_t band = srsran::srsran_band_helper().get_band_from_dl_freq_Hz(carrier_center_freq); srsran_ssb_cfg_t ssb_cfg = {}; - ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy->cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs); + ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy.cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs); ssb_cfg.center_freq_hz = carrier_center_freq; ssb_cfg.ssb_freq_hz = abs_freq_ssb_freq; - ssb_cfg.scs = phy->cfg.ssb.scs; - ssb_cfg.pattern = srsran::srsran_band_helper().get_ssb_pattern(band, phy->cfg.ssb.scs); + ssb_cfg.scs = phy.cfg.ssb.scs; + ssb_cfg.pattern = srsran::srsran_band_helper().get_ssb_pattern(band, phy.cfg.ssb.scs); ssb_cfg.duplex_mode = srsran::srsran_band_helper().get_duplex_mode(band); - ssb_cfg.periodicity_ms = phy->cfg.ssb.periodicity_ms; + ssb_cfg.periodicity_ms = phy.cfg.ssb.periodicity_ms; if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) { logger.error("Error setting SSB configuration"); @@ -119,7 +119,7 @@ void cc_worker::set_tti(uint32_t tti) cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx) { - if (antenna_idx >= phy->args.dl.nof_rx_antennas) { + if (antenna_idx >= phy.args.dl.nof_rx_antennas) { return nullptr; } @@ -128,7 +128,7 @@ cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx) cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx) { - if (antenna_idx >= phy->args.dl.nof_rx_antennas) { + if (antenna_idx >= phy.args.dl.nof_rx_antennas) { return nullptr; } @@ -143,7 +143,7 @@ uint32_t cc_worker::get_buffer_len() void cc_worker::decode_pdcch_dl() { std::array dci_rx = {}; - srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy->stack->get_dl_sched_rnti_nr(dl_slot_cfg.idx); + srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy.stack->get_dl_sched_rnti_nr(dl_slot_cfg.idx); // Skip search if no valid RNTI is given if (rnti.id == SRSRAN_INVALID_RNTI) { @@ -168,7 +168,7 @@ void cc_worker::decode_pdcch_dl() } // Enqueue UL grants - phy->set_dl_pending_grant(dl_slot_cfg, dci_rx[i]); + phy.set_dl_pending_grant(dl_slot_cfg, dci_rx[i]); } if (logger.debug.enabled()) { @@ -194,7 +194,7 @@ void cc_worker::decode_pdcch_dl() void cc_worker::decode_pdcch_ul() { std::array dci_rx = {}; - srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy->stack->get_ul_sched_rnti_nr(ul_slot_cfg.idx); + srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy.stack->get_ul_sched_rnti_nr(ul_slot_cfg.idx); // Skip search if no valid RNTI is given if (rnti.id == SRSRAN_INVALID_RNTI) { @@ -219,7 +219,7 @@ void cc_worker::decode_pdcch_ul() } // Enqueue UL grants - phy->set_ul_pending_grant(dl_slot_cfg.idx, dci_rx[i]); + phy.set_ul_pending_grant(dl_slot_cfg.idx, dci_rx[i]); } } @@ -229,7 +229,7 @@ bool cc_worker::decode_pdsch_dl() uint32_t pid = 0; srsran_sch_cfg_nr_t pdsch_cfg = {}; srsran_pdsch_ack_resource_nr_t ack_resource = {}; - if (not phy->get_dl_pending_grant(dl_slot_cfg.idx, pdsch_cfg, ack_resource, pid)) { + if (not phy.get_dl_pending_grant(dl_slot_cfg.idx, pdsch_cfg, ack_resource, pid)) { // Early return if no grant was available return true; } @@ -242,13 +242,13 @@ bool cc_worker::decode_pdsch_dl() mac_dl_grant.ndi = pdsch_cfg.grant.tb[0].ndi; mac_dl_grant.tbs = pdsch_cfg.grant.tb[0].tbs / 8; mac_dl_grant.tti = dl_slot_cfg.idx; - phy->stack->new_grant_dl(0, mac_dl_grant, &dl_action); + phy.stack->new_grant_dl(0, mac_dl_grant, &dl_action); // Abort if MAC says it doesn't need the TB if (not dl_action.tb.enabled) { // Force positive ACK if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_c) { - phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, true); + phy.set_pending_ack(dl_slot_cfg.idx, ack_resource, true); } logger.info("Decoding not required. Skipping PDSCH. ack_tti_tx=%d", TTI_ADD(dl_slot_cfg.idx, ack_resource.k1)); @@ -302,17 +302,17 @@ bool cc_worker::decode_pdsch_dl() // Enqueue PDSCH ACK information only if the RNTI is type C if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_c) { - phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res.tb[0].crc); + phy.set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res.tb[0].crc); } // Notify MAC about PDSCH decoding result mac_interface_phy_nr::tb_action_dl_result_t mac_dl_result = {}; mac_dl_result.ack = pdsch_res.tb[0].crc; mac_dl_result.payload = mac_dl_result.ack ? std::move(data) : nullptr; // only pass data when successful - phy->stack->tb_decoded(cc_idx, mac_dl_grant, std::move(mac_dl_result)); + phy.stack->tb_decoded(cc_idx, mac_dl_grant, std::move(mac_dl_result)); if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_ra) { - phy->rar_grant_tti = dl_slot_cfg.idx; + phy.rar_grant_tti = dl_slot_cfg.idx; } if (pdsch_res.tb[0].crc) { @@ -321,7 +321,7 @@ bool cc_worker::decode_pdsch_dl() dl_m.mcs = pdsch_cfg.grant.tb[0].mcs; dl_m.fec_iters = pdsch_res.tb[0].avg_iter; dl_m.evm = pdsch_res.evm[0]; - phy->set_dl_metrics(dl_m); + phy.set_dl_metrics(dl_m); } return true; @@ -334,7 +334,7 @@ bool cc_worker::measure_csi() srsran_csi_trs_measurements_t meas = {}; // Iterate all possible candidates - const std::array position_in_burst = phy->cfg.ssb.position_in_burst; + const std::array position_in_burst = phy.cfg.ssb.position_in_burst; for (uint32_t ssb_idx = 0; ssb_idx < SRSRAN_SSB_NOF_CANDIDATES; ssb_idx++) { // Skip SSB candidate if not enabled if (not position_in_burst[ssb_idx]) { @@ -342,7 +342,7 @@ bool cc_worker::measure_csi() } // Measure SSB candidate - if (srsran_ssb_csi_measure(&ssb, phy->cfg.carrier.pci, ssb_idx, rx_buffer[0], &meas) < SRSRAN_SUCCESS) { + if (srsran_ssb_csi_measure(&ssb, phy.cfg.carrier.pci, ssb_idx, rx_buffer[0], &meas) < SRSRAN_SUCCESS) { logger.error("Error measuring SSB"); return false; } @@ -360,13 +360,13 @@ bool cc_worker::measure_csi() ch_metrics.rsrq = 0.0f; // Not supported ch_metrics.rssi = 0.0f; // Not supported ch_metrics.sync_err = - meas.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs)); - phy->set_channel_metrics(ch_metrics); + meas.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs)); + phy.set_channel_metrics(ch_metrics); // Compute synch metrics and report it to the PHY state sync_metrics_t sync_metrics = {}; sync_metrics.cfo = meas.cfo_hz; - phy->set_sync_metrics(sync_metrics); + phy.set_sync_metrics(sync_metrics); // Report SSB candidate channel measurement to the PHY state // ... @@ -376,7 +376,7 @@ bool cc_worker::measure_csi() // Iterate all NZP-CSI-RS marked as TRS and perform channel measurements for (uint32_t resource_set_id = 0; resource_set_id < SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_SETS; resource_set_id++) { // Select NZP-CSI-RS set - const srsran_csi_rs_nzp_set_t& nzp_set = phy->cfg.pdsch.nzp_csi_rs_sets[resource_set_id]; + const srsran_csi_rs_nzp_set_t& nzp_set = phy.cfg.pdsch.nzp_csi_rs_sets[resource_set_id]; // Skip set if not set as TRS (it will be processed later) if (not nzp_set.trs_info) { @@ -409,13 +409,13 @@ bool cc_worker::measure_csi() ch_metrics.rsrq = 0.0f; // Not supported ch_metrics.rssi = 0.0f; // Not supported ch_metrics.sync_err = - trs_measurements.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy->cfg.carrier.scs)); - phy->set_channel_metrics(ch_metrics); + trs_measurements.delay_us / (float)(ue_dl.fft->fft_plan.size * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs)); + phy.set_channel_metrics(ch_metrics); // Compute synch metrics and report it to the PHY state sync_metrics_t sync_metrics = {}; sync_metrics.cfo = trs_measurements.cfo_hz; - phy->set_sync_metrics(sync_metrics); + phy.set_sync_metrics(sync_metrics); // Convert to CSI channel measurement and report new NZP-CSI-RS measurement to the PHY state srsran_csi_channel_measurements_t measurements = {}; @@ -425,13 +425,13 @@ bool cc_worker::measure_csi() measurements.wideband_snr_db = trs_measurements.snr_dB; measurements.nof_ports = 1; // Other values are not supported measurements.K_csi_rs = (uint32_t)n; - phy->new_nzp_csi_rs_channel_measurement(measurements, resource_set_id); + phy.new_nzp_csi_rs_channel_measurement(measurements, resource_set_id); } // Iterate all NZP-CSI-RS not marked as TRS and perform channel measurements for (uint32_t resource_set_id = 0; resource_set_id < SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_SETS; resource_set_id++) { // Select NZP-CSI-RS set - const srsran_csi_rs_nzp_set_t& nzp_set = phy->cfg.pdsch.nzp_csi_rs_sets[resource_set_id]; + const srsran_csi_rs_nzp_set_t& nzp_set = phy.cfg.pdsch.nzp_csi_rs_sets[resource_set_id]; // Skip set if set as TRS (it was processed previously) if (nzp_set.trs_info) { @@ -458,7 +458,7 @@ bool cc_worker::measure_csi() measurements.wideband_snr_db); // Report new measurement to the PHY state - phy->new_nzp_csi_rs_channel_measurement(measurements, resource_set_id); + phy.new_nzp_csi_rs_channel_measurement(measurements, resource_set_id); } return true; @@ -472,7 +472,7 @@ bool cc_worker::work_dl() } // Check if it is a DL slot, if not skip - if (!srsran_tdd_nr_is_dl(&phy->cfg.tdd, 0, dl_slot_cfg.idx)) { + if (!srsran_tdd_nr_is_dl(&phy.cfg.tdd, 0, dl_slot_cfg.idx)) { return true; } @@ -503,7 +503,7 @@ bool cc_worker::work_dl() bool cc_worker::work_ul() { // Check if it is a UL slot, if not skip - if (!srsran_tdd_nr_is_ul(&phy->cfg.tdd, 0, ul_slot_cfg.idx)) { + if (!srsran_tdd_nr_is_ul(&phy.cfg.tdd, 0, ul_slot_cfg.idx)) { // No NR signal shall be transmitted srsran_vec_cf_zero(tx_buffer[0], ue_ul.ifft.sf_sz); return true; @@ -514,11 +514,11 @@ bool cc_worker::work_ul() // Gather PDSCH ACK information srsran_pdsch_ack_nr_t pdsch_ack = {}; - bool has_ul_ack = phy->get_pending_ack(ul_slot_cfg.idx, pdsch_ack); + bool has_ul_ack = phy.get_pending_ack(ul_slot_cfg.idx, pdsch_ack); // Request grant to PHY state for this transmit TTI srsran_sch_cfg_nr_t pusch_cfg = {}; - bool has_pusch_grant = phy->get_ul_pending_grant(ul_slot_cfg.idx, pusch_cfg, pid); + bool has_pusch_grant = phy.get_ul_pending_grant(ul_slot_cfg.idx, pusch_cfg, pid); // If PDSCH UL ACK is available, load into UCI if (has_ul_ack) { @@ -531,7 +531,7 @@ bool cc_worker::work_ul() } } - if (srsran_ue_dl_nr_gen_ack(&phy->cfg.harq_ack, &pdsch_ack, &uci_data) < SRSRAN_SUCCESS) { + if (srsran_ue_dl_nr_gen_ack(&phy.cfg.harq_ack, &pdsch_ack, &uci_data) < SRSRAN_SUCCESS) { ERROR("Filling UCI ACK bits"); return false; } @@ -539,11 +539,11 @@ bool cc_worker::work_ul() // Add SR to UCI data only if there is no UL grant! if (!has_ul_ack) { - phy->get_pending_sr(ul_slot_cfg.idx, uci_data); + phy.get_pending_sr(ul_slot_cfg.idx, uci_data); } // Add CSI reports to UCI data if available - phy->get_periodic_csi(ul_slot_cfg.idx, uci_data); + phy.get_periodic_csi(ul_slot_cfg.idx, uci_data); if (has_pusch_grant) { // Notify MAC about PUSCH found grant @@ -556,7 +556,7 @@ bool cc_worker::work_ul() mac_ul_grant.ndi = pusch_cfg.grant.tb[0].ndi; mac_ul_grant.rv = pusch_cfg.grant.tb[0].rv; mac_ul_grant.is_rar_grant = (pusch_cfg.grant.rnti_type == srsran_rnti_type_ra); - phy->stack->new_grant_ul(0, mac_ul_grant, &ul_action); + phy.stack->new_grant_ul(0, mac_ul_grant, &ul_action); // Don't process further if MAC can't provide PDU if (not ul_action.tb.enabled) { @@ -565,7 +565,7 @@ bool cc_worker::work_ul() } // Set UCI configuration following procedures - srsran_ra_ul_set_grant_uci_nr(&phy->cfg.carrier, &phy->cfg.pusch, &uci_data.cfg, &pusch_cfg); + srsran_ra_ul_set_grant_uci_nr(&phy.cfg.carrier, &phy.cfg.pusch, &uci_data.cfg, &pusch_cfg); // Assigning MAC provided values to PUSCH config structs pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer; @@ -612,18 +612,18 @@ bool cc_worker::work_ul() ul_metrics_t ul_m = {}; ul_m.mcs = pusch_cfg.grant.tb[0].mcs; ul_m.power = srsran_convert_power_to_dB(srsran_vec_avg_power_cf(tx_buffer[0], ue_ul.ifft.sf_sz)); - phy->set_ul_metrics(ul_m); + phy.set_ul_metrics(ul_m); } else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) { // Get PUCCH resource srsran_pucch_nr_resource_t resource = {}; - if (srsran_ra_ul_nr_pucch_resource(&phy->cfg.pucch, &uci_data.cfg, &resource) < SRSRAN_SUCCESS) { + if (srsran_ra_ul_nr_pucch_resource(&phy.cfg.pucch, &uci_data.cfg, &resource) < SRSRAN_SUCCESS) { ERROR("Selecting PUCCH resource"); return false; } // Encode PUCCH message - if (srsran_ue_ul_nr_encode_pucch(&ue_ul, &ul_slot_cfg, &phy->cfg.pucch.common, &resource, &uci_data) < + if (srsran_ue_ul_nr_encode_pucch(&ue_ul, &ul_slot_cfg, &phy.cfg.pucch.common, &resource, &uci_data) < SRSRAN_SUCCESS) { ERROR("Encoding PUCCH"); return false; diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index a9e004276..bb596d1c9 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -27,10 +27,10 @@ static int plot_worker_id = -1; namespace srsue { namespace nr { -sf_worker::sf_worker(phy_common* phy_, state* phy_state_, srslog::basic_logger& log) : - phy_state(phy_state_), phy(phy_), logger(log) +sf_worker::sf_worker(srsran::phy_common_interface& common_, state& phy_state_, srslog::basic_logger& log) : + phy_state(phy_state_), common(common_), logger(log) { - for (uint32_t i = 0; i < phy_state->args.nof_carriers; i++) { + for (uint32_t i = 0; i < phy_state.args.nof_carriers; i++) { cc_worker* w = new cc_worker(i, log, phy_state); cc_workers.push_back(std::unique_ptr(w)); } @@ -79,8 +79,8 @@ void sf_worker::work_imp() } // Align workers, wait for previous workers to finish DL processing before starting UL processing - phy_state->dl_ul_semaphore.wait(this); - phy_state->dl_ul_semaphore.release(); + phy_state.dl_ul_semaphore.wait(this); + phy_state.dl_ul_semaphore.release(); // Check if PRACH is available if (prach_ptr != nullptr) { @@ -88,14 +88,14 @@ void sf_worker::work_imp() tx_buffer.set(0, prach_ptr); // Notify MAC about PRACH transmission - phy_state->stack->prach_sent(TTI_TX(tti_rx), - srsran_prach_nr_start_symbol_fr1_unpaired(phy_state->cfg.prach.config_idx), - SRSRAN_SLOT_NR_MOD(phy_state->cfg.carrier.scs, TTI_TX(tti_rx)), - 0, - 0); + phy_state.stack->prach_sent(TTI_TX(tti_rx), + srsran_prach_nr_start_symbol_fr1_unpaired(phy_state.cfg.prach.config_idx), + SRSRAN_SLOT_NR_MOD(phy_state.cfg.carrier.scs, TTI_TX(tti_rx)), + 0, + 0); // Transmit NR PRACH - phy->worker_end(this, false, tx_buffer, dummy_ts, true); + common.worker_end(this, tx_buffer, dummy_ts, true); // Reset PRACH pointer prach_ptr = nullptr; @@ -114,7 +114,7 @@ void sf_worker::work_imp() } // Always call worker_end before returning - phy->worker_end(this, false, tx_buffer, dummy_ts, true); + common.worker_end(this, tx_buffer, dummy_ts, true); // Tell the plotting thread to draw the plots #ifdef ENABLE_GUI diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index f4d66bc9f..44a30b656 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -16,7 +16,10 @@ namespace nr { worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers), logger(srslog::fetch_basic_logger("PHY-NR")) {} -bool worker_pool::init(const phy_args_nr_t& args, phy_common* common, stack_interface_phy_nr* stack_, int prio) +bool worker_pool::init(const phy_args_nr_t& args, + srsran::phy_common_interface& common, + stack_interface_phy_nr* stack_, + int prio) { phy_state.stack = stack_; phy_state.args = args; @@ -43,7 +46,7 @@ bool worker_pool::init(const phy_args_nr_t& args, phy_common* common, stack_inte log.set_level(srslog::str_to_basic_level(args.log.phy_level)); log.set_hex_dump_max_size(args.log.phy_hex_limit); - auto w = new sf_worker(common, &phy_state, log); + auto w = new sf_worker(common, phy_state, log); pool.init_worker(i, w, prio, args.worker_cpu_mask); workers.push_back(std::unique_ptr(w)); } diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 12de63ba3..e9d84e7c6 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -615,7 +615,7 @@ void phy::set_mch_period_stop(uint32_t stop) int phy::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) { - if (!nr_workers.init(args_, &common, stack_, WORKERS_THREAD_PRIO)) { + if (!nr_workers.init(args_, common, stack_, WORKERS_THREAD_PRIO)) { return SRSRAN_ERROR; } diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 4803d5fce..4b4462052 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -531,12 +531,10 @@ bool phy_common::get_dl_pending_ack(srsran_ul_sf_cfg_t* sf, uint32_t cc_idx, srs * Each worker uses this function to indicate that all processing is done and data is ready for transmission or * there is no transmission at all (tx_enable). In that case, the end of burst message will be sent to the radio */ -void phy_common::worker_end(void* tx_sem_id, - bool tx_enable, - srsran::rf_buffer_t& buffer, - srsran::rf_timestamp_t& tx_time, - bool is_nr) +void phy_common::worker_end(void* tx_sem_id, srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& tx_time, bool is_nr) { + bool tx_enable = buffer.get_nof_samples() > 0; + // Wait for the green light to transmit in the current TTI semaphore.wait(tx_sem_id); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d08986bd..996426ab2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,3 +19,5 @@ if (ZEROMQ_FOUND AND ENABLE_ZMQ_TEST) endforeach (cell_n_prb) endforeach (num_cc) endif (ZEROMQ_FOUND AND ENABLE_ZMQ_TEST) + +add_subdirectory(phy) \ No newline at end of file diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt new file mode 100644 index 000000000..943cf44d8 --- /dev/null +++ b/test/phy/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# 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. +# + +add_executable(nr_phy_test nr_phy_test.cc) +target_link_libraries(nr_phy_test + srsue_phy_nr + srsue_phy + srsran_common + srsran_phy + srsran_radio + srsenb_phy + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES} + ${ATOMIC_LIBS}) + +add_nr_test(nr_phy_test nr_phy_test) \ No newline at end of file diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc new file mode 100644 index 000000000..e7ea7ec8e --- /dev/null +++ b/test/phy/nr_phy_test.cc @@ -0,0 +1,111 @@ +/** + * + * \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. + * + */ + +#include "srsenb/hdr/phy/nr/worker_pool.h" +#include "srsran/common/test_common.h" +#include "srsue/hdr/phy/nr/worker_pool.h" + +class phy_common : public srsran::phy_common_interface +{ +public: + void worker_end(void* h, srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& tx_time, bool is_nr) override {} +}; + +class ue_dummy_stack : public srsue::stack_interface_phy_nr +{ +public: + void in_sync() override {} + void out_of_sync() override {} + void run_tti(const uint32_t tti) override {} + int sf_indication(const uint32_t tti) override { return 0; } + sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) override { return sched_rnti_t(); } + sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) override { return sched_rnti_t(); } + void new_grant_dl(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_t* action) override {} + void tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_result_t result) override {} + void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, tb_action_ul_t* action) override {} + 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 { return false; } +}; + +class test_bench +{ +private: + srsenb::nr::worker_pool gnb_phy; + phy_common gnb_phy_com; + srsue::nr::worker_pool ue_phy; + phy_common ue_phy_com; + ue_dummy_stack ue_stack; + bool initialised = false; + +public: + struct args_t { + uint32_t nof_threads = 6; + uint32_t nof_prb = 52; + + bool parse(int argc, char** argv); + }; + + test_bench(const args_t& args) : ue_phy(args.nof_threads), gnb_phy(args.nof_threads) + { + // Prepare cell list + srsenb::phy_cell_cfg_list_nr_t cell_list(1); + cell_list[0].carrier.nof_prb = args.nof_prb; + + // Prepare gNb PHY arguments + srsenb::phy_args_t gnb_phy_args = {}; + + // Initialise gnb + if (not gnb_phy.init(cell_list, gnb_phy_args, gnb_phy_com, srslog::get_default_sink(), 31)) { + return; + } + + // Prepare PHY + srsue::phy_args_nr_t ue_phy_args = {}; + + // Initialise UE PHY + if (not ue_phy.init(ue_phy_args, ue_phy_com, &ue_stack, 31)) { + return; + } + + initialised = true; + } + + ~test_bench() + { + gnb_phy.stop(); + ue_phy.stop(); + } + + bool is_initialised() const { return initialised; } +}; + +bool test_bench::args_t::parse(int argc, char** argv) +{ + return true; +} + +int main(int argc, char** argv) +{ + test_bench::args_t args = {}; + + // Parse arguments + TESTASSERT(args.parse(argc, argv)); + + // Create test bench + test_bench tb(args); + + // Assert bench is initialised correctly + TESTASSERT(tb.is_initialised()); + + // If reached here, the test is successful + return SRSRAN_SUCCESS; +} \ No newline at end of file