aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-10-24 13:30:59 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 12:21:32 -0800
commitea89fd0dd4e7bd9a4050f6ae2b79d3b359c60a9a (patch)
treea18dfb692d9f2cff6a4df9ca3743aa189e74c6ed /host
parentb4ef7ca804be35830a2c8ac5a143afafd33362f6 (diff)
downloaduhd-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.hpp23
-rw-r--r--host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp21
-rw-r--r--host/lib/include/uhdlib/rfnoc/chdr_types.hpp4
-rw-r--r--host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp10
-rw-r--r--host/lib/rfnoc/chdr_rx_data_xport.cpp1
-rw-r--r--host/lib/rfnoc/chdr_tx_data_xport.cpp1
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