15 static void check_sink(
int inode,
int inet,
boolean * pin_done);
20 static void reset_flags(
int inet,
boolean * connected_to_route);
36 int inet, ipin, max_pins, inode, prev_node;
37 boolean valid, connects;
38 boolean * connected_to_route;
43 vpr_printf(TIO_MESSAGE_INFO,
"Checking to ensure routing is legal...\n");
52 vpr_printf(TIO_MESSAGE_ERROR,
"Error in check_route -- routing resources are overused.\n");
61 for (inet = 0; inet <
num_nets; inet++)
64 pin_done = (
boolean *)
my_malloc(max_pins *
sizeof(
boolean));
68 for (inet = 0; inet <
num_nets; inet++) {
74 pin_done[ipin] =
FALSE;
80 vpr_printf(TIO_MESSAGE_ERROR,
"in check_route: net %d has no routing.\n", inet);
87 connected_to_route[inode] =
TRUE;
97 while (tptr != NULL) {
103 if (connected_to_route[inode] ==
FALSE) {
104 vpr_printf(TIO_MESSAGE_ERROR,
"in check_route: node %d does not link into existing routing for net %d.\n", inode, inet);
112 vpr_printf(TIO_MESSAGE_ERROR,
"in check_route: found non-adjacent segments in traceback while checking net %d.\n", inet);
116 if (connected_to_route[inode] &&
rr_node[inode].type !=
SINK) {
121 vpr_printf(TIO_MESSAGE_ERROR,
"in check_route: net %d routing is not a tree.\n", inet);
125 connected_to_route[inode] =
TRUE;
136 vpr_printf(TIO_MESSAGE_ERROR,
"in check_route: net %d does not end with a SINK.\n", inet);
141 if (pin_done[ipin] ==
FALSE) {
142 vpr_printf(TIO_MESSAGE_ERROR,
"in check_route: net %d does not connect to pin %d.\n", inet, ipin);
152 free(connected_to_route);
153 vpr_printf(TIO_MESSAGE_INFO,
"Completed routing consistency check successfully.\n");
157 static void check_sink(
int inode,
int inet,
boolean * pin_done) {
162 int i, j, ipin, ifound, ptc_num, bnum, iclass, node_block_pin, iblk;
172 for (iblk = 0; iblk < type->
capacity; iblk++) {
175 if (
clb_net[inet].node_block[ipin] == bnum) {
177 iclass = type->
pin_class[node_block_pin];
178 if (iclass == ptc_num) {
182 if (pin_done[ipin] ==
FALSE) {
184 pin_done[ipin] =
TRUE;
191 if (ifound > 1 && type ==
IO_TYPE) {
192 vpr_printf(TIO_MESSAGE_ERROR,
"in check_sink: found %d terminals of net %d of pad %d at location (%d, %d).\n", ifound, inet, ptc_num, i, j);
197 vpr_printf(TIO_MESSAGE_ERROR,
"in check_sink: node %d does not connect to any terminal of net %s #%d.\n"
198 "This error is usually caused by incorrectly specified logical equivalence in your architecture file.\n"
199 "You should try to respecify what pins are equivalent or turn logical equivalence off.\n", inode,
clb_net[inet].name, inet);
210 int i, j, ptc_num, bnum, node_block_pin, iclass;
214 vpr_printf(TIO_MESSAGE_ERROR,
"in check_source: net %d begins with a node of type %d.\n", inet, rr_type);
224 if (
block[bnum].x != i ||
block[bnum].y != j) {
225 vpr_printf(TIO_MESSAGE_ERROR,
"in check_source: net SOURCE is in wrong location (%d,%d).\n", i, j);
230 iclass = type->
pin_class[node_block_pin];
232 if (ptc_num != iclass) {
233 vpr_printf(TIO_MESSAGE_ERROR,
"in check_source: net SOURCE is of wrong class (%d).\n", ptc_num);
250 if (switch_type < 0 || switch_type >= num_switch) {
251 vpr_printf(TIO_MESSAGE_ERROR,
"in check_switch: rr_node %d left via switch type %d.\n", inode, switch_type);
252 vpr_printf(TIO_MESSAGE_ERROR,
"\tSwitch type is out of range.\n");
262 if (switch_type !=
OPEN) {
263 vpr_printf(TIO_MESSAGE_ERROR,
"in check_switch: rr_node %d is a SINK, but attempts to use a switch of type %d.\n",
282 while (tptr != NULL) {
284 connected_to_route[inode] =
FALSE;
300 int from_xlow, from_ylow, to_xlow, to_ylow, from_ptc, to_ptc, iclass;
301 int num_adj, to_xhigh, to_yhigh, from_xhigh, from_yhigh, iconn;
309 if (
rr_node[from_node].edges[iconn] == to_node) {
339 assert(to_type ==
OPIN);
340 if (from_xlow == to_xlow && from_ylow == to_ylow
341 && from_xhigh == to_xhigh && from_yhigh == to_yhigh) {
343 from_grid_type =
grid[from_xlow][from_ylow].
type;
344 to_grid_type =
grid[to_xlow][to_ylow].
type;
345 assert(from_grid_type == to_grid_type);
347 iclass = to_grid_type->
pin_class[to_ptc];
348 if (iclass == from_ptc)
361 assert(to_type ==
IPIN);
368 assert(to_type ==
SINK);
369 if (from_xlow == to_xlow && from_ylow == to_ylow
370 && from_xhigh == to_xhigh && from_yhigh == to_yhigh) {
372 from_grid_type =
grid[from_xlow][from_ylow].
type;
373 to_grid_type =
grid[to_xlow][to_ylow].
type;
374 assert(from_grid_type == to_grid_type);
376 iclass = from_grid_type->
pin_class[from_ptc];
377 if (iclass == to_ptc)
383 if (to_type ==
IPIN) {
385 }
else if (to_type ==
CHANX) {
388 if (from_ylow == to_ylow) {
391 if (to_xhigh == from_xlow - 1 || from_xhigh == to_xlow - 1) {
398 for (i = from_xlow; i <= from_xhigh; i++) {
399 if (i >= to_xlow && i <= to_xhigh) {
407 }
else if (to_type ==
CHANY) {
415 if (to_type ==
IPIN) {
417 }
else if (to_type ==
CHANY) {
420 if (from_xlow == to_xlow) {
422 if (to_yhigh == from_ylow - 1 || from_yhigh == to_ylow - 1) {
429 for (j = from_ylow; j <= from_yhigh; j++) {
430 if (j >= to_ylow && j <= to_yhigh) {
438 }
else if (to_type ==
CHANX) {
452 else if (num_adj == 0)
455 vpr_printf(TIO_MESSAGE_ERROR,
"in check_adjacent: num_adj = %d. Expected 0 or 1.\n", num_adj);
464 int chanx_y, chanx_xlow, chanx_xhigh;
465 int chany_x, chany_ylow, chany_yhigh;
475 if (chany_ylow > chanx_y + 1 || chany_yhigh < chanx_y)
478 if (chanx_xlow > chany_x + 1 || chanx_xhigh < chany_x)
490 int num_adj, pin_xlow, pin_ylow, pin_xhigh, pin_yhigh, chan_xlow, chan_ylow,
491 chan_xhigh, chan_yhigh;
501 pin_grid_type =
grid[pin_xlow][pin_ylow].
type;
509 if (chan_type ==
CHANX) {
510 if (chan_ylow == pin_yhigh) {
512 == 1 && pin_xlow <= chan_xhigh && pin_xhigh >= chan_xlow)
514 }
else if (chan_ylow == pin_ylow - 1) {
516 && pin_xlow <= chan_xhigh && pin_xhigh >= chan_xlow)
519 }
else if (chan_type ==
CHANY) {
520 for (i = 0; i < pin_grid_type->
height; i++) {
521 if (chan_xlow == pin_xhigh) {
523 && pin_ylow <= chan_yhigh && pin_yhigh >= chan_ylow)
525 }
else if (chan_xlow == pin_xlow - 1) {
526 if (pin_grid_type->
pinloc[i][
LEFT][pin_ptc] == 1
527 && pin_ylow <= chan_yhigh && pin_yhigh >= chan_ylow)
541 int inode, inet, iblk, iclass, ipin, num_local_opins;
551 for (inet = 0; inet <
num_nets; inet++) {
580 num_local_opins = clb_opins_used_locally[iblk][iclass].
nelem;
582 for (ipin = 0; ipin < num_local_opins; ipin++) {
583 inode = clb_opins_used_locally[iblk][iclass].
list[ipin];
596 int iclass, iblk, num_local_opins, inode, ipin;
601 num_local_opins = clb_opins_used_locally[iblk][iclass].
nelem;
604 for (ipin = 0; ipin < num_local_opins; ipin++) {
605 inode = clb_opins_used_locally[iblk][iclass].
list[ipin];
611 if (rr_type !=
OPIN) {
612 vpr_printf(TIO_MESSAGE_ERROR,
"in check_locally_used_opins: block #%d (%s)\n",
613 iblk,
block[iblk].name);
614 vpr_printf(TIO_MESSAGE_ERROR,
"\tClass %d local OPIN is wrong rr_type -- rr_node #%d of type %d.\n",
615 iclass, inode, rr_type);
620 if (
block[iblk].type->pin_class[ipin] != iclass) {
621 vpr_printf(TIO_MESSAGE_ERROR,
"in check_locally_used_opins: block #%d (%s):\n",
622 iblk,
block[iblk].name);
623 vpr_printf(TIO_MESSAGE_ERROR,
"\tExpected class %d local OPIN has class %d -- rr_node #: %d.\n",
624 iclass,
block[iblk].type->pin_class[ipin], inode);
638 vpr_printf(TIO_MESSAGE_ERROR,
"in check_node_and_range: rr_node #%d is out of legal, range (0 to %d).\n",
static void recompute_occupancy_from_scratch(t_ivec **clb_opins_used_locally)
boolean feasible_routing(void)
static void check_locally_used_clb_opins(t_ivec **clb_opins_used_locally, enum e_route_type route_type)
static void check_node_and_range(int inode, enum e_route_type route_type)
void * my_calloc(size_t nelem, size_t size)
void check_node(int inode, enum e_route_type route_type)
void check_route(enum e_route_type route_type, int num_switch, t_ivec **clb_opins_used_locally)
static t_ivec ** clb_opins_used_locally
static void * my_malloc(int ibytes)
static void check_source(int inode, int inet)
static boolean check_adjacent(int from_node, int to_node)
struct s_trace ** trace_head
struct s_grid_tile ** grid
static int chanx_chany_adjacent(int chanx_node, int chany_node)
static int pin_and_chan_adjacent(int pin_node, int chan_node)
static void reset_flags(int inet, boolean *connected_to_route)
static void check_sink(int inode, int inet, boolean *pin_done)
static void check_switch(struct s_trace *tptr, int num_switch)