magic/garouter/gaMain.c

468 lines
17 KiB
C

/*
* 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 <stdio.h>
#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);
}