aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/rfnoc/traffic_counter.hpp81
-rw-r--r--host/lib/rfnoc/null_block_ctrl_impl.cpp19
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");