aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/rfnoc/window_block_ctrl_impl.cpp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2018-06-22 14:50:19 +0100
committerMartin Braun <martin.braun@ettus.com>2018-06-22 09:13:11 -0700
commit1ae324575c203dc5fdb7ac4833562fd8c9860235 (patch)
treec3487e234b7f13e3954ce503277537dbba0e2ed2 /host/lib/rfnoc/window_block_ctrl_impl.cpp
parentb5be620d1922e924eb5da5bf26955b570eab2584 (diff)
downloaduhd-1ae324575c203dc5fdb7ac4833562fd8c9860235.tar.gz
uhd-1ae324575c203dc5fdb7ac4833562fd8c9860235.tar.bz2
uhd-1ae324575c203dc5fdb7ac4833562fd8c9860235.zip
RFNoC: Add FIR, Null, and Window block controllers
Diffstat (limited to 'host/lib/rfnoc/window_block_ctrl_impl.cpp')
-rw-r--r--host/lib/rfnoc/window_block_ctrl_impl.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/host/lib/rfnoc/window_block_ctrl_impl.cpp b/host/lib/rfnoc/window_block_ctrl_impl.cpp
new file mode 100644
index 000000000..74ebd146d
--- /dev/null
+++ b/host/lib/rfnoc/window_block_ctrl_impl.cpp
@@ -0,0 +1,94 @@
+//
+// Copyright 2014-2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/rfnoc/window_block_ctrl.hpp>
+#include <uhd/convert.hpp>
+#include <uhd/utils/log.hpp>
+
+using namespace uhd::rfnoc;
+
+class window_block_ctrl_impl : public window_block_ctrl
+{
+public:
+ UHD_RFNOC_BLOCK_CONSTRUCTOR(window_block_ctrl),
+ _item_type("sc16"), // We only support sc16 in this block
+ _bpi(uhd::convert::get_bytes_per_item("sc16"))
+ {
+ _max_len = uint32_t(user_reg_read64(RB_MAX_WINDOW_LEN));
+ UHD_LOGGER_DEBUG(unique_id())
+ << "window_block::window_block() max_len ==" << _max_len << std::endl;
+ UHD_ASSERT_THROW(_max_len);
+
+ // TODO we need a coercer to check that spp on the prop tree doesn't get set to anything invalid
+ _set_default_window(std::min<size_t>(get_arg<int>("spp"), _max_len));
+ }
+
+ //! Set window coefficients and length
+ void set_window(const std::vector<int> &coeffs)
+ {
+ UHD_LOGGER_TRACE(unique_id())
+ << "window_block::set_window()" << std::endl;
+ if (coeffs.size() > _max_len) {
+ throw uhd::value_error(str(
+ boost::format("window_block::set_window(): Too many window "
+ "coefficients! Provided %d, window allows up to %d.\n")
+ % coeffs.size() % _max_len
+ ));
+ }
+
+ size_t window_len = coeffs.size();
+
+ // Window block can take complex coefficients in sc16 format, but typical usage is
+ // to have real(coeffs) == imag(coeffs)
+ std::vector<uint32_t> coeffs_;
+ for (size_t i = 0; i < window_len - 1; i++) {
+ if (coeffs[i] > 32767 || coeffs[i] < -32768) {
+ throw uhd::value_error(str(
+ boost::format("window_block::set_window(): Coefficient %d "
+ "(index %d) outside coefficient range [-32768,32767].\n")
+ % coeffs[i] % i));
+ }
+ coeffs_.push_back(coeffs[i]);
+ }
+
+ // Write coefficients via the load bus
+ for (size_t i = 0; i < window_len - 1; i++) {
+ sr_write(AXIS_WINDOW_LOAD, coeffs_[i]);
+ }
+ // Assert tlast when sending the final coefficient (sorry, no joke here)
+ sr_write(AXIS_WINDOW_LOAD_TLAST, coeffs_.back());
+ // Set the window length
+ sr_write(SR_WINDOW_LEN, window_len);
+
+ // This block requires spp to match the window length:
+ set_arg<int>("spp", int(window_len));
+ }
+
+ //! Returns the maximum window length of this block.
+ size_t get_max_len() const
+ {
+ return _max_len;
+ }
+
+ size_t get_window_len() const
+ {
+ return size_t(get_arg<int>("spp"));
+ }
+
+
+private:
+ const std::string _item_type;
+ const size_t _bpi;
+ size_t _max_len;
+
+ //! Default is a rectangular window
+ void _set_default_window(size_t window_len) {
+ std::vector<int> default_coeffs(window_len, (1 << 15)-1);
+ set_window(default_coeffs);
+ }
+};
+
+UHD_RFNOC_BLOCK_REGISTER(window_block_ctrl, "Window");