OpenFPGA/openfpga/src/annotation/rr_gsb.h

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