#include <assert.h>
#include <stdio.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "mst.h"
#include "route_export.h"
#include "check_route.h"
#include "rr_graph.h"
#include "check_rr_graph.h"
Go to the source code of this file.
Functions | |
static void | check_node_and_range (int inode, enum e_route_type route_type) |
static void | check_source (int inode, int inet) |
static void | check_sink (int inode, int inet, boolean *pin_done) |
static void | check_switch (struct s_trace *tptr, int num_switch) |
static boolean | check_adjacent (int from_node, int to_node) |
static int | pin_and_chan_adjacent (int pin_node, int chan_node) |
static int | chanx_chany_adjacent (int chanx_node, int chany_node) |
static void | reset_flags (int inet, boolean *connected_to_route) |
static void | recompute_occupancy_from_scratch (t_ivec **fb_opins_used_locally) |
static void | check_locally_used_fb_opins (t_ivec **fb_opins_used_locally, enum e_route_type route_type) |
void | check_route (enum e_route_type route_type, int num_switch, t_ivec **fb_opins_used_locally) |
static int chanx_chany_adjacent | ( | int | chanx_node, | |
int | chany_node | |||
) | [static] |
Definition at line 572 of file check_route.c.
00574 { 00575 00576 /* Returns 1 if the specified CHANX and CHANY nodes are adjacent, 0 * 00577 * otherwise. */ 00578 00579 int chanx_y, chanx_xlow, chanx_xhigh; 00580 int chany_x, chany_ylow, chany_yhigh; 00581 00582 chanx_y = rr_node[chanx_node].ylow; 00583 chanx_xlow = rr_node[chanx_node].xlow; 00584 chanx_xhigh = rr_node[chanx_node].xhigh; 00585 00586 chany_x = rr_node[chany_node].xlow; 00587 chany_ylow = rr_node[chany_node].ylow; 00588 chany_yhigh = rr_node[chany_node].yhigh; 00589 00590 if(chany_ylow > chanx_y + 1 || chany_yhigh < chanx_y) 00591 return (0); 00592 00593 if(chanx_xlow > chany_x + 1 || chanx_xhigh < chany_x) 00594 return (0); 00595 00596 return (1); 00597 }
static boolean check_adjacent | ( | int | from_node, | |
int | to_node | |||
) | [static] |
Definition at line 374 of file check_route.c.
00376 { 00377 00378 /* This routine checks if the rr_node to_node is reachable from from_node. * 00379 * It returns TRUE if is reachable and FALSE if it is not. Check_node has * 00380 * already been used to verify that both nodes are valid rr_nodes, so only * 00381 * adjacency is checked here. */ 00382 00383 int from_xlow, from_ylow, to_xlow, to_ylow, from_ptc, to_ptc, iclass; 00384 int num_adj, to_xhigh, to_yhigh, from_xhigh, from_yhigh, iconn; 00385 boolean reached; 00386 t_rr_type from_type, to_type; 00387 t_type_ptr from_grid_type, to_grid_type; 00388 00389 reached = FALSE; 00390 00391 for(iconn = 0; iconn < rr_node[from_node].num_edges; iconn++) 00392 { 00393 if(rr_node[from_node].edges[iconn] == to_node) 00394 { 00395 reached = TRUE; 00396 break; 00397 } 00398 } 00399 00400 if(!reached) 00401 return (FALSE); 00402 00403 /* Now we know the rr graph says these two nodes are adjacent. Double * 00404 * check that this makes sense, to verify the rr graph. */ 00405 00406 num_adj = 0; 00407 00408 from_type = rr_node[from_node].type; 00409 from_xlow = rr_node[from_node].xlow; 00410 from_ylow = rr_node[from_node].ylow; 00411 from_xhigh = rr_node[from_node].xhigh; 00412 from_yhigh = rr_node[from_node].yhigh; 00413 from_ptc = rr_node[from_node].ptc_num; 00414 to_type = rr_node[to_node].type; 00415 to_xlow = rr_node[to_node].xlow; 00416 to_ylow = rr_node[to_node].ylow; 00417 to_xhigh = rr_node[to_node].xhigh; 00418 to_yhigh = rr_node[to_node].yhigh; 00419 to_ptc = rr_node[to_node].ptc_num; 00420 00421 switch (from_type) 00422 { 00423 00424 case SOURCE: 00425 assert(to_type == OPIN); 00426 if(from_xlow == to_xlow && from_ylow == to_ylow 00427 && from_xhigh == to_xhigh && from_yhigh == to_yhigh) 00428 { 00429 00430 from_grid_type = grid[from_xlow][from_ylow].type; 00431 to_grid_type = grid[to_xlow][to_ylow].type; 00432 assert(from_grid_type == to_grid_type); 00433 00434 iclass = to_grid_type->pin_class[to_ptc]; 00435 if(iclass == from_ptc) 00436 num_adj++; 00437 } 00438 break; 00439 00440 case SINK: 00441 /* SINKS are adjacent to not connected */ 00442 break; 00443 00444 case OPIN: 00445 assert(to_type == CHANX || to_type == CHANY); 00446 num_adj += pin_and_chan_adjacent(from_node, to_node); 00447 00448 break; 00449 00450 case IPIN: 00451 assert(to_type == SINK); 00452 if(from_xlow == to_xlow && from_ylow == to_ylow 00453 && from_xhigh == to_xhigh && from_yhigh == to_yhigh) 00454 { 00455 00456 from_grid_type = grid[from_xlow][from_ylow].type; 00457 to_grid_type = grid[to_xlow][to_ylow].type; 00458 assert(from_grid_type == to_grid_type); 00459 00460 iclass = from_grid_type->pin_class[from_ptc]; 00461 if(iclass == to_ptc) 00462 num_adj++; 00463 } 00464 break; 00465 00466 case CHANX: 00467 if(to_type == IPIN) 00468 { 00469 num_adj += pin_and_chan_adjacent(to_node, from_node); 00470 } 00471 else if(to_type == CHANX) 00472 { 00473 from_xhigh = rr_node[from_node].xhigh; 00474 to_xhigh = rr_node[to_node].xhigh; 00475 if(from_ylow == to_ylow) 00476 { 00477 /* UDSD Modification by WMF Begin */ 00478 /*For Fs > 3, can connect to overlapping wire segment */ 00479 if(to_xhigh == from_xlow - 1 00480 || from_xhigh == to_xlow - 1) 00481 { 00482 num_adj++; 00483 } 00484 /* Overlapping */ 00485 else 00486 { 00487 int i; 00488 00489 for(i = from_xlow; i <= from_xhigh; i++) 00490 { 00491 if(i >= to_xlow && i <= to_xhigh) 00492 { 00493 num_adj++; 00494 break; 00495 } 00496 } 00497 } 00498 /* UDSD Modification by WMF End */ 00499 } 00500 } 00501 else if(to_type == CHANY) 00502 { 00503 num_adj += chanx_chany_adjacent(from_node, to_node); 00504 } 00505 else 00506 { 00507 assert(0); 00508 } 00509 break; 00510 00511 case CHANY: 00512 if(to_type == IPIN) 00513 { 00514 num_adj += pin_and_chan_adjacent(to_node, from_node); 00515 } 00516 else if(to_type == CHANY) 00517 { 00518 from_yhigh = rr_node[from_node].yhigh; 00519 to_yhigh = rr_node[to_node].yhigh; 00520 if(from_xlow == to_xlow) 00521 { 00522 /* UDSD Modification by WMF Begin */ 00523 if(to_yhigh == from_ylow - 1 00524 || from_yhigh == to_ylow - 1) 00525 { 00526 num_adj++; 00527 } 00528 /* Overlapping */ 00529 else 00530 { 00531 int j; 00532 00533 for(j = from_ylow; j <= from_yhigh; j++) 00534 { 00535 if(j >= to_ylow && j <= to_yhigh) 00536 { 00537 num_adj++; 00538 break; 00539 } 00540 } 00541 } 00542 /* UDSD Modification by WMF End */ 00543 } 00544 } 00545 else if(to_type == CHANX) 00546 { 00547 num_adj += chanx_chany_adjacent(to_node, from_node); 00548 } 00549 else 00550 { 00551 assert(0); 00552 } 00553 break; 00554 00555 default: 00556 break; 00557 00558 } 00559 00560 if(num_adj == 1) 00561 return (TRUE); 00562 else if(num_adj == 0) 00563 return (FALSE); 00564 00565 printf("Error in check_adjacent: num_adj = %d. Expected 0 or 1.\n", 00566 num_adj); 00567 exit(1); 00568 }
static void check_locally_used_fb_opins | ( | t_ivec ** | fb_opins_used_locally, | |
enum e_route_type | route_type | |||
) | [static] |
Definition at line 736 of file check_route.c.
00738 { 00739 00740 /* Checks that enough OPINs on CLBs have been set aside (used up) to make a * 00741 * legal routing if subblocks connect to OPINs directly. */ 00742 00743 int iclass, iblk, num_local_opins, inode, ipin; 00744 t_rr_type rr_type; 00745 00746 for(iblk = 0; iblk < num_blocks; iblk++) 00747 { 00748 for(iclass = 0; iclass < block[iblk].type->num_class; iclass++) 00749 { 00750 num_local_opins = 00751 fb_opins_used_locally[iblk][iclass].nelem; 00752 /* Always 0 for pads and for SINK classes */ 00753 00754 for(ipin = 0; ipin < num_local_opins; ipin++) 00755 { 00756 inode = 00757 fb_opins_used_locally[iblk][iclass]. 00758 list[ipin]; 00759 check_node_and_range(inode, route_type); /* Node makes sense? */ 00760 00761 /* Now check that node is an OPIN of the right type. */ 00762 00763 rr_type = rr_node[inode].type; 00764 if(rr_type != OPIN) 00765 { 00766 printf 00767 ("Error in check_locally_used_opins: Block #%d (%s)\n" 00768 "\tclass %d locally used OPIN is of the wrong rr_type --\n" 00769 "\tit is rr_node #%d of type %d.\n", 00770 iblk, block[iblk].name, iclass, 00771 inode, rr_type); 00772 exit(1); 00773 } 00774 00775 ipin = rr_node[inode].ptc_num; 00776 if(block[iblk].type->pin_class[ipin] != iclass) 00777 { 00778 printf 00779 ("Error in check_locally_used_opins: Block #%d (%s):\n" 00780 "\tExpected class %d locally used OPIN, got class %d." 00781 "\trr_node #: %d.\n", iblk, 00782 block[iblk].name, iclass, 00783 block[iblk].type->pin_class[ipin], 00784 inode); 00785 exit(1); 00786 } 00787 } 00788 } 00789 } 00790 }
static void check_node_and_range | ( | int | inode, | |
enum e_route_type | route_type | |||
) | [static] |
Definition at line 794 of file check_route.c.
00796 { 00797 00798 /* Checks that inode is within the legal range, then calls check_node to * 00799 * check that everything else about the node is OK. */ 00800 00801 if(inode < 0 || inode >= num_rr_nodes) 00802 { 00803 printf 00804 ("Error in check_node_and_range: rr_node #%d is out of legal " 00805 "\trange (0 to %d).\n", inode, num_rr_nodes - 1); 00806 exit(1); 00807 } 00808 check_node(inode, route_type); 00809 }
void check_route | ( | enum e_route_type | route_type, | |
int | num_switch, | |||
t_ivec ** | fb_opins_used_locally | |||
) |
Definition at line 39 of file check_route.c.
00042 { 00043 00044 /* This routine checks that a routing: (1) Describes a properly * 00045 * connected path for each net, (2) this path connects all the * 00046 * pins spanned by that net, and (3) that no routing resources are * 00047 * oversubscribed (the occupancy of everything is recomputed from * 00048 * scratch). */ 00049 00050 int inet, ipin, max_pins, inode, prev_node; 00051 boolean valid, connects; 00052 boolean *connected_to_route; /* [0 .. num_rr_nodes-1] */ 00053 struct s_trace *tptr; 00054 boolean *pin_done; 00055 00056 printf("\nChecking to ensure routing is legal ...\n"); 00057 00058 /* Recompute the occupancy from scratch and check for overuse of routing * 00059 * resources. This was already checked in order to determine that this * 00060 * is a successful routing, but I want to double check it here. */ 00061 00062 recompute_occupancy_from_scratch(fb_opins_used_locally); 00063 valid = feasible_routing(); 00064 if(valid == FALSE) 00065 { 00066 printf 00067 ("Error in check_route -- routing resources are overused.\n"); 00068 exit(1); 00069 } 00070 00071 check_locally_used_fb_opins(fb_opins_used_locally, route_type); 00072 00073 connected_to_route = (boolean *) my_calloc(num_rr_nodes, sizeof(boolean)); 00074 00075 max_pins = 0; 00076 for(inet = 0; inet < num_nets; inet++) 00077 max_pins = max(max_pins, (net[inet].num_sinks + 1)); 00078 00079 pin_done = (boolean *) my_malloc(max_pins * sizeof(boolean)); 00080 00081 /* Now check that all nets are indeed connected. */ 00082 00083 for(inet = 0; inet < num_nets; inet++) 00084 { 00085 00086 if(net[inet].is_global) /* Skip global nets. */ 00087 continue; 00088 00089 for(ipin = 0; ipin < (net[inet].num_sinks + 1); ipin++) 00090 pin_done[ipin] = FALSE; 00091 00092 /* Check the SOURCE of the net. */ 00093 00094 tptr = trace_head[inet]; 00095 if(tptr == NULL) 00096 { 00097 printf("Error in check_route: net %d has no routing.\n", 00098 inet); 00099 exit(1); 00100 } 00101 00102 inode = tptr->index; 00103 check_node_and_range(inode, route_type); 00104 check_switch(tptr, num_switch); 00105 connected_to_route[inode] = TRUE; /* Mark as in path. */ 00106 00107 check_source(inode, inet); 00108 pin_done[0] = TRUE; 00109 00110 prev_node = inode; 00111 tptr = tptr->next; 00112 00113 /* Check the rest of the net */ 00114 00115 while(tptr != NULL) 00116 { 00117 inode = tptr->index; 00118 check_node_and_range(inode, route_type); 00119 check_switch(tptr, num_switch); 00120 00121 if(rr_node[prev_node].type == SINK) 00122 { 00123 if(connected_to_route[inode] == FALSE) 00124 { 00125 printf 00126 ("Error in check_route. Node %d does not link " 00127 "into the existing routing for net %d.\n", 00128 inode, inet); 00129 exit(1); 00130 } 00131 } 00132 00133 else 00134 { 00135 connects = check_adjacent(prev_node, inode); 00136 if(!connects) 00137 { 00138 printf 00139 ("Error in check_route while checking net %d.\n", 00140 inet); 00141 printf 00142 ("Non-adjacent segments in traceback.\n"); 00143 exit(1); 00144 } 00145 00146 if(connected_to_route[inode] 00147 && rr_node[inode].type != SINK) 00148 { 00149 00150 /* Note: Can get multiple connections to the same logically-equivalent * 00151 * SINK in some logic blocks. */ 00152 00153 printf 00154 ("Error in check_route: net %d routing is not a tree.\n", 00155 inet); 00156 exit(1); 00157 } 00158 00159 connected_to_route[inode] = TRUE; /* Mark as in path. */ 00160 00161 if(rr_node[inode].type == SINK) 00162 check_sink(inode, inet, pin_done); 00163 00164 } /* End of prev_node type != SINK */ 00165 prev_node = inode; 00166 tptr = tptr->next; 00167 } /* End while */ 00168 00169 if(rr_node[prev_node].type != SINK) 00170 { 00171 printf("Error in check_route. Net %d does not end\n", 00172 inet); 00173 printf("with a SINK.\n"); 00174 exit(1); 00175 } 00176 00177 for(ipin = 0; ipin < (net[inet].num_sinks + 1); ipin++) 00178 { 00179 if(pin_done[ipin] == FALSE) 00180 { 00181 printf 00182 ("Error in check_route. Net %d does not \n", 00183 inet); 00184 printf("connect to pin %d.\n", ipin); 00185 exit(1); 00186 } 00187 } 00188 00189 reset_flags(inet, connected_to_route); 00190 00191 } /* End for each net */ 00192 00193 free(pin_done); 00194 free(connected_to_route); 00195 printf("Completed routing consistency check successfully.\n\n"); 00196 }
static void check_sink | ( | int | inode, | |
int | inet, | |||
boolean * | pin_done | |||
) | [static] |
Definition at line 199 of file check_route.c.
00202 { 00203 00204 /* Checks that this SINK node is one of the terminals of inet, and marks * 00205 * the appropriate pin as being reached. */ 00206 00207 int i, j, ipin, ifound, ptc_num, bnum, iclass, node_block_pin, iblk; 00208 t_type_ptr type; 00209 00210 assert(rr_node[inode].type == SINK); 00211 i = rr_node[inode].xlow; 00212 j = rr_node[inode].ylow; 00213 type = grid[i][j].type; 00214 ptc_num = rr_node[inode].ptc_num; /* For sinks, ptc_num is the class */ 00215 ifound = 0; 00216 00217 for(iblk = 0; iblk < type->capacity; iblk++) 00218 { 00219 bnum = grid[i][j].blocks[iblk]; /* Hardcoded to one block */ 00220 for(ipin = 1; ipin < (net[inet].num_sinks + 1); ipin++) 00221 { /* All net SINKs */ 00222 if(net[inet].node_block[ipin] == bnum) 00223 { 00224 node_block_pin = net[inet].node_block_pin[ipin]; 00225 iclass = type->pin_class[node_block_pin]; 00226 if(iclass == ptc_num) 00227 { 00228 /* Could connect to same pin class on the same fb more than once. Only * 00229 * update pin_done for a pin that hasn't been reached yet. */ 00230 00231 if(pin_done[ipin] == FALSE) 00232 { 00233 ifound++; 00234 pin_done[ipin] = TRUE; 00235 } 00236 } 00237 } 00238 } 00239 } 00240 00241 if(ifound > 1 && type == IO_TYPE) 00242 { 00243 printf("Error in check_sink: found %d terminals of net %d of pad" 00244 "\n %d at location (%d, %d).\n", ifound, inet, ptc_num, i, 00245 j); 00246 exit(1); 00247 } 00248 00249 if(ifound < 1) 00250 { 00251 printf 00252 ("Error in check_sink: node %d does not connect to any terminal " 00253 "\n of net %d.\n", inode, inet); 00254 exit(1); 00255 } 00256 }
static void check_source | ( | int | inode, | |
int | inet | |||
) | [static] |
Definition at line 260 of file check_route.c.
00262 { 00263 00264 /* Checks that the node passed in is a valid source for this net. */ 00265 00266 t_rr_type rr_type; 00267 t_type_ptr type; 00268 int i, j, ptc_num, bnum, node_block_pin, iclass; 00269 00270 rr_type = rr_node[inode].type; 00271 if(rr_type != SOURCE) 00272 { 00273 printf 00274 ("Error in check_source: net %d begins with a node of type %d.\n", 00275 inet, rr_type); 00276 exit(1); 00277 } 00278 00279 i = rr_node[inode].xlow; 00280 j = rr_node[inode].ylow; 00281 ptc_num = rr_node[inode].ptc_num; /* for sinks and sources, ptc_num is class */ 00282 bnum = net[inet].node_block[0]; /* First node_block for net is the source */ 00283 type = grid[i][j].type; 00284 00285 if(block[bnum].x != i || block[bnum].y != j) 00286 { 00287 printf 00288 ("Error in check_source: net SOURCE is in wrong location (%d,%d)." 00289 "\n", i, j); 00290 exit(1); 00291 } 00292 00293 node_block_pin = net[inet].node_block_pin[0]; 00294 iclass = type->pin_class[node_block_pin]; 00295 00296 if(ptc_num != iclass) 00297 { 00298 printf 00299 ("Error in check_source: net SOURCE is of wrong class (%d).\n", 00300 ptc_num); 00301 exit(1); 00302 } 00303 }
static void check_switch | ( | struct s_trace * | tptr, | |
int | num_switch | |||
) | [static] |
Definition at line 307 of file check_route.c.
00309 { 00310 00311 /* Checks that the switch leading from this traceback element to the next * 00312 * one is a legal switch type. */ 00313 00314 int inode; 00315 short switch_type; 00316 00317 inode = tptr->index; 00318 switch_type = tptr->iswitch; 00319 00320 if(rr_node[inode].type != SINK) 00321 { 00322 if(switch_type < 0 || switch_type >= num_switch) 00323 { 00324 printf 00325 ("Error in check_switch: rr_node %d left via switch type %d.\n", 00326 inode, switch_type); 00327 printf("Switch type is out of range.\n"); 00328 exit(1); 00329 } 00330 } 00331 00332 else 00333 { /* Is a SINK */ 00334 00335 /* Without feedthroughs, there should be no switch. If feedthroughs are * 00336 * allowed, change to treat a SINK like any other node (as above). */ 00337 00338 if(switch_type != OPEN) 00339 { 00340 printf 00341 ("Error in check_switch: rr_node %d is a SINK, but attempts \n" 00342 "to use a switch of type %d.\n", inode, switch_type); 00343 exit(1); 00344 } 00345 } 00346 }
static int pin_and_chan_adjacent | ( | int | pin_node, | |
int | chan_node | |||
) | [static] |
Definition at line 601 of file check_route.c.
00603 { 00604 00605 /* Checks if pin_node is adjacent to chan_node. It returns 1 if the two * 00606 * nodes are adjacent and 0 if they are not (any other value means there's * 00607 * a bug in this routine). */ 00608 00609 int num_adj, pin_xlow, pin_ylow, pin_xhigh, pin_yhigh, chan_xlow, 00610 chan_ylow, chan_xhigh, chan_yhigh; 00611 int pin_ptc, i; 00612 t_rr_type chan_type; 00613 t_type_ptr pin_grid_type; 00614 00615 num_adj = 0; 00616 pin_xlow = rr_node[pin_node].xlow; 00617 pin_ylow = rr_node[pin_node].ylow; 00618 pin_xhigh = rr_node[pin_node].xhigh; 00619 pin_yhigh = rr_node[pin_node].yhigh; 00620 pin_grid_type = grid[pin_xlow][pin_ylow].type; 00621 pin_ptc = rr_node[pin_node].ptc_num; 00622 chan_type = rr_node[chan_node].type; 00623 chan_xlow = rr_node[chan_node].xlow; 00624 chan_ylow = rr_node[chan_node].ylow; 00625 chan_xhigh = rr_node[chan_node].xhigh; 00626 chan_yhigh = rr_node[chan_node].yhigh; 00627 00628 if(chan_type == CHANX) 00629 { 00630 if(chan_ylow == pin_yhigh) 00631 { /* CHANX above FB */ 00632 if(pin_grid_type-> 00633 pinloc[pin_grid_type->height - 1][TOP][pin_ptc] == 1 00634 && pin_xlow <= chan_xhigh && pin_xhigh >= chan_xlow) 00635 num_adj++; 00636 } 00637 else if(chan_ylow == pin_ylow - 1) 00638 { /* CHANX below FB */ 00639 if(pin_grid_type->pinloc[0][BOTTOM][pin_ptc] == 1 00640 && pin_xlow <= chan_xhigh && pin_xhigh >= chan_xlow) 00641 num_adj++; 00642 } 00643 } 00644 else if(chan_type == CHANY) 00645 { 00646 for(i = 0; i < pin_grid_type->height; i++) 00647 { 00648 if(chan_xlow == pin_xhigh) 00649 { /* CHANY to right of FB */ 00650 if(pin_grid_type->pinloc[i][RIGHT][pin_ptc] == 1 00651 && pin_ylow <= chan_yhigh 00652 && pin_yhigh >= chan_ylow) 00653 num_adj++; 00654 } 00655 else if(chan_xlow == pin_xlow - 1) 00656 { /* CHANY to left of FB */ 00657 if(pin_grid_type->pinloc[i][LEFT][pin_ptc] == 1 00658 && pin_ylow <= chan_yhigh 00659 && pin_yhigh >= chan_ylow) 00660 num_adj++; 00661 } 00662 } 00663 } 00664 return (num_adj); 00665 }
static void recompute_occupancy_from_scratch | ( | t_ivec ** | fb_opins_used_locally | ) | [static] |
Definition at line 669 of file check_route.c.
00670 { 00671 00672 /* This routine updates the occ field in the rr_node structure according to * 00673 * the resource usage of the current routing. It does a brute force * 00674 * recompute from scratch that is useful for sanity checking. */ 00675 00676 int inode, inet, iblk, iclass, ipin, num_local_opins; 00677 struct s_trace *tptr; 00678 00679 /* First set the occupancy of everything to zero. */ 00680 00681 for(inode = 0; inode < num_rr_nodes; inode++) 00682 rr_node[inode].occ = 0; 00683 00684 /* Now go through each net and count the tracks and pins used everywhere */ 00685 00686 for(inet = 0; inet < num_nets; inet++) 00687 { 00688 00689 if(net[inet].is_global) /* Skip global nets. */ 00690 continue; 00691 00692 tptr = trace_head[inet]; 00693 if(tptr == NULL) 00694 continue; 00695 00696 for(;;) 00697 { 00698 inode = tptr->index; 00699 rr_node[inode].occ++; 00700 00701 if(rr_node[inode].type == SINK) 00702 { 00703 tptr = tptr->next; /* Skip next segment. */ 00704 if(tptr == NULL) 00705 break; 00706 } 00707 00708 tptr = tptr->next; 00709 } 00710 } 00711 00712 /* Now update the occupancy of each of the "locally used" OPINs on each FB * 00713 * (FB outputs used up by being directly wired to subblocks used only * 00714 * locally). */ 00715 00716 for(iblk = 0; iblk < num_blocks; iblk++) 00717 { 00718 for(iclass = 0; iclass < block[iblk].type->num_class; iclass++) 00719 { 00720 num_local_opins = 00721 fb_opins_used_locally[iblk][iclass].nelem; 00722 /* Will always be 0 for pads or SINK classes. */ 00723 for(ipin = 0; ipin < num_local_opins; ipin++) 00724 { 00725 inode = 00726 fb_opins_used_locally[iblk][iclass]. 00727 list[ipin]; 00728 rr_node[inode].occ++; 00729 } 00730 } 00731 } 00732 }
static void reset_flags | ( | int | inet, | |
boolean * | connected_to_route | |||
) | [static] |
Definition at line 350 of file check_route.c.
00352 { 00353 00354 /* This routine resets the flags of all the channel segments contained * 00355 * in the traceback of net inet to 0. This allows us to check the * 00356 * next net for connectivity (and the default state of the flags * 00357 * should always be zero after they have been used). */ 00358 00359 struct s_trace *tptr; 00360 int inode; 00361 00362 tptr = trace_head[inet]; 00363 00364 while(tptr != NULL) 00365 { 00366 inode = tptr->index; 00367 connected_to_route[inode] = FALSE; /* Not in routed path now. */ 00368 tptr = tptr->next; 00369 } 00370 }