mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
rfnoc: Fix disconnecting back-edges from graphs
This fixes a bug where calling rfnoc_graph::disconnect() fails when the edge is not a forward edge, because the code would try and find an edge to remove that was a forward edge, even if source/destination ports would match. Error was discovered during use of X410_X4_400 image. The prevented the following use case: - Stream data from host to Replay Block - FDx Play and Record data via radio from/to replaz block - Stream recorded data from replay block to host The FDx use case requires one connection to be marked as back-edge (not is_forward_edge). The X410_X4_400 fpga does not include DDC/DUC block and the Radio and Replay blocks are directly connected to each other. To enable streaming data back to the host the required back-edge connecting needs to be disconnected. Commit also adds 2 additional rfnoc units tests modeling this use case w/o (X410_X4_400) and with (all 200MHz images) DDC/DUC blocks.
This commit is contained in:
parent
873c48184a
commit
085aff591f
@ -208,9 +208,11 @@ void graph_t::disconnect(node_ref_t src_node, node_ref_t dst_node, graph_edge_t
|
||||
edge_info.src_blockid = src_node->get_unique_id();
|
||||
edge_info.dst_blockid = dst_node->get_unique_id();
|
||||
|
||||
boost::remove_out_edge_if(src_vertex_desc,
|
||||
boost::remove_out_edge_if(
|
||||
src_vertex_desc,
|
||||
[this, edge_info](rfnoc_graph_t::edge_descriptor edge_desc) {
|
||||
return (edge_info == boost::get(edge_property_t(), this->_graph, edge_desc));
|
||||
return (edge_info.is_equal(
|
||||
boost::get(edge_property_t(), this->_graph, edge_desc), false));
|
||||
},
|
||||
_graph);
|
||||
|
||||
|
||||
@ -256,3 +256,98 @@ BOOST_AUTO_TEST_CASE(test_graph_disconnect_reconnect)
|
||||
|
||||
BOOST_CHECK_EQUAL(graph.enumerate_edges().size(), 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_graph_backedge_w_ddc_disconnect_reconnect)
|
||||
{
|
||||
graph_t graph{};
|
||||
node_accessor_t node_accessor{};
|
||||
|
||||
// Define some mock nodes:
|
||||
// radio
|
||||
mock_radio_node_t mock_radio(0);
|
||||
// Replay (use mock_edge_node instead of replay)
|
||||
mock_edge_node_t mock_replay_node(1, 1, "MOCK_EDGE_NODE<replay>");
|
||||
// TX streamer
|
||||
mock_streamer_t mock_rx_streamer(1);
|
||||
// RX streamer
|
||||
mock_streamer_t mock_tx_streamer(1);
|
||||
// DUC
|
||||
mock_ddc_node_t mock_ddc_node{};
|
||||
// DDC
|
||||
mock_ddc_node_t mock_duc_node{};
|
||||
|
||||
// These init calls would normally be done by the framework
|
||||
node_accessor.init_props(&mock_radio);
|
||||
node_accessor.init_props(&mock_replay_node);
|
||||
node_accessor.init_props(&mock_rx_streamer);
|
||||
node_accessor.init_props(&mock_tx_streamer);
|
||||
node_accessor.init_props(&mock_ddc_node);
|
||||
node_accessor.init_props(&mock_duc_node);
|
||||
|
||||
uhd::rfnoc::detail::graph_t::graph_edge_t edge_info_ddc(
|
||||
0, 0, graph_t::graph_edge_t::STATIC, true);
|
||||
|
||||
uhd::rfnoc::detail::graph_t::graph_edge_t edge_info(
|
||||
0, 0, graph_t::graph_edge_t::DYNAMIC, true);
|
||||
|
||||
uhd::rfnoc::detail::graph_t::graph_edge_t edge_info_backedge(
|
||||
0, 0, graph_t::graph_edge_t::DYNAMIC, false);
|
||||
|
||||
// Now create the graph (FDx Replay and Record):
|
||||
// RX: radio (src) >> DDC >> Replay Block (sink)
|
||||
graph.connect(&mock_radio, &mock_ddc_node, edge_info);
|
||||
graph.connect(&mock_ddc_node, &mock_replay_node, edge_info);
|
||||
// TX: Replay Block (src) >> DUC >> radio (sink)
|
||||
graph.connect(&mock_replay_node, &mock_duc_node, edge_info);
|
||||
graph.connect(&mock_duc_node, &mock_radio, edge_info_backedge);
|
||||
graph.commit();
|
||||
BOOST_CHECK_EQUAL(graph.enumerate_edges().size(), 4);
|
||||
|
||||
// Disconnect Replay Block source (used for TX Radio)
|
||||
// in preparation for connecting to RX streamer
|
||||
graph.disconnect(&mock_replay_node, &mock_duc_node, edge_info);
|
||||
graph.commit();
|
||||
BOOST_CHECK_EQUAL(graph.enumerate_edges().size(), 3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_graph_backedge_wo_ddc_disconnect_reconnect)
|
||||
{
|
||||
graph_t graph{};
|
||||
node_accessor_t node_accessor{};
|
||||
|
||||
// Define some mock nodes:
|
||||
// radio
|
||||
mock_radio_node_t mock_radio(0);
|
||||
// Replay (use mock_edge_node instead of replay)
|
||||
mock_edge_node_t mock_replay_node(1, 1, "MOCK_EDGE_NODE<replay>");
|
||||
// TX streamer
|
||||
mock_streamer_t mock_rx_streamer(1);
|
||||
// RX streamer
|
||||
mock_streamer_t mock_tx_streamer(1);
|
||||
|
||||
// These init calls would normally be done by the framework
|
||||
node_accessor.init_props(&mock_radio);
|
||||
node_accessor.init_props(&mock_replay_node);
|
||||
node_accessor.init_props(&mock_rx_streamer);
|
||||
node_accessor.init_props(&mock_tx_streamer);
|
||||
|
||||
uhd::rfnoc::detail::graph_t::graph_edge_t edge_info(
|
||||
0, 0, graph_t::graph_edge_t::DYNAMIC, true);
|
||||
|
||||
uhd::rfnoc::detail::graph_t::graph_edge_t edge_info_backedge(
|
||||
0, 0, graph_t::graph_edge_t::DYNAMIC, false);
|
||||
|
||||
// Now create the graph (FDx Replay and Record):
|
||||
// RX: radio (src) sends data to Replay Block (sink)
|
||||
graph.connect(&mock_radio, &mock_replay_node, edge_info);
|
||||
// TX: Replay Block (src) sends data to radio (sink)
|
||||
graph.connect(&mock_replay_node, &mock_radio, edge_info_backedge);
|
||||
graph.commit();
|
||||
BOOST_CHECK_EQUAL(graph.enumerate_edges().size(), 2);
|
||||
|
||||
// Disconnect Replay Block source (used for TX Radio)
|
||||
// in preparation for connecting to RX streamer
|
||||
graph.disconnect(&mock_replay_node, &mock_radio, edge_info);
|
||||
graph.commit();
|
||||
BOOST_CHECK_EQUAL(graph.enumerate_edges().size(), 1);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user