aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Rossetto <aaron.rossetto@ni.com>2020-08-05 07:33:46 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2020-08-05 07:47:22 -0500
commit72e4cc81d2d3305b7e5b9d6f884b10120547700e (patch)
treee83a53a0aea36a7b70e62f7854157e95c9e23fed
parentb39021ac2e642c22349183b6bc697daae01da5e9 (diff)
downloaduhd-72e4cc81d2d3305b7e5b9d6f884b10120547700e.tar.gz
uhd-72e4cc81d2d3305b7e5b9d6f884b10120547700e.tar.bz2
uhd-72e4cc81d2d3305b7e5b9d6f884b10120547700e.zip
rfnoc: Add Keep One in N block support
-rw-r--r--host/include/uhd/rfnoc/CMakeLists.txt1
-rw-r--r--host/include/uhd/rfnoc/defaults.hpp1
-rw-r--r--host/include/uhd/rfnoc/keep_one_in_n_block_control.hpp84
-rw-r--r--host/lib/rfnoc/CMakeLists.txt1
-rw-r--r--host/lib/rfnoc/keep_one_in_n_block_control.cpp120
5 files changed, 207 insertions, 0 deletions
diff --git a/host/include/uhd/rfnoc/CMakeLists.txt b/host/include/uhd/rfnoc/CMakeLists.txt
index 965710a59..7fd1cd21d 100644
--- a/host/include/uhd/rfnoc/CMakeLists.txt
+++ b/host/include/uhd/rfnoc/CMakeLists.txt
@@ -37,6 +37,7 @@ UHD_INSTALL(FILES
ddc_block_control.hpp
duc_block_control.hpp
dmafifo_block_control.hpp
+ keep_one_in_n_block_control.hpp
fft_block_control.hpp
fir_filter_block_control.hpp
fosphor_block_control.hpp
diff --git a/host/include/uhd/rfnoc/defaults.hpp b/host/include/uhd/rfnoc/defaults.hpp
index f96dad8a0..1b9cb5016 100644
--- a/host/include/uhd/rfnoc/defaults.hpp
+++ b/host/include/uhd/rfnoc/defaults.hpp
@@ -81,6 +81,7 @@ static const noc_id_t FFT_BLOCK = 0xFF700000;
static const noc_id_t FIR_FILTER_BLOCK = 0xF1120000;
static const noc_id_t FOSPHOR_BLOCK = 0x666F0000;
static const noc_id_t LOGPWR_BLOCK = 0x4C500000;
+static const noc_id_t KEEP_ONE_IN_N_BLOCK = 0x02460000;
static const noc_id_t MOVING_AVERAGE_BLOCK = 0xAAD20000;
static const noc_id_t RADIO_BLOCK = 0x12AD1000;
static const noc_id_t REPLAY_BLOCK = 0x4E91A000;
diff --git a/host/include/uhd/rfnoc/keep_one_in_n_block_control.hpp b/host/include/uhd/rfnoc/keep_one_in_n_block_control.hpp
new file mode 100644
index 000000000..fc6f0511b
--- /dev/null
+++ b/host/include/uhd/rfnoc/keep_one_in_n_block_control.hpp
@@ -0,0 +1,84 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <uhd/config.hpp>
+#include <uhd/rfnoc/noc_block_base.hpp>
+#include <uhd/types/ranges.hpp>
+
+namespace uhd { namespace rfnoc {
+
+/*! Keep One in N Block Control Class
+ *
+ * The Keep One in N block has two modes: sample mode and packet mode.
+ * In sample mode, the first sample is kept and then N-1 samples are dropped.
+ * Packet mode is similar to sample mode, except a packet of samples is kept
+ * and then N-1 packets are dropped. The packet size is determined automatically.
+ */
+class UHD_API keep_one_in_n_block_control : public noc_block_base
+{
+public:
+ RFNOC_DECLARE_BLOCK(keep_one_in_n_block_control)
+
+ enum class mode {SAMPLE_MODE, PACKET_MODE};
+
+ // Block registers
+ static const uint32_t REG_N_OFFSET;
+ static const uint32_t REG_MODE_OFFSET;
+ static const uint32_t REG_WIDTH_N_OFFSET;
+
+ /*! Get the maximum supported value for N
+ *
+ * Get the maximum supported value for N for all channels
+ *
+ * \returns The maximum supported value for N
+ */
+ virtual size_t get_max_n() const = 0;
+
+ /*! Get the current value of N
+ *
+ * Get the current value of N
+ *
+ * \param chan The block channel
+ * \returns The current value of N
+ */
+ virtual size_t get_n(const size_t chan = 0) const = 0;
+
+ /*! Set the value of N
+ *
+ * Set the value of N.
+ * See set_mode() for how the value of N is interpreted
+ * depending on the mode.
+ *
+ * \param n The number of samples or packets to drop (minus one)
+ * \param chan The block channel
+ */
+ virtual void set_n(const size_t n, const size_t chan = 0) = 0;
+
+ /*! Get the current mode
+ *
+ * Get the current mode (sample or packet mode, see mode enum)
+ *
+ * \param chan The block channel
+ * \returns The current mode
+ */
+ virtual mode get_mode(const size_t chan = 0) const = 0;
+
+ /*! Set the mode
+ *
+ * Set the mode.
+ * There are two modes, sample mode (0) and packet mode (1).
+ * In sample mode, the block will keep 1 value and then drop N-1 values.
+ * In packet mode, the block will keep 1 packet and then drop N-1 packets.
+ *
+ * \param mode The mode of the block
+ * \param chan The block channel
+ */
+ virtual void set_mode(const mode mode, const size_t chan = 0) = 0;
+};
+
+}} // namespace uhd::rfnoc
diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt
index 6c7b8c726..33da287fe 100644
--- a/host/lib/rfnoc/CMakeLists.txt
+++ b/host/lib/rfnoc/CMakeLists.txt
@@ -45,6 +45,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/ddc_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/duc_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dmafifo_block_control.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/keep_one_in_n_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fft_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fir_filter_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fosphor_block_control.cpp
diff --git a/host/lib/rfnoc/keep_one_in_n_block_control.cpp b/host/lib/rfnoc/keep_one_in_n_block_control.cpp
new file mode 100644
index 000000000..baec58fbf
--- /dev/null
+++ b/host/lib/rfnoc/keep_one_in_n_block_control.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/exception.hpp>
+#include <uhd/rfnoc/keep_one_in_n_block_control.hpp>
+#include <uhd/rfnoc/defaults.hpp>
+#include <uhd/rfnoc/multichan_register_iface.hpp>
+#include <uhd/rfnoc/property.hpp>
+#include <uhd/rfnoc/registry.hpp>
+
+using namespace uhd::rfnoc;
+
+//! Space (in bytes) between register banks per channel
+const uint32_t REG_BANK_OFFSET = 2048;
+
+const uint32_t keep_one_in_n_block_control::REG_N_OFFSET = 0 * 8;
+const uint32_t keep_one_in_n_block_control::REG_MODE_OFFSET = 1 * 8;
+const uint32_t keep_one_in_n_block_control::REG_WIDTH_N_OFFSET = 2 * 8;
+
+// User property names
+const std::string PROP_KEY_N = "n";
+const std::string PROP_KEY_MODE = "mode";
+
+class keep_one_in_n_block_control_impl : public keep_one_in_n_block_control
+{
+public:
+ RFNOC_BLOCK_CONSTRUCTOR(keep_one_in_n_block_control),
+ _keep_one_in_n_reg_iface(*this, 0, REG_BANK_OFFSET),
+ _max_n( (2 << regs().peek32(REG_WIDTH_N_OFFSET))-1 ) // Fixed HDL parameter
+ {
+ UHD_ASSERT_THROW(get_num_input_ports() == get_num_output_ports());
+ _register_props();
+ }
+
+ size_t get_max_n() const
+ {
+ return _max_n;
+ }
+
+ void set_n(const size_t n, const size_t chan = 0)
+ {
+ set_property<int>(PROP_KEY_N, static_cast<int>(n), chan);
+ }
+
+ size_t get_n(const size_t chan = 0) const
+ {
+ return _n.at(chan).get();
+ }
+
+ void set_mode(const mode mode, const size_t chan = 0)
+ {
+ set_property<int>(PROP_KEY_MODE, static_cast<int>(mode), chan);
+ }
+
+ mode get_mode(const size_t chan = 0) const
+ {
+ return static_cast<mode>(_mode.at(chan).get());
+ }
+
+protected:
+ //! Block-specific register interface
+ multichan_register_iface _keep_one_in_n_reg_iface;
+
+private:
+ void _register_props()
+ {
+ const size_t num_chans = get_num_input_ports();
+ _n.reserve(num_chans);
+ _mode.reserve(num_chans);
+
+ for (size_t chan = 0; chan < num_chans; chan++) {
+
+ _n.push_back(property_t<int>(
+ PROP_KEY_N, 1, {res_source_info::USER, chan}));
+ _mode.push_back(property_t<int>(
+ PROP_KEY_MODE, static_cast<int>(mode::SAMPLE_MODE),
+ {res_source_info::USER, chan}));
+
+ register_property(&_n.back());
+ register_property(&_mode.back());
+
+ add_property_resolver({&_n.back()}, {&_n.back()}, [this, chan]() {
+ const int max_n = this->_max_n;
+ const int n = this->_n.at(chan).get();
+ if (n < 1) {
+ throw uhd::value_error("Value of n must be positive");
+ }
+ else if (n > max_n) {
+ throw uhd::value_error("Value of n must be less than "
+ + std::to_string(max_n));
+ }
+ this->regs().poke32(REG_N_OFFSET, n);
+ });
+ add_property_resolver({&_mode.back()},
+ {&_mode.back()}, [this, chan]() {
+ const int mode = this->_mode.at(chan).get();
+ this->regs().poke32(REG_MODE_OFFSET, mode);
+ });
+ }
+ }
+
+ /**************************************************************************
+ * Attributes
+ *************************************************************************/
+ //! Maximum value for N
+ const int _max_n;
+
+ //! Properties for scaling_in (one per port)
+ std::vector<property_t<int>> _n;
+
+ //! Sample mode or Packet mode
+ std::vector<property_t<int>> _mode;
+
+};
+
+UHD_RFNOC_BLOCK_REGISTER_DIRECT(
+ keep_one_in_n_block_control, KEEP_ONE_IN_N_BLOCK, "KeepOneInN", CLOCK_KEY_GRAPH, "bus_clk")