RouteImpl.mesa ///Route/RouteImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bryan Preas, July 10, 1985 11:14:39 am PDT
last edited Bryan Preas, July 10, 1985 11:14:48 am PDT
DIRECTORY
CD,
CDBasics,
CDCells,
List,
Rope,
Route,
RouteChannel,
RoutePrivate,
RouteTechnology,
RouteUtil;
RouteImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDCells, Route, RouteChannel, RouteTechnology, RouteUtil
EXPORTS Route, RoutePrivate
SHARES Route = {
RoutingLayerName: PUBLIC ARRAY RoutePrivate.RoutingLayerOrNone OF Rope.ROPE ← ["trunk", "branch", "none"];
Error: PUBLIC ERROR[errorType: Route.ErrorType ← callingError, explanation: Rope.ROPE ← NIL] = CODE;
Signal: PUBLIC SIGNAL[errorType: Route.ErrorType ← callingError, explanation: Rope.ROPE ← NIL] = CODE;
CreateDesignRules:
PUBLIC
PROC [technologyKey:
ATOM, horizLayer, vertLayer: Route.Layer, trunkDirection: Route.Direction, properties: Route.PropList ←
NIL]
RETURNS [dr: Route.DesignRules] =
{
Define the routing design rules. technologyKey values are predefinded for now.
IF technologyKey # NIL
THEN
{technology: CD.Technology ← CD.FetchTechnology[technologyKey];
dr ← NEW[Route.DesignRulesRec];
dr.CDLambda ← technology.lambda;
dr.technology ← technology;
dr.horizLayer ← horizLayer; dr.vertLayer ← vertLayer;
SELECT trunkDirection
FROM
horizontal =>
{dr.branchDirection ← vertical; dr.trunkDirection ← horizontal;
RouteTechnology.CmosDesignRules[dr, horizLayer, vertLayer]};
vertical =>
{dr.branchDirection ← horizontal; dr.trunkDirection ← vertical;
RouteTechnology.CmosDesignRules[dr, vertLayer, horizLayer]};
ENDCASE}
ELSE
-- invalid technology
Error[callingError, "Invalid technology."]};
CreateRoutingBarrier:
PUBLIC
PROC [layer: Route.Layer, barrier: Route.RectList ←
NIL, properties: Route.PropList ←
NIL]
RETURNS [routingBarrier: Route.RoutingBarrier] =
{
Create a routing barrier for a layer.
routingBarrier ← NEW[Route.RoutingBarrierRec];
routingBarrier.layer ← layer;
routingBarrier.barrier ← barrier;
routingBarrier.properties ← properties};
IncludeRoutingAreaSide:
PUBLIC
PROC [routingArea: Route.RoutingArea, side: Route.Side, sideFiducial: Route.Position, barriers: Route.RoutingBarrierList ←
NIL, properties: Route.PropList ←
NIL] =
{
Include a routing area side in a routing area. Each side has its own coordinate system: the barriers, pins and the *ChannelEnd's have coordinates with respect to the side. fixedSide = TRUE -> the side should not be moved with respect to the routing area.
routingSides: RoutePrivate.RoutingAreaSides ← NARROW[routingArea.routingSides];
IF routingSides[side] #
NIL
THEN
Route.Error[callingError, "Multiple side descriptions."]
ELSE
{routingAreaSide: RoutePrivate.RoutingAreaSide ← NEW[RoutePrivate.RoutingAreaSideRec];
routingAreaSide.side ← side;
routingAreaSide.sideFiducial ← sideFiducial;
routingAreaSide.properties ← properties;
routingAreaSide.barrierList ← barriers;
routingSides[side] ← routingAreaSide}};
CreateRoutingArea:
PUBLIC
PROC [routingAreaName: Rope.
ROPE ←
NIL, designRules: Route.DesignRules, properties: Route.PropList ←
NIL]
RETURNS [routingArea: Route.RoutingArea] =
{
Create a RoutingArea. The RoutingArea definition includes the design rules (conductor and via widths and spacings) and definition of the routing area sides.
IF designRules = NIL THEN
Route.Error[callingError, "No design rules."]
ELSE {
routingSides: RoutePrivate.RoutingAreaSides ← NEW[RoutePrivate.RoutingAreaSidesRec ← [NIL, NIL, NIL, NIL]];
routingArea ← NEW[Route.RoutingAreaRec];
routingArea.name ← routingAreaName;
routingArea.rules ← designRules;
routingArea.properties ← properties;
routingArea.routingSides ← routingSides;
set up the parameter data
routingArea.parms ← NARROW[NEW[RoutePrivate.RoutingAreaParmsRec], RoutePrivate.RoutingAreaParms];
set up the net data
routingArea.nets ← NARROW[NEW[RoutePrivate.NetTabRec ← [size: RoutePrivate.maxNets, count: 0, n: ALL[NIL]]], RoutePrivate.NetTab]}};
CreatePin:
PUBLIC
PROC [cdPin:
CD.Instance, side: Route.Side] RETURNS [pin: Route.Pin] = {
Create a pin. Use IncludeNet to specify the pins that are to be connected.
pin ← NEW[Route.PinRec ← [cdPin, side]]};
IncludeNet:
PUBLIC
PROC [routingArea: Route.RoutingArea, netName: Rope.
ROPE, connections: Route.PinList, properties: Route.PropList ←
NIL] =
{
Create a net within the interconnection area.
parms: RoutePrivate.RoutingAreaParms ← NARROW[routingArea.parms];
netTab: RoutePrivate.NetTab ← NARROW[routingArea.nets, RoutePrivate.NetTab];
netPart: NAT ← 1;
nextNetNum: NAT ← netTab.count + 1;
FOR netIndex: RoutePrivate.ZMaxNets
IN [1 .. netTab.count]
DO
IF netTab.n[netIndex].name = netName THEN netPart ← netPart + 1;
ENDLOOP;
IF nextNetNum > netTab.size
THEN
Route.Error[noResource, "Too many nets."]
ELSE {
channelDirection: Route.Direction ← routingArea.rules.trunkDirection;
trunkAtom, branchAtom: ATOM;
trunkWidth, trunkWidthSpec, branchWidth, branchWidthSpec, widestBranchPin, widestTrunkPin: Route.Number;
IF channelDirection = horizontal
THEN
{trunkAtom ← $horizontalWidth; branchAtom ← $verticalWidth}
ELSE
{trunkAtom ← $verticalWidth; branchAtom ← $horizontalWidth};
[widestBranchPin, widestTrunkPin] ← RouteUtil.GetPinWidth[routingArea, connections, channelDirection];
trunkWidthSpec ← RouteUtil.GetNumberProp[properties, trunkAtom, routingArea.rules.trunkWidth];
trunkWidth ← IF trunkWidthSpec > routingArea.rules.trunkWidth THEN
trunkWidthSpec
ELSE MAX[routingArea.rules.trunkWidth, widestBranchPin, widestTrunkPin];
branchWidthSpec ← RouteUtil.GetNumberProp[properties, branchAtom, routingArea.rules.branchWidth];
branchWidth ← IF branchWidthSpec > routingArea.rules.branchWidth THEN
branchWidthSpec
ELSE MAX[routingArea.rules.branchWidth, widestBranchPin, widestTrunkPin];
parms.widestTrunk ← MAX[trunkWidth, parms.widestTrunk];
parms.widestBranch ← MAX[branchWidth, parms.widestBranch];
parms.numTracksToUse ← parms.numTracksToUse + (2 + RouteChannel.InfluenceTracks[routingArea, trunkWidth])*2;
netTab.n[nextNetNum] ← NEW[RoutePrivate.NetRec ← [name: netName, netNum: nextNetNum, netPart: netPart, branchWidth: branchWidth, trunkWidth: trunkWidth, pinList: connections, properties: properties]];
netTab.count ← nextNetNum}};
ChannelRoute:
PUBLIC
PROC [routingArea: Route.RoutingArea, sideOrgins: Route.PositionVec, routingRect: Route.Rect, opt: Route.Optimization ← full]
RETURNS [routingResult: Route.RoutingResult] =
{
Channel Route the routing area.
RouteChannel.InitChannel[routingArea, sideOrgins, routingRect, channel];
IF RouteChannel.GenerateConstraints[routingArea, channel]
THEN
routingResult ← RouteChannel.TopoWiring[routingArea, opt]
ELSE
routingResult ← NEW[Route.RoutingResultRec ← [routingArea]]};
SwitchBoxRoute:
PUBLIC
PROC [routingArea: Route.RoutingArea, sideOrgins: Route.PositionVec, routingRect: Route.Rect, opt: Route.Optimization ← full]
RETURNS [routingResult: Route.RoutingResult] =
{
SwitchBox Route the routing area.
RouteChannel.InitChannel[routingArea, sideOrgins, routingRect, switchBox];
IF RouteChannel.GenerateConstraints[routingArea, switchBox]
THEN
routingResult ← RouteChannel.TopoWiring[routingArea, opt]
ELSE
routingResult ← NEW[Route.RoutingResultRec ← [routingArea]]};
MazeRoute:
PUBLIC
PROC [routingArea: Route.RoutingArea, sideCoords: Route.PositionVec, routingRect: Route.Rect, opt: Route.Optimization ← full]
RETURNS [routingResult: Route.RoutingResult] =
{
Maze Route the routing area.
RetrieveRouting:
PUBLIC
PROC [routingResult: Route.RoutingResult, cellName: Rope.
ROPE ←
NIL, retrieveRect: Route.RefRect ←
NIL, properties: Route.PropList ←
NIL]
RETURNS [object: Route.Object, externalConnections: Route.PinList] =
{
Create a ChipNDale object and include the routing in the object. This object will be included in design if design # NIL. RetreiveRouting is a separate procedure to allow routingArea size to be modified after routing is complete.
The externalConnections describe the location of a pin connecting the routingArea to the external environment. Equivalent information is recorded as pins in the CND object.
parms: RoutePrivate.RoutingAreaParms ← NARROW[routingResult.routingArea.parms];
parms.cellName ← cellName;
parms.object ← object ← CDCells.CreateEmptyCell[];
SELECT parms.routerUsed
FROM
channel, switchBox => {
rect: Route.Rect ← IF retrieveRect = NIL THEN routingResult.routingRect
ELSE CDBasics.Surround[retrieveRect^, routingResult.routingRect];
externalConnections ← RouteChannel.GetRouting[routingResult.routingArea, rect, properties, RouteChannel.RetrieveSegments, RouteChannel.RetrievePins, RouteChannel.RetrieveVias, RouteChannel.RetrieveExits, RouteChannel.RetrieveIncompletes];
CDCells.SetInterestRect[object, rect];
[] ← CDCells.RepositionCell[object, NIL];
};
maze => NULL;
ENDCASE};
Destroy:
PUBLIC PROC [routingArea: Route.RoutingArea] ~ {
Remove circular references so garbage collection can work
parms: RoutePrivate.RoutingAreaParms ← NARROW[routingArea.parms];
SELECT parms.routerUsed
FROM
channel, switchBox => RouteChannel.CleanUp[routingArea];
maze => NULL;
ENDCASE;
};
}.