aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include/uhdlib/rfnoc
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/include/uhdlib/rfnoc')
-rw-r--r--host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp46
-rw-r--r--host/lib/include/uhdlib/rfnoc/graph_impl.hpp80
-rw-r--r--host/lib/include/uhdlib/rfnoc/legacy_compat.hpp49
-rw-r--r--host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp247
-rw-r--r--host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp41
-rw-r--r--host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp79
-rw-r--r--host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp80
-rw-r--r--host/lib/include/uhdlib/rfnoc/utils.hpp67
-rw-r--r--host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp60
-rw-r--r--host/lib/include/uhdlib/rfnoc/xports.hpp29
10 files changed, 778 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp b/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp
new file mode 100644
index 000000000..2ef50a1a1
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp
@@ -0,0 +1,46 @@
+//
+// Copyright 2012-2016 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP
+#define INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP
+
+#include <uhd/utils/msg_task.hpp>
+#include <uhd/types/time_spec.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <uhd/types/wb_iface.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <string>
+
+namespace uhd { namespace rfnoc {
+
+/*!
+ * Provide access to peek, poke for the radio ctrl module
+ */
+class ctrl_iface : public uhd::timed_wb_iface
+{
+public:
+ typedef boost::shared_ptr<ctrl_iface> sptr;
+
+ virtual ~ctrl_iface(void) = 0;
+
+ //! Make a new control object
+ static sptr make(
+ const bool big_endian,
+ uhd::transport::zero_copy_if::sptr ctrl_xport,
+ uhd::transport::zero_copy_if::sptr resp_xport,
+ const uint32_t sid,
+ const std::string &name = "0"
+ );
+
+ //! Set the tick rate (converting time into ticks)
+ virtual void set_tick_rate(const double rate) = 0;
+};
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/graph_impl.hpp b/host/lib/include/uhdlib/rfnoc/graph_impl.hpp
new file mode 100644
index 000000000..182befbf4
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/graph_impl.hpp
@@ -0,0 +1,80 @@
+//
+// Copyright 2016 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP
+#define INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP
+
+#include <uhd/rfnoc/graph.hpp>
+#include <uhd/device3.hpp>
+
+namespace uhd { namespace rfnoc {
+
+class graph_impl : public graph
+{
+public:
+ /*!
+ * \param name An optional name to describe this graph
+ * \param device_ptr Weak pointer to the originating device3
+ * \param msg_handler Pointer to the async message handler
+ */
+ graph_impl(
+ const std::string &name,
+ boost::weak_ptr<uhd::device3> device_ptr
+ //async_msg_handler::sptr msg_handler
+ );
+ virtual ~graph_impl() {};
+
+ /************************************************************************
+ * Connection API
+ ***********************************************************************/
+ void connect(
+ const block_id_t &src_block,
+ size_t src_block_port,
+ const block_id_t &dst_block,
+ size_t dst_block_port,
+ const size_t pkt_size = 0
+ );
+
+ void connect(
+ const block_id_t &src_block,
+ const block_id_t &dst_block
+ );
+
+ void connect_src(
+ const block_id_t &src_block,
+ const size_t src_block_port,
+ const uhd::sid_t dst_sid,
+ const size_t buf_size_dst_bytes,
+ const size_t pkt_size_
+ );
+
+ void connect_sink(
+ const block_id_t &sink_block,
+ const size_t dst_block_port,
+ const size_t pkts_per_ack
+ );
+
+ /************************************************************************
+ * Utilities
+ ***********************************************************************/
+ std::string get_name() const { return _name; }
+
+
+private:
+
+ //! Optional: A string to describe this graph
+ const std::string _name;
+
+ //! Reference to the generating device object
+ const boost::weak_ptr<uhd::device3> _device_ptr;
+
+};
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP */
+// vim: sw=4 et:
diff --git a/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp b/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp
new file mode 100644
index 000000000..185b89f82
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp
@@ -0,0 +1,49 @@
+//
+// Copyright 2016 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_RFNOC_LEGACY_COMPAT_HPP
+#define INCLUDED_RFNOC_LEGACY_COMPAT_HPP
+
+#include <uhd/device3.hpp>
+#include <uhd/stream.hpp>
+
+namespace uhd { namespace rfnoc {
+
+ /*! Legacy compatibility layer class.
+ */
+ class legacy_compat
+ {
+ public:
+ typedef boost::shared_ptr<legacy_compat> sptr;
+
+ virtual uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t chan) = 0;
+
+ virtual uhd::fs_path tx_dsp_root(const size_t mboard_idx, const size_t chan) = 0;
+
+ virtual uhd::fs_path rx_fe_root(const size_t mboard_idx, const size_t chan) = 0;
+
+ virtual uhd::fs_path tx_fe_root(const size_t mboard_idx, const size_t chan) = 0;
+
+ virtual void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, size_t mboard, size_t chan) = 0;
+
+ virtual uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args) = 0;
+
+ virtual uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args) = 0;
+
+ virtual void set_rx_rate(const double rate, const size_t chan) = 0;
+
+ virtual void set_tx_rate(const double rate, const size_t chan) = 0;
+
+ static sptr make(
+ uhd::device3::sptr device,
+ const uhd::device_addr_t &args
+ );
+ };
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_RFNOC_LEGACY_COMPAT_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp
new file mode 100644
index 000000000..a5876584e
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp
@@ -0,0 +1,247 @@
+//
+// Copyright 2014-2016 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP
+#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP
+
+#include <uhd/rfnoc/radio_ctrl.hpp>
+#include <uhd/types/direction.hpp>
+#include <uhdlib/usrp/cores/rx_vita_core_3000.hpp>
+#include <uhdlib/usrp/cores/tx_vita_core_3000.hpp>
+#include <uhdlib/usrp/cores/time_core_3000.hpp>
+#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
+#include <boost/thread.hpp>
+#include <mutex>
+
+//! Shorthand for radio block constructor
+#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(CLASS_NAME) \
+ CLASS_NAME##_impl(const make_args_t &make_args);
+
+#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(CLASS_NAME) \
+ CLASS_NAME##_impl::CLASS_NAME##_impl( \
+ const make_args_t &make_args \
+ ) : block_ctrl_base(make_args), radio_ctrl_impl()
+
+namespace uhd {
+ namespace rfnoc {
+
+/*! \brief Provide access to a radio.
+ *
+ */
+class radio_ctrl_impl : public radio_ctrl
+{
+public:
+ /************************************************************************
+ * Structors
+ ***********************************************************************/
+ radio_ctrl_impl();
+ virtual ~radio_ctrl_impl() {};
+
+ /************************************************************************
+ * Public Radio API calls
+ ***********************************************************************/
+ virtual double set_rate(double rate);
+ virtual void set_tx_antenna(const std::string &ant, const size_t chan);
+ virtual void set_rx_antenna(const std::string &ant, const size_t chan);
+ virtual double set_tx_frequency(const double freq, const size_t chan);
+ virtual double set_rx_frequency(const double freq, const size_t chan);
+ virtual double set_tx_gain(const double gain, const size_t chan);
+ virtual double set_rx_gain(const double gain, const size_t chan);
+ virtual double set_tx_bandwidth(const double bandwidth, const size_t chan);
+ virtual double set_rx_bandwidth(const double bandwidth, const size_t chan);
+
+ virtual double get_rate() const;
+ virtual std::string get_tx_antenna(const size_t chan) /* const */;
+ virtual std::string get_rx_antenna(const size_t chan) /* const */;
+ virtual double get_tx_frequency(const size_t) /* const */;
+ virtual double get_rx_frequency(const size_t) /* const */;
+ virtual double get_tx_gain(const size_t) /* const */;
+ virtual double get_rx_gain(const size_t) /* const */;
+ virtual double get_tx_bandwidth(const size_t) /* const */;
+ virtual double get_rx_bandwidth(const size_t) /* const */;
+
+ virtual std::vector<std::string> get_rx_lo_names(const size_t chan);
+ virtual std::vector<std::string> get_rx_lo_sources(const std::string &name, const size_t chan);
+ virtual freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan);
+
+ virtual void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan);
+ virtual const std::string get_rx_lo_source(const std::string &name, const size_t chan);
+
+ virtual void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan);
+ virtual bool get_rx_lo_export_enabled(const std::string &name, const size_t chan);
+
+ virtual double set_rx_lo_freq(const double freq, const std::string &name, const size_t chan);
+ virtual double get_rx_lo_freq(const std::string &name, const size_t chan);
+
+ virtual std::vector<std::string> get_tx_lo_names(const size_t chan);
+ virtual std::vector<std::string> get_tx_lo_sources(const std::string &name, const size_t chan);
+ virtual freq_range_t get_tx_lo_freq_range(const std::string &name, const size_t chan);
+
+ virtual void set_tx_lo_source(const std::string &src, const std::string &name, const size_t chan);
+ virtual const std::string get_tx_lo_source(const std::string &name, const size_t chan);
+
+ virtual void set_tx_lo_export_enabled(const bool enabled, const std::string &name, const size_t chan);
+ virtual bool get_tx_lo_export_enabled(const std::string &name, const size_t chan);
+
+ virtual double set_tx_lo_freq(const double freq, const std::string &name, const size_t chan);
+ virtual double get_tx_lo_freq(const std::string &name, const size_t chan);
+
+ void set_time_now(const time_spec_t &time_spec);
+ void set_time_next_pps(const time_spec_t &time_spec);
+ void set_time_sync(const uhd::time_spec_t &time);
+ time_spec_t get_time_now();
+ time_spec_t get_time_last_pps();
+ virtual void set_time_source(const std::string &source);
+ virtual std::string get_time_source();
+ virtual std::vector<std::string> get_time_sources();
+ virtual void set_clock_source(const std::string &source);
+ virtual std::string get_clock_source();
+ virtual std::vector<std::string> get_clock_sources();
+
+ virtual std::vector<std::string> get_gpio_banks() const;
+ virtual void set_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const uint32_t value,
+ const uint32_t mask
+ );
+ virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr);
+
+ /***********************************************************************
+ * Block control API calls
+ **********************************************************************/
+ void set_rx_streamer(bool active, const size_t port);
+ void set_tx_streamer(bool active, const size_t port);
+
+ void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t port);
+
+ virtual double get_input_samp_rate(size_t /* port */) { return get_rate(); }
+ virtual double get_output_samp_rate(size_t /* port */) { return get_rate(); }
+ double _get_tick_rate() { return get_rate(); }
+
+ std::vector<size_t> get_active_rx_ports();
+ bool in_continuous_streaming_mode(const size_t chan) { return _continuous_streaming.at(chan); }
+ void rx_ctrl_clear_cmds(const size_t port) { sr_write(regs::RX_CTRL_CLEAR_CMDS, 0, port); }
+
+protected: // TODO see what's protected and what's private
+ void _register_loopback_self_test(size_t chan);
+
+ /***********************************************************************
+ * Registers
+ **********************************************************************/
+ struct regs {
+ static inline uint32_t sr_addr(const uint32_t offset)
+ {
+ return offset * 4;
+ }
+
+ static const uint32_t BASE = 128;
+
+ // defined in radio_core_regs.vh
+ static const uint32_t TIME = 128; // time hi - 128, time lo - 129, ctrl - 130
+ static const uint32_t CLEAR_CMDS = 131; // Any write to this reg clears the command FIFO
+ static const uint32_t LOOPBACK = 132;
+ static const uint32_t TEST = 133;
+ static const uint32_t CODEC_IDLE = 134;
+ static const uint32_t TX_CTRL_ERROR_POLICY = 144;
+ static const uint32_t RX_CTRL_CMD = 152;
+ static const uint32_t RX_CTRL_TIME_HI = 153;
+ static const uint32_t RX_CTRL_TIME_LO = 154;
+ static const uint32_t RX_CTRL_HALT = 155;
+ static const uint32_t RX_CTRL_MAXLEN = 156;
+ static const uint32_t RX_CTRL_CLEAR_CMDS = 157;
+ static const uint32_t MISC_OUTS = 160;
+ static const uint32_t DACSYNC = 161;
+ static const uint32_t SPI = 168;
+ static const uint32_t LEDS = 176;
+ static const uint32_t FP_GPIO = 184;
+ static const uint32_t GPIO = 192;
+ // NOTE: Upper 32 registers (224-255) are reserved for the output settings bus for use with
+ // device specific front end control
+
+ // frontend control: needs rethinking TODO
+ //static const uint32_t TX_FRONT = BASE + 96;
+ //static const uint32_t RX_FRONT = BASE + 112;
+ //static const uint32_t READBACK = BASE + 127;
+
+ static const uint32_t RB_TIME_NOW = 0;
+ static const uint32_t RB_TIME_PPS = 1;
+ static const uint32_t RB_TEST = 2;
+ static const uint32_t RB_CODEC_READBACK = 3;
+ static const uint32_t RB_RADIO_NUM = 4;
+ static const uint32_t RB_MISC_IO = 16;
+ static const uint32_t RB_SPI = 17;
+ static const uint32_t RB_LEDS = 18;
+ static const uint32_t RB_DB_GPIO = 19;
+ static const uint32_t RB_FP_GPIO = 20;
+ };
+
+ /***********************************************************************
+ * Block control API calls
+ **********************************************************************/
+ void _update_spp(int spp);
+
+ inline size_t _get_num_radios() const {
+ return std::max(_num_rx_channels, _num_tx_channels);
+ }
+
+ inline timed_wb_iface::sptr _get_ctrl(size_t radio_num) const {
+ return _perifs.at(radio_num).ctrl;
+ }
+
+ inline bool _is_streamer_active(uhd::direction_t dir, const size_t chan) const {
+ switch (dir) {
+ case uhd::TX_DIRECTION:
+ return _tx_streamer_active.at(chan);
+ case uhd::RX_DIRECTION:
+ return _rx_streamer_active.at(chan);
+ case uhd::DX_DIRECTION:
+ return _rx_streamer_active.at(chan) and _tx_streamer_active.at(chan);
+ default:
+ return false;
+ }
+ }
+
+ virtual bool check_radio_config() { return true; };
+
+ //! There is always only one time core per radio
+ time_core_3000::sptr _time64;
+
+ std::mutex _mutex;
+
+private:
+ /************************************************************************
+ * Peripherals
+ ***********************************************************************/
+ //! Stores pointers to all streaming-related radio cores
+ struct radio_perifs_t
+ {
+ timed_wb_iface::sptr ctrl;
+ };
+ std::map<size_t, radio_perifs_t> _perifs;
+
+ size_t _num_tx_channels;
+ size_t _num_rx_channels;
+
+ // Cached values
+ double _tick_rate;
+ std::map<size_t, std::string> _tx_antenna;
+ std::map<size_t, std::string> _rx_antenna;
+ std::map<size_t, double> _tx_freq;
+ std::map<size_t, double> _rx_freq;
+ std::map<size_t, double> _tx_gain;
+ std::map<size_t, double> _rx_gain;
+ std::map<size_t, double> _tx_bandwidth;
+ std::map<size_t, double> _rx_bandwidth;
+
+ std::vector<bool> _continuous_streaming;
+}; /* class radio_ctrl_impl */
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP */
+// vim: sw=4 et:
diff --git a/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp b/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp
new file mode 100644
index 000000000..91091d8c2
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp
@@ -0,0 +1,41 @@
+//
+// Copyright 2017 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP
+#define INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP
+
+#include <uhd/types/device_addr.hpp>
+#include <uhdlib/utils/rpc.hpp>
+
+namespace uhd {
+ namespace rfnoc {
+
+/*! Abstraction for RPC client
+ *
+ * Purpose of this class is to wrap the underlying RPC implementation.
+ * This class holds a connection to an RPC server (the connection is severed on
+ * destruction).
+ */
+class rpc_block_ctrl
+{
+public:
+ virtual ~rpc_block_ctrl() {}
+
+ /*! Pass in an RPC client for the block to use
+ *
+ * \param rpcc Reference to the RPC client
+ * \param block_args Additional block arguments
+ */
+ virtual void set_rpc_client(
+ uhd::rpc_client::sptr rpcc,
+ const uhd::device_addr_t &block_args
+ ) = 0;
+
+};
+
+}}
+
+#endif /* INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp b/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp
new file mode 100644
index 000000000..3f82ab12f
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp
@@ -0,0 +1,79 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP
+#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP
+
+#include <uhd/rfnoc/sink_node_ctrl.hpp>
+#include <uhd/rfnoc/rate_node_ctrl.hpp>
+#include <uhd/rfnoc/tick_node_ctrl.hpp>
+#include <uhd/rfnoc/scalar_node_ctrl.hpp>
+#include <uhd/rfnoc/terminator_node_ctrl.hpp>
+#include <uhd/rfnoc/block_ctrl_base.hpp> // For the block macros
+#include <mutex>
+
+namespace uhd {
+ namespace rfnoc {
+
+/*! \brief Terminator node for Rx streamers.
+ *
+ * This node is only used by rx_streamers. It terminates the flow graph
+ * inside the streamer and does not have a counterpart on the FPGA.
+ */
+class rx_stream_terminator :
+ public sink_node_ctrl,
+ public rate_node_ctrl,
+ public tick_node_ctrl,
+ public scalar_node_ctrl,
+ public terminator_node_ctrl
+{
+public:
+ UHD_RFNOC_BLOCK_OBJECT(rx_stream_terminator)
+
+ static sptr make()
+ {
+ return sptr(new rx_stream_terminator);
+ }
+
+ // If this is called, then by a send terminator at the other end
+ // of a flow graph.
+ double get_input_samp_rate(size_t) { return _samp_rate; };
+
+ // Same for the scaling factor
+ double get_input_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; };
+
+ std::string unique_id() const;
+
+ void set_rx_streamer(bool active, const size_t port);
+
+ void set_tx_streamer(bool active, const size_t port);
+
+ virtual ~rx_stream_terminator();
+
+ void handle_overrun(boost::weak_ptr<uhd::rx_streamer>, const size_t);
+
+protected:
+ rx_stream_terminator();
+
+ virtual double _get_tick_rate() { return _tick_rate; };
+
+private:
+ //! Every terminator has a unique index
+ const size_t _term_index;
+ static size_t _count;
+
+ double _samp_rate;
+ double _tick_rate;
+
+ std::mutex _overrun_handler_mutex;
+
+}; /* class rx_stream_terminator */
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP */
+// vim: sw=4 et:
diff --git a/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp b/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp
new file mode 100644
index 000000000..0a07e48ef
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp
@@ -0,0 +1,80 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP
+#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP
+
+#include <uhd/rfnoc/source_node_ctrl.hpp>
+#include <uhd/rfnoc/rate_node_ctrl.hpp>
+#include <uhd/rfnoc/tick_node_ctrl.hpp>
+#include <uhd/rfnoc/scalar_node_ctrl.hpp>
+#include <uhd/rfnoc/terminator_node_ctrl.hpp>
+#include <uhd/rfnoc/block_ctrl_base.hpp> // For the block macros
+#include <uhd/utils/log.hpp>
+
+namespace uhd {
+ namespace rfnoc {
+
+/*! \brief Terminator node for Tx streamers.
+ *
+ * This node is only used by tx_streamers. It terminates the flow graph
+ * inside the streamer and does not have a counterpart on the FPGA.
+ */
+class tx_stream_terminator :
+ public source_node_ctrl,
+ public rate_node_ctrl,
+ public tick_node_ctrl,
+ public scalar_node_ctrl,
+ public terminator_node_ctrl
+{
+public:
+ UHD_RFNOC_BLOCK_OBJECT(tx_stream_terminator)
+
+ static sptr make()
+ {
+ return sptr(new tx_stream_terminator);
+ }
+
+ void issue_stream_cmd(const uhd::stream_cmd_t &, const size_t)
+ {
+ UHD_RFNOC_BLOCK_TRACE() << "tx_stream_terminator::issue_stream_cmd()" ;
+ }
+
+ // If this is called, then by a send terminator at the other end
+ // of a flow graph.
+ double get_output_samp_rate(size_t) { return _samp_rate; };
+
+ // Same for the scaling factor
+ double get_output_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; };
+
+ std::string unique_id() const;
+
+ void set_rx_streamer(bool active, const size_t port);
+
+ void set_tx_streamer(bool active, const size_t port);
+
+ virtual ~tx_stream_terminator();
+
+protected:
+ tx_stream_terminator();
+
+ virtual double _get_tick_rate() { return _tick_rate; };
+
+private:
+ //! Every terminator has a unique index
+ const size_t _term_index;
+ static size_t _count;
+
+ double _samp_rate;
+ double _tick_rate;
+
+}; /* class tx_stream_terminator */
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP */
+// vim: sw=4 et:
diff --git a/host/lib/include/uhdlib/rfnoc/utils.hpp b/host/lib/include/uhdlib/rfnoc/utils.hpp
new file mode 100644
index 000000000..28c69987f
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/utils.hpp
@@ -0,0 +1,67 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_UTILS_HPP
+#define INCLUDED_LIBUHD_RFNOC_UTILS_HPP
+
+#include <uhd/rfnoc/node_ctrl_base.hpp>
+#include <boost/lexical_cast.hpp>
+#include <set>
+
+namespace uhd { namespace rfnoc { namespace utils {
+
+ /*! If \p suggested_port equals ANY_PORT, return the first available
+ * port number on \p nodes. Otherwise, return \p suggested_port.
+ *
+ * If \p allowed_ports is given, another condition is that the port
+ * number must be listed in here.
+ * If \p allowed_ports is not specified or empty, the assumption is
+ * that all ports are valid.
+ *
+ * On failure, ANY_PORT is returned.
+ */
+ static size_t node_map_find_first_free(
+ node_ctrl_base::node_map_t nodes,
+ const size_t suggested_port,
+ const std::set<size_t> allowed_ports=std::set<size_t>()
+ ) {
+ size_t port = suggested_port;
+ if (port == ANY_PORT) {
+ if (allowed_ports.empty()) {
+ port = 0;
+ while (nodes.count(port) and (port != ANY_PORT)) {
+ port++;
+ }
+ } else {
+ for(const size_t allowed_port: allowed_ports) {
+ if (not nodes.count(port)) {
+ return allowed_port;
+ }
+ return ANY_PORT;
+ }
+ }
+ } else {
+ if (not (allowed_ports.empty() or allowed_ports.count(port))) {
+ return ANY_PORT;
+ }
+ }
+ return port;
+ }
+
+ template <typename T>
+ static std::set<T> str_list_to_set(const std::vector<std::string> &list) {
+ std::set<T> return_set;
+ for(const std::string &S: list) {
+ return_set.insert(boost::lexical_cast<T>(S));
+ }
+ return return_set;
+ }
+
+}}}; /* namespace uhd::rfnoc::utils */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_UTILS_HPP */
+// vim: sw=4 et:
diff --git a/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp b/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp
new file mode 100644
index 000000000..753fa13af
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp
@@ -0,0 +1,60 @@
+//
+// Copyright 2016 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP
+#define INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/wb_iface.hpp>
+#include <boost/function.hpp>
+
+namespace uhd {
+ namespace rfnoc {
+
+class UHD_API wb_iface_adapter : public uhd::timed_wb_iface
+{
+public:
+ typedef boost::shared_ptr<wb_iface_adapter> sptr;
+ typedef boost::function<void(wb_addr_type, uint32_t)> poke32_type;
+ typedef boost::function<uint32_t(wb_addr_type)> peek32_type;
+ typedef boost::function<uint64_t(wb_addr_type)> peek64_type;
+ typedef boost::function<time_spec_t(void)> gettime_type;
+ typedef boost::function<void(const time_spec_t&)> settime_type;
+
+ wb_iface_adapter(
+ const poke32_type &,
+ const peek32_type &,
+ const peek64_type &,
+ const gettime_type &,
+ const settime_type &
+ );
+
+ wb_iface_adapter(
+ const poke32_type &,
+ const peek32_type &,
+ const peek64_type &
+ );
+
+ virtual ~wb_iface_adapter(void) {};
+
+ virtual void poke32(const wb_addr_type addr, const uint32_t data);
+ virtual uint32_t peek32(const wb_addr_type addr);
+ virtual uint64_t peek64(const wb_addr_type addr);
+ virtual time_spec_t get_time(void);
+ virtual void set_time(const time_spec_t& t);
+
+private:
+ const poke32_type poke32_functor;
+ const peek32_type peek32_functor;
+ const peek64_type peek64_functor;
+ const gettime_type gettime_functor;
+ const settime_type settime_functor;
+};
+
+}} // namespace uhd::rfnoc
+
+#endif /* INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/xports.hpp b/host/lib/include/uhdlib/rfnoc/xports.hpp
new file mode 100644
index 000000000..5ee65175a
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/xports.hpp
@@ -0,0 +1,29 @@
+//
+// Copyright 2016 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/types/sid.hpp>
+#include <uhd/types/endianness.hpp>
+#include <uhd/transport/zero_copy.hpp>
+
+namespace uhd {
+
+ /*! Holds all necessary items for a bidirectional link
+ */
+ struct both_xports_t
+ {
+ both_xports_t(): recv_buff_size(0), send_buff_size(0) {}
+ uhd::transport::zero_copy_if::sptr recv;
+ uhd::transport::zero_copy_if::sptr send;
+ size_t recv_buff_size;
+ size_t send_buff_size;
+ uhd::sid_t send_sid;
+ uhd::sid_t recv_sid;
+ uhd::endianness_t endianness;
+ };
+
+};
+