diff options
author | Ashish Chaudhari <ashish@ettus.com> | 2019-05-28 13:21:08 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:20 -0800 |
commit | b99d0f348eada0500ea5d668d5eba283afa6c4a4 (patch) | |
tree | bed87ff733aab37c7d5d3851f5cc5cbcffe056d4 /host/lib/include/uhdlib | |
parent | 374b30cc0eb0842e567d01486d9be8155e361d9f (diff) | |
download | uhd-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.hpp | 4 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/epid_allocator.hpp | 58 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/graph_stream_manager.hpp | 85 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/link_stream_manager.hpp | 88 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/mb_iface.hpp | 52 |
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 */ |