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] = { 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] = { 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; 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] = { 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] = { 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] = { }; 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.CleanUp[routingArea]; maze => NULL; ENDCASE; }; }. ¼RouteImpl.mesa ///Route/RouteImpl.mesa Copyright c 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 Define the routing design rules. technologyKey values are predefinded for now. Create a routing barrier for a layer. 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. Create a RoutingArea. The RoutingArea definition includes the design rules (conductor and via widths and spacings) and definition of the routing area sides. set up the parameter data set up the net data Create a pin. Use IncludeNet to specify the pins that are to be connected. Create a net within the interconnection area. Channel Route the routing area. SwitchBox Route the routing area. Maze Route the routing area. 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. Remove circular references so garbage collection can work ÊŸ˜šœ'™'Jšœ Ïmœ1™žœžœžœ˜dJ˜Jš œžœžœ>žœžœžœ˜fJ˜J˜š Ïnœžœžœžœdžœžœž˜¿JšœO™OJ˜šžœž˜Jšœžœ ˜?Jšœžœ˜Jšœ ˜ Jšœ˜Jšœ6˜6šžœž˜šœ ˜ Jšœ?˜?Jšœ<˜<—šœ ˜ Jšœ?˜?Jšœ<˜<—Jšžœ˜J˜——šžœÏc˜Jšœ*žœ˜,—J˜——š  œžœžœ0žœžœžœ)ž˜ªJ™%J™Jšœžœ˜.Jšœ˜Jšœ!˜!Jšœ&žœ˜(—J˜š  œžœžœwžœžœž˜ÄJšœÿ™ÿJ˜JšœO˜Ošžœžœž˜ J˜8—šž˜Jšœ1žœ"˜VJšœ˜Jšœ,˜,Jšœ(˜(Jšœ'˜'Jšœ$žœ˜'——J˜š œžœžœžœžœ?žœžœ#ž˜°J™J˜šœ˜J˜-—šžœ˜Jšœk˜kJšœžœ˜(Jšœ#˜#Jšœ ˜ Jšœ$˜$Jšœ(˜(J™Jšœ™JšœžœžœC˜aJ˜Jšœ™Jš œžœžœCžœžœžœ˜„——J˜š  œžœžœ ž œ0˜ZJšœ  œ.™KJ™Jšœ)˜)J˜—š   œžœžœ0žœ;žœž˜ŽJšœ-™-J˜Jšœ'žœ˜AJšœžœ(˜LJšœ žœ˜Jšœ žœ˜#J˜šžœ!žœž˜=Jšžœ#žœ˜@Jšžœ˜J˜—šžœž˜ Jšœ)˜)—šž˜JšœE˜EJšœžœ˜Jšœh˜hšžœž˜%Jšœ;˜;—šž˜Jšœ<˜<—J˜Jšœf˜fJšœ^˜^šœB˜BJšœ˜JšœI˜I—J˜Jšœa˜ašœE˜EJšœ˜JšœJ˜J—J˜Jšœ7˜7Jšœ:˜:Jšœl˜lJšœžœ®˜ÈJšœžœ˜——J˜š   œžœžœzžœ'ž˜ÃJ™J˜JšœH˜Hšžœ8ž˜>Jšœ9˜9—šž˜Jšœ;žœ˜=——J˜š  œžœžœzžœ'ž˜ÅJ™!—˜JšœJ˜Jšžœ:ž˜@Jšœ9˜9—šž˜Jšœ;žœ˜=——J˜š   œžœžœzžœ'ž˜ÀJ™—˜Jšžœ˜—J˜š œžœžœ5žœžœ žœžœžœ=ž˜èJšœå™åJšœ­™­J˜JšœO˜OJšœ˜Jšœ2˜2J˜šžœž˜šœ˜JšœG˜GJšœA˜AJ˜Jšœï˜ïJšœ&˜&Jšœ)˜)Jšœ˜—J˜Jšœžœ˜ Jšžœ˜ ——J˜š œž œ%˜9Jšœ9™9J™Jšœ'žœ˜Ašžœž˜Jšœ8˜8J˜Jšœžœ˜ Jšžœ˜—Jšœ˜—J˜Jšžœ˜J˜J˜J˜J˜—…—°*