/* * gaMain.c - * * Top-level of the gate-array router. * * For an overview of how routing systems work in general, see * the papers: * * "Magic's Obstacle-Avoiding Global Router", G.T. Hamachi and * J.K. Ousterhout, Proceedings of the 1985 Chapel Hill Conference * on VLSI, May 1985, pp. 393-418 * * "A Switchbox Router with Obstacle Avoidance", G.T. Hamachi * and J.K. Ousterhout, Proc 21st Design Automation Conference, * June 1984, pp. 173-179. * * "The PI (Placement and Interconnect) System", R.L. Rivest, * Proc 19th Design Automation Conference, June 1982, pp. 475-481. * * This router shares much code with the standard router in the "router" * module, and also makes use of the "grouter" (global-router) "gcr" * (channel-router), and "mzrouter" (maze-router) modules. * * The primary differences between this module and the "router" module * are that "garouter" allows the user to define channels explicitly * (rather than having them be generated automatically as they are in * the "router" module). These channels can overlap subcells arbitrarily, * unlike automatically generated channels which only appear in areas * where there are no subcells. * * User-specified channels can be specially identified as "river-routing" * channels. Unlike ordinary channels, these may contain routing terminals. * However, the routing across a river-routing channel is simpler than * that in an ordinary channel: tracks run either straight across horizontally, * for horizontal river routing channels, or vertically, for vertical * river routing channels, but never both. (See gcr.h for a description * of normal channels and the two kinds of river routing channels). * * Router organization: * ------------------- * * Routing is composed of a number of steps. First, the channels are * defined (by the user in this module) by calls to GADefineChannel(). * The remainder of the work is done in GARoute(), which: * * - reads the list of intended connections into a NLNetList * structure, * - generates "stems" for all terminals, * - sets up the channels for global routing, * - calls the global router to determine the sequence of channel * boundary points through which the route for each net will pass, * - calls the channel router to fill in the detailed routes for * each net in each channel structure, and then paint this * information back into the edit cell, * - generates paint for each stem generated at the start of routing * * The following sections briefly describe each of the above tasks in * a bit more detail: * * Nets and terminals: * ------------------ * * The connections that the router must make are described to it in * the form of a netlist, which comes from a text file that is either * generated outside of Magic or created using the netlist editor in * the "netmenu" module of Magic. Each "net" is a collection of named * terminals that must be connected. These terminals are described by * the hierarchical names of labels. Each terminal appears in exactly * one net. A given label may appear in several places in the same cell, * so a terminal may have several locations. The router assumes that all * of these locations are already electrically connected. * * * Channels and pins: * ----------------- * * This router is grid-based, meaning that wires are generated so that * their left-hand side and bottom align with evenly-spaced grid lines * in x and y. Two key structures, defined in gcr.h, represent the * routing problem in this grid-based world: the channel (GCRChannel) * and pin (GCRPin). Channels are rectangular areas with pins along * their boundaries: * * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * . . . . . . . * . +---X---------X---------X---------X---------X-----+ . * . | . . . . . | . * . | . . . . . | . * . . . X . P---------P---------P---------P---------P . . X . . * . | | . . . | | . * . | | . . . | | . * . | | . . . | | . * . . . X . P . . . . . . . . . . . . . . . . . . . P . . X . . * . | | . . . | | . * . | | . . . | | . * . | | . . . | | . * . . . X . P . . . . . . . . . . . . . . . . . . . P . . X . . * . | | . . . | | . * . | | . . . | | . * . | | . . . | | . * . . . X . P---------P---------P---------P---------P . . X . . * . | . . . . . | . * . +---X---------X---------X---------X---------X-----+ . * . . . . . . . * . . . . . . . * O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * * The dots indicate the grid lines. The set of grid points enclosed * by the channel is the inner dashed line. The actual channel boundary * lies between these grid lines and the next grid lines out. (To handle * the case where the grid spacing is odd, the boundary actually lies * at a location that is half the grid spacing (rounded down to the nearest * integer) DOWN and to the LEFT of a grid line, hence the asymmetry in * the diagram above. * * "Crossing points" lie along the channel boundary and are marked by X's. * Each crossing point has a pin associated with it; these pins are marked * by P's. (Note that the pins in the corners occupy the same grid * points but different crossing points; this reflects the fact that * the routing for a column and a track can overlap). * Each channel structure has four arrays of pins: one along each of its * LHS, RHS, and top and bottom (indexed as 1, 2, ... in order of * increasing x or y as appropriate; the 0th element of the pin * arrays is not used). * * When two channels share a common boundary, a single crossing * point may be associated with two pins: one in each channel. * During channel initialization (below), those pairs of pins * that share a crossing point are made to point to each other. * * * Stem generation: * --------------- * * Although the router is grid based, terminals in cells need not be * aligned to the routing grid. Stem generation is the process of * finding one (or two) channel pin(s) that are reachable from each * terminal in the routing problem, and marking these pins with the * net to which the terminal belongs. If a terminal lies in the middle * of a river-routing channel, up to two pins will be assigned to it * (on opposite sides of the channel). Otherwise, (e.g., if the terminal * is inside a cell but not in any channel) only one pin will be assigned, * in the channel closest to the terminal. * * Stem generation actually has two parts. The first only determines * if a stem CAN be run from a terminal to a pin, but doesn't generate * any paint, since not all terminals will necessarily be used by * the global router. (For example, if a terminal appears in more * than one place in a cell, it may be that only one of these places * is actually connected by the router). The second part of stem * generation, invoked after channel routing is complete, actually * paints the stems into the edit cell. * * Since the stem generator has no way of knowing which layer the * channel router will use for a signal it routes to a pin, it must * be possible for the final stems to connect to either routing * layer. The stem generator checks to ensure that it can connect * to either layer during the first part, and rejects pins it can't * reach on either layer (unless the area of the pin itself is covered * by one layer, in which case the stem only has to be able to connect * to the free layer). * * The code for stem generation is split between this module (for * stems inside river-routing channels), the "router" module (for * stems for terminals outside of any channel), and the "mzrouter" * module (used to determine when stems can be routed, if it isn't * obvious). * * Global routing: * -------------- * * Initially, all the pins in each channel are marked as not belonging * to any net, except for the pins that were assigned to terminals by * stem generation. The job of the global router is to find paths * (as sequences of pins) for all nets, and to mark the pins on a * given net's path with that net's identifier. These channels * and marked pins will be used as the input to the channel router. * * Channel routing: * --------------- * * Each channel structure contains a two-dimensional array with one * element for each internal grid point in the channel. The channel * router accepts a channel whose pins have been marked with net * identifiers, and fills in this internal array with flags indicating * the type of material/contact to place at that grid location. After * all channels have been routed, we use the information in these * internal arrays to generate actual paint for the edit cell. Since * channels are routed independently of what material is in adjacent * channels, sometimes it is necessary during this paintback to add * contacts at channel boundaries to switch routing layers. * * * ********************************************************************* * * Copyright (C) 1985, 1990 Regents of the University of California. * * * Permission to use, copy, modify, and distribute this * * * software and its documentation for any purpose and without * * * fee is hereby granted, provided that the above copyright * * * notice appear in all copies. The University of California * * * makes no representations about the suitability of this * * * software for any purpose. It is provided "as is" without * * * express or implied warranty. Export of this software outside * * * of the United States of America may require an export license. * * ********************************************************************* */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/garouter/gaMain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/heap.h" #include "tiles/tile.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "utils/signals.h" #include "netmenu/netmenu.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "garouter/garouter.h" #include "utils/netlist.h" #include "textio/textio.h" #include "debug/debug.h" #include "drc/drc.h" /* C99 compat */ #include "utils/netlist.h" #include "garouter/gaInternal.h" /* * ---------------------------------------------------------------------------- * * GARouteCmd -- * * Top-level procedure for the gate-array router. * Routes the cell 'routeUse->cu_def' using the netlist 'netListName'. * * Results: * Returns the number of routing errors left as feedback. * Returning -1 means that routing was unable to commence * because of other errors (e.g, the netlist couldn't be * read) which were already reported to the user. * * Side effects: * Leaves paint in routeUse->cu_def. Leaves feedback where routing * errors occurred. Frees all the memory associated with channel * structures when done. * * ---------------------------------------------------------------------------- */ int GARouteCmd(routeUse, netListName) CellUse *routeUse; char *netListName; { int errs = -1; NLNetList netList; GCRChannel *ch; NLNet *net; /* Initialize ga maze routing */ if(gaMazeInit(routeUse)==FALSE) { TxError("Could not initialize maze router.\n"); return(-1); } /* Ensure that there are channels defined */ if (gaChannelList == (GCRChannel *) NULL) { TxError("Must define channels before routing.\n"); return (-1); } /* Read the netlist */ if (gaBuildNetList(netListName, routeUse, &netList) < 0) return (-1); if (SigInterruptPending) goto done; /* Figure out the size of the routing area */ RouteArea.r_xbot = RouteArea.r_ybot = INFINITY; RouteArea.r_xtop = RouteArea.r_ytop = MINFINITY; for (ch = gaChannelList; ch && !SigInterruptPending; ch = ch->gcr_next) (void) GeoIncludeAll(&ch->gcr_area, &RouteArea); for (net = netList.nnl_nets; net; net = net->nnet_next) (void) GeoIncludeAll(&net->nnet_area, &RouteArea); errs = GARoute(gaChannelList, routeUse, &netList); done: /* Cleanup */ NLFree(&netList); GAClearChannels(); return (errs); } /* * ---------------------------------------------------------------------------- * * GARoute -- * * Routes the cell 'routeUse->cu_def' using the netlist 'netList'. * The list of channels is 'list'. These channels are fresh from * being allocated by GCRNewChannel(). * * Results: * Returns the number of routing errors left as feedback. * Returning -1 means that routing was unable to commence * because of other errors (e.g, the netlist couldn't be * read) which were already reported to the user. * * Side effects: * Leaves paint in routeUse->cu_def. Leaves feedback where routing * errors occurred. Frees all the memory associated with channel * structures when done. * * ---------------------------------------------------------------------------- */ int GARoute(list, routeUse, netList) GCRChannel *list; /* List of channels */ CellUse *routeUse; /* Cell being routed */ NLNetList *netList; /* List of nets to route */ { int feedCount = DBWFeedbackCount, errs; GCRChannel *ch; /* * Initialize all the pointers in the channel structure (stem assignment), * and also determine which tracks are available for river-routing * in channels so marked (CHAN_HRIVER or CHAN_VRIVER). */ gaChannelInit(list, routeUse, netList); if (SigInterruptPending || DebugIsSet(gaDebugID, gaDebChanOnly) || DebugIsSet(glDebugID, glDebStemsOnly)) goto done; /* Perform global routing */ RtrMilestoneStart("Global routing"); GlGlobalRoute(list, netList); RtrMilestoneDone(); if (SigInterruptPending || DebugIsSet(glDebugID, glDebGreedy)) goto done; /* Channel routing */ errs = 0; RtrMilestoneStart("Channel routing"); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) RtrChannelRoute(ch, &errs); RtrMilestoneDone(); if (errs > 0) TxError("%d bad connection%s.\n", errs, errs != 1 ? "s" : ""); if (SigInterruptPending) goto done; /* Paint results in a separate pass */ RtrMilestoneStart("Painting results"); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) { RtrMilestonePrint(); RtrPaintBack(ch, routeUse->cu_def); /* update bounding box NOW so searches during stem gen. * work correctly. */ DBReComputeBbox(routeUse->cu_def); } RtrMilestoneDone(); if (SigInterruptPending) goto done; if (DebugIsSet(gaDebugID, gaDebPaintStems)) { DRCCheckThis(routeUse->cu_def, TT_CHECKPAINT, &RouteArea); DBWAreaChanged(routeUse->cu_def, &RouteArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); WindUpdate(); TxMore("After channel paintback"); } gaStemPaintAll(routeUse, netList); /* * Mark the areas modified. * Only areas inside the routing channels are actually affected. */ SigDisableInterrupts(); /* recomp bbox again just in case stem gen changed it (unlikely) */ DBReComputeBbox(routeUse->cu_def); DRCCheckThis(routeUse->cu_def, TT_CHECKPAINT, &RouteArea); DBWAreaChanged(routeUse->cu_def, &RouteArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); SigEnableInterrupts(); done: /* Return number of errors */ return (DBWFeedbackCount - feedCount); } /* * ---------------------------------------------------------------------------- * * gaBuildNetList -- * * Construct the netlist that will be used for routing. * Use netListName if supplied; otherwise use the name of * the current netlist; if neither are set, use the name * of the cell 'routeUse->cu_def'. * * Leaves the constructed netlist in 'netList'. * * Results: * Returns the number of nets in netList. If there were * no nets, returns 0. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int gaBuildNetList(netListName, routeUse, netList) char *netListName; CellUse *routeUse; NLNetList *netList; { CellDef *routeDef = routeUse->cu_def; int numNets; /* Select the netlist */ if (netListName == NULL) { if (!NMHasList()) { netListName = routeDef->cd_name; TxPrintf("No netlist selected yet; using \"%s\".\n", netListName); NMNewNetlist(netListName); } else netListName = NMNetlistName(); } else NMNewNetlist(netListName); if (DebugIsSet(gaDebugID, gaDebVerbose)) TxPrintf("Reading netlist %s.\n", netListName); RtrMilestoneStart("Building netlist"); numNets = NLBuild(routeUse, netList); RtrMilestoneDone(); if (numNets == 0) TxError("No nets to route.\n"); if (DebugIsSet(gaDebugID, gaDebVerbose)) TxPrintf("Read %d nets.\n", numNets); return (numNets); }