aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/rfnoc
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2016-11-14 14:30:34 -0800
committerMartin Braun <martin.braun@ettus.com>2018-07-25 15:34:03 -0700
commit988515ab19a715773086a7a8c023ddb8249c7e37 (patch)
tree71c861c3a1d0a5e295dad5939358dd30e0a33f3b /host/lib/rfnoc
parent8b16ab706fb4768f802ddb65a81fc26e1562cb0d (diff)
downloaduhd-988515ab19a715773086a7a8c023ddb8249c7e37.tar.gz
uhd-988515ab19a715773086a7a8c023ddb8249c7e37.tar.bz2
uhd-988515ab19a715773086a7a8c023ddb8249c7e37.zip
Device3: Change packet-based flow control to byte-based flow control
Diffstat (limited to 'host/lib/rfnoc')
-rw-r--r--host/lib/rfnoc/ctrl_iface.cpp1
-rw-r--r--host/lib/rfnoc/graph_impl.cpp31
-rw-r--r--host/lib/rfnoc/legacy_compat.cpp4
-rw-r--r--host/lib/rfnoc/sink_block_ctrl_base.cpp19
-rw-r--r--host/lib/rfnoc/source_block_ctrl_base.cpp33
5 files changed, 47 insertions, 41 deletions
diff --git a/host/lib/rfnoc/ctrl_iface.cpp b/host/lib/rfnoc/ctrl_iface.cpp
index 11dfa7aaa..29e18fc3a 100644
--- a/host/lib/rfnoc/ctrl_iface.cpp
+++ b/host/lib/rfnoc/ctrl_iface.cpp
@@ -108,6 +108,7 @@ private:
packet_info.tsf = timestamp;
packet_info.sob = false;
packet_info.eob = false;
+ packet_info.fc_ack = false;
packet_info.sid = _xports.send_sid;
packet_info.has_sid = true;
packet_info.has_cid = false;
diff --git a/host/lib/rfnoc/graph_impl.cpp b/host/lib/rfnoc/graph_impl.cpp
index c361ea8f2..a2e0e64f4 100644
--- a/host/lib/rfnoc/graph_impl.cpp
+++ b/host/lib/rfnoc/graph_impl.cpp
@@ -122,9 +122,9 @@ void graph_impl::connect(
UHD_LOGGER_WARNING("RFNOC") << "Assuming max packet size for " << src->get_block_id() ;
pkt_size = uhd::rfnoc::MAX_PACKET_SIZE;
}
- // FC window (in packets) depends on FIFO size... ...and packet size.
- size_t buf_size_pkts = dst->get_fifo_size(dst_block_port) / pkt_size;
- if (buf_size_pkts == 0) {
+ // FC window (in bytes) depends on FIFO size.
+ size_t buf_size_bytes = dst->get_fifo_size(dst_block_port);
+ if (buf_size_bytes < pkt_size) {
throw uhd::runtime_error(str(
boost::format("Input FIFO for block %s is too small (%d kiB) for packets of size %d kiB\n"
"coming from block %s.")
@@ -132,19 +132,20 @@ void graph_impl::connect(
% (pkt_size / 1024) % src->get_block_id().get()
));
}
- src->configure_flow_control_out(buf_size_pkts, src_block_port);
- // On the same crossbar, use lots of FC packets
- size_t pkts_per_ack = std::min(
- uhd::rfnoc::DEFAULT_FC_XBAR_PKTS_PER_ACK,
- buf_size_pkts - 1
+ src->configure_flow_control_out(
+ true, /* enable output */
+ buf_size_bytes,
+ 0, /* no packet limit. We need to revisit this at some point. */
+ src_block_port
);
+ // On the same crossbar, use lots of FC packets
+ size_t bytes_per_response = std::ceil<size_t>(buf_size_bytes / uhd::rfnoc::DEFAULT_FC_XBAR_RESPONSE_FREQ);
// Over the network, use less or we'd flood the transport
if (sid.get_src_addr() != sid.get_dst_addr()) {
- pkts_per_ack = std::max<size_t>(buf_size_pkts / uhd::rfnoc::DEFAULT_FC_TX_RESPONSE_FREQ, 1);
+ bytes_per_response = std::ceil<size_t>(buf_size_bytes / uhd::rfnoc::DEFAULT_FC_TX_RESPONSE_FREQ);
}
dst->configure_flow_control_in(
- 0, // Default to not use cycles
- pkts_per_ack,
+ bytes_per_response,
dst_block_port
);
@@ -209,7 +210,7 @@ void graph_impl::connect_src(
void graph_impl::connect_sink(
const block_id_t &sink_block,
const size_t dst_block_port,
- const size_t pkts_per_ack
+ const size_t bytes_per_ack
) {
device3::sptr device_ptr = _device_ptr.lock();
if (not device_ptr) {
@@ -222,11 +223,7 @@ void graph_impl::connect_sink(
uhd::rfnoc::sink_block_ctrl_base::sptr dst =
device_ptr->get_block_ctrl<rfnoc::sink_block_ctrl_base>(sink_block);
- dst->configure_flow_control_in(
- 0,
- pkts_per_ack,
- dst_block_port
- );
+ dst->configure_flow_control_in(bytes_per_ack, dst_block_port);
/********************************************************************
* 5. Configure error policy
diff --git a/host/lib/rfnoc/legacy_compat.cpp b/host/lib/rfnoc/legacy_compat.cpp
index 7e9eec20e..c5bd7891a 100644
--- a/host/lib/rfnoc/legacy_compat.cpp
+++ b/host/lib/rfnoc/legacy_compat.cpp
@@ -158,10 +158,10 @@ public:
UHD_LOGGER_WARNING("RFNOC") << "[legacy_compat] No DUCs detected. You will only be able to transmit at the radio frontend rate." ;
}
if (args.has_key("skip_dram")) {
- UHD_LEGACY_LOG() << "[legacy_compat] Skipping DRAM by user request." << std::endl;
+ UHD_LEGACY_LOG() << "[legacy_compat] Skipping DRAM by user request." ;
}
if (args.has_key("skip_sram")) {
- UHD_LEGACY_LOG() << "[legacy_compat] Skipping SRAM by user request." << std::endl;
+ UHD_LEGACY_LOG() << "[legacy_compat] Skipping SRAM by user request.";
}
if (not _has_dmafifo and not _has_sramfifo) {
UHD_LOGGER_WARNING("RFNOC") << "[legacy_compat] No FIFO detected. Higher transmit rates may encounter errors.";
diff --git a/host/lib/rfnoc/sink_block_ctrl_base.cpp b/host/lib/rfnoc/sink_block_ctrl_base.cpp
index b620f917f..1562e134b 100644
--- a/host/lib/rfnoc/sink_block_ctrl_base.cpp
+++ b/host/lib/rfnoc/sink_block_ctrl_base.cpp
@@ -52,22 +52,17 @@ size_t sink_block_ctrl_base::get_fifo_size(size_t block_port) const {
}
void sink_block_ctrl_base::configure_flow_control_in(
- size_t cycles,
- size_t packets,
+ size_t bytes,
size_t block_port
) {
- UHD_RFNOC_BLOCK_TRACE() << boost::format("sink_block_ctrl_base::configure_flow_control_in(cycles=%d, packets=%d)") % cycles % packets ;
- uint32_t cycles_word = 0;
- if (cycles) {
- cycles_word = (1<<31) | cycles;
- }
- sr_write(SR_FLOW_CTRL_CYCS_PER_ACK, cycles_word, block_port);
+ UHD_RFNOC_BLOCK_TRACE() << boost::format("sink_block_ctrl_base::configure_flow_control_in(bytes=%d)") % bytes;
- uint32_t packets_word = 0;
- if (packets) {
- packets_word = (1<<31) | packets;
+ uint32_t bytes_word = 0;
+ if (bytes) {
+ // Bit 32 enables flow control
+ bytes_word = (1<<31) | bytes;
}
- sr_write(SR_FLOW_CTRL_PKTS_PER_ACK, packets_word, block_port);
+ sr_write(SR_FLOW_CTRL_BYTES_PER_ACK, bytes_word, block_port);
}
void sink_block_ctrl_base::set_error_policy(
diff --git a/host/lib/rfnoc/source_block_ctrl_base.cpp b/host/lib/rfnoc/source_block_ctrl_base.cpp
index 5ede899cb..afec6ba1b 100644
--- a/host/lib/rfnoc/source_block_ctrl_base.cpp
+++ b/host/lib/rfnoc/source_block_ctrl_base.cpp
@@ -77,25 +77,27 @@ void source_block_ctrl_base::set_destination(
}
void source_block_ctrl_base::configure_flow_control_out(
- size_t buf_size_pkts,
+ bool enable_fc_output,
+ size_t buf_size_bytes,
+ size_t pkt_limit,
size_t block_port,
UHD_UNUSED(const uhd::sid_t &sid)
) {
- UHD_RFNOC_BLOCK_TRACE() << "source_block_ctrl_base::configure_flow_control_out() buf_size_pkts==" << buf_size_pkts ;
- if (buf_size_pkts < 2) {
+ UHD_RFNOC_BLOCK_TRACE() << "source_block_ctrl_base::configure_flow_control_out() buf_size_bytes==" << buf_size_bytes;
+ if (buf_size_bytes == 0) {
throw uhd::runtime_error(str(
- boost::format("Invalid window size %d for block %s. Window size must at least be 2.")
- % buf_size_pkts % unique_id()
+ boost::format("Invalid window size %d for block %s. Window size cannot be 0 bytes.")
+ % buf_size_bytes % unique_id()
));
}
- //Disable the window and let all upstream data flush out
+ //Disable flow control entirely and let all upstream data flush out
//We need to do this every time the window is changed because
//a) We don't know what state the flow-control module was left in
// in the previous run (it should still be enabled)
//b) Changing the window size where data is buffered upstream may
// result in stale packets entering the stream.
- sr_write(SR_FLOW_CTRL_WINDOW_EN, 0, block_port);
+ sr_write(SR_FLOW_CTRL_EN, 0, block_port);
//Wait for data to flush out.
//In the FPGA we are guaranteed that all buffered packets are more-or-less consecutive.
@@ -107,13 +109,24 @@ void source_block_ctrl_base::configure_flow_control_out(
// module is done flushing.
std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ //Enable source flow control module and conditionally enable byte based and/or packet count
+ //based flow control
+ const bool enable_byte_fc = (buf_size_bytes != 0);
+ const bool enable_pkt_cnt_fc = (pkt_limit != 0);
+ const size_t config = enable_fc_output + (enable_byte_fc << 1) + (enable_pkt_cnt_fc << 2);
+
//Resize the FC window.
//Precondition: No data can be buffered upstream.
- sr_write(SR_FLOW_CTRL_WINDOW_SIZE, buf_size_pkts, block_port);
+ if (enable_byte_fc) {
+ sr_write(SR_FLOW_CTRL_WINDOW_SIZE, buf_size_bytes, block_port);
+ }
+ if (enable_pkt_cnt_fc) {
+ sr_write(SR_FLOW_CTRL_PKT_LIMIT, pkt_limit, block_port);
+ }
//Enable the FC window.
- //Precondition: The window size must be set.
- sr_write(SR_FLOW_CTRL_WINDOW_EN, (buf_size_pkts != 0), block_port);
+ //Precondition: The window size and/or packet limit must be set.
+ sr_write(SR_FLOW_CTRL_EN, config, block_port);
}
/***********************************************************************