diff options
author | Brent Stapleton <brent.stapleton@ettus.com> | 2019-05-07 17:33:36 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:16 -0800 |
commit | cd36d9d2d3dfdecae42b715d734547e48347cf4a (patch) | |
tree | a80ad2f1d44da87887fb7c21bb5fc2835a7651e7 /host/lib/include | |
parent | 53becb55e1211a85b27a3d862afec4e7ffd0818e (diff) | |
download | uhd-cd36d9d2d3dfdecae42b715d734547e48347cf4a.tar.gz uhd-cd36d9d2d3dfdecae42b715d734547e48347cf4a.tar.bz2 uhd-cd36d9d2d3dfdecae42b715d734547e48347cf4a.zip |
rfnoc: adding client_zero
- Adding client_zero class, which gathers information about our device
form the global registers on port 0 of the RFNoC backend registers.
- adding unit tests to exercise client_zero
- mock_reg_iface class: adding fake register_iface so we can run
unit tests in software only
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Diffstat (limited to 'host/lib/include')
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/client_zero.hpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/client_zero.hpp b/host/lib/include/uhdlib/rfnoc/client_zero.hpp new file mode 100644 index 000000000..8eb2d6397 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/client_zero.hpp @@ -0,0 +1,199 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_CLIENT_ZERO_HPP +#define INCLUDED_LIBUHD_CLIENT_ZERO_HPP + +#include <uhd/rfnoc/register_iface_holder.hpp> +#include <chrono> +#include <cstdint> +#include <string> +#include <vector> + +namespace uhd { namespace rfnoc { namespace detail { + +/*! + * Class that uses a register_iface to read important configuration information from the + * RFNoC backend registers + */ +class client_zero : public uhd::rfnoc::register_iface_holder +{ +public: + client_zero(register_iface::sptr reg); + + //! Definition of an edge in the static router + struct edge_def_t + { + uint16_t src_blk_index; + uint8_t src_blk_port; + uint16_t dst_blk_index; + uint8_t dst_blk_port; + }; + + //! Contents of the backend status block configuration register + struct block_config_info + { + uint8_t protover; + uint8_t num_inputs; + uint8_t num_outputs; + uint8_t ctrl_fifo_size; + uint8_t mtu; + }; + + //! Return the RFNoC protocol version for this motherboard + uint16_t get_proto_ver() + { + return _proto_ver; + }; + + //! Return the device type + uint16_t get_device_type() + { + return _device_type; + }; + + //! Return the number of blocks in our RFNoC graph + size_t get_num_blocks() + { + return _num_blocks; + }; + + //! Return the number of stream endpoints in our RFNoC graph + size_t get_num_stream_endpoints() + { + return _num_stream_endpoints; + }; + + //! Return the number of transports available + size_t get_num_transports() + { + return _num_transports; + }; + + //! Return whether or not the device includes a CHDR crossbar + bool has_chdr_crossbar() + { + return _has_chdr_crossbar; + }; + + //! Return the number of edges in our graph (the number of static connections) + size_t get_num_edges() + { + return _num_edges; + }; + + //! Return a vector containing the edge definitions + std::vector<edge_def_t>& get_adjacency_list() + { + return _adjacency_list; + }; + + /*! Return the NOC ID of the block located at `portno` + * + * \throws uhd::index_error if no NOC block is connected to the port + */ + uint32_t get_noc_id(uint16_t portno); + + /*! Return whether the port is actively flushing + * + * \throws uhd::index_error if no NOC block is connected to the port + * \return boolean status + */ + bool get_flush_active(uint16_t portno); + + /*! Return whether the port is done flushing + * + * \throws uhd::index_error if no NOC block is connected to the port + * \return boolean status + */ + bool get_flush_done(uint16_t portno); + + /*! Returns once the port is done flushing + * + * Note: this function queries the port once every millisecond + * + * \param portno Port number + * \param timeout time, in milliseconds, to poll before quitting + * \throws uhd::index_error if no NOC block is connected to the port + * \return boolean whether or not the flush had completed in the timeout period + */ + bool poll_flush_done(uint16_t portno, std::chrono::milliseconds timeout); + + /*! Set the port's hardware flush timeout + * + * \param timeout number of cycles the device waits for the flushing to complete + * \param portno Port number + * \throws uhd::index_error if no NOC block is connected to the port + */ + void set_flush_timeout(uint32_t timeout, uint16_t portno); + + /*! Send a request to flush a port + * + * \param portno Port number + * \throws uhd::index_error if no NOC block is connected to the port + */ + void set_flush(uint16_t portno); + + /*! Go through the entire flush process for a port + * + * \param portno Port number + * \throws uhd::index_error if no NOC block is connected to the port + * \return whether or not the flush succeeded + */ + bool complete_flush(uint16_t portno); + + /*! Reset a port's control logic + * + * It is recommended to flush a port calling this. + * + * \param portno Port number + * \throws uhd::index_error if no NOC block is connected to the port + */ + void reset_ctrl(uint16_t portno); + + /*! Reset a port's CHDR logic + * + * It is recommended to flush a port calling this. + * + * \param portno Port number + * \throws uhd::index_error if no NOC block is connected to the port + */ + void reset_chdr(uint16_t portno); + + /*! Get the port's configuration information + * + * \return Struct containing configuration information + */ + block_config_info get_block_info(uint16_t portno); + + // TODO: handle callbacks? + +private: + uint16_t _proto_ver; + uint16_t _device_type; + uint16_t _num_blocks; + uint16_t _num_stream_endpoints; + uint16_t _num_transports; + bool _has_chdr_crossbar; + uint16_t _num_edges; + std::vector<edge_def_t> _adjacency_list; + + std::vector<client_zero::edge_def_t> _get_adjacency_list(); + + /* Helper function to determine if the given port number has a block connected + * + * \throws uhd::index_error if no NOC block is connected to the port + */ + void _check_port_number(uint16_t portno); + //! Translate port number to base address for the register + uint32_t _get_port_base_addr(uint16_t portno); + //! Helper function to get the backend control flush status flags + uint32_t _get_flush_status_flags(uint16_t portno); +}; + +}}} /* namespace uhd::rfnoc::detail */ + +#endif /* INCLUDED_LIBUHD_CLIENT_ZERO_HPP */ |