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.ROPENIL] = CODE;
Signal: PUBLIC SIGNAL[errorType: Route.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
trunkWidthKey: PUBLIC REF ATOMNEW[ATOM ← $trunkWidth];
branchWidthKey: PUBLIC REF ATOMNEW[ATOM ← $branchWidth];
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.ROPENIL, 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;
trunkWidth, trunkWidthSpec, branchWidth, branchWidthSpec, widestBranchPin, widestTrunkPin: Route.Number;
[widestBranchPin, widestTrunkPin] ← RouteUtil.GetPinWidth[routingArea, connections, channelDirection];
trunkWidthSpec ← RouteUtil.GetNumberProp[properties, Route.trunkWidthKey, routingArea.rules.trunkWidth];
trunkWidth ← IF trunkWidthSpec > routingArea.rules.trunkWidth THEN
trunkWidthSpec
ELSE IF widestTrunkPin > 0 THEN MAX[routingArea.rules.trunkWidth, widestTrunkPin]
ELSE MAX[routingArea.rules.trunkWidth, widestBranchPin];
branchWidthSpec ← RouteUtil.GetNumberProp[properties, Route.branchWidthKey, routingArea.rules.branchWidth];
branchWidth ← IF branchWidthSpec > routingArea.rules.branchWidth THEN
branchWidthSpec
ELSE MAX[routingArea.rules.branchWidth, widestBranchPin, trunkWidth];
parms.widestTrunk ← MAX[trunkWidth, parms.widestTrunk];
parms.widestBranch ← MAX[branchWidth, parms.widestBranch];
parms.numTracksToUse ← parms.numTracksToUse + 2*RouteChannel.InfluenceTracks[routingArea, trunkWidth];
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, signalSinglePinNets, signalCoincidentPins: BOOLEANTRUE] RETURNS [routingResult: Route.RoutingResult] = {
Channel Route the routing area.
RouteChannel.InitChannel[routingArea, sideOrgins, routingRect, channel, signalSinglePinNets, signalCoincidentPins, FALSE, FALSE];
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, signalSinglePinNets, signalCoincidentPins: BOOLEANTRUE, okToDiddleLLPins, okToDiddleURPins: BOOLEANFALSE] RETURNS [routingResult: Route.RoutingResult] = {
SwitchBox Route the routing area.
RouteChannel.InitChannel[routingArea, sideOrgins, routingRect, switchBox, signalSinglePinNets, signalCoincidentPins, okToDiddleLLPins, okToDiddleURPins];
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.ROPENIL, 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.Destroy[routingArea];
maze => NULL;
ENDCASE;
};
}.