diff options
Diffstat (limited to 'host/lib/rfnoc')
-rw-r--r-- | host/lib/rfnoc/ctrl_iface.cpp | 1 | ||||
-rw-r--r-- | host/lib/rfnoc/graph_impl.cpp | 31 | ||||
-rw-r--r-- | host/lib/rfnoc/legacy_compat.cpp | 4 | ||||
-rw-r--r-- | host/lib/rfnoc/sink_block_ctrl_base.cpp | 19 | ||||
-rw-r--r-- | host/lib/rfnoc/source_block_ctrl_base.cpp | 33 |
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); } /*********************************************************************** |