From 2f84ce59551c53837cae10e3bf6a293b8ec91a9f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 6 Sep 2022 11:48:21 -0700 Subject: [PATCH 1/5] [engine] now move rr_gsb mirror function outside the class, because of the circuit_lib should be used --- openfpga/src/annotation/device_rr_gsb.cpp | 5 +- openfpga/src/utils/rr_gsb_utils.cpp | 254 +++++++++++++++++++++ openfpga/src/utils/rr_gsb_utils.h | 4 + vpr/src/tileable_rr_graph/rr_gsb.cpp | 255 +--------------------- vpr/src/tileable_rr_graph/rr_gsb.h | 3 + 5 files changed, 268 insertions(+), 253 deletions(-) diff --git a/openfpga/src/annotation/device_rr_gsb.cpp b/openfpga/src/annotation/device_rr_gsb.cpp index 9abbea351..883b32191 100644 --- a/openfpga/src/annotation/device_rr_gsb.cpp +++ b/openfpga/src/annotation/device_rr_gsb.cpp @@ -3,6 +3,7 @@ ***********************************************************************/ #include "vtr_log.h" #include "vtr_assert.h" +#include "rr_gsb_utils.h" #include "device_rr_gsb.h" /* namespace openfpga begins */ @@ -230,7 +231,7 @@ void DeviceRRGSB::build_cb_unique_module(const RRGraph& rr_graph, const t_rr_typ /* Traverse the unique_mirror list and check it is an mirror of another */ for (size_t id = 0; id < get_num_cb_unique_module(cb_type); ++id) { const RRGSB& unique_module = get_cb_unique_module(cb_type, id); - if (true == rr_gsb_[ix][iy].is_cb_mirror(rr_graph, unique_module, cb_type)) { + if (true == is_cb_mirror(rr_graph, rr_gsb_[ix][iy], unique_module, cb_type)) { /* This is a mirror, raise the flag and we finish */ is_unique_module = false; /* Record the id of unique mirror */ @@ -266,7 +267,7 @@ void DeviceRRGSB::build_sb_unique_module(const RRGraph& rr_graph) { * else the sb is unique */ const RRGSB& unique_module = get_sb_unique_module(id); - if (true == rr_gsb_[ix][iy].is_sb_mirror(rr_graph, unique_module)) { + if (true == is_sb_mirror(rr_graph, rr_gsb_[ix][iy], unique_module)) { /* This is a mirror, raise the flag and we finish */ is_unique_module = false; /* Record the id of unique mirror */ diff --git a/openfpga/src/utils/rr_gsb_utils.cpp b/openfpga/src/utils/rr_gsb_utils.cpp index 90b63bff4..599e9552c 100644 --- a/openfpga/src/utils/rr_gsb_utils.cpp +++ b/openfpga/src/utils/rr_gsb_utils.cpp @@ -55,4 +55,258 @@ std::vector get_rr_gsb_chan_node_configurable_driver_nodes(const RRGra return driver_nodes; } +/** @brief check if two rr_nodes in two GSBs have a similar set of drive_rr_nodes for each drive_rr_node: + * 1. CHANX or CHANY: should have the same side and index + * 2. OPIN or IPIN: should have the same side and index + * 3. each drive_rr_switch should be the same + */ +static +bool is_sb_node_mirror(const RRGraph& rr_graph, + const RRGSB& base, + const RRGSB& cand, + const e_side& node_side, + const size_t& track_id) { + /* Ensure rr_nodes are either the output of short-connection or multiplexer */ + bool is_short_conkt = base.is_sb_node_passing_wire(rr_graph, node_side, track_id); + + if (is_short_conkt != cand.is_sb_node_passing_wire(rr_graph, node_side, track_id)) { + return false; + } + + if (true == is_short_conkt) { + /* Since, both are pass wires, + * The two node should be equivalent + * we can return here + */ + return true; + } + + /* Use unsorted/sorted edges */ + std::vector node_in_edges = base.get_chan_node_in_edges(rr_graph, node_side, track_id); + std::vector cand_node_in_edges = cand.get_chan_node_in_edges(rr_graph, node_side, track_id); + + /* For non-passing wires, check driving rr_nodes */ + if (node_in_edges.size() != cand_node_in_edges.size()) { + return false; + } + + VTR_ASSERT(node_in_edges.size() == cand_node_in_edges.size()); + + for (size_t iedge = 0; iedge < node_in_edges.size(); ++iedge) { + RREdgeId src_edge = node_in_edges[iedge]; + RREdgeId src_cand_edge = cand_node_in_edges[iedge]; + RRNodeId src_node = rr_graph.edge_src_node(src_edge); + RRNodeId src_cand_node = rr_graph.edge_src_node(src_cand_edge); + /* node type should be the same */ + if (rr_graph.node_type(src_node) != rr_graph.node_type(src_cand_node)) { + return false; + } + /* switch type should be the same */ + if (rr_graph.edge_switch(src_edge) != rr_graph.edge_switch(src_cand_edge)) { + return false; + } + int src_node_id, des_node_id; + enum e_side src_node_side, des_node_side; + base.get_node_side_and_index(rr_graph, src_node, OUT_PORT, src_node_side, src_node_id); + cand.get_node_side_and_index(rr_graph, src_cand_node, OUT_PORT, des_node_side, des_node_id); + if (src_node_id != des_node_id) { + return false; + } + if (src_node_side != des_node_side) { + return false; + } + } + + return true; +} + +/** @brief Check if all the routing segments of a side of candidate SB is a mirror of the current one */ +static +bool is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, + const e_side& side, const RRSegmentId& seg_id) { + /* Create a side manager */ + SideManager side_manager(side); + + /* Make sure both Switch blocks has this side!!! */ + VTR_ASSERT ( side_manager.to_size_t() < base.get_num_sides() ); + VTR_ASSERT ( side_manager.to_size_t() < cand.get_num_sides() ); + + /* check the numbers/directionality of channel rr_nodes */ + /* Ensure we have the same channel width on this side */ + if (base.get_chan_width(side) != cand.get_chan_width(side)) { + return false; + } + for (size_t itrack = 0; itrack < base.get_chan_width(side); ++itrack) { + /* Bypass unrelated segments */ + if (seg_id != base.get_chan_node_segment(side, itrack)) { + continue; + } + /* Check the directionality of each node */ + if (base.get_chan_node_direction(side, itrack) != cand.get_chan_node_direction(side, itrack)) { + return false; + } + /* Check the track_id of each node + * ptc is not necessary, we care the connectivity! + */ + /* For OUT_PORT rr_node, we need to check fan-in */ + if (OUT_PORT != base.get_chan_node_direction(side, itrack)) { + continue; /* skip IN_PORT */ + } + + if (false == is_sb_node_mirror(rr_graph, base, cand, side, itrack)) { + return false; + } + } + + /* check the numbers of opin_rr_nodes */ + if (base.get_num_opin_nodes(side) != cand.get_num_opin_nodes(side)) { + return false; + } + + /* check the numbers of ipin_rr_nodes */ + if (base.get_num_ipin_nodes(side) != cand.get_num_ipin_nodes(side)) { + return false; + } + + return true; +} + + +/** @brief check if a side of candidate SB is a mirror of the current one */ +static +bool is_sb_side_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, const e_side& side) { + + /* get a list of segments */ + std::vector seg_ids = base.get_chan_segment_ids(side); + + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + if (false == is_sb_side_segment_mirror(rr_graph, base, cand, side, seg_ids[iseg])) { + return false; + } + } + + return true; +} + +/** @brief Identify if the Switch Block part of two GSBs are mirror (same in structure) or not. Return true if so, otherwise return false */ +bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand) { + /* check the numbers of sides */ + if (base.get_num_sides() != cand.get_num_sides()) { + return false; + } + + /* check the numbers/directionality of channel rr_nodes */ + for (size_t side = 0; side < base.get_num_sides(); ++side) { + SideManager side_manager(side); + if (false == is_sb_side_mirror(rr_graph, base, cand, side_manager.get_side())) { + return false; + } + } + + return true; +} + +/** @brief Check if two ipin_nodes have a similar set of drive_rr_nodes for each drive_rr_node: + * 1. CHANX or CHANY: should have the same side and index + * 2. each drive_rr_switch should be the same + */ +bool is_cb_node_mirror(const RRGraph& rr_graph, + const RRGSB& base, + const RRGSB& cand, + const t_rr_type& cb_type, + const e_side& node_side, + const size_t& node_id) { + /* Ensure rr_nodes are either the output of short-connection or multiplexer */ + RRNodeId node = base.get_ipin_node(node_side, node_id); + RRNodeId cand_node = cand.get_ipin_node(node_side, node_id); + + if ( rr_graph.node_in_edges(node).size() != rr_graph.node_in_edges(cand_node).size() ) { + return false; + } + + std::vector node_in_edges; + for (const RREdgeId& edge : rr_graph.node_in_edges(node)) { + node_in_edges.push_back(edge); + } + + std::vector cand_node_in_edges; + for (const RREdgeId& edge : rr_graph.node_in_edges(cand_node)) { + cand_node_in_edges.push_back(edge); + } + VTR_ASSERT(node_in_edges.size() == cand_node_in_edges.size()); + + for (size_t iedge = 0; iedge < node_in_edges.size(); ++iedge) { + RREdgeId src_edge = node_in_edges[iedge]; + RREdgeId src_cand_edge = cand_node_in_edges[iedge]; + RRNodeId src_node = rr_graph.edge_src_node(src_edge); + RRNodeId src_cand_node = rr_graph.edge_src_node(src_cand_edge); + /* node type should be the same */ + if (rr_graph.node_type(src_node) != rr_graph.node_type(src_cand_node)) { + return false; + } + /* switch type should be the same */ + if (rr_graph.edge_switch(src_edge)!= rr_graph.edge_switch(src_cand_edge)) { + return false; + } + + int src_node_id, des_node_id; + enum e_side src_node_side, des_node_side; + enum e_side chan_side = get_cb_chan_side(cb_type); + switch (rr_graph.node_type(src_node)) { + case CHANX: + case CHANY: + /* if the drive rr_nodes are routing tracks, find index */ + src_node_id = base.get_chan_node_index(chan_side, src_node); + des_node_id = cand.get_chan_node_index(chan_side, src_cand_node); + break; + case OPIN: + base.get_node_side_and_index(rr_graph, src_node, OUT_PORT, src_node_side, src_node_id); + cand.get_node_side_and_index(rr_graph, src_cand_node, OUT_PORT, des_node_side, des_node_id); + if (src_node_side != des_node_side) { + return false; + } + break; + default: + VTR_LOG("Invalid type of drive_rr_nodes for ipin_node!\n"); + exit(1); + } + if (src_node_id != des_node_id) { + return false; + } + } + + return true; +} + +/** @brief Check if the candidate CB is a mirror of the current baselien */ +bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, const t_rr_type& cb_type) { + /* Check if channel width is the same */ + if ( base.get_cb_chan_width(cb_type) != cand.get_cb_chan_width(cb_type) ) { + return false; + } + + enum e_side chan_side = base.get_cb_chan_side(cb_type); + + /* check the numbers/directionality of channel rr_nodes */ + if ( false == base.chan(chan_side).is_mirror(rr_graph, cand.chan_node(chan_side)) ) { + return false; + } + + /* check the equivalence of ipins */ + std::vector ipin_side = base.get_cb_ipin_sides(cb_type); + for (size_t side = 0; side < ipin_side.size(); ++side) { + /* Ensure we have the same number of IPINs on this side */ + if ( base.get_num_ipin_nodes(ipin_side[side]) != cand.get_num_ipin_nodes(ipin_side[side]) ) { + return false; + } + for (size_t inode = 0; inode < base.get_num_ipin_nodes(ipin_side[side]); ++inode) { + if (false == is_cb_node_mirror(rr_graph, base, cand, cb_type, ipin_side[side], inode)) { + return false; + } + } + } + + return true; +} + } /* end namespace openfpga */ diff --git a/openfpga/src/utils/rr_gsb_utils.h b/openfpga/src/utils/rr_gsb_utils.h index 175734db4..f6c81b77c 100644 --- a/openfpga/src/utils/rr_gsb_utils.h +++ b/openfpga/src/utils/rr_gsb_utils.h @@ -23,6 +23,10 @@ std::vector get_rr_gsb_chan_node_configurable_driver_nodes(const RRGra const e_side& chan_side, const size_t& track_id); +bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand); + +bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, const t_rr_type& cb_type); + } /* end namespace openfpga */ #endif diff --git a/vpr/src/tileable_rr_graph/rr_gsb.cpp b/vpr/src/tileable_rr_graph/rr_gsb.cpp index eff2ebf00..e59765d3c 100644 --- a/vpr/src/tileable_rr_graph/rr_gsb.cpp +++ b/vpr/src/tileable_rr_graph/rr_gsb.cpp @@ -65,6 +65,10 @@ size_t RRGSB::get_max_chan_width() const { return max_chan_width; } +const RRChan& RRGSB::chan(const e_side& chan_side) const { + return chan_node_[size_t(chan_side)]; +} + /* Get the number of routing tracks of a X/Y-direction CB */ size_t RRGSB::get_cb_chan_width(const t_rr_type& cb_type) const { return get_chan_width(get_cb_chan_side(cb_type)); @@ -346,37 +350,6 @@ bool RRGSB::is_sb_node_exist_opposite_side(const RRGraph& rr_graph, return (-1 != index); } -/* check if the candidate CB is a mirror of the current one */ -bool RRGSB::is_cb_mirror(const RRGraph& rr_graph, const RRGSB& cand, const t_rr_type& cb_type) const { - /* Check if channel width is the same */ - if ( get_cb_chan_width(cb_type) != cand.get_cb_chan_width(cb_type) ) { - return false; - } - - enum e_side chan_side = get_cb_chan_side(cb_type); - - /* check the numbers/directionality of channel rr_nodes */ - if ( false == chan_node_[size_t(chan_side)].is_mirror(rr_graph, cand.chan_node_[size_t(chan_side)]) ) { - return false; - } - - /* check the equivalence of ipins */ - std::vector ipin_side = get_cb_ipin_sides(cb_type); - for (size_t side = 0; side < ipin_side.size(); ++side) { - /* Ensure we have the same number of IPINs on this side */ - if ( get_num_ipin_nodes(ipin_side[side]) != cand.get_num_ipin_nodes(ipin_side[side]) ) { - return false; - } - for (size_t inode = 0; inode < get_num_ipin_nodes(ipin_side[side]); ++inode) { - if (false == is_cb_node_mirror(rr_graph, cand, cb_type, ipin_side[side], inode)) { - return false; - } - } - } - - return true; -} - /* check if the CB exist in this GSB */ bool RRGSB::is_cb_exist(const t_rr_type& cb_type) const { /* if channel width is zero, there is no CB */ @@ -495,89 +468,6 @@ bool RRGSB::is_sb_mirrorable(const RRGraph& rr_graph, const RRGSB& cand) const { return true; } -/* check if all the routing segments of a side of candidate SB is a mirror of the current one */ -bool RRGSB::is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& cand, - const e_side& side, const RRSegmentId& seg_id) const { - /* Create a side manager */ - SideManager side_manager(side); - - /* Make sure both Switch blocks has this side!!! */ - VTR_ASSERT ( side_manager.to_size_t() < get_num_sides() ); - VTR_ASSERT ( side_manager.to_size_t() < cand.get_num_sides() ); - - /* check the numbers/directionality of channel rr_nodes */ - /* Ensure we have the same channel width on this side */ - if (get_chan_width(side) != cand.get_chan_width(side)) { - return false; - } - for (size_t itrack = 0; itrack < get_chan_width(side); ++itrack) { - /* Bypass unrelated segments */ - if (seg_id != get_chan_node_segment(side, itrack)) { - continue; - } - /* Check the directionality of each node */ - if (get_chan_node_direction(side, itrack) != cand.get_chan_node_direction(side, itrack)) { - return false; - } - /* Check the track_id of each node - * ptc is not necessary, we care the connectivity! - */ - /* For OUT_PORT rr_node, we need to check fan-in */ - if (OUT_PORT != get_chan_node_direction(side, itrack)) { - continue; /* skip IN_PORT */ - } - - if (false == is_sb_node_mirror(rr_graph, cand, side, itrack)) { - return false; - } - } - - /* check the numbers of opin_rr_nodes */ - if (get_num_opin_nodes(side) != cand.get_num_opin_nodes(side)) { - return false; - } - - /* check the numbers of ipin_rr_nodes */ - if (get_num_ipin_nodes(side) != cand.get_num_ipin_nodes(side)) { - return false; - } - - return true; -} - -/* check if a side of candidate SB is a mirror of the current one */ -bool RRGSB::is_sb_side_mirror(const RRGraph& rr_graph, const RRGSB& cand, const e_side& side) const { - - /* get a list of segments */ - std::vector seg_ids = chan_node_[size_t(side)].get_segment_ids(); - - for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { - if (false == is_sb_side_segment_mirror(rr_graph, cand, side, seg_ids[iseg])) { - return false; - } - } - - return true; -} - -/* check if the candidate SB is a mirror of the current one */ -bool RRGSB::is_sb_mirror(const RRGraph& rr_graph, const RRGSB& cand) const { - /* check the numbers of sides */ - if (get_num_sides() != cand.get_num_sides()) { - return false; - } - - /* check the numbers/directionality of channel rr_nodes */ - for (size_t side = 0; side < get_num_sides(); ++side) { - SideManager side_manager(side); - if (false == is_sb_side_mirror(rr_graph, cand, side_manager.get_side())) { - return false; - } - } - - return true; -} - /* Public Accessors: Cooridinator conversion */ /* get the x coordinate of this GSB */ @@ -940,143 +830,6 @@ void RRGSB::clear_one_side(const e_side& node_side) { /************************************************************************ * Internal Accessors: identify mirrors ***********************************************************************/ - -/* check if two rr_nodes have a similar set of drive_rr_nodes - * for each drive_rr_node: - * 1. CHANX or CHANY: should have the same side and index - * 2. OPIN or IPIN: should have the same side and index - * 3. each drive_rr_switch should be the same - */ -bool RRGSB::is_sb_node_mirror(const RRGraph& rr_graph, - const RRGSB& cand, - const e_side& node_side, - const size_t& track_id) const { - /* Ensure rr_nodes are either the output of short-connection or multiplexer */ - bool is_short_conkt = this->is_sb_node_passing_wire(rr_graph, node_side, track_id); - - if (is_short_conkt != cand.is_sb_node_passing_wire(rr_graph, node_side, track_id)) { - return false; - } - - if (true == is_short_conkt) { - /* Since, both are pass wires, - * The two node should be equivalent - * we can return here - */ - return true; - } - - /* Use unsorted/sorted edges */ - std::vector node_in_edges = get_chan_node_in_edges(rr_graph, node_side, track_id); - std::vector cand_node_in_edges = cand.get_chan_node_in_edges(rr_graph, node_side, track_id); - - /* For non-passing wires, check driving rr_nodes */ - if (node_in_edges.size() != cand_node_in_edges.size()) { - return false; - } - - VTR_ASSERT(node_in_edges.size() == cand_node_in_edges.size()); - - for (size_t iedge = 0; iedge < node_in_edges.size(); ++iedge) { - RREdgeId src_edge = node_in_edges[iedge]; - RREdgeId src_cand_edge = cand_node_in_edges[iedge]; - RRNodeId src_node = rr_graph.edge_src_node(src_edge); - RRNodeId src_cand_node = rr_graph.edge_src_node(src_cand_edge); - /* node type should be the same */ - if (rr_graph.node_type(src_node) != rr_graph.node_type(src_cand_node)) { - return false; - } - /* switch type should be the same */ - if (rr_graph.edge_switch(src_edge) != rr_graph.edge_switch(src_cand_edge)) { - return false; - } - int src_node_id, des_node_id; - enum e_side src_node_side, des_node_side; - this->get_node_side_and_index(rr_graph, src_node, OUT_PORT, src_node_side, src_node_id); - cand.get_node_side_and_index(rr_graph, src_cand_node, OUT_PORT, des_node_side, des_node_id); - if (src_node_id != des_node_id) { - return false; - } - if (src_node_side != des_node_side) { - return false; - } - } - - return true; -} - -/* check if two ipin_nodes have a similar set of drive_rr_nodes - * for each drive_rr_node: - * 1. CHANX or CHANY: should have the same side and index - * 2. each drive_rr_switch should be the same - */ -bool RRGSB::is_cb_node_mirror(const RRGraph& rr_graph, - const RRGSB& cand, - const t_rr_type& cb_type, - const e_side& node_side, - const size_t& node_id) const { - /* Ensure rr_nodes are either the output of short-connection or multiplexer */ - RRNodeId node = this->get_ipin_node(node_side, node_id); - RRNodeId cand_node = cand.get_ipin_node(node_side, node_id); - - if ( rr_graph.node_in_edges(node).size() != rr_graph.node_in_edges(cand_node).size() ) { - return false; - } - - std::vector node_in_edges; - for (const RREdgeId& edge : rr_graph.node_in_edges(node)) { - node_in_edges.push_back(edge); - } - - std::vector cand_node_in_edges; - for (const RREdgeId& edge : rr_graph.node_in_edges(cand_node)) { - cand_node_in_edges.push_back(edge); - } - VTR_ASSERT(node_in_edges.size() == cand_node_in_edges.size()); - - for (size_t iedge = 0; iedge < node_in_edges.size(); ++iedge) { - RREdgeId src_edge = node_in_edges[iedge]; - RREdgeId src_cand_edge = cand_node_in_edges[iedge]; - RRNodeId src_node = rr_graph.edge_src_node(src_edge); - RRNodeId src_cand_node = rr_graph.edge_src_node(src_cand_edge); - /* node type should be the same */ - if (rr_graph.node_type(src_node) != rr_graph.node_type(src_cand_node)) { - return false; - } - /* switch type should be the same */ - if (rr_graph.edge_switch(src_edge)!= rr_graph.edge_switch(src_cand_edge)) { - return false; - } - - int src_node_id, des_node_id; - enum e_side src_node_side, des_node_side; - enum e_side chan_side = get_cb_chan_side(cb_type); - switch (rr_graph.node_type(src_node)) { - case CHANX: - case CHANY: - /* if the drive rr_nodes are routing tracks, find index */ - src_node_id = this->get_chan_node_index(chan_side, src_node); - des_node_id = cand.get_chan_node_index(chan_side, src_cand_node); - break; - case OPIN: - this->get_node_side_and_index(rr_graph, src_node, OUT_PORT, src_node_side, src_node_id); - cand.get_node_side_and_index(rr_graph, src_cand_node, OUT_PORT, des_node_side, des_node_id); - if (src_node_side != des_node_side) { - return false; - } - break; - default: - VTR_LOG("Invalid type of drive_rr_nodes for ipin_node!\n"); - exit(1); - } - if (src_node_id != des_node_id) { - return false; - } - } - - return true; -} - size_t RRGSB::get_track_id_first_short_connection(const RRGraph& rr_graph, const e_side& node_side) const { VTR_ASSERT(validate_side(node_side)); diff --git a/vpr/src/tileable_rr_graph/rr_gsb.h b/vpr/src/tileable_rr_graph/rr_gsb.h index 38465369d..3738be92b 100644 --- a/vpr/src/tileable_rr_graph/rr_gsb.h +++ b/vpr/src/tileable_rr_graph/rr_gsb.h @@ -66,6 +66,9 @@ class RRGSB { /* Get the maximum number of routing tracks on all sides */ size_t get_max_chan_width() const; + /* Return read-only object of the routing channels with a given side */ + const RRChan& chan(const e_side& chan_side) const; + /* Get the number of routing tracks of a X/Y-direction CB */ size_t get_cb_chan_width(const t_rr_type& cb_type) const; From 59440082edeb426fa2f684a1b10e8276f1ce0abe Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 6 Sep 2022 11:55:40 -0700 Subject: [PATCH 2/5] [engine] fixed some syntax errors --- openfpga/src/utils/rr_gsb_utils.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openfpga/src/utils/rr_gsb_utils.cpp b/openfpga/src/utils/rr_gsb_utils.cpp index 599e9552c..532c6b7e0 100644 --- a/openfpga/src/utils/rr_gsb_utils.cpp +++ b/openfpga/src/utils/rr_gsb_utils.cpp @@ -4,6 +4,7 @@ *******************************************************************/ /* Headers from vtrutil library */ #include "vtr_assert.h" +#include "vtr_log.h" /* Headers from openfpgautil library */ #include "openfpga_side_manager.h" @@ -210,6 +211,7 @@ bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand) * 1. CHANX or CHANY: should have the same side and index * 2. each drive_rr_switch should be the same */ +static bool is_cb_node_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, @@ -251,7 +253,7 @@ bool is_cb_node_mirror(const RRGraph& rr_graph, int src_node_id, des_node_id; enum e_side src_node_side, des_node_side; - enum e_side chan_side = get_cb_chan_side(cb_type); + enum e_side chan_side = base.get_cb_chan_side(cb_type); switch (rr_graph.node_type(src_node)) { case CHANX: case CHANY: @@ -288,7 +290,7 @@ bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, enum e_side chan_side = base.get_cb_chan_side(cb_type); /* check the numbers/directionality of channel rr_nodes */ - if ( false == base.chan(chan_side).is_mirror(rr_graph, cand.chan_node(chan_side)) ) { + if ( false == base.chan(chan_side).is_mirror(rr_graph, cand.chan(chan_side)) ) { return false; } From eab3580f79face255beb84da8da4c89f0f586c75 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 6 Sep 2022 13:40:29 -0700 Subject: [PATCH 3/5] [engine] now consider circuit model rather than switchId and SegmentId when identifying GSB structure similarity --- openfpga/src/annotation/device_rr_gsb.cpp | 7 +- openfpga/src/annotation/device_rr_gsb.h | 5 ++ openfpga/src/base/openfpga_context.h | 2 +- openfpga/src/utils/rr_gsb_utils.cpp | 103 ++++++++++++++++++---- openfpga/src/utils/rr_gsb_utils.h | 12 ++- vpr/src/tileable_rr_graph/rr_chan.cpp | 30 ------- vpr/src/tileable_rr_graph/rr_chan.h | 1 - vpr/src/tileable_rr_graph/rr_gsb.h | 45 ---------- 8 files changed, 108 insertions(+), 97 deletions(-) diff --git a/openfpga/src/annotation/device_rr_gsb.cpp b/openfpga/src/annotation/device_rr_gsb.cpp index 883b32191..9438df057 100644 --- a/openfpga/src/annotation/device_rr_gsb.cpp +++ b/openfpga/src/annotation/device_rr_gsb.cpp @@ -12,6 +12,9 @@ namespace openfpga { /************************************************************************ * Constructors ***********************************************************************/ +DeviceRRGSB::DeviceRRGSB(const VprDeviceAnnotation& device_annotation) + : device_annotation_(device_annotation) { +} /************************************************************************ * Public accessors @@ -231,7 +234,7 @@ void DeviceRRGSB::build_cb_unique_module(const RRGraph& rr_graph, const t_rr_typ /* Traverse the unique_mirror list and check it is an mirror of another */ for (size_t id = 0; id < get_num_cb_unique_module(cb_type); ++id) { const RRGSB& unique_module = get_cb_unique_module(cb_type, id); - if (true == is_cb_mirror(rr_graph, rr_gsb_[ix][iy], unique_module, cb_type)) { + if (true == is_cb_mirror(rr_graph, device_annotation_, rr_gsb_[ix][iy], unique_module, cb_type)) { /* This is a mirror, raise the flag and we finish */ is_unique_module = false; /* Record the id of unique mirror */ @@ -267,7 +270,7 @@ void DeviceRRGSB::build_sb_unique_module(const RRGraph& rr_graph) { * else the sb is unique */ const RRGSB& unique_module = get_sb_unique_module(id); - if (true == is_sb_mirror(rr_graph, rr_gsb_[ix][iy], unique_module)) { + if (true == is_sb_mirror(rr_graph, device_annotation_, rr_gsb_[ix][iy], unique_module)) { /* This is a mirror, raise the flag and we finish */ is_unique_module = false; /* Record the id of unique mirror */ diff --git a/openfpga/src/annotation/device_rr_gsb.h b/openfpga/src/annotation/device_rr_gsb.h index 290322079..81f5ead90 100644 --- a/openfpga/src/annotation/device_rr_gsb.h +++ b/openfpga/src/annotation/device_rr_gsb.h @@ -11,6 +11,7 @@ #include "rr_graph_obj.h" #include "rr_gsb.h" +#include "vpr_device_annotation.h" /* namespace openfpga begins */ namespace openfpga { @@ -26,6 +27,7 @@ namespace openfpga { *******************************************************************/ class DeviceRRGSB { public: /* Contructors */ + DeviceRRGSB(const VprDeviceAnnotation& device_annotation); public: /* Accessors */ vtr::Point get_gsb_range() const; /* get the max coordinate of the switch block array */ const RRGSB& get_gsb(const vtr::Point& coordinate) const; /* Get a rr switch block in the array with a coordinate */ @@ -84,6 +86,9 @@ class DeviceRRGSB { std::vector> cby_unique_module_id_; /* A map from rr_gsb to its unique mirror */ std::vector> cby_unique_module_; /* For each side of connection block, we identify a list of unique modules based on its connection. This is a matrix [0..num_module] */ + + /* Cached data */ + const VprDeviceAnnotation& device_annotation_; }; } /* End namespace openfpga*/ diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index f4d356550..01d8b271a 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -124,7 +124,7 @@ class OpenfpgaContext : public Context { openfpga::VprBitstreamAnnotation vpr_bitstream_annotation_; /* Device-level annotation */ - openfpga::DeviceRRGSB device_rr_gsb_; + openfpga::DeviceRRGSB device_rr_gsb_{vpr_device_annotation_}; /* Library of physical implmentation of routing multiplexers */ openfpga::MuxLibrary mux_lib_; diff --git a/openfpga/src/utils/rr_gsb_utils.cpp b/openfpga/src/utils/rr_gsb_utils.cpp index 532c6b7e0..a8107d09e 100644 --- a/openfpga/src/utils/rr_gsb_utils.cpp +++ b/openfpga/src/utils/rr_gsb_utils.cpp @@ -56,6 +56,40 @@ std::vector get_rr_gsb_chan_node_configurable_driver_nodes(const RRGra return driver_nodes; } +/** @brief Evaluate if two RRChan is mirror to each other */ +static +bool is_chan_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRChan& base, + const RRChan& cand) { + /* If any following element does not match, it is not mirror */ + /* 1. type */ + if (base.get_type() != cand.get_type()) { + return false; + } + /* 2. track_width */ + if (base.get_chan_width() != cand.get_chan_width()) { + return false; + } + /* 3. for each node */ + for (size_t inode = 0; inode < base.get_chan_width(); ++inode) { + /* 3.1 check node type */ + if (rr_graph.node_type(base.get_node(inode)) != rr_graph.node_type(cand.get_node(inode))) { + return false; + } + /* 3.2 check node directionality */ + if (rr_graph.node_direction(base.get_node(inode)) != rr_graph.node_direction(cand.get_node(inode))) { + return false; + } + /* 3.3 check node segment */ + if (device_annotation.rr_segment_circuit_model(base.get_node_segment(inode)) != device_annotation.rr_segment_circuit_model(cand.get_node_segment(inode))) { + return false; + } + } + + return true; +} + /** @brief check if two rr_nodes in two GSBs have a similar set of drive_rr_nodes for each drive_rr_node: * 1. CHANX or CHANY: should have the same side and index * 2. OPIN or IPIN: should have the same side and index @@ -63,6 +97,7 @@ std::vector get_rr_gsb_chan_node_configurable_driver_nodes(const RRGra */ static bool is_sb_node_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, const RRGSB& base, const RRGSB& cand, const e_side& node_side, @@ -103,7 +138,7 @@ bool is_sb_node_mirror(const RRGraph& rr_graph, return false; } /* switch type should be the same */ - if (rr_graph.edge_switch(src_edge) != rr_graph.edge_switch(src_cand_edge)) { + if (device_annotation.rr_switch_circuit_model(rr_graph.edge_switch(src_edge)) != device_annotation.rr_switch_circuit_model(rr_graph.edge_switch(src_cand_edge))) { return false; } int src_node_id, des_node_id; @@ -123,8 +158,12 @@ bool is_sb_node_mirror(const RRGraph& rr_graph, /** @brief Check if all the routing segments of a side of candidate SB is a mirror of the current one */ static -bool is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, - const e_side& side, const RRSegmentId& seg_id) { +bool is_sb_side_segment_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRGSB& base, + const RRGSB& cand, + const e_side& side, + const RRSegmentId& seg_id) { /* Create a side manager */ SideManager side_manager(side); @@ -139,7 +178,7 @@ bool is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& base, const } for (size_t itrack = 0; itrack < base.get_chan_width(side); ++itrack) { /* Bypass unrelated segments */ - if (seg_id != base.get_chan_node_segment(side, itrack)) { + if (device_annotation.rr_segment_circuit_model(seg_id) != device_annotation.rr_segment_circuit_model(base.get_chan_node_segment(side, itrack))) { continue; } /* Check the directionality of each node */ @@ -154,7 +193,7 @@ bool is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& base, const continue; /* skip IN_PORT */ } - if (false == is_sb_node_mirror(rr_graph, base, cand, side, itrack)) { + if (false == is_sb_node_mirror(rr_graph, device_annotation, base, cand, side, itrack)) { return false; } } @@ -172,16 +211,29 @@ bool is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& base, const return true; } - -/** @brief check if a side of candidate SB is a mirror of the current one */ +/** @brief check if a side of candidate SB is a mirror of the current one + * Check the specified side of two switch blocks: + * 1. Number of channel/opin/ipin rr_nodes are same + * For channel rr_nodes + * 2. check if their track_ids (ptc_num) are same + * 3. Check if the switches (ids) are same + * For opin/ipin rr_nodes, + * 4. check if their parent type_descriptors same, + * 5. check if pin class id and pin id are same + * If all above are satisfied, the side of the two switch blocks are mirrors! + */ static -bool is_sb_side_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, const e_side& side) { +bool is_sb_side_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRGSB& base, + const RRGSB& cand, + const e_side& side) { /* get a list of segments */ std::vector seg_ids = base.get_chan_segment_ids(side); for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { - if (false == is_sb_side_segment_mirror(rr_graph, base, cand, side, seg_ids[iseg])) { + if (false == is_sb_side_segment_mirror(rr_graph, device_annotation, base, cand, side, seg_ids[iseg])) { return false; } } @@ -189,8 +241,22 @@ bool is_sb_side_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& return true; } -/** @brief Identify if the Switch Block part of two GSBs are mirror (same in structure) or not. Return true if so, otherwise return false */ -bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand) { +/** @brief Identify if the Switch Block part of two GSBs are mirror (same in structure) or not. Return true if so, otherwise return false + * Idenify mirror Switch blocks + * Check each two switch blocks: + * 1. Number of channel/opin/ipin rr_nodes are same + * For channel rr_nodes + * 2. check if their track_ids (ptc_num) are same + * 3. Check if the switches (ids) are same + * For opin/ipin rr_nodes, + * 4. check if their parent type_descriptors same, + * 5. check if pin class id and pin id are same + * If all above are satisfied, the two switch blocks are mirrors! + */ +bool is_sb_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRGSB& base, + const RRGSB& cand) { /* check the numbers of sides */ if (base.get_num_sides() != cand.get_num_sides()) { return false; @@ -199,7 +265,7 @@ bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand) /* check the numbers/directionality of channel rr_nodes */ for (size_t side = 0; side < base.get_num_sides(); ++side) { SideManager side_manager(side); - if (false == is_sb_side_mirror(rr_graph, base, cand, side_manager.get_side())) { + if (false == is_sb_side_mirror(rr_graph, device_annotation, base, cand, side_manager.get_side())) { return false; } } @@ -213,6 +279,7 @@ bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand) */ static bool is_cb_node_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, const RRGSB& base, const RRGSB& cand, const t_rr_type& cb_type, @@ -247,7 +314,7 @@ bool is_cb_node_mirror(const RRGraph& rr_graph, return false; } /* switch type should be the same */ - if (rr_graph.edge_switch(src_edge)!= rr_graph.edge_switch(src_cand_edge)) { + if (device_annotation.rr_switch_circuit_model(rr_graph.edge_switch(src_edge)) != device_annotation.rr_switch_circuit_model(rr_graph.edge_switch(src_cand_edge))) { return false; } @@ -281,7 +348,11 @@ bool is_cb_node_mirror(const RRGraph& rr_graph, } /** @brief Check if the candidate CB is a mirror of the current baselien */ -bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, const t_rr_type& cb_type) { +bool is_cb_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRGSB& base, + const RRGSB& cand, + const t_rr_type& cb_type) { /* Check if channel width is the same */ if ( base.get_cb_chan_width(cb_type) != cand.get_cb_chan_width(cb_type) ) { return false; @@ -290,7 +361,7 @@ bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, enum e_side chan_side = base.get_cb_chan_side(cb_type); /* check the numbers/directionality of channel rr_nodes */ - if ( false == base.chan(chan_side).is_mirror(rr_graph, cand.chan(chan_side)) ) { + if ( false == is_chan_mirror(rr_graph, device_annotation, base.chan(chan_side), cand.chan(chan_side)) ) { return false; } @@ -302,7 +373,7 @@ bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, return false; } for (size_t inode = 0; inode < base.get_num_ipin_nodes(ipin_side[side]); ++inode) { - if (false == is_cb_node_mirror(rr_graph, base, cand, cb_type, ipin_side[side], inode)) { + if (false == is_cb_node_mirror(rr_graph, device_annotation, base, cand, cb_type, ipin_side[side], inode)) { return false; } } diff --git a/openfpga/src/utils/rr_gsb_utils.h b/openfpga/src/utils/rr_gsb_utils.h index f6c81b77c..379638371 100644 --- a/openfpga/src/utils/rr_gsb_utils.h +++ b/openfpga/src/utils/rr_gsb_utils.h @@ -7,6 +7,7 @@ #include #include #include "rr_gsb.h" +#include "vpr_device_annotation.h" /******************************************************************** * Function declaration @@ -23,9 +24,16 @@ std::vector get_rr_gsb_chan_node_configurable_driver_nodes(const RRGra const e_side& chan_side, const size_t& track_id); -bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand); +bool is_sb_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRGSB& base, + const RRGSB& cand); -bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& base, const RRGSB& cand, const t_rr_type& cb_type); +bool is_cb_mirror(const RRGraph& rr_graph, + const VprDeviceAnnotation& device_annotation, + const RRGSB& base, + const RRGSB& cand, + const t_rr_type& cb_type); } /* end namespace openfpga */ diff --git a/vpr/src/tileable_rr_graph/rr_chan.cpp b/vpr/src/tileable_rr_graph/rr_chan.cpp index 0aea3cee4..4e5b9a98d 100644 --- a/vpr/src/tileable_rr_graph/rr_chan.cpp +++ b/vpr/src/tileable_rr_graph/rr_chan.cpp @@ -69,36 +69,6 @@ RRSegmentId RRChan::get_node_segment(const size_t& track_num) const { return node_segments_[track_num]; } -/* evaluate if two RRChan is mirror to each other */ -bool RRChan::is_mirror(const RRGraph& rr_graph, const RRChan& cand) const { - /* If any following element does not match, it is not mirror */ - /* 1. type */ - if (this->get_type() != cand.get_type()) { - return false; - } - /* 2. track_width */ - if (this->get_chan_width() != cand.get_chan_width()) { - return false; - } - /* 3. for each node */ - for (size_t inode = 0; inode < this->get_chan_width(); ++inode) { - /* 3.1 check node type */ - if (rr_graph.node_type(this->get_node(inode)) != rr_graph.node_type(cand.get_node(inode))) { - return false; - } - /* 3.2 check node directionality */ - if (rr_graph.node_direction(this->get_node(inode)) != rr_graph.node_direction(cand.get_node(inode))) { - return false; - } - /* 3.3 check node segment */ - if (this->get_node_segment(inode) != cand.get_node_segment(inode)) { - return false; - } - } - - return true; -} - /* Get a list of segments used in this routing channel */ std::vector RRChan::get_segment_ids() const { std::vector seg_list; diff --git a/vpr/src/tileable_rr_graph/rr_chan.h b/vpr/src/tileable_rr_graph/rr_chan.h index d06d894ca..a45cac0d9 100644 --- a/vpr/src/tileable_rr_graph/rr_chan.h +++ b/vpr/src/tileable_rr_graph/rr_chan.h @@ -51,7 +51,6 @@ class RRChan { RRNodeId get_node(const size_t& track_num) const; /* get the rr_node with the track_id */ RRSegmentId get_node_segment(const RRNodeId& node) const; RRSegmentId get_node_segment(const size_t& track_num) const; - bool is_mirror(const RRGraph& rr_graph, const RRChan& cand) const; /* evaluate if two RR_chan is mirror to each other */ std::vector get_segment_ids() const; /* Get a list of segments used in this routing channel */ std::vector get_node_ids_by_segment_ids(const RRSegmentId& seg_id) const; /* Get a list of segments used in this routing channel */ public: /* Mutators */ diff --git a/vpr/src/tileable_rr_graph/rr_gsb.h b/vpr/src/tileable_rr_graph/rr_gsb.h index 3738be92b..375e3222e 100644 --- a/vpr/src/tileable_rr_graph/rr_gsb.h +++ b/vpr/src/tileable_rr_graph/rr_gsb.h @@ -121,9 +121,6 @@ class RRGSB { /* Check if the node exist in the opposite side of this Switch Block */ bool is_sb_node_exist_opposite_side(const RRGraph& rr_graph, const RRNodeId& node, const e_side& node_side) const; public: /* Accessors: to identify mirrors */ - /* check if the candidate SB is a mirror of the current one */ - bool is_cb_mirror(const RRGraph& rr_graph, const RRGSB& cand, const t_rr_type& cb_type) const; - /* check if the connect block exists in the GSB */ bool is_cb_exist(const t_rr_type& cb_type) const; @@ -138,37 +135,6 @@ class RRGSB { */ bool is_sb_mirrorable(const RRGraph& rr_graph, const RRGSB& cand) const; - /* check if all the routing segments of a side of candidate SB is a mirror of the current one */ - bool is_sb_side_segment_mirror(const RRGraph& rr_graph, const RRGSB& cand, - const e_side& side, const RRSegmentId& seg_id) const; - - /* check if a side of candidate SB is a mirror of the current one - * Check the specified side of two switch blocks: - * 1. Number of channel/opin/ipin rr_nodes are same - * For channel rr_nodes - * 2. check if their track_ids (ptc_num) are same - * 3. Check if the switches (ids) are same - * For opin/ipin rr_nodes, - * 4. check if their parent type_descriptors same, - * 5. check if pin class id and pin id are same - * If all above are satisfied, the side of the two switch blocks are mirrors! - */ - bool is_sb_side_mirror(const RRGraph& rr_graph, const RRGSB& cand, const e_side& side) const; - - /* check if the candidate SB is a mirror of the current one - * Idenify mirror Switch blocks - * Check each two switch blocks: - * 1. Number of channel/opin/ipin rr_nodes are same - * For channel rr_nodes - * 2. check if their track_ids (ptc_num) are same - * 3. Check if the switches (ids) are same - * For opin/ipin rr_nodes, - * 4. check if their parent type_descriptors same, - * 5. check if pin class id and pin id are same - * If all above are satisfied, the two switch blocks are mirrors! - */ - bool is_sb_mirror(const RRGraph& rr_graph, const RRGSB& cand) const; - public: /* Cooridinator conversion and output */ size_t get_x() const; /* get the x coordinate of this switch block */ size_t get_y() const; /* get the y coordinate of this switch block */ @@ -234,17 +200,6 @@ class RRGSB { const size_t& track_id); private: /* internal functions */ - bool is_sb_node_mirror(const RRGraph& rr_graph, - const RRGSB& cand, - const e_side& node_side, - const size_t& track_id) const; - - bool is_cb_node_mirror(const RRGraph& rr_graph, - const RRGSB& cand, - const t_rr_type& cb_type, - const e_side& node_side, - const size_t& node_id) const; - size_t get_track_id_first_short_connection(const RRGraph& rr_graph, const e_side& node_side) const; private: /* internal validators */ From e748c7697d839e35f60e7d64c201b20d7c67b94b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 6 Sep 2022 13:51:29 -0700 Subject: [PATCH 4/5] [engine] update code comments --- openfpga/src/utils/rr_gsb_utils.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openfpga/src/utils/rr_gsb_utils.cpp b/openfpga/src/utils/rr_gsb_utils.cpp index a8107d09e..43175514c 100644 --- a/openfpga/src/utils/rr_gsb_utils.cpp +++ b/openfpga/src/utils/rr_gsb_utils.cpp @@ -56,7 +56,7 @@ std::vector get_rr_gsb_chan_node_configurable_driver_nodes(const RRGra return driver_nodes; } -/** @brief Evaluate if two RRChan is mirror to each other */ +/** @brief Evaluate if two routing channels are mirror to each other */ static bool is_chan_mirror(const RRGraph& rr_graph, const VprDeviceAnnotation& device_annotation, @@ -82,6 +82,7 @@ bool is_chan_mirror(const RRGraph& rr_graph, return false; } /* 3.3 check node segment */ + /* FIXME: Maybe this is too tight! Consider to remove the restrictions on segments */ if (device_annotation.rr_segment_circuit_model(base.get_node_segment(inode)) != device_annotation.rr_segment_circuit_model(cand.get_node_segment(inode))) { return false; } @@ -177,7 +178,7 @@ bool is_sb_side_segment_mirror(const RRGraph& rr_graph, return false; } for (size_t itrack = 0; itrack < base.get_chan_width(side); ++itrack) { - /* Bypass unrelated segments */ + /* FIXME: Maybe this is too tight! Consider to remove the restrictions on segments */ if (device_annotation.rr_segment_circuit_model(seg_id) != device_annotation.rr_segment_circuit_model(base.get_chan_node_segment(side, itrack))) { continue; } From 8d09773e655f5ad697ba8faf6247999820e5c0fa Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 7 Sep 2022 11:55:08 +0800 Subject: [PATCH 5/5] [engine] remove unnecessary checks from sb mirror checker --- openfpga/src/utils/rr_gsb_utils.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openfpga/src/utils/rr_gsb_utils.cpp b/openfpga/src/utils/rr_gsb_utils.cpp index 43175514c..58b1df4ba 100644 --- a/openfpga/src/utils/rr_gsb_utils.cpp +++ b/openfpga/src/utils/rr_gsb_utils.cpp @@ -204,11 +204,6 @@ bool is_sb_side_segment_mirror(const RRGraph& rr_graph, return false; } - /* check the numbers of ipin_rr_nodes */ - if (base.get_num_ipin_nodes(side) != cand.get_num_ipin_nodes(side)) { - return false; - } - return true; }