234 lines
12 KiB
C++
234 lines
12 KiB
C++
#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<enum e_side> 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<RRSegmentId> get_chan_segment_ids(const e_side& side) const;
|
|
|
|
/* Get a list of segments used in this routing channel */
|
|
std::vector<RRNodeId> 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<size_t> 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<size_t> 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<size_t> get_side_block_coordinate(const e_side& side) const;
|
|
vtr::Point<size_t> 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<enum PORTS>& 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<size_t> coordinate_;
|
|
/* Routing channel data */
|
|
std::vector<RRChan> chan_node_;
|
|
std::vector<std::vector<PORTS>> chan_node_direction_;
|
|
|
|
/* Logic Block Inputs data */
|
|
std::vector<std::vector<RRNodeId>> ipin_node_;
|
|
|
|
/* Logic Block Outputs data */
|
|
std::vector<std::vector<RRNodeId>> opin_node_;
|
|
};
|
|
|
|
} /* End namespace openfpga*/
|
|
|
|
#endif
|