diff options
-rw-r--r-- | host/include/uhd/rfnoc/traffic_counter.hpp | 81 | ||||
-rw-r--r-- | host/lib/rfnoc/null_block_ctrl_impl.cpp | 19 |
2 files changed, 100 insertions, 0 deletions
diff --git a/host/include/uhd/rfnoc/traffic_counter.hpp b/host/include/uhd/rfnoc/traffic_counter.hpp new file mode 100644 index 000000000..4077596cd --- /dev/null +++ b/host/include/uhd/rfnoc/traffic_counter.hpp @@ -0,0 +1,81 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_TRAFFIC_COUNTER_HPP +#define INCLUDED_LIBUHD_TRAFFIC_COUNTER_HPP + +#include <uhd/property_tree.hpp> +#include <stdint.h> +#include <memory> +#include <functional> +#include <type_traits> + +namespace uhd { + namespace rfnoc { + +class traffic_counter +{ +public: + typedef std::shared_ptr<traffic_counter> sptr; + typedef std::function<void(const uint32_t addr, const uint32_t data)> write_reg_fn_t ; + typedef std::function<uint64_t(const uint32_t addr)> read_reg_fn_t ; + + traffic_counter( + uhd::property_tree::sptr tree, + uhd::fs_path root_path, + write_reg_fn_t write_reg_fn, + read_reg_fn_t read_reg_fn + ) : + _write_reg_fn(write_reg_fn), + _read_reg_fn(read_reg_fn) + { + const uint32_t id_reg_offset = 0; + const uint32_t first_counter_offset = 1; + const uint64_t traffic_counter_id = 0x712AFF1C00000000ULL; + + // Check traffic counter id to determine if it's present + const uint64_t id = _read_reg_fn(id_reg_offset); + + // If present, add properties + if (id == traffic_counter_id) + { + tree->create<bool>(root_path/"traffic_counter/enable") + .add_coerced_subscriber([this](const bool enable) { + uint32_t val = enable? 1 : 0; + return _write_reg_fn(0, val); + }).set(false); + + const char* counters[] = { + "bus_clock_ticks", + "xbar_to_shell_last", + "xbar_to_shell_valid", + "xbar_to_shell_ready", + "shell_to_xbar_last", + "shell_to_xbar_valid", + "shell_to_xbar_ready", + "shell_to_ce_last", + "shell_to_ce_valid", + "shell_to_ce_ready", + "ce_to_shell_last", + "ce_to_shell_valid", + "ce_to_shell_ready"}; + + for (size_t i = 0; i < std::extent<decltype(counters)>::value; i++) { + tree->create<uint64_t>(root_path/"traffic_counter"/counters[i]) + .set_publisher([this, i, first_counter_offset]() { + return _read_reg_fn(i+first_counter_offset); + }); + } + } + } +private: + write_reg_fn_t _write_reg_fn; + read_reg_fn_t _read_reg_fn; +}; + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_TRAFFIC_COUNTER_HPP */ diff --git a/host/lib/rfnoc/null_block_ctrl_impl.cpp b/host/lib/rfnoc/null_block_ctrl_impl.cpp index 7e62a2b3e..568933e7a 100644 --- a/host/lib/rfnoc/null_block_ctrl_impl.cpp +++ b/host/lib/rfnoc/null_block_ctrl_impl.cpp @@ -7,6 +7,7 @@ #include <uhd/utils/log.hpp> #include <uhd/types/ranges.hpp> #include <uhd/rfnoc/null_block_ctrl.hpp> +#include <uhd/rfnoc/traffic_counter.hpp> #include <boost/format.hpp> using namespace uhd::rfnoc; @@ -30,6 +31,21 @@ public: }) .update() ; + + traffic_counter::write_reg_fn_t write = + [this](const uint32_t addr, const uint32_t data) { + const uint64_t traffic_counter_sr_base = 192; + sr_write(addr+traffic_counter_sr_base, data); + }; + + traffic_counter::read_reg_fn_t read = + [this](const uint32_t addr) { + const uint64_t traffic_counter_rb_base = 64; + return user_reg_read64(addr+traffic_counter_rb_base); + }; + + _traffic_counter = std::make_shared<traffic_counter>( + _tree, _root_path, write, read); } void set_line_delay_cycles(int cycles) @@ -101,6 +117,9 @@ public: } sr_write(SR_NEXT_DST_SID, sid.get(), output_block_port); } + +private: + traffic_counter::sptr _traffic_counter; }; UHD_RFNOC_BLOCK_REGISTER(null_block_ctrl, "NullSrcSink"); |