#ifndef RR_GSB_H #define RR_GSB_H /******************************************************************** * Include header files required by the data structure definition *******************************************************************/ /* Headers from vtrutil library */ #include "vtr_geometry.h" #include "rr_chan.h" /* Begin namespace openfpga */ namespace openfpga { /******************************************************************** * Object Generic Switch Block * This block contains * 1. A switch block * 2. A X-direction Connection block locates at the left side of the switch block * 2. A Y-direction Connection block locates at the top side of the switch block * * +---------------------------------+ * | Y-direction CB | * | [x][y + 1] | * +---------------------------------+ * * TOP SIDE * +-------------+ +---------------------------------+ * | | | OPIN_NODE CHAN_NODES OPIN_NODES | * | | | | * | | | OPIN_NODES OPIN_NODES | * | X-direction | | | * | CB | LEFT SIDE | Switch Block | RIGHT SIDE * | [x][y] | | [x][y] | * | | | | * | | | CHAN_NODES CHAN_NODES | * | | | | * | | | OPIN_NODES OPIN_NODES | * | | | | * | | | OPIN_NODE CHAN_NODES OPIN_NODES | * +-------------+ +---------------------------------+ * BOTTOM SIDE * num_sides: number of sides of this switch block * chan_rr_node: a collection of rr_nodes as routing tracks locating at each side of the Switch block <0..num_sides-1><0..chan_width-1> * chan_rr_node_direction: Indicate if this rr_node is an input or an output of the Switch block <0..num_sides-1><0..chan_width-1> * ipin_rr_node: a collection of rr_nodes as IPIN of a GRID locating at each side of the Switch block <0..num_sides-1><0..num_ipin_rr_nodes-1> * ipin_rr_node_grid_side: specify the side of the input pins on which side of a GRID <0..num_sides-1><0..num_ipin_rr_nodes-1> * opin_rr_node: a collection of rr_nodes as OPIN of a GRID locating at each side of the Switch block <0..num_sides-1><0..num_opin_rr_nodes-1> * opin_rr_node_grid_side: specify the side of the output pins on which side of a GRID <0..num_sides-1><0..num_opin_rr_nodes-1> * num_reserved_conf_bits: number of reserved configuration bits this switch block requires (mainly due to RRAM-based multiplexers) * num_conf_bits: number of configuration bits this switch block requires *******************************************************************/ class RRGSB { public: /* Contructors */ RRGSB(const RRGSB&);/* Copy constructor */ RRGSB();/* Default constructor */ public: /* Accessors */ /* Get the number of sides of this SB */ size_t get_num_sides() const; /* Get the number of routing tracks on a side */ size_t get_chan_width(const e_side& side) const; /* Get the maximum number of routing tracks on all sides */ size_t get_max_chan_width() 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; /* Get the sides of CB ipins in the array */ std::vector get_cb_ipin_sides(const t_rr_type& cb_type) const; /* Get the direction of a rr_node at a given side and track_id */ enum PORTS get_chan_node_direction(const e_side& side, const size_t& track_id) const; /* Get a list of segments used in this routing channel */ std::vector get_chan_segment_ids(const e_side& side) const; /* Get a list of segments used in this routing channel */ std::vector get_chan_node_ids_by_segment_ids(const e_side& side, const RRSegmentId& seg_id) const; /* get a rr_node at a given side and track_id */ RRNodeId get_chan_node(const e_side& side, const size_t& track_id) const; /* get the segment id of a channel rr_node */ RRSegmentId get_chan_node_segment(const e_side& side, const size_t& track_id) const; /* Get the number of IPIN rr_nodes on a side */ size_t get_num_ipin_nodes(const e_side& side) const; /* get a rr_node at a given side and track_id */ RRNodeId get_ipin_node(const e_side& side, const size_t& node_id) const; /* Get the number of OPIN rr_nodes on a side */ size_t get_num_opin_nodes(const e_side& side) const; /* get a rr_node at a given side and track_id */ RRNodeId get_opin_node(const e_side& side, const size_t& node_id) const; int get_cb_chan_node_index(const t_rr_type& cb_type, const RRNodeId& node) const; int get_chan_node_index(const e_side& node_side, const RRNodeId& node) const; /* Get the node index in the array, return -1 if not found */ int get_node_index(const RRGraph& rr_graph, const RRNodeId& node, const e_side& node_side, const PORTS& node_direction) const; /* Given a rr_node, try to find its side and index in the Switch block */ void get_node_side_and_index(const RRGraph& rr_graph, const RRNodeId& node, const PORTS& node_direction, e_side& node_side, int& node_index) const; /* 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; /* check if the switch block exists in the GSB */ bool is_sb_exist() const; /* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */ bool is_sb_node_passing_wire(const RRGraph& rr_graph, const e_side& node_side, const size_t& track_id) const; /* check if the candidate SB satisfy the basic requirements * on being a mirror of the current one */ 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 */ size_t get_sb_x() const; /* get the x coordinate of this switch block */ size_t get_sb_y() const; /* get the y coordinate of this switch block */ vtr::Point get_sb_coordinate() const; /* Get the coordinate of the SB */ size_t get_cb_x(const t_rr_type& cb_type) const; /* get the x coordinate of this X/Y-direction block */ size_t get_cb_y(const t_rr_type& cb_type) const; /* get the y coordinate of this X/Y-direction block */ vtr::Point get_cb_coordinate(const t_rr_type& cb_type) const; /* Get the coordinate of the X/Y-direction CB */ e_side get_cb_chan_side(const t_rr_type& cb_type) const; /* get the side of a Connection block */ e_side get_cb_chan_side(const e_side& ipin_side) const; /* get the side of a Connection block */ vtr::Point get_side_block_coordinate(const e_side& side) const; vtr::Point get_grid_coordinate() const; public: /* Mutators */ void set(const RRGSB& src); /* get a copy from a source */ void set_coordinate(const size_t& x, const size_t& y); void init_num_sides(const size_t& num_sides); /* Allocate the vectors with the given number of sides */ void add_chan_node(const e_side& node_side, RRChan& rr_chan, const std::vector& rr_chan_dir); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */ void add_ipin_node(const RRNodeId& node, const e_side& node_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */ void add_opin_node(const RRNodeId& node, const e_side& node_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */ public: /* Mutators: cleaners */ void clear(); /* Clean the chan_width of a side */ void clear_chan_nodes(const e_side& node_side); /* Clean the number of IPINs of a side */ void clear_ipin_nodes(const e_side& node_side); /* Clean the number of OPINs of a side */ void clear_opin_nodes(const e_side& node_side); /* Clean chan/opin/ipin nodes at one side */ void clear_one_side(const e_side& node_side); 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 */ bool validate_num_sides() const; bool validate_side(const e_side& side) const; bool validate_track_id(const e_side& side, const size_t& track_id) const; bool validate_opin_node_id(const e_side& side, const size_t& node_id) const; bool validate_ipin_node_id(const e_side& side, const size_t& node_id) const; bool validate_cb_type(const t_rr_type& cb_type) const; private: /* Internal Data */ /* Coordinator */ vtr::Point coordinate_; /* Routing channel data */ std::vector chan_node_; std::vector> chan_node_direction_; /* Logic Block Inputs data */ std::vector> ipin_node_; /* Logic Block Outputs data */ std::vector> opin_node_; }; } /* End namespace openfpga*/ #endif