<> <> <> <> DIRECTORY CD, CDBasics, CDRoutingObjects, CDSimpleRules, DABasics, List, RefTab, Rope, Route, RouteChannel, RoutePrivate, RouteTechnology, RTBasic, SymTab; RouteImpl: CEDAR PROGRAM IMPORTS CDBasics, CDRoutingObjects, CDSimpleRules, RefTab, Route, RouteChannel, RouteTechnology, SymTab EXPORTS Route = { <> Error: PUBLIC ERROR[errorType: Route.ErrorType _ callingError, explanation: Rope.ROPE _ NIL] = CODE; Signal: PUBLIC SIGNAL[errorType: Route.ErrorType _ callingError, explanation: Rope.ROPE _ NIL] = CODE; <> DefaultDesignRulesParameters: PUBLIC PROC [technologyHint: REF, horizLayer, vertLayer: CD.Layer, trunkDirection: DABasics.Direction] RETURNS [designRules: Route.DesignRulesParameters] = { <> <> IF technologyHint # NIL THEN { tech: CD.Technology _ CDSimpleRules.GetTechnology[technologyHint]; designRules _ RouteTechnology.DesignRulesParameters[tech, horizLayer, vertLayer, trunkDirection]} ELSE -- invalid technology Error[callingError, "Invalid technology."]}; <> Channel: PUBLIC PROC [enumerateNets: Route.EnumerateChannelNetsProc, min, max: CD.Number, rulesParameters: Route.DesignRulesParameters, name: Rope.ROPE, brokenNets: Route.BrokenNetProc, enumerateObstructions: Route.EnumerateChannelBarriersProc, channelData: REF, optimization: Route.Optimization, signalSinglePinNets, signalCoincidentPins: BOOL] RETURNS [result: Route.Result] = { <> <> designRules: Route.DesignRules _ DefaultDesignRules[rulesParameters]; intermediateResult: Route.IntermediateResult _ ChannelRoute[enumerateNets, min, max, rulesParameters, designRules, name, enumerateObstructions, channelData, optimization, signalSinglePinNets, signalCoincidentPins]; result _ ChannelRetrieve[intermediateResult, brokenNets, channelData]}; <> SwitchBox: PUBLIC PROC [enumerateNets: Route.EnumerateSwitchBoxNetsProc, routingRect: DABasics.Rect, rulesParameters: Route.DesignRulesParameters, name: Rope.ROPE, enumerateObstructions: Route.EnumerateSwitchBoxBarriersProc, switchBoxData: REF, optimization: Route.Optimization, signalSinglePinNets, signalCoincidentPins: BOOL, okToDiddleLLPins, okToDiddleURPins: BOOL] RETURNS [result: Route.Result] = { <> <> designRules: Route.DesignRules _ DefaultDesignRules[rulesParameters]; intermediateResult: Route.IntermediateResult _ SwitchBoxRoute[enumerateNets, routingRect, rulesParameters, designRules, name, enumerateObstructions, switchBoxData, optimization, signalSinglePinNets, signalCoincidentPins, okToDiddleLLPins, okToDiddleURPins]; result _ SwitchBoxRetrieve[intermediateResult]}; <> ChannelRoute: PUBLIC PROC [enumerateNets: Route.EnumerateChannelNetsProc, min, max: CD.Number, rulesParameters: Route.DesignRulesParameters, rules: Route.DesignRules, name: Rope.ROPE, enumerateObstructions: Route.EnumerateChannelBarriersProc, channelData: REF, optimization: Route.Optimization, signalSinglePinNets, signalCoincidentPins: BOOL] RETURNS [intermediateResult: Route.IntermediateResult] = { <> <> EachNet: Route.EachChannelNetProc ~ { <> EachPin: Route.EachChannelPinProc ~ { <> side: DABasics.Side; side _ SELECT trunkDirection FROM horizontal => IF bottomOrLeftSide THEN bottom ELSE top, vertical => IF bottomOrLeftSide THEN left ELSE right, ENDCASE => Route.Error[programmingError, "Call maintainer."]; widestBranchPin _ MAX[widestBranchPin, max - min]; connections _ CONS[CreatePin[side, min, max, depth, layer], connections]}; <> parms: RoutePrivate.RoutingAreaParms _ routingArea.parms; netTab: RoutePrivate.NetTab _ routingArea.nets; nextNum: NAT _ netTab.count + 1; trunkWidth, branchWidth: CD.Number; widestBranchPin, lowerPos, upperPos: CD.Number _ 0; connections: RoutePrivate.PinList _ NIL; trunkDirection: DABasics.Direction _ routingArea.ruleParameters.trunkDirection; <> enumeratePins[channelData, netData, EachPin]; trunkWidth _ IF trunkSize > 0 THEN MAX[routingArea.rules.trunkWidth, trunkSize] ELSE MAX[routingArea.rules.trunkWidth, widestBranchPin]; branchWidth _ MAX[routingArea.rules.branchWidth, widestBranchPin, trunkWidth]; <> IF exitRightOrTop THEN { pinSide: DABasics.Side _ IF trunkDirection = horizontal THEN right ELSE top; upperPos _ upperPos + routingArea.rules.trunkSpacing; connections _ CONS[CreatePin[pinSide, upperPos, upperPos + trunkWidth, 0, routingArea.rules.trunkLayer], connections]; upperPos _ upperPos + trunkWidth}; IF exitLeftOrBottom THEN { pinSide: DABasics.Side _ IF trunkDirection = horizontal THEN left ELSE bottom; lowerPos _ upperPos + routingArea.rules.trunkSpacing; connections _ CONS[CreatePin[pinSide, lowerPos, lowerPos + trunkWidth, 0, routingArea.rules.trunkLayer], connections]; lowerPos _ lowerPos + trunkWidth}; parms.widestTrunk _ MAX[trunkWidth, parms.widestTrunk]; parms.widestBranch _ MAX[branchWidth, parms.widestBranch]; parms.numTracksToUse _ parms.numTracksToUse + 2*RouteChannel.InfluenceTracks[routingArea, trunkWidth]; netTab.n[nextNum] _ NEW[RoutePrivate.NetRec _ [name: name, num: nextNum, branchWidth: branchWidth, trunkWidth: trunkWidth, pinList: connections, netData: netData, mayExit: mayExit]]; netTab.count _ nextNum}; EachObstruction: Route.EachChannelBarrierProc ~ { <> }; parms: RoutePrivate.RoutingAreaParms _ NEW[RoutePrivate.RoutingAreaParmsRec]; routingSides: RoutePrivate.RoutingAreaSides _ NEW[RoutePrivate.RoutingAreaSidesRec _ [NIL, NIL, NIL, NIL]]; nets: RoutePrivate.NetTab _ NEW[RoutePrivate.NetTabRec _ [size: RoutePrivate.maxNets, count: 0, n: ALL[NIL]]]; routingArea: RoutePrivate.RoutingArea _ NEW[RoutePrivate.RoutingAreaRec _ [name: name, ruleParameters: rulesParameters, rules: rules, routingSides: routingSides, nets: nets, parms: parms, channelData: channelData]]; routingRect: DABasics.Rect _ IF rulesParameters.trunkDirection = horizontal THEN [min, 0, max, routingArea.rules.trunkToTrunk] ELSE [0, min, routingArea.rules.trunkToTrunk, max]; enumerateNets[channelData, EachNet]; IF enumerateObstructions # NIL THEN { enumerateObstructions[channelData, EachObstruction]}; RouteChannel.InitChannel[routingArea, routingRect, channel, signalSinglePinNets, signalCoincidentPins, FALSE, FALSE]; intermediateResult _ IF RouteChannel.GenerateConstraints[routingArea, channel] THEN RouteChannel.TopoWiring[routingArea, optimization] ELSE NEW[Route.IntermediateResultRec _ [routingArea: routingArea, routingRect: routingRect]]}; ChannelRetrieve: PUBLIC PROC [intermediateResult: Route.IntermediateResult, brokenNets: Route.BrokenNetProc, channelData: REF, retrieveRect: REF DABasics.Rect _ NIL] RETURNS [result: Route.Result] = { <> <> <<>> routingArea: RoutePrivate.RoutingArea _ NARROW[intermediateResult.routingArea]; rect: DABasics.Rect _ IF retrieveRect = NIL THEN intermediateResult.routingRect ELSE CDBasics.Surround[retrieveRect^, intermediateResult.routingRect]; object: CD.Object; parms: RoutePrivate.RoutingAreaParms _ NARROW[routingArea.parms]; parms.viaTable _ RefTab.Create[equal: EqualProc, hash: HashProc]; parms.entityTable _ SymTab.Create[]; RouteChannel.GetRouting[routingArea, rect, brokenNets, RouteChannel.RetrieveSegments, RouteChannel.RetrieveVias, RouteChannel.RetrieveIncompletes]; object _ CDRoutingObjects.CreateRoutingObject[CDRoutingObjects.CreateNodes[routingArea.parms.entityTable], rect]; result _ NEW[Route.ResultRec _ [ object: object, polyLength: intermediateResult.polyLength, metalLength: intermediateResult.metalLength, metal2Length: intermediateResult.metal2Length, polyToMetal: intermediateResult.polyToMetal, metalToMetal2: intermediateResult.metalToMetal2, numTrunkTracks: intermediateResult.numTrunkTracks, numIncompletes: intermediateResult.numIncompletes, incompleteNets: intermediateResult.incompleteNets]]; RouteChannel.Destroy[routingArea]}; SwitchBoxRoute: PUBLIC PROC [enumerateNets: Route.EnumerateSwitchBoxNetsProc, routingRect: DABasics.Rect, rulesParameters: Route.DesignRulesParameters, rules: Route.DesignRules, name: Rope.ROPE, enumerateObstructions: Route.EnumerateSwitchBoxBarriersProc, switchBoxData: REF, optimization: Route.Optimization, signalSinglePinNets, signalCoincidentPins: BOOL, okToDiddleLLPins, okToDiddleURPins: BOOL] RETURNS [intermediateResult: Route.IntermediateResult] = { <> <> EachNet: Route.EachSwitchBoxNetProc ~ { <> EachPin: Route.EachSwitchBoxPinProc ~ { <> widestBranchPin _ MAX[widestBranchPin, max - min]; connections _ CONS[CreatePin[side, min, max, depth, layer], connections]}; <> parms: RoutePrivate.RoutingAreaParms _ routingArea.parms; netTab: RoutePrivate.NetTab _ routingArea.nets; nextNum: NAT _ netTab.count + 1; trunkWidth, branchWidth: CD.Number; widestBranchPin, lowerPos, upperPos: CD.Number _ 0; connections: RoutePrivate.PinList _ NIL; trunkDirection: DABasics.Direction _ routingArea.ruleParameters.trunkDirection; <> enumeratePins[switchBoxData, netData, EachPin]; trunkWidth _ IF trunkSize > 0 THEN MAX[routingArea.rules.trunkWidth, trunkSize] ELSE MAX[routingArea.rules.trunkWidth, widestBranchPin]; branchWidth _ 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[nextNum] _ NEW[RoutePrivate.NetRec _ [name: name, num: nextNum, branchWidth: branchWidth, trunkWidth: trunkWidth, pinList: connections, mayExit: FALSE]]; netTab.count _ nextNum}; EachObstruction: Route.EachSwitchBoxBarrierProc ~ { <> }; parms: RoutePrivate.RoutingAreaParms _ NEW[RoutePrivate.RoutingAreaParmsRec]; routingSides: RoutePrivate.RoutingAreaSides _ NEW[RoutePrivate.RoutingAreaSidesRec _ [NIL, NIL, NIL, NIL]]; nets: RoutePrivate.NetTab _ NEW[RoutePrivate.NetTabRec _ [size: RoutePrivate.maxNets, count: 0, n: ALL[NIL]]]; routingArea: RoutePrivate.RoutingArea _ NEW[RoutePrivate.RoutingAreaRec _ [name: name, ruleParameters: rulesParameters, rules: rules, routingSides: routingSides, nets: nets, parms: parms, channelData: switchBoxData]]; enumerateNets[switchBoxData, EachNet]; IF enumerateObstructions # NIL THEN { enumerateObstructions[switchBoxData, EachObstruction]}; RouteChannel.InitChannel[routingArea, routingRect, switchBox, signalSinglePinNets, signalCoincidentPins, okToDiddleLLPins, okToDiddleURPins]; intermediateResult _ IF RouteChannel.GenerateConstraints[routingArea, switchBox] THEN RouteChannel.TopoWiring[routingArea, optimization] ELSE NEW[Route.IntermediateResultRec _ [routingArea: routingArea, routingRect: routingRect]]}; SwitchBoxRetrieve: PUBLIC PROC [intermediateResult: Route.IntermediateResult] RETURNS [result: Route.Result] = { <> <> routingArea: RoutePrivate.RoutingArea _ NARROW[intermediateResult.routingArea]; object: CD.Object; parms: RoutePrivate.RoutingAreaParms _ NARROW[routingArea.parms]; parms.viaTable _ RefTab.Create[equal: EqualProc, hash: HashProc]; parms.entityTable _ SymTab.Create[]; RouteChannel.GetRouting[routingArea, intermediateResult.routingRect, NIL, RouteChannel.RetrieveSegments, RouteChannel.RetrieveVias, RouteChannel.RetrieveIncompletes]; object _ CDRoutingObjects.CreateRoutingObject[CDRoutingObjects.CreateNodes[routingArea.parms.entityTable], intermediateResult.routingRect]; result _ NEW[Route.ResultRec _ [ object: object, polyLength: intermediateResult.polyLength, metalLength: intermediateResult.metalLength, metal2Length: intermediateResult.metal2Length, polyToMetal: intermediateResult.polyToMetal, metalToMetal2: intermediateResult.metalToMetal2, numTrunkTracks: intermediateResult.numTrunkTracks, numIncompletes: intermediateResult.numIncompletes, incompleteNets: intermediateResult.incompleteNets]]; RouteChannel.Destroy[routingArea]}; DefaultDesignRules: PUBLIC PROC [designRuleParameters: Route.DesignRulesParameters] RETURNS [designRules: Route.DesignRules] ~ { <> designRules _ RouteTechnology.CmosDesignRules[designRuleParameters]}; <> CreatePin: PROC [side: DABasics.Side, min, max, depth: DABasics.Number, layer: CD.Layer] RETURNS [pin: RoutePrivate.Pin] ~ { <> pin _ NEW[RoutePrivate.PinRec _ [side: side, min: min, max: max, depth: depth, layer: layer]]}; EqualProc: RefTab.EqualProc = { p1: DABasics.Position _ NARROW[key1, REF DABasics.Position]^; p2: DABasics.Position _ NARROW[key2, REF DABasics.Position]^; RETURN [p1.x = p2.x AND p1.y = p2.y]}; HashProc: RefTab.HashProc = { size: DABasics.Position _ NARROW[key, REF DABasics.Position]^; RETURN [size.x + size.y]}; }.