468 lines
17 KiB
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);
|
|
}
|