@@ -27,6 +27,7 @@ RRGSB::RRGSB() {
27
27
ipin_node_.clear ();
28
28
29
29
opin_node_.clear ();
30
+ cb_opin_node_.clear ();
30
31
}
31
32
32
33
/* ***********************************************************************
@@ -97,6 +98,31 @@ std::vector<enum e_side> RRGSB::get_cb_ipin_sides(const t_rr_type& cb_type) cons
97
98
return ipin_sides;
98
99
}
99
100
101
+ /* Get the sides of ipin_nodes belong to the cb */
102
+ std::vector<enum e_side> RRGSB::get_cb_opin_sides (const t_rr_type& cb_type) const {
103
+ VTR_ASSERT (validate_cb_type (cb_type));
104
+
105
+ std::vector<enum e_side> opin_sides;
106
+
107
+ /* Make sure a clean start */
108
+ opin_sides.clear ();
109
+
110
+ switch (cb_type) {
111
+ case CHANX:
112
+ case CHANY:
113
+ opin_sides.push_back (TOP);
114
+ opin_sides.push_back (RIGHT);
115
+ opin_sides.push_back (BOTTOM);
116
+ opin_sides.push_back (LEFT);
117
+ break ;
118
+ default :
119
+ VTR_LOG (" Invalid type of connection block!\n " );
120
+ exit (1 );
121
+ }
122
+
123
+ return opin_sides;
124
+ }
125
+
100
126
/* Get the direction of a rr_node at a given side and track_id */
101
127
enum PORTS RRGSB::get_chan_node_direction (const e_side& side, const size_t & track_id) const {
102
128
SideManager side_manager (side);
@@ -257,6 +283,29 @@ RRNodeId RRGSB::get_opin_node(const e_side& side, const size_t& node_id) const {
257
283
return opin_node_[side_manager.to_size_t ()][node_id];
258
284
}
259
285
286
+ /* Get the number of OPIN rr_nodes on a side */
287
+ size_t RRGSB::get_num_cb_opin_nodes (const t_rr_type& cb_type, const e_side& side) const {
288
+ SideManager side_manager (side);
289
+ VTR_ASSERT (side_manager.validate ());
290
+ size_t icb_type = get_cb_opin_type_id (cb_type);
291
+ return cb_opin_node_[icb_type][side_manager.to_size_t ()].size ();
292
+ }
293
+
294
+ /* get a opin_node at a given side and track_id */
295
+ RRNodeId RRGSB::get_cb_opin_node (const t_rr_type& cb_type, const e_side& side, const size_t & node_id) const {
296
+ SideManager side_manager (side);
297
+ VTR_ASSERT (side_manager.validate ());
298
+
299
+ /* Ensure the side is valid in the context of this switch block */
300
+ VTR_ASSERT (validate_side (side));
301
+
302
+ /* Ensure the track is valid in the context of this switch block at a specific side */
303
+ VTR_ASSERT (validate_cb_opin_node_id (cb_type, side, node_id));
304
+
305
+ size_t icb_type = get_cb_opin_type_id (cb_type);
306
+ return cb_opin_node_[icb_type][side_manager.to_size_t ()][node_id];
307
+ }
308
+
260
309
/* Get the node index of a routing track of a connection block, return -1 if not found */
261
310
int RRGSB::get_cb_chan_node_index (const t_rr_type& cb_type, const RRNodeId& node) const {
262
311
enum e_side chan_side = get_cb_chan_side (cb_type);
@@ -921,6 +970,37 @@ void RRGSB::sort_ipin_node_in_edges(const RRGraphView& rr_graph) {
921
970
}
922
971
}
923
972
973
+ void RRGSB::build_cb_opin_nodes (const RRGraphView& rr_graph) {
974
+ for (t_rr_type cb_type : {CHANX, CHANY}) {
975
+ size_t icb_type = cb_type == CHANX ? 0 : 1 ;
976
+ std::vector<enum e_side> cb_opin_sides = rr_gsb.get_cb_ipin_sides (cb_type);
977
+ for (size_t iside = 0 ; iside < cb_ipin_sides.size (); ++iside) {
978
+ enum e_side cb_ipin_side = cb_ipin_sides[iside];
979
+ for (size_t inode = 0 ; inode < rr_gsb.get_num_ipin_nodes (cb_ipin_side);
980
+ ++inode) {
981
+ std::vector<RREdgeId> driver_rr_edges =
982
+ get_ipin_node_in_edges (rr_graph, cb_ipin_side, inode);
983
+ for (const RREdgeId curr_edge : driver_rr_edges) {
984
+ RRNodeId cand_node = rr_graph.edge_src_node (curr_edge);
985
+ if (OPIN != rr_graph.node_type (cand_node)) {
986
+ continue ;
987
+ }
988
+ enum e_side cb_opin_side = NUM_SIDES;
989
+ int cb_opin_index = -1 ;
990
+ rr_gsb.get_node_side_and_index (rr_graph, cand_node, IN_PORT, cb_opin_side,
991
+ cb_opin_index);
992
+ VTR_ASSERT ((-1 != cb_opin_index) && (NUM_SIDES != cb_opin_side));
993
+
994
+ if (cb_opin_node_[icb_type][size_t (cb_opin_side)].end () ==
995
+ std::find (cb_opin_node_[icb_type][size_t (cb_opin_side)].begin (), cb_opin_node_[icb_type][size_t (cb_opin_side)].end (), cand_node)) {
996
+ cb_opin_node_[icb_type][size_t (cb_opin_side)] = cand_node;
997
+ }
998
+ }
999
+ }
1000
+ }
1001
+ }
1002
+ }
1003
+
924
1004
/* ***********************************************************************
925
1005
* Public Mutators: clean-up functions
926
1006
***********************************************************************/
@@ -1031,6 +1111,15 @@ bool RRGSB::validate_opin_node_id(const e_side& side, const size_t& node_id) con
1031
1111
return (node_id < opin_node_[size_t (side)].size ());
1032
1112
}
1033
1113
1114
+ /* Check the opin_node_id is valid for opin_node_ and opin_node_grid_side_ */
1115
+ bool RRGSB::validate_cb_opin_node_id (const t_rr_type& cb_type, const e_side& side, const size_t & node_id) const {
1116
+ if (false == validate_side (side)) {
1117
+ return false ;
1118
+ }
1119
+ size_t icb_type = get_cb_opin_type_id (cb_type);
1120
+ return (node_id < cb_opin_node_[icb_type][size_t (side)].size ());
1121
+ }
1122
+
1034
1123
/* Check the ipin_node_id is valid for opin_node_ and opin_node_grid_side_ */
1035
1124
bool RRGSB::validate_ipin_node_id (const e_side& side, const size_t & node_id) const {
1036
1125
if (false == validate_side (side)) {
@@ -1042,3 +1131,9 @@ bool RRGSB::validate_ipin_node_id(const e_side& side, const size_t& node_id) con
1042
1131
bool RRGSB::validate_cb_type (const t_rr_type& cb_type) const {
1043
1132
return ((CHANX == cb_type) || (CHANY == cb_type));
1044
1133
}
1134
+
1135
+ size_t RRGSB::get_cb_opin_type_id (const t_rr_type& cb_type) const {
1136
+ VTR_ASSERT (validate_cb_type (cb_type));
1137
+ return cb_type == CHANX ? 0 : 1 ;
1138
+ }
1139
+
0 commit comments