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 */