<> <> <> <> 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; trunkWidthKey: PUBLIC REF ATOM _ NEW[ATOM _ $trunkWidth]; branchWidthKey: PUBLIC REF ATOM _ NEW[ATOM _ $branchWidth]; CreateDesignRules: PUBLIC PROC [technologyKey: ATOM, horizLayer, vertLayer: Route.Layer, trunkDirection: Route.Direction, properties: Route.PropList _ NIL] RETURNS [dr: Route.DesignRules] = { <> 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] = { <> <<>> 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] = { < 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] = { <> 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; <<>> <> routingArea.parms _ NARROW[NEW[RoutePrivate.RoutingAreaParmsRec], RoutePrivate.RoutingAreaParms]; <> 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] = { <> <<>> pin _ NEW[Route.PinRec _ [cdPin, side]]}; IncludeNet: PUBLIC PROC [routingArea: Route.RoutingArea, netName: Rope.ROPE, connections: Route.PinList, properties: Route.PropList _ NIL] = { <> 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: BOOLEAN _ TRUE] RETURNS [routingResult: Route.RoutingResult] = { <> 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: BOOLEAN _ TRUE, okToDiddleLLPins, okToDiddleURPins: BOOLEAN _ FALSE] RETURNS [routingResult: Route.RoutingResult] = { <> 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] = { <> }; 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] = { <> <> 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] ~ { <> <<>> parms: RoutePrivate.RoutingAreaParms _ NARROW[routingArea.parms]; SELECT parms.routerUsed FROM channel, switchBox => RouteChannel.Destroy[routingArea]; maze => NULL; ENDCASE; }; }.