1
1
#include " vtr_log.h"
2
2
#include " vtr_memory.h"
3
+ #include " vtr_util.h"
3
4
4
- #include " vpr_types.h"
5
5
#include " vpr_error.h"
6
-
7
- #include " globals.h"
8
- #include " rr_graph.h"
9
6
#include " check_rr_graph.h"
10
7
8
+ #include " rr_node.h"
9
+ #include " physical_types_util.h"
10
+
11
+ #include " describe_rr_node.h"
12
+
11
13
/* ********************** Subroutines local to this module *******************/
12
14
13
- static bool rr_node_is_global_clb_ipin (RRNodeId inode);
15
+ static bool rr_node_is_global_clb_ipin (const RRGraphView& rr_graph, const DeviceGrid& grid, RRNodeId inode);
14
16
15
- static void check_unbuffered_edges (int from_node);
17
+ static void check_unbuffered_edges (const RRGraphView& rr_graph, int from_node);
16
18
17
- static bool has_adjacent_channel (const t_rr_node& node , const DeviceGrid& grid);
19
+ static bool has_adjacent_channel (const RRGraphView& rr_graph , const DeviceGrid& grid, const t_rr_node& node );
18
20
19
- static void check_rr_edge (int from_node, int from_edge, int to_node);
21
+ static void check_rr_edge (const RRGraphView& rr_graph, const DeviceGrid& grid, const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data, int from_node, int from_edge, int to_node);
20
22
21
23
/* *********************** Subroutine definitions ****************************/
22
24
@@ -39,17 +41,18 @@ class node_edge_sorter {
39
41
}
40
42
};
41
43
42
- void check_rr_graph (const t_graph_type graph_type,
44
+ void check_rr_graph (const RRGraphView& rr_graph,
45
+ const std::vector<t_physical_tile_type>& types,
46
+ const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
43
47
const DeviceGrid& grid,
44
- const std::vector<t_physical_tile_type>& types) {
48
+ const t_chan_width& chan_width,
49
+ const t_graph_type graph_type,
50
+ const int virtual_clock_network_root_idx) {
45
51
e_route_type route_type = DETAILED;
46
52
if (graph_type == GRAPH_GLOBAL) {
47
53
route_type = GLOBAL;
48
54
}
49
55
50
- auto & device_ctx = g_vpr_ctx.device ();
51
- const auto & rr_graph = device_ctx.rr_graph ;
52
-
53
56
auto total_edges_to_node = std::vector<int >(rr_graph.num_nodes ());
54
57
auto switch_types_from_current_to_node = std::vector<unsigned char >(rr_graph.num_nodes ());
55
58
const int num_rr_switches = rr_graph.num_rr_switches ();
@@ -66,14 +69,14 @@ void check_rr_graph(const t_graph_type graph_type,
66
69
}
67
70
68
71
// Virtual clock network sink is special, ignore.
69
- if (device_ctx. virtual_clock_network_root_idx == int (inode)) {
72
+ if (virtual_clock_network_root_idx == int (inode)) {
70
73
continue ;
71
74
}
72
75
73
76
t_rr_type rr_type = rr_graph.node_type (rr_node);
74
77
int num_edges = rr_graph.num_edges (RRNodeId (inode));
75
78
76
- check_rr_node (inode, route_type, device_ctx );
79
+ check_rr_node (rr_graph, rr_indexed_data, grid, chan_width, route_type, inode );
77
80
78
81
/* Check all the connectivity (edges, etc.) information. */
79
82
edges.resize (0 );
@@ -89,7 +92,7 @@ void check_rr_graph(const t_graph_type graph_type,
89
92
inode, to_node);
90
93
}
91
94
92
- check_rr_edge (inode, iedge, to_node);
95
+ check_rr_edge (rr_graph, grid, rr_indexed_data, inode, iedge, to_node);
93
96
94
97
edges.emplace_back (to_node, iedge);
95
98
total_edges_to_node[to_node]++;
@@ -181,7 +184,7 @@ void check_rr_graph(const t_graph_type graph_type,
181
184
}
182
185
183
186
/* Slow test could leave commented out most of the time. */
184
- check_unbuffered_edges (inode);
187
+ check_unbuffered_edges (rr_graph, inode);
185
188
186
189
// Check that all config/non-config edges are appropriately organized
187
190
for (auto edge : rr_graph.configurable_edges (RRNodeId (inode))) {
@@ -204,19 +207,19 @@ void check_rr_graph(const t_graph_type graph_type,
204
207
* now I check that everything is reachable. */
205
208
bool is_fringe_warning_sent = false ;
206
209
207
- for (const RRNodeId& rr_node : device_ctx. rr_graph .nodes ()) {
210
+ for (const RRNodeId& rr_node : rr_graph.nodes ()) {
208
211
size_t inode = (size_t )rr_node;
209
212
t_rr_type rr_type = rr_graph.node_type (rr_node);
210
213
211
214
if (rr_type != SOURCE) {
212
- if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin (rr_node)) {
215
+ if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin (rr_graph, grid, rr_node)) {
213
216
/* A global CLB input pin will not have any edges, and neither will *
214
217
* a SOURCE or the start of a carry-chain. Anything else is an error.
215
218
* For simplicity, carry-chain input pin are entirely ignored in this test
216
219
*/
217
220
bool is_chain = false ;
218
221
if (rr_type == IPIN) {
219
- t_physical_tile_type_ptr type = device_ctx. grid [rr_graph.node_xlow (rr_node)][rr_graph.node_ylow (rr_node)].type ;
222
+ t_physical_tile_type_ptr type = grid[rr_graph.node_xlow (rr_node)][rr_graph.node_ylow (rr_node)].type ;
220
223
for (const t_fc_specification& fc_spec : types[type->index ].fc_specs ) {
221
224
if (fc_spec.fc_value == 0 && fc_spec.seg_index == 0 ) {
222
225
is_chain = true ;
@@ -235,8 +238,8 @@ void check_rr_graph(const t_graph_type graph_type,
235
238
236
239
if (!is_chain && !is_fringe && !is_wire) {
237
240
if (rr_graph.node_type (rr_node) == IPIN || rr_graph.node_type (rr_node) == OPIN) {
238
- if (has_adjacent_channel (node, device_ctx. grid )) {
239
- auto block_type = device_ctx. grid [rr_graph.node_xlow (rr_node)][rr_graph.node_ylow (rr_node)].type ;
241
+ if (has_adjacent_channel (rr_graph, grid, node )) {
242
+ auto block_type = grid[rr_graph.node_xlow (rr_node)][rr_graph.node_ylow (rr_node)].type ;
240
243
std::string pin_name = block_type_pin_index_to_name (block_type, rr_graph.node_pin_num (rr_node));
241
244
/* Print error messages for all the sides that a node may appear */
242
245
for (const e_side& node_side : SIDES) {
@@ -268,16 +271,13 @@ void check_rr_graph(const t_graph_type graph_type,
268
271
}
269
272
}
270
273
271
- static bool rr_node_is_global_clb_ipin (RRNodeId inode) {
274
+ static bool rr_node_is_global_clb_ipin (const RRGraphView& rr_graph, const DeviceGrid& grid, RRNodeId inode) {
272
275
/* Returns true if inode refers to a global CLB input pin node. */
273
276
274
277
int ipin;
275
278
t_physical_tile_type_ptr type;
276
279
277
- auto & device_ctx = g_vpr_ctx.device ();
278
- const auto & rr_graph = device_ctx.rr_graph ;
279
-
280
- type = device_ctx.grid [rr_graph.node_xlow (inode)][rr_graph.node_ylow (inode)].type ;
280
+ type = grid[rr_graph.node_xlow (inode)][rr_graph.node_ylow (inode)].type ;
281
281
282
282
if (rr_graph.node_type (inode) != IPIN)
283
283
return (false );
@@ -287,7 +287,12 @@ static bool rr_node_is_global_clb_ipin(RRNodeId inode) {
287
287
return type->is_ignored_pin [ipin];
288
288
}
289
289
290
- void check_rr_node (int inode, enum e_route_type route_type, const DeviceContext& device_ctx) {
290
+ void check_rr_node (const RRGraphView& rr_graph,
291
+ const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
292
+ const DeviceGrid& grid,
293
+ const t_chan_width& chan_width,
294
+ const enum e_route_type route_type,
295
+ const int inode) {
291
296
/* This routine checks that the rr_node is inside the grid and has a valid
292
297
* pin number, etc.
293
298
*/
@@ -298,7 +303,6 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
298
303
int nodes_per_chan, tracks_per_node, num_edges;
299
304
RRIndexedDataId cost_index;
300
305
float C, R;
301
- const auto & rr_graph = device_ctx.rr_graph ;
302
306
RRNodeId rr_node = RRNodeId (inode);
303
307
304
308
rr_type = rr_graph.node_type (rr_node);
@@ -311,7 +315,6 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
311
315
cost_index = rr_graph.node_cost_index (rr_node);
312
316
type = nullptr ;
313
317
314
- const auto & grid = device_ctx.grid ;
315
318
if (xlow > xhigh || ylow > yhigh) {
316
319
VPR_ERROR (VPR_ERROR_ROUTE,
317
320
" in check_rr_node: rr endpoints are (%d,%d) and (%d,%d).\n " , xlow, ylow, xhigh, yhigh);
@@ -327,13 +330,13 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
327
330
" in check_rr_node: inode %d (type %d) had a ptc_num of %d.\n " , inode, rr_type, ptc_num);
328
331
}
329
332
330
- if (!cost_index || (size_t )cost_index >= (size_t )device_ctx. rr_indexed_data .size ()) {
333
+ if (!cost_index || (size_t )cost_index >= (size_t )rr_indexed_data.size ()) {
331
334
VPR_FATAL_ERROR (VPR_ERROR_ROUTE,
332
335
" in check_rr_node: node %d cost index (%d) is out of range.\n " , inode, cost_index);
333
336
}
334
337
335
338
/* Check that the segment is within the array and such. */
336
- type = device_ctx. grid [xlow][ylow].type ;
339
+ type = grid[xlow][ylow].type ;
337
340
338
341
switch (rr_type) {
339
342
case SOURCE:
@@ -439,11 +442,11 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
439
442
440
443
case CHANX:
441
444
if (route_type == DETAILED) {
442
- nodes_per_chan = device_ctx. chan_width .max ;
445
+ nodes_per_chan = chan_width.max ;
443
446
tracks_per_node = 1 ;
444
447
} else {
445
448
nodes_per_chan = 1 ;
446
- tracks_per_node = device_ctx. chan_width .x_list [ylow];
449
+ tracks_per_node = chan_width.x_list [ylow];
447
450
}
448
451
449
452
if (ptc_num >= nodes_per_chan) {
@@ -459,11 +462,11 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
459
462
460
463
case CHANY:
461
464
if (route_type == DETAILED) {
462
- nodes_per_chan = device_ctx. chan_width .max ;
465
+ nodes_per_chan = chan_width.max ;
463
466
tracks_per_node = 1 ;
464
467
} else {
465
468
nodes_per_chan = 1 ;
466
- tracks_per_node = device_ctx. chan_width .y_list [xlow];
469
+ tracks_per_node = chan_width.y_list [xlow];
467
470
}
468
471
469
472
if (ptc_num >= nodes_per_chan) {
@@ -494,13 +497,13 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
494
497
// Don't worry about disconnect PINs which have no adjacent channels (i.e. on the device perimeter)
495
498
bool check_for_out_edges = true ;
496
499
if (rr_type == IPIN || rr_type == OPIN) {
497
- if (!has_adjacent_channel (rr_graph.rr_nodes ()[inode], device_ctx. grid )) {
500
+ if (!has_adjacent_channel (rr_graph, grid, rr_graph .rr_nodes ()[inode])) {
498
501
check_for_out_edges = false ;
499
502
}
500
503
}
501
504
502
505
if (check_for_out_edges) {
503
- std::string info = describe_rr_node (inode);
506
+ std::string info = describe_rr_node (rr_graph, grid, rr_indexed_data, inode);
504
507
VTR_LOG_WARN (" in check_rr_node: %s has no out-going edges.\n " , info.c_str ());
505
508
}
506
509
}
@@ -528,7 +531,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
528
531
}
529
532
}
530
533
531
- static void check_unbuffered_edges (int from_node) {
534
+ static void check_unbuffered_edges (const RRGraphView& rr_graph, int from_node) {
532
535
/* This routine checks that all pass transistors in the routing truly are *
533
536
* bidirectional. It may be a slow check, so don't use it all the time. */
534
537
@@ -537,9 +540,6 @@ static void check_unbuffered_edges(int from_node) {
537
540
short from_switch_type;
538
541
bool trans_matched;
539
542
540
- auto & device_ctx = g_vpr_ctx.device ();
541
- const auto & rr_graph = device_ctx.rr_graph ;
542
-
543
543
from_rr_type = rr_graph.node_type (RRNodeId (from_node));
544
544
if (from_rr_type != CHANX && from_rr_type != CHANY)
545
545
return ;
@@ -584,11 +584,10 @@ static void check_unbuffered_edges(int from_node) {
584
584
} /* End for all from_node edges */
585
585
}
586
586
587
- static bool has_adjacent_channel (const t_rr_node& node , const DeviceGrid& grid) {
587
+ static bool has_adjacent_channel (const RRGraphView& rr_graph , const DeviceGrid& grid, const t_rr_node& node ) {
588
588
/* TODO: this function should be reworked later to adapt RRGraphView interface
589
589
* once xlow(), ylow(), side() APIs are implemented
590
590
*/
591
- const auto & rr_graph = g_vpr_ctx.device ().rr_graph ;
592
591
VTR_ASSERT (rr_graph.node_type (node.id ()) == IPIN || rr_graph.node_type (node.id ()) == OPIN);
593
592
594
593
if ((rr_graph.node_xlow (node.id ()) == 0 && !rr_graph.is_node_on_specific_side (node.id (), RIGHT)) // left device edge connects only along block's right side
@@ -601,9 +600,7 @@ static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid)
601
600
return true ; // All other blocks will be surrounded on all sides by channels
602
601
}
603
602
604
- static void check_rr_edge (int from_node, int iedge, int to_node) {
605
- auto & device_ctx = g_vpr_ctx.device ();
606
- const auto & rr_graph = device_ctx.rr_graph ;
603
+ static void check_rr_edge (const RRGraphView& rr_graph, const DeviceGrid& grid, const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data, int from_node, int iedge, int to_node) {
607
604
608
605
// Check that to to_node's fan-in is correct, given the switch type
609
606
int iswitch = rr_graph.edge_switch (RRNodeId (from_node), iedge);
@@ -617,7 +614,7 @@ static void check_rr_edge(int from_node, int iedge, int to_node) {
617
614
std::string msg = " Non-configurable BUFFER type switch must have only one driver. " ;
618
615
msg += vtr::string_fmt (" Actual fan-in was %d (expected 1).\n " , to_fanin);
619
616
msg += " Possible cause is complex block output pins connecting to:\n " ;
620
- msg += " " + describe_rr_node (to_node);
617
+ msg += " " + describe_rr_node (rr_graph, grid, rr_indexed_data, to_node);
621
618
622
619
VPR_FATAL_ERROR (VPR_ERROR_ROUTE, msg.c_str ());
623
620
}
0 commit comments