put rr_gsb data structure online

This commit is contained in:
tangxifan 2020-02-09 00:20:44 -07:00
parent 0b6b3bc029
commit 230c7b709a
4 changed files with 1251 additions and 119 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,9 @@
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_geometry.h"
#include "rr_chan.h"
/* Begin namespace openfpga */
@ -15,7 +18,6 @@ namespace openfpga {
* 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
* This is a collection of rr_nodes, which may be replaced with RRNodeId in new RRGraph
*
* +---------------------------------+
* | Y-direction CB |
@ -53,141 +55,176 @@ class RRGSB {
RRGSB(const RRGSB&);/* Copy constructor */
RRGSB();/* Default constructor */
public: /* Accessors */
size_t get_num_sides() const; /* Get the number of sides of this SB */
size_t get_chan_width(enum e_side side) const; /* Get the number of routing tracks on a side */
size_t get_cb_chan_width(t_rr_type cb_type) const; /* Get the number of routing tracks of a X/Y-direction CB */
std::vector<enum e_side> get_cb_ipin_sides(t_rr_type cb_type) const; /* Get the sides of CB ipins in the array */
size_t get_max_chan_width() const; /* Get the maximum number of routing tracks on all sides */
enum PORTS get_chan_node_direction(enum e_side side, size_t track_id) const; /* Get the direction of a rr_node at a given side and track_id */
RRChan get_chan(enum e_side side) const; /* get a rr_node at a given side and track_id */
std::vector<size_t> get_chan_segment_ids(enum e_side side) const; /* Get a list of segments used in this routing channel */
std::vector<size_t> get_chan_node_ids_by_segment_ids(enum e_side side, size_t seg_id) const; /* Get a list of segments used in this routing channel */
t_rr_node* get_chan_node(enum e_side side, size_t track_id) const; /* get a rr_node at a given side and track_id */
size_t get_chan_node_segment(enum e_side side, size_t track_id) const; /* get the segment id of a channel rr_node */
size_t get_num_ipin_nodes(enum e_side side) const; /* Get the number of IPIN rr_nodes on a side */
t_rr_node* get_ipin_node(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_ipin_node_grid_side(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_ipin_node_grid_side(t_rr_node* ipin_node) const; /* get a rr_node at a given side and track_id */
size_t get_num_opin_nodes(enum e_side side) const; /* Get the number of OPIN rr_nodes on a side */
t_rr_node* get_opin_node(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_opin_node_grid_side(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_opin_node_grid_side(t_rr_node* opin_node) const; /* get a rr_node at a given side and track_id */
int get_cb_chan_node_index(t_rr_type cb_type, t_rr_node* node) const;
int get_chan_node_index(enum e_side node_side, t_rr_node* node) const;
int get_node_index(t_rr_node* node, enum e_side node_side, enum PORTS node_direction) const; /* Get the node index in the array, return -1 if not found */
void get_node_side_and_index(t_rr_node* node, enum PORTS node_direction, enum e_side* node_side, int* node_index) const; /* Given a rr_node, try to find its side and index in the Switch block */
bool is_sb_node_exist_opposite_side(t_rr_node* node, enum e_side node_side) const; /* Check if the node exist in the opposite side of this Switch Block */
public: /* Accessors: get information about configuration ports */
size_t get_sb_num_reserved_conf_bits() const;
size_t get_sb_reserved_conf_bits_lsb() const;
size_t get_sb_reserved_conf_bits_msb() const;
size_t get_sb_num_conf_bits() const;
size_t get_sb_conf_bits_lsb() const;
size_t get_sb_conf_bits_msb() const;
size_t get_cb_num_reserved_conf_bits(t_rr_type cb_type) const;
size_t get_cb_reserved_conf_bits_lsb(t_rr_type cb_type) const;
size_t get_cb_reserved_conf_bits_msb(t_rr_type cb_type) const;
size_t get_cb_num_conf_bits(t_rr_type cb_type) const;
size_t get_cb_conf_bits_lsb(t_rr_type cb_type) const;
size_t get_cb_conf_bits_msb(t_rr_type cb_type) const;
bool is_sb_node_passing_wire(const enum e_side node_side, const size_t track_id) const; /* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */
bool is_sb_side_mirror(const RRGSB& cand, enum e_side side) const; /* check if a side of candidate SB is a mirror of the current one */
bool is_sb_side_segment_mirror(const RRGSB& cand, enum e_side side, size_t seg_id) const; /* check if all the routing segments of a side of candidate SB is a mirror of the current one */
bool is_sb_mirror(const RRGSB& cand) const; /* check if the candidate SB is a mirror of the current one */
bool is_sb_mirrorable(const RRGSB& cand) const; /* check if the candidate SB satisfy the basic requirements on being a mirror of the current one */
bool is_cb_mirror(const RRGSB& cand, t_rr_type cb_type) const; /* check if the candidate SB is a mirror of the current one */
bool is_cb_exist(t_rr_type cb_type) const; /* check if the candidate SB is a mirror of the current one */
size_t get_hint_rotate_offset(const RRGSB& cand) const; /* Determine an initial offset in rotating the candidate Switch Block to find a mirror matching*/
/* 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 candidate SB is a mirror of the current one */
bool is_cb_exist(const t_rr_type& cb_type) 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 coordinator of this switch block */
size_t get_y() const; /* get the y coordinator of this switch block */
size_t get_sb_x() const; /* get the x coordinator of this switch block */
size_t get_sb_y() const; /* get the y coordinator of this switch block */
DeviceCoordinator get_sb_coordinator() const; /* Get the coordinator of the SB */
size_t get_cb_x(t_rr_type cb_type) const; /* get the x coordinator of this X/Y-direction block */
size_t get_cb_y(t_rr_type cb_type) const; /* get the y coordinator of this X/Y-direction block */
DeviceCoordinator get_cb_coordinator(t_rr_type cb_type) const; /* Get the coordinator of the X/Y-direction CB */
enum e_side get_cb_chan_side(t_rr_type cb_type) const; /* get the side of a Connection block */
enum e_side get_cb_chan_side(enum e_side ipin_side) const; /* get the side of a Connection block */
DeviceCoordinator get_side_block_coordinator(enum e_side side) const;
DeviceCoordinator get_grid_coordinator() const;
public: /* Verilog writer */
const char* gen_gsb_verilog_module_name() const;
const char* gen_gsb_verilog_instance_name() const;
const char* gen_sb_verilog_module_name() const;
const char* gen_sb_verilog_instance_name() const;
const char* gen_sb_verilog_side_module_name(enum e_side side, size_t seg_id) const;
const char* gen_sb_verilog_side_instance_name(enum e_side side, size_t seg_id) const;
const char* gen_cb_verilog_module_name(t_rr_type cb_type) const;
const char* gen_cb_verilog_instance_name(t_rr_type cb_type) const;
const char* gen_cb_verilog_routing_track_name(t_rr_type cb_type, size_t track_id) const;
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_coordinator(size_t x, size_t y);
void init_num_sides(size_t num_sides); /* Allocate the vectors with the given number of sides */
void add_chan_node(enum e_side node_side, RRChan& rr_chan, 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(t_rr_node* node, const enum e_side node_side, const enum e_side grid_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
void add_opin_node(t_rr_node* node, const enum e_side node_side, const enum e_side grid_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
void set_sb_num_reserved_conf_bits(size_t num_reserved_conf_bits);
void set_sb_conf_bits_lsb(size_t conf_bits_lsb);
void set_sb_conf_bits_msb(size_t conf_bits_msb);
void set_cb_num_reserved_conf_bits(t_rr_type cb_type, size_t num_reserved_conf_bits);
void set_cb_conf_bits_lsb(t_rr_type cb_type, size_t conf_bits_lsb);
void set_cb_conf_bits_msb(t_rr_type cb_type, size_t conf_bits_msb);
void rotate_side_chan_node_by_direction(enum e_side side, enum e_direction chan_dir, size_t offset); /* rotate all the channel nodes by a given offset */
void counter_rotate_side_chan_node_by_direction(enum e_side side, enum e_direction chan_dir, size_t offset); /* rotate all the channel nodes by a given offset */
void rotate_side_chan_node(enum e_side side, size_t offset); /* rotate all the channel nodes by a given offset */
void rotate_chan_node(size_t offset); /* rotate all the channel nodes by a given offset */
void rotate_chan_node_in_group(size_t offset); /* rotate all the channel nodes by a given offset */
void rotate_side_opin_node_in_group(enum e_side side, size_t offset); /* rotate all the opin nodes by a given offset */
void rotate_opin_node_in_group(size_t offset); /* rotate all the opin nodes by a given offset */
void rotate_side(enum e_side side, size_t offset); /* rotate all the channel and opin nodes by a given offset */
void rotate(size_t offset); /* rotate all the channel and opin nodes by a given offset */
void swap_chan_node(enum e_side src_side, enum e_side des_side); /* swap the chan rr_nodes on two sides */
void swap_opin_node(enum e_side src_side, enum e_side des_side); /* swap the OPIN rr_nodes on two sides */
void swap_ipin_node(enum e_side src_side, enum e_side des_side); /* swap the IPIN rr_nodes on two sides */
void reverse_opin_node(enum e_side side); /* reverse the OPIN rr_nodes on two sides */
void reverse_ipin_node(enum e_side side); /* reverse the IPIN rr_nodes on two sides */
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();
void clear_chan_nodes(enum e_side node_side); /* Clean the chan_width of a side */
void clear_ipin_nodes(enum e_side node_side); /* Clean the number of IPINs of a side */
void clear_opin_nodes(enum e_side node_side); /* Clean the number of OPINs of a side */
void clear_one_side(enum e_side node_side); /* Clean chan/opin/ipin nodes at one side */
private: /* Internal Mutators */
void mirror_side_chan_node_direction(enum e_side side); /* Mirror the node direction and port direction of routing track nodes on a side */
/* 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 RRGSB& cand, enum e_side node_side, size_t track_id) const;
bool is_cb_node_mirror (const RRGSB& cand, t_rr_type cb_type, enum e_side node_side, size_t node_id) const;
size_t get_track_id_first_short_connection(enum e_side node_side) const;
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(enum e_side side) const;
bool validate_track_id(enum e_side side, size_t track_id) const;
bool validate_opin_node_id(enum e_side side, size_t node_id) const;
bool validate_ipin_node_id(enum e_side side, size_t node_id) const;
bool validate_cb_type(t_rr_type cb_type) 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 */
DeviceCoordinator coordinator_;
vtr::Point<size_t> coordinate_;
/* Routing channel data */
std::vector<RRChan> chan_node_;
std::vector< std::vector<enum PORTS> > chan_node_direction_;
std::vector<std::vector<PORTS>> chan_node_direction_;
/* Logic Block Inputs data */
std::vector< std::vector<t_rr_node*> > ipin_node_;
std::vector< std::vector<enum e_side> > ipin_node_grid_side_;
std::vector<std::vector<RRNodeId>> ipin_node_;
/* Logic Block Outputs data */
std::vector< std::vector<t_rr_node*> > opin_node_;
std::vector< std::vector<enum e_side> > opin_node_grid_side_;
/* Configuration bits */
ConfPorts sb_conf_port_;
ConfPorts cbx_conf_port_;
ConfPorts cby_conf_port_;
std::vector<std::vector<RRNodeId>> opin_node_;
};
} /* End namespace openfpga*/
#endif

View File

@ -0,0 +1,66 @@
/********************************************************************
* This file includes most utilized functions for the rr_graph
* data structure in the OpenFPGA context
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "openfpga_rr_graph_utils.h"
/* begin namespace openfpga */
namespace openfpga {
/************************************************************************
* Get the coordinator of a starting point of a routing track
* For routing tracks in INC_DIRECTION
* (xlow, ylow) should be the starting point
*
* For routing tracks in DEC_DIRECTION
* (xhigh, yhigh) should be the starting point
***********************************************************************/
vtr::Point<size_t> get_track_rr_node_start_coordinate(const RRGraph& rr_graph,
const RRNodeId& track_rr_node) {
/* Make sure we have CHANX or CHANY */
VTR_ASSERT( (CHANX == rr_graph.node_type(track_rr_node))
|| (CHANY == rr_graph.node_type(track_rr_node)) );
vtr::Point<size_t> start_coordinator;
if (INC_DIRECTION == rr_graph.node_direction(track_rr_node)) {
start_coordinator.set(rr_graph.node_xlow(track_rr_node), rr_graph.node_ylow(track_rr_node));
} else {
VTR_ASSERT(DEC_DIRECTION == rr_graph.node_direction(track_rr_node));
start_coordinator.set(rr_graph.node_xhigh(track_rr_node), rr_graph.node_yhigh(track_rr_node));
}
return start_coordinator;
}
/************************************************************************
* Get the coordinator of a end point of a routing track
* For routing tracks in INC_DIRECTION
* (xhigh, yhigh) should be the starting point
*
* For routing tracks in DEC_DIRECTION
* (xlow, ylow) should be the starting point
***********************************************************************/
vtr::Point<size_t> get_track_rr_node_end_coordinate(const RRGraph& rr_graph,
const RRNodeId& track_rr_node) {
/* Make sure we have CHANX or CHANY */
VTR_ASSERT( (CHANX == rr_graph.node_type(track_rr_node))
|| (CHANY == rr_graph.node_type(track_rr_node)) );
vtr::Point<size_t> end_coordinator;
if (INC_DIRECTION == rr_graph.node_direction(track_rr_node)) {
end_coordinator.set(rr_graph.node_xhigh(track_rr_node), rr_graph.node_yhigh(track_rr_node));
} else {
VTR_ASSERT(DEC_DIRECTION == rr_graph.node_direction(track_rr_node));
end_coordinator.set(rr_graph.node_xlow(track_rr_node), rr_graph.node_ylow(track_rr_node));
}
return end_coordinator;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,28 @@
#ifndef OPENFPGA_RR_GRAPH_UTILS_H
#define OPENFPGA_RR_GRAPH_UTILS_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_geometry.h"
/* Headers from vpr library */
#include "rr_graph_obj.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
vtr::Point<size_t> get_track_rr_node_start_coordinate(const RRGraph& rr_graph,
const RRNodeId& track_rr_node);
vtr::Point<size_t> get_track_rr_node_end_coordinate(const RRGraph& rr_graph,
const RRNodeId& track_rr_node);
} /* end namespace openfpga */
#endif