aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include/uhdlib
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2019-05-28 13:21:08 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:20 -0800
commitb99d0f348eada0500ea5d668d5eba283afa6c4a4 (patch)
treebed87ff733aab37c7d5d3851f5cc5cbcffe056d4 /host/lib/include/uhdlib
parent374b30cc0eb0842e567d01486d9be8155e361d9f (diff)
downloaduhd-b99d0f348eada0500ea5d668d5eba283afa6c4a4.tar.gz
uhd-b99d0f348eada0500ea5d668d5eba283afa6c4a4.tar.bz2
uhd-b99d0f348eada0500ea5d668d5eba283afa6c4a4.zip
rfnoc: Added link/graph specific stream managers
- Fleshed out mb_iface - Managers currently only export ctrl APIs. Data APIs TBD
Diffstat (limited to 'host/lib/include/uhdlib')
-rw-r--r--host/lib/include/uhdlib/rfnoc/client_zero.hpp4
-rw-r--r--host/lib/include/uhdlib/rfnoc/epid_allocator.hpp58
-rw-r--r--host/lib/include/uhdlib/rfnoc/graph_stream_manager.hpp85
-rw-r--r--host/lib/include/uhdlib/rfnoc/link_stream_manager.hpp88
-rw-r--r--host/lib/include/uhdlib/rfnoc/mb_iface.hpp52
5 files changed, 260 insertions, 27 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/client_zero.hpp b/host/lib/include/uhdlib/rfnoc/client_zero.hpp
index c6d3e879b..52330bffa 100644
--- a/host/lib/include/uhdlib/rfnoc/client_zero.hpp
+++ b/host/lib/include/uhdlib/rfnoc/client_zero.hpp
@@ -25,6 +25,10 @@ namespace uhd { namespace rfnoc { namespace detail {
class client_zero : public uhd::rfnoc::register_iface_holder
{
public:
+ using sptr = std::shared_ptr<client_zero>;
+
+ static sptr make(chdr_ctrl_endpoint& chdr_ctrl_ep, sep_id_t dst_epid);
+
client_zero(register_iface::sptr reg);
//! Definition of an edge in the static router
diff --git a/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp b/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp
new file mode 100644
index 000000000..c92ca013d
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp
@@ -0,0 +1,58 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_EPID_ALLOCATOR_HPP
+#define INCLUDED_LIBUHD_EPID_ALLOCATOR_HPP
+
+#include <uhdlib/rfnoc/rfnoc_common.hpp>
+#include <map>
+#include <memory>
+#include <mutex>
+
+namespace uhd { namespace rfnoc {
+
+/*! A class that is responsible for allocating and keeping track of endpoint
+ * IDs. There shall be one instance of this class per rfnoc_graph
+ */
+class epid_allocator
+{
+public:
+ using sptr = std::shared_ptr<epid_allocator>;
+
+ epid_allocator(sep_id_t start_epid = 1);
+ epid_allocator(const epid_allocator& rhs) = delete;
+ epid_allocator(epid_allocator&& rhs) = delete;
+
+ /*! \brief Allocate an EPID for the specified endpoint.
+ *
+ * \param addr The physical address (device, instance) of the stream endpoint
+ * \return The allocated EPID
+ */
+ sep_id_t allocate_epid(const sep_addr_t& addr);
+
+ /*! \brief Lookup an EPID and return the address associated with it.
+ *
+ * \param epid The allocated EPID
+ * \return The physical address (device, instance) of the stream endpoint
+ */
+ sep_addr_t lookup_epid(const sep_id_t& epid) const;
+
+ /*! \brief Deallocate the specified EPID.
+ *
+ * \param epid The EPID to deallocate
+ */
+ void deallocate_epid(sep_id_t epid);
+
+private:
+ std::map<sep_addr_t, sep_id_t> _epid_map;
+ std::map<sep_id_t, sep_addr_t> _addr_map;
+ sep_id_t _next_epid;
+ mutable std::mutex _mutex;
+};
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_EPID_ALLOCATOR_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/graph_stream_manager.hpp b/host/lib/include/uhdlib/rfnoc/graph_stream_manager.hpp
new file mode 100644
index 000000000..81657453d
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/graph_stream_manager.hpp
@@ -0,0 +1,85 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_STREAM_MANAGER_HPP
+#define INCLUDED_LIBUHD_RFNOC_GRAPH_STREAM_MANAGER_HPP
+
+#include <uhdlib/rfnoc/chdr_packet.hpp>
+#include <uhdlib/rfnoc/client_zero.hpp>
+#include <uhdlib/rfnoc/ctrlport_endpoint.hpp>
+#include <uhdlib/rfnoc/epid_allocator.hpp>
+#include <uhdlib/rfnoc/mb_iface.hpp>
+#include <functional>
+#include <memory>
+#include <set>
+
+namespace uhd { namespace rfnoc {
+
+/*! A class that is responsible managing all data endpoints, control endpoints and client
+ * zero instances accessible through this graph. There must be one instance of this
+ * class per graph
+ */
+class graph_stream_manager
+{
+public:
+ using uptr = std::unique_ptr<graph_stream_manager>;
+
+ virtual ~graph_stream_manager() = 0;
+
+ /*! \brief Get all the local devices that can be taken from this graph
+ *
+ * \return A vector of IDs of all local devices
+ */
+ virtual std::vector<device_id_t> get_local_devices() const = 0;
+
+ /*! \brief Get all the endpoints reachable from this graph
+ *
+ * \return A set of addresses for all reachable endpoints
+ */
+ virtual const std::set<sep_addr_t>& get_reachable_endpoints() const = 0;
+
+ /*! \brief Initialize a control endpoint to the specified destination
+ *
+ * \param dst_addr The physical address of the destination endpoint
+ * \param via_device The preference for the device to take to get to the destination
+ * \return A pair (source, destination) endpoint IDs for the control stream
+ */
+ virtual sep_id_pair_t init_ctrl_stream(
+ sep_addr_t dst_addr, device_id_t via_device = NULL_DEVICE_ID) = 0;
+
+ /*! \brief Get a register iface (ctrlport endpoint) to a particular block
+ *
+ * \param dst_epid The endpoint ID of the destination
+ * \param block_index The index of the block in the device
+ * \param client_clk The clock that is driving the ctrlport slave
+ * \param timebase_clk The clock that is driving the timebase
+ * \param via_device The preference for the device to take to get to the destination
+ * \return An interface to the ctrlport endpoint
+ */
+ virtual ctrlport_endpoint::sptr get_block_register_iface(sep_id_t dst_epid,
+ uint16_t block_index,
+ const clock_iface& client_clk,
+ const clock_iface& timebase_clk,
+ device_id_t via_device = NULL_DEVICE_ID) = 0;
+
+ /*! \brief Get a pointer to the client zero instance for the specified EPID
+ *
+ * \param dst_epid The endpoint ID of the destination
+ * \param via_device The preference for the device to take to get to the destination
+ * \return An interface to the client zero instance
+ */
+ virtual detail::client_zero::sptr get_client_zero(
+ sep_id_t dst_epid, device_id_t via_device = NULL_DEVICE_ID) const = 0;
+
+ static uptr make(const chdr::chdr_packet_factory& pkt_factory,
+ const epid_allocator::sptr& epid_alloc,
+ const std::vector<std::pair<device_id_t, mb_iface*>>& links);
+
+}; // class graph_stream_manager
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_STREAM_MANAGER_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/link_stream_manager.hpp b/host/lib/include/uhdlib/rfnoc/link_stream_manager.hpp
new file mode 100644
index 000000000..c31bf8987
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/link_stream_manager.hpp
@@ -0,0 +1,88 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_LINK_STREAM_MANAGER_HPP
+#define INCLUDED_LIBUHD_RFNOC_LINK_STREAM_MANAGER_HPP
+
+#include <uhdlib/rfnoc/client_zero.hpp>
+#include <uhdlib/rfnoc/ctrlport_endpoint.hpp>
+#include <uhdlib/rfnoc/epid_allocator.hpp>
+#include <uhdlib/rfnoc/mb_iface.hpp>
+#include <functional>
+#include <memory>
+
+namespace uhd { namespace rfnoc {
+
+/*! A class that is responsible managing all data endpoints, control endpoints and client
+ * zero instances accessible via a physical link. There must be one instance this this
+ * class per physical link (Ethernet cable, PCIe connection, etc)
+ */
+class link_stream_manager
+{
+public:
+ using uptr = std::unique_ptr<link_stream_manager>;
+
+ virtual ~link_stream_manager() = 0;
+
+ /*! \brief Get the software device ID associated with this instance
+ *
+ * \return A vector of addresses for all reachable endpoints
+ */
+ virtual device_id_t get_self_device_id() const = 0;
+
+ /*! \brief Get all the endpoints reachable from this link
+ *
+ * \return A vector of addresses for all reachable endpoints
+ */
+ virtual const std::set<sep_addr_t>& get_reachable_endpoints() const = 0;
+
+ /*! \brief Initialize a control endpoint to the specified destination
+ *
+ * \param dst_addr The physical address of the destination endpoint
+ * \return A pair (source, destination) endpoint IDs for the control stream
+ */
+ virtual sep_id_pair_t init_ctrl_stream(sep_addr_t dst_addr) = 0;
+
+ /*! \brief Get a register iface (ctrlport endpoint) to a particular block
+ *
+ * \param dst_epid The endpoint ID of the destination
+ * \param block_index The index of the block in the device
+ * \param client_clk The clock that is driving the ctrlport slave
+ * \param timebase_clk The clock that is driving the timebase
+ * \return An interface to the ctrlport endpoint
+ */
+ virtual ctrlport_endpoint::sptr get_block_register_iface(sep_id_t dst_epid,
+ uint16_t block_index,
+ const clock_iface& client_clk,
+ const clock_iface& timebase_clk) = 0;
+
+ /*! \brief Get a pointer to the client zero instance for the specified EPID
+ *
+ * \param dst_epid The endpoint ID of the destination
+ * \return An interface to the client zero instance
+ */
+ virtual detail::client_zero::sptr get_client_zero(sep_id_t dst_epid) const = 0;
+
+ /*! \brief Create a data stream
+ *
+ * \param dst_epid The endpoint ID of the destination
+ * \param vc The virtual channel
+ * \param xport_args The transport argument
+ * \return An transport instance
+ */
+ virtual chdr_data_xport_t create_data_stream(
+ sep_addr_t dst_addr, sep_vc_t vc, const device_addr_t& xport_args) = 0;
+
+ static uptr make(const chdr::chdr_packet_factory& pkt_factory,
+ mb_iface& mb_if,
+ const epid_allocator::sptr& epid_alloc,
+ device_id_t device_id);
+
+}; // class link_stream_manager
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_LINK_STREAM_MANAGER_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/mb_iface.hpp b/host/lib/include/uhdlib/rfnoc/mb_iface.hpp
index 60afa92fa..ce1106c4c 100644
--- a/host/lib/include/uhdlib/rfnoc/mb_iface.hpp
+++ b/host/lib/include/uhdlib/rfnoc/mb_iface.hpp
@@ -7,7 +7,7 @@
#ifndef INCLUDED_LIBUHD_MB_IFACE_HPP
#define INCLUDED_LIBUHD_MB_IFACE_HPP
-#include <uhdlib/rfnoc/chdr_types.hpp>
+#include <uhdlib/rfnoc/rfnoc_common.hpp>
#include <memory>
namespace uhd { namespace rfnoc {
@@ -22,54 +22,52 @@ namespace uhd { namespace rfnoc {
* It's up to the various device implementations (e.g., x300_impl) to implement
* this interface.
*/
-class mb_iface {
+class mb_iface
+{
public:
using uptr = std::unique_ptr<mb_iface>;
- virtual ~mb_iface() = 0;
+ virtual ~mb_iface() = default;
- /*! Return the RFNoC protocol version for this motherboard
+ /*! Return the RFNoC protocol version of the firmware running on this motherboard
*/
virtual uint16_t get_proto_ver() = 0;
- /*! Return the CHDR width for this motherboard
+ /*! Return the CHDR width of the firmware running on this motherboard
*/
- virtual chdr_w_t get_chdr_width() = 0;
+ virtual chdr_w_t get_chdr_w() = 0;
- /*! Set the device ID of this motherboard
+ /*! Get the device ID assigned to the motherboard
*
- * Every motherboard in a multi-USRP setup needs a unique device ID. It is
- * up to the rfnoc_graph to choose the various IDs, and then call this
- * function to set it.
+ * A freshly reset motherboard should return 0.
+ *
+ * \returns the motherboard's device ID
*/
- virtual void set_device_id(const uint16_t id) = 0;
+ virtual device_id_t get_remote_device_id() = 0;
- /*! Get device ID
- *
- * Returns the value previously written by set_device_id(). A freshly
- * resetted motherboard which has not been assigned a device ID should
- * return 0xFFFF.
+ /*! Get the local (software) device IDs on this motherboard that can actively
+ * communicate with the sea of RFNoC FPGAs. The number of local devices returned
+ * should be equal to the number of physical links on the motherboard that are
+ * actively connected.
*
- * \returns the motherboard's device ID
+ * \returns The active software device IDs
*/
- virtual uint16_t get_device_id() = 0;
+ virtual std::vector<device_id_t> get_local_device_ids() = 0;
/*! Reset the device
*/
virtual void reset_network() = 0;
- /*! Return a list of all physical links available from the current UHD
- * session to the motherboard.
- *
- * FIXME determine appropriate return type
+ /*! Create a control transport
*/
- //virtual <link info> enumerate_links() = 0;
+ virtual chdr_ctrl_xport_t make_ctrl_transport(
+ device_id_t local_device_id, const sep_id_t& src_epid) = 0;
- /*!
- *
- * FIXME determine appropriate return type and arg types
+ /*! Create a data transport
*/
- //virtual link_iface::uptr create_link(<link_params>) = 0;
+ virtual chdr_data_xport_t make_data_transport(device_id_t local_device_id,
+ const sep_id_t& src_epid,
+ const device_addr_t& xport_args) = 0;
};
}} /* namespace uhd::rfnoc */