SRC/check_route.c File Reference

#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"
Include dependency graph for check_route.c:

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)

Function Documentation

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:


Generated on Tue Jan 5 15:25:15 2010 for VPR5.0 by  doxygen 1.6.1