diff options
-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 |