diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-10-24 13:30:59 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 12:21:32 -0800 |
commit | ea89fd0dd4e7bd9a4050f6ae2b79d3b359c60a9a (patch) | |
tree | a18dfb692d9f2cff6a4df9ca3743aa189e74c6ed /host | |
parent | b4ef7ca804be35830a2c8ac5a143afafd33362f6 (diff) | |
download | uhd-ea89fd0dd4e7bd9a4050f6ae2b79d3b359c60a9a.tar.gz uhd-ea89fd0dd4e7bd9a4050f6ae2b79d3b359c60a9a.tar.bz2 uhd-ea89fd0dd4e7bd9a4050f6ae2b79d3b359c60a9a.zip |
rfnoc: xports: Count FC bytes as multiples of CHDR width
SEPs on the FPGA can only occupy multiples of the CHDR width in their
FIFOs, unlike SW, where buffers are stored in RAM and can be aligned
anyhow. Therefore, we align the counting of bytes for FC purpose and
count multiples of CHDR width instead of the true number of bytes per
packet.
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp | 23 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp | 21 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/chdr_types.hpp | 4 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp | 10 | ||||
-rw-r--r-- | host/lib/rfnoc/chdr_rx_data_xport.cpp | 1 | ||||
-rw-r--r-- | host/lib/rfnoc/chdr_tx_data_xport.cpp | 1 |
6 files changed, 43 insertions, 17 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp b/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp index 4ff41899c..dab308279 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp @@ -239,8 +239,11 @@ private: return false; } - const auto type = header.get_pkt_type(); - const auto packet_size = header.get_length(); + const auto type = header.get_pkt_type(); + // We need to round the packet size to the nearest multiple of a CHDR + // width, because that's how the FPGA tracks bytes, and want to match + // that behaviour. + const auto packet_size_rounded = _round_pkt_size(header.get_length()); if (type == chdr::PKT_TYPE_STRC) { chdr::strc_payload strc; @@ -257,11 +260,11 @@ private: _fc_state.resynchronize(strc_counts); // Update state that we received a packet - _fc_state.data_received(packet_size); + _fc_state.data_received(packet_size_rounded); recv_link->release_recv_buff(std::move(buff)); buff = buff_t::uptr(); - _fc_state.xfer_done(packet_size); + _fc_state.xfer_done(packet_size_rounded); _send_fc_response(send_link); } else { throw uhd::value_error("Unexpected opcode value in STRC packet."); @@ -275,7 +278,7 @@ private: } else if (type == chdr::PKT_TYPE_DATA_NO_TS || type == chdr::PKT_TYPE_DATA_WITH_TS) { // Update state that we received a packet - _fc_state.data_received(packet_size); + _fc_state.data_received(packet_size_rounded); // If this is a data packet, just claim it by returning true. The // I/O service will queue this packet in the recv_io_if. @@ -302,7 +305,7 @@ private: { _recv_packet_cb->refresh(buff->data()); const auto header = _recv_packet_cb->get_chdr_header(); - const size_t packet_size = header.get_length(); + const size_t packet_size = _round_pkt_size(header.get_length()); recv_link->release_recv_buff(std::move(buff)); _fc_state.xfer_done(packet_size); _send_fc_response(send_link); @@ -371,6 +374,11 @@ private: return std::make_tuple(info, header.get_seq_num()); } + inline size_t _round_pkt_size(const size_t pkt_size_bytes) + { + return ((pkt_size_bytes + _chdr_w_bytes - 1) / _chdr_w_bytes) * _chdr_w_bytes; + } + // Interface to the I/O service transport::recv_io_if::sptr _recv_io; @@ -394,6 +402,9 @@ private: // Local / Sink EPID sep_id_t _epid; + + //! The CHDR width in bytes. + size_t _chdr_w_bytes; }; }} // namespace uhd::rfnoc diff --git a/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp b/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp index 0d709fae1..3226ba59b 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp @@ -320,25 +320,33 @@ private: */ void _send_callback(buff_t::uptr& buff, transport::send_link_if* send_link) { - const size_t packet_size = buff->packet_size(); + // If the packet size is not a multiple of the word size, then we will + // still occupy an integer multiple of word size bytes in the FPGA, so + // we need to calculate appropriately. + const size_t packet_size_rounded = _round_pkt_size(buff->packet_size()); - if (_fc_state.dest_has_space(packet_size)) { + if (_fc_state.dest_has_space(packet_size_rounded)) { send_link->release_send_buff(std::move(buff)); buff = nullptr; - _fc_state.data_sent(packet_size); + _fc_state.data_sent(packet_size_rounded); if (_fc_state.get_fc_resync_req_pending() - && _fc_state.dest_has_space(chdr::strc_payload::PACKET_SIZE)) { + && _fc_state.dest_has_space(chdr::strc_payload::MAX_PACKET_SIZE)) { const auto& xfer_counts = _fc_state.get_xfer_counts(); const size_t strc_size = - _fc_sender.send_strc_resync(send_link, xfer_counts); + _round_pkt_size(_fc_sender.send_strc_resync(send_link, xfer_counts)); _fc_state.clear_fc_resync_req_pending(); _fc_state.data_sent(strc_size); } } } + inline size_t _round_pkt_size(const size_t pkt_size_bytes) + { + return ((pkt_size_bytes + _chdr_w_bytes - 1) / _chdr_w_bytes) * _chdr_w_bytes; + } + // Interface to the I/O service transport::send_io_if::sptr _send_io; @@ -368,6 +376,9 @@ private: // Local / Source EPID sep_id_t _epid; + + //! The CHDR width in bytes. + size_t _chdr_w_bytes; }; }} // namespace uhd::rfnoc diff --git a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp index 8bb345b32..fd6a6e829 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp @@ -488,8 +488,8 @@ public: // Members uint64_t num_pkts = 0; //! Number of bytes to use for operation (64 bits) uint64_t num_bytes = 0; - //! Size of a strc packet (including header) - static constexpr size_t PACKET_SIZE = 24; + //! Worst-case size of a strc packet (including header) + static constexpr size_t MAX_PACKET_SIZE = 128; public: // Functions strc_payload() = default; diff --git a/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp b/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp index ed6553bf3..b8bb411d4 100644 --- a/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp +++ b/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp @@ -37,10 +37,12 @@ public: _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 + << "Flow control state mismatch: bytes reported: " << counts.bytes + << " bytes counted locally: " << _recv_counts.bytes + << " delta: " << (counts.bytes - _recv_counts.bytes) + << " Packets reported: " << counts.packets + << " Packets counted locally: " << _recv_counts.packets + << " delta: " << (counts.packets - _recv_counts.packets) << " src_epid=" << _epids.first << " dst_epid=" << _epids.second << std::endl; diff --git a/host/lib/rfnoc/chdr_rx_data_xport.cpp b/host/lib/rfnoc/chdr_rx_data_xport.cpp index b0c68f2b4..df7162a73 100644 --- a/host/lib/rfnoc/chdr_rx_data_xport.cpp +++ b/host/lib/rfnoc/chdr_rx_data_xport.cpp @@ -40,6 +40,7 @@ chdr_rx_data_xport::chdr_rx_data_xport(uhd::transport::io_service::sptr io_srv, : _fc_state(epids, fc_params.freq) , _fc_sender(pkt_factory, epids) , _epid(epids.second) + , _chdr_w_bytes(chdr_w_to_bits(pkt_factory.get_chdr_w()) / 8) { UHD_LOG_TRACE("XPORT::RX_DATA_XPORT", "Creating rx xport with local epid=" << epids.second diff --git a/host/lib/rfnoc/chdr_tx_data_xport.cpp b/host/lib/rfnoc/chdr_tx_data_xport.cpp index 550dde59a..bb9d1b63e 100644 --- a/host/lib/rfnoc/chdr_tx_data_xport.cpp +++ b/host/lib/rfnoc/chdr_tx_data_xport.cpp @@ -35,6 +35,7 @@ chdr_tx_data_xport::chdr_tx_data_xport(uhd::transport::io_service::sptr io_srv, : _fc_state(fc_params.buff_capacity) , _fc_sender(pkt_factory, epids) , _epid(epids.first) + , _chdr_w_bytes(chdr_w_to_bits(pkt_factory.get_chdr_w()) / 8) { UHD_LOG_TRACE("XPORT::TX_DATA_XPORT", "Creating tx xport with local epid=" << epids.first |