diff options
author | Ciro Nishiguchi <ciro.nishiguchi@ni.com> | 2019-05-23 20:38:07 -0500 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:29 -0800 |
commit | 75a090543b8fb8e7c875387eee6d3fe7227e4450 (patch) | |
tree | 2904b48607cc07158aa6b068ada35ab56c4da516 /host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp | |
parent | d8e9705bc6c34b8d015b56a76955ee2f15426bd8 (diff) | |
download | uhd-75a090543b8fb8e7c875387eee6d3fe7227e4450.tar.gz uhd-75a090543b8fb8e7c875387eee6d3fe7227e4450.tar.bz2 uhd-75a090543b8fb8e7c875387eee6d3fe7227e4450.zip |
rfnoc: add rx and tx transports, and amend rfnoc_graph
transports:
Transports build on I/O service and implements flow control and
sequence number checking.
The rx streamer subclass extends the streamer implementation to connect
it to the rfnoc graph. It receives configuration values from property
propagation and configures the streamer accordingly. It also implements
the issue_stream_cmd rx_streamer API method.
Add implementation of rx streamer creation and method to connect it to
an rfnoc block.
rfnoc_graph: Cache more connection info, clarify contract
Summary of changes:
- rfnoc_graph stores more information about static connections at the
beginning. Some search algorithms are replaced by simpler lookups.
- The contract for connect() was clarified. It is required to call
connect, even for static connections.
Diffstat (limited to 'host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp')
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp b/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp new file mode 100644 index 000000000..937baf982 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp @@ -0,0 +1,130 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP +#define INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP + +#include <uhd/utils/log.hpp> +#include <uhdlib/rfnoc/rfnoc_common.hpp> + +namespace uhd { namespace rfnoc { + +//! Class to manage rx flow control state +class rx_flow_ctrl_state +{ +public: + //! Constructor + rx_flow_ctrl_state(const rfnoc::sep_id_pair_t epids) : _epids(epids) {} + + //! Initialize frequency parameters + void initialize(const stream_buff_params_t fc_freq) + { + _fc_freq = fc_freq; + } + + //! Resynchronize with transfer counts from the sender + void resynchronize(const stream_buff_params_t counts) + { + if (_recv_counts.bytes != counts.bytes + || _recv_counts.packets != counts.packets) { + // If there is a discrepancy between the amount of data sent by + // the device and received by the transport, adjust the counts + // of data received and transferred to include the dropped data. + auto bytes_dropped = counts.bytes - _recv_counts.bytes; + auto pkts_dropped = counts.packets - _recv_counts.packets; + _xfer_counts.bytes += bytes_dropped; + _xfer_counts.packets += pkts_dropped; + + UHD_LOGGER_DEBUG("rx_flow_ctrl_state") + << "oh noes: bytes_sent=" << counts.bytes + << " bytes_received=" << _recv_counts.bytes + << " pkts_sent=" << counts.packets + << " pkts_received=" << _recv_counts.packets + << " src_epid=" << _epids.first << " dst_epid=" << _epids.second + << std::endl; + + _recv_counts = counts; + } + } + + //! Reset the transfer counts (happens during init) + void reset_counts() + { + UHD_LOGGER_TRACE("rx_flow_ctrl_state") + << "Resetting transfer counts" << std::endl; + _recv_counts = {0, 0}; + _xfer_counts = {0, 0}; + } + + //! Update state when data is received + void data_received(const size_t bytes) + { + _recv_counts.bytes += bytes; + _recv_counts.packets++; + } + + //! Update state when transfer is complete (buffer space freed) + void xfer_done(const size_t bytes) + { + _xfer_counts.bytes += bytes; + _xfer_counts.packets++; + } + + //! Returns whether a flow control response is needed + bool fc_resp_due() const + { + stream_buff_params_t accum_counts = { + _xfer_counts.bytes - _last_fc_resp_counts.bytes, + _xfer_counts.packets - _last_fc_resp_counts.packets}; + + return accum_counts.bytes >= _fc_freq.bytes + || accum_counts.packets >= _fc_freq.packets; + } + + //! Update state after flow control response was sent + void fc_resp_sent() + { + _last_fc_resp_counts = _xfer_counts; + } + + //! Returns counts for completed transfers + stream_buff_params_t get_xfer_counts() const + { + return _xfer_counts; + } + + //! Returns counts for completed transfers + stream_buff_params_t get_recv_counts() const + { + return _recv_counts; + } + + //! Returns configured flow control frequency + stream_buff_params_t get_fc_freq() const + { + return _fc_freq; + } + +private: + // Counts for data received, including any data still in use + stream_buff_params_t _recv_counts{0, 0}; + + // Counts for data read and whose buffer space is ok to reuse + stream_buff_params_t _xfer_counts{0, 0}; + + // Counts sent in last flow control response + stream_buff_params_t _last_fc_resp_counts{0, 0}; + + // Frequency of flow control responses + stream_buff_params_t _fc_freq{0, 0}; + + // Endpoint ID for log messages + const sep_id_pair_t _epids; +}; + +}} // namespace uhd::rfnoc + +#endif /* INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP */ |