11 #define BUF_AND_PTRANS_FLAG 3
22 INP int L_nx,
INP int L_ny,
INP int nodes_per_chan,
INP int Fs,
23 INP int num_seg_types,
INP int num_switches,
25 INP int delayless_switch,
INP int wire_to_ipin_switch,
27 int *****opin_to_track_map,
int *****ipin_to_track_map,
28 t_ivec **** track_to_ipin_lookup,
t_ivec *** switch_block_conn,
29 boolean * perturb_ipins) {
31 int *num_edges_from_current_to_node;
32 int *total_edges_to_node;
33 char *switch_types_from_current_to_node;
34 int inode, iedge, to_node, num_edges;
38 boolean is_fringe_warning_sent;
60 for (iedge = 0; iedge < num_edges; iedge++) {
63 if (to_node < 0 || to_node >= num_rr_nodes) {
64 vpr_printf(TIO_MESSAGE_ERROR,
"in check_rr_graph: node %d has an edge %d.\n", inode, to_node);
65 vpr_printf(TIO_MESSAGE_ERROR,
"\tEdge is out of range.\n");
69 num_edges_from_current_to_node[to_node]++;
70 total_edges_to_node[to_node]++;
74 if (switch_type < 0 || switch_type >= num_switches) {
75 vpr_printf(TIO_MESSAGE_ERROR,
"in check_rr_graph: node %d has a switch type %d.\n", inode, switch_type);
76 vpr_printf(TIO_MESSAGE_ERROR,
"\tSwitch type is out of range.\n");
81 switch_types_from_current_to_node[to_node] |=
BUF_FLAG;
83 switch_types_from_current_to_node[to_node] |=
PTRANS_FLAG;
87 for (iedge = 0; iedge < num_edges; iedge++) {
90 if (num_edges_from_current_to_node[to_node] > 1) {
93 if ((to_rr_type !=
CHANX && to_rr_type !=
CHANY)
95 vpr_printf(TIO_MESSAGE_ERROR,
"in check_rr_graph: node %d connects to node %d %d times.\n",
96 inode, to_node, num_edges_from_current_to_node[to_node]);
103 else if (num_edges_from_current_to_node[to_node] != 2
105 vpr_printf(TIO_MESSAGE_ERROR,
"in check_rr_graph: node %d connects to node %d %d times.\n",
106 inode, to_node, num_edges_from_current_to_node[to_node]);
111 num_edges_from_current_to_node[to_node] = 0;
112 switch_types_from_current_to_node[to_node] = 0;
125 is_fringe_warning_sent =
FALSE;
131 if (total_edges_to_node[inode] < 1
135 boolean is_chain =
FALSE;
142 if(rr_type ==
IPIN) {
151 || (
rr_node[inode].xhigh == L_nx)
156 if (!is_chain && !is_fringe && !is_wire) {
157 vpr_printf(TIO_MESSAGE_ERROR,
"in check_rr_graph: node %d has no fanin.\n", inode);
159 }
else if (!is_chain && !is_fringe_warning_sent) {
160 vpr_printf(TIO_MESSAGE_WARNING,
"in check_rr_graph: fringe node %d has no fanin.\n", inode);
161 vpr_printf(TIO_MESSAGE_WARNING,
"\tThis is possible on the fringe for low Fc_out, N, and certain Lengths\n");
162 is_fringe_warning_sent =
TRUE;
168 if (total_edges_to_node[inode] != 0) {
169 vpr_printf(TIO_MESSAGE_ERROR,
"in check_rr_graph: SOURCE node %d has a fanin of %d, expected 0.\n",
170 inode, total_edges_to_node[inode]);
176 free(num_edges_from_current_to_node);
177 free(total_edges_to_node);
178 free(switch_types_from_current_to_node);
204 int xlow, ylow, xhigh, yhigh, ptc_num, capacity;
207 int nodes_per_chan, tracks_per_node, num_edges, cost_index;
219 if (xlow > xhigh || ylow > yhigh) {
220 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: rr endpoints are (%d,%d) and (%d,%d).\n",
221 xlow, ylow, xhigh, yhigh);
225 if (xlow < 0 || xhigh >
nx + 1 || ylow < 0 || yhigh >
ny + 1) {
226 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: rr endpoints (%d,%d) and (%d,%d) are out of range.\n",
227 xlow, ylow, xhigh, yhigh);
232 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) had a ptc_num of %d.\n",
233 inode, rr_type, ptc_num);
249 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d (type %d) is at an illegal clb location (%d, %d).\n",
250 inode, rr_type, xlow, ylow);
253 if (xlow != xhigh || ylow != (yhigh - type->
height + 1)) {
254 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d (type %d) has endpoints (%d,%d) and (%d,%d)\n",
255 inode, rr_type, xlow, ylow, xhigh, yhigh);
261 if (xlow < 1 || xhigh >
nx || yhigh >
ny || yhigh != ylow) {
262 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: CHANX out of range for endpoints (%d,%d) and (%d,%d)\n",
263 xlow, ylow, xhigh, yhigh);
266 if (route_type ==
GLOBAL && xlow != xhigh) {
267 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d spans multiple channel segments (not allowed for global routing).\n",
274 if (xhigh >
nx || ylow < 1 || yhigh >
ny || xlow != xhigh) {
275 vpr_printf(TIO_MESSAGE_ERROR,
"Error in check_node: CHANY out of range for endpoints (%d,%d) and (%d,%d)\n",
276 xlow, ylow, xhigh, yhigh);
279 if (route_type ==
GLOBAL && ylow != yhigh) {
280 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d spans multiple channel segments (not allowed for global routing).\n",
287 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: Unexpected segment type: %d\n", rr_type);
299 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) had a ptc_num of %d.\n",
300 inode, rr_type, ptc_num);
304 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) had a capacity of %d.\n",
305 inode, rr_type, capacity);
315 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) had a ptc_num of %d.\n",
316 inode, rr_type, ptc_num);
320 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a capacity of %d.\n",
321 inode, rr_type, capacity);
330 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) had a ptc_num of %d.\n",
331 inode, rr_type, ptc_num);
336 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a capacity of %d.\n",
337 inode, rr_type, capacity);
345 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) had a ptc_num of %d.\n",
346 inode, rr_type, ptc_num);
350 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a capacity of %d.\n",
351 inode, rr_type, capacity);
365 if (ptc_num >= nodes_per_chan) {
366 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a ptc_num of %d.\n",
367 inode, rr_type, ptc_num);
371 if (capacity != tracks_per_node) {
372 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a capacity of %d.\n",
373 inode, rr_type, capacity);
387 if (ptc_num >= nodes_per_chan) {
388 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a ptc_num of %d.\n",
389 inode, rr_type, ptc_num);
393 if (capacity != tracks_per_node) {
394 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: inode %d (type %d) has a capacity of %d.\n",
395 inode, rr_type, capacity);
401 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: Unexpected segment type: %d\n", rr_type);
409 if (rr_type !=
SINK && rr_type !=
IPIN) {
410 if (num_edges <= 0) {
414 vpr_printf(TIO_MESSAGE_WARNING,
"in check_node: node %d has no edges.\n", inode);
418 else if (rr_type ==
SINK) {
419 if (num_edges != 0) {
420 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d is a sink, but has %d edges.\n",
432 if (C < 0. || R < 0.) {
433 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d of type %d has R = %g and C = %g.\n",
434 inode, rr_type, R, C);
440 if (C != 0. || R != 0.) {
441 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d of type %d has R = %g and C = %g.\n",
442 inode, rr_type, R, C);
449 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node: node %d cost index (%d) is out of range.\n",
460 int from_edge, to_node, to_edge, from_num_edges, to_num_edges;
462 short from_switch_type;
463 boolean trans_matched;
466 if (from_rr_type !=
CHANX && from_rr_type !=
CHANY)
471 for (from_edge = 0; from_edge < from_num_edges; from_edge++) {
475 if (to_rr_type !=
CHANX && to_rr_type !=
CHANY)
488 trans_matched =
FALSE;
490 for (to_edge = 0; to_edge < to_num_edges; to_edge++) {
491 if (
rr_node[to_node].edges[to_edge] == from_node
492 &&
rr_node[to_node].switches[to_edge] == from_switch_type) {
493 trans_matched =
TRUE;
498 if (trans_matched ==
FALSE) {
499 vpr_printf(TIO_MESSAGE_ERROR,
"in check_pass_transistors:\n");
500 vpr_printf(TIO_MESSAGE_ERROR,
"connection from node %d to node %d uses a pass transistor (switch type %d)\n",
501 from_node, to_node, from_switch_type);
502 vpr_printf(TIO_MESSAGE_ERROR,
"but there is no corresponding pass transistor edge in the other direction.\n");
static void check_pass_transistors(int from_node)
struct s_class * class_inf
enum e_graph_type t_graph_type
void check_rr_graph(INP t_graph_type graph_type, INP t_type_ptr types, INP int L_nx, INP int L_ny, INP int nodes_per_chan, INP int Fs, INP int num_seg_types, INP int num_switches, INP t_segment_inf *segment_inf, INP int global_route_switch, INP int delayless_switch, INP int wire_to_ipin_switch, t_seg_details *seg_details, int **Fc_in, int **Fc_out, int *****opin_to_track_map, int *****ipin_to_track_map, t_ivec ****track_to_ipin_lookup, t_ivec ***switch_block_conn, boolean *perturb_ipins)
void * my_calloc(size_t nelem, size_t size)
void check_node(int inode, enum e_route_type route_type)
struct s_switch_inf * switch_inf
struct s_grid_tile ** grid
#define BUF_AND_PTRANS_FLAG
static boolean rr_node_is_global_clb_ipin(int inode)