DIRECTORY Atom, CD, CDBasics, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, DABasics, GC, IO, PWCore, RefTab, Rope, Route, Sisyph, SymTab, TerminalIO; CoreRouteFlatImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, GC, IO, PWCore, RefTab, Rope, Sisyph, SymTab, TerminalIO EXPORTS CoreRouteFlat = BEGIN Structure: TYPE = CoreRouteFlat.Structure; Instance: TYPE = CoreRouteFlat.Instance; CellType: TYPE = Core.CellType; Atoms: TYPE = LIST OF ATOM; LeafProc: TYPE = PROC[ flatCell: CoreFlat.FlatCellTypeRec, instance: CoreClasses.CellInstance, bindings: CoreFlat.Bindings, -- cell.public to flatWires wrt root position: CD.Position]; layDeco: CoreGeometry.Decoration _ PWCore.extractMode.decoration; schDeco: CoreGeometry.Decoration _ Sisyph.mode.decoration; FlattenToLayout: PUBLIC PROC[ root: CellType, propKeys: Atoms _ NIL, properties: Core.Properties _ NIL ] RETURNS [structure: Structure] = { EachLeaf: LeafProc = { instName: Rope.ROPE _ CoreFlat.CellTypePathRope[root, flatCell]; schObj: CD.Object _ CoreGeometry.GetObject[schDeco, instance.type]; inst: Instance _ NEW[CoreRouteFlat.InstanceRec _ [ name: instName, flatCell: NEW[CoreFlat.FlatCellTypeRec _ flatCell], position: position, schIR: CD.InterestRect[schObj], cdObject: PWCore.Layout[instance.type], props: CopyProps[instance.properties, instance.type.properties, propKeys]]]; nodes: RefTab.Ref _ RefTab.Create[]; actuals: RefTab.Ref _ CoreOps.CreateBindingTable[instance.type.public, instance.actual]; structure.instances _ CONS[inst, structure.instances]; FOR side: DABasics.Side IN DABasics.Side DO instPins: CoreRoute.WirePins _ CoreRoute.FilteredCellTypeLayoutPins[instance.type, side]; FOR instPins _ instPins, instPins.rest WHILE instPins#NIL DO wp: CoreRoute.WirePin _ instPins.first; pin: CoreRouteFlat.Pin _ [range: [wp.min, wp.max], side: side, layer: wp.layer]; net: CoreRouteFlat.Net _ BoundInternalNet[wp.wire, root, bindings, structure]; act: Core.Wire _ NARROW[RefTab.Fetch[actuals, wp.wire].val]; AddNodePin[pin, wp.wire, act, nodes, net, inst, propKeys]; ENDLOOP ENDLOOP; CoreRoute.FlushLayPinCache[instance.type]; CoreRoute.FlushSchPinCache[instance.type]}; rootName: Rope.ROPE _ CoreOps.GetCellTypeName[root]; TerminalIO.PutF["Flatten %g into routing structure.\n", IO.rope[rootName]]; structure _ CreateRootStructure[root, properties, propKeys]; FlattenWithSchLocs[root, EachLeaf]}; IsPublic: PUBLIC PROC[net: CoreRouteFlat.Net] RETURNS [isPublic: BOOLEAN] ~ { FOR ins: LIST OF CoreRouteFlat.InstNode _ net.instNodes, ins.rest WHILE ins#NIL DO IF ins.first.node.public THEN RETURN[TRUE] ENDLOOP; RETURN[FALSE]}; TranslateRange: PUBLIC PROC[instance: Instance, pin: CoreRouteFlat.Pin] RETURNS [range: CoreRouteFlat.Range]~ { range _ SELECT pin.side FROM top, bottom => [instance.position.x + pin.range.min, instance.position.x + pin.range.max], left, right => [instance.position.y + pin.range.min, instance.position.y + pin.range.max], ENDCASE => ERROR}; PrintStructure: PUBLIC PROC[structure: Structure] ~ { TerminalIO.PutF["Core Route Flat Structure: %g\n", IO.rope[structure.name]]; FOR insts: LIST OF Instance _ structure.instances, insts.rest WHILE insts#NIL DO PrintInstance[insts.first] ENDLOOP}; CreateRootStructure: PROC [root: CellType, properties: Core.Properties, propKeys: Atoms] RETURNS[structure: Structure] ~ { rootName: Rope.ROPE _ CoreOps.GetCellTypeName[root]; bindings: RefTab.Ref _ CoreFlat.InitialBindingTable[root]; nodes: RefTab.Ref _ RefTab.Create[]; rootInstance: Instance _ NEW[CoreRouteFlat.InstanceRec _ [ name: rootName, rootInstance: TRUE, props: CopyProps[properties, root.properties, propKeys]]]; structure _ NEW[CoreRouteFlat.StructureRec _[ name: rootName, instances: LIST[rootInstance], nets: SymTab.Create[], outerInstance: rootInstance, bindings: bindings, auxLabels: SymTab.Create[] ] ]; FOR side: DABasics.Side IN DABasics.Side DO step: INT _ 8*8; -- Just to record order of nodes on each side index: INT _ 0; wires: Core.Wires _ CoreRoute.OrderedAtomicSchWires[root, side]; FOR wires _ wires, wires.rest WHILE wires#NIL DO pin: CoreRouteFlat.Pin _ [range: [index*step, index*step + step/2], side: side]; net: CoreRouteFlat.Net _ BoundInternalNet[wires.first, root, bindings, structure]; AddNodePin[pin, wires.first, NIL, nodes, net, rootInstance, propKeys]; index _ index + 1 ENDLOOP ENDLOOP}; AddNodePin: PROC[ pin: CoreRouteFlat.Pin, wire: Core.Wire, actual: Core.Wire, nodes: RefTab.Ref, -- wire to node net: CoreRouteFlat.Net, inst: Instance, propKeys: Atoms] = { node: CoreRouteFlat.Node _ NARROW[RefTab.Fetch[nodes, wire].val]; IF node=NIL THEN { shortName: Rope.ROPE _ CoreOps.GetShortWireName[wire]; node _ NEW[CoreRouteFlat.NodeRec _ [name: shortName, public: actual=NIL]]; [] _ RefTab.Store[nodes, wire, node]; net.instNodes _ LIST[CoreRouteFlat.InstNode[inst, node]]; inst.netNodes _ LIST[CoreRouteFlat.NetNode[net, node]]; net.properties _ CopyProps[wire.properties, net.properties, propKeys]; net.properties _ CopyProps[actual.properties, net.properties, propKeys]; node.properties _ CopyProps[wire.properties, NIL, propKeys]}; node.pins _ CONS[pin, node.pins ]}; BoundInternalNet: PROC[ wire: Core.Wire, root: CellType, bindings: CoreFlat.Bindings, structure: Structure ] RETURNS[net: CoreRouteFlat.Net] = { name: Rope.ROPE _ BoundFlatWireName[wire, root, bindings]; IF (net _ NARROW[SymTab.Fetch[structure.nets, name].val])=NIL THEN { net _ NEW[CoreRouteFlat.NetRec _ [name: name]]; [] _ SymTab.Store[structure.nets, name, net]} }; BoundFlatWireName: PROC[wire: Core.Wire, root: CellType, bindings: CoreFlat.Bindings] RETURNS[Rope.ROPE] = { flatWire: CoreFlat.FlatWire _ NARROW [RefTab.Fetch[bindings, wire].val]; RETURN[CoreRoute.LabelFlatWire[root, flatWire^]]}; CopyProps: PROC[primary, secondary: Core.Properties _ NIL, propKeys: Atoms] RETURNS [destProperties: Core.Properties _ NIL] ~ { FOR keys: Atoms _ propKeys, keys.rest WHILE keys#NIL DO val: REF _ CoreProperties.GetProp[primary, keys.first]; IF val=NIL THEN val _ CoreProperties.GetProp[secondary, keys.first]; destProperties _ CoreProperties.PutProp[destProperties, keys.first, val] ENDLOOP}; FlattenWithSchLocs: PROC[ root: CellType, leafProc: LeafProc ] = { Loc: TYPE = CD.Position; PathName: PROC[flatInstance: CoreFlat.FlatCellTypeRec _ [ ]] RETURNS[name: Rope.ROPE] = { RETURN[IF flatInstance = CoreFlat.rootCellType THEN CoreOps.GetCellTypeName[root] ELSE CoreFlat.CellTypePathRope[root, flatInstance]]}; FlattenCell: CoreFlat.BoundFlatCellProc = { childLoc: REF Loc; IF instance#NIL THEN { parentPath: Rope.ROPE _ PathName[flatParent]; childPath: Rope.ROPE _ PathName[flatCell]; childTran: DABasics.Transformation _ CoreGeometry.GetTrans[schDeco, instance]; parentLoc: REF Loc _ NARROW[SymTab.Fetch[locations, parentPath].val]; childLoc _ NEW[Loc _ CDBasics.AddPoints[childTran.off, parentLoc^ ]]; IF childTran.orient#original THEN ERROR; -- Rotated instances are not allowed. IF NOT SymTab.Insert[locations, childPath, childLoc] THEN ERROR}; IF instance=NIL OR (PWCore.GetLayoutAtom[cell]=NIL AND cell.class.recast#NIL) THEN CoreFlat.NextBoundCellType [cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCell] ELSE leafProc[flatCell, instance, bindings, childLoc^]}; locations: SymTab.Ref _ SymTab.Create[]; [] _ SymTab.Store[locations, PathName[], NEW[Loc _ [0,0] ] ]; FlattenCell[root]}; PrintInstance: PROC[inst: Instance] ~ { TerminalIO.PutF[" Instance: %g\n", IO.rope[inst.name]]; TerminalIO.PutF[" Pos: [%g, %g]\n", IO.int[inst.position.x], IO.int[inst.position.y]]; TerminalIO.PutF[" SchIR: [%g, %g, %g, %g]\n", IO.int[inst.schIR.x1], IO.int[inst.schIR.y1], IO.int[inst.schIR.x2], IO.int[inst.schIR.y2]]; FOR nn: LIST OF CoreRouteFlat.NetNode _ inst.netNodes, nn.rest WHILE nn#NIL DO PrintNetNode[nn.first] ENDLOOP}; PrintNetNode: PROC[nNode: CoreRouteFlat.NetNode] ~ { TerminalIO.PutF[" NetNode: %g %g%g\n", IO.rope[nNode.net.name], IO.rope[nNode.node.name], IO.rope[IF nNode.node.public THEN " (public)" ELSE ""]]; FOR pins: LIST OF CoreRouteFlat.Pin _ nNode.node.pins, pins.rest WHILE pins#NIL DO PrintPin[pins.first] ENDLOOP}; PrintPin: PROC[pin: CoreRouteFlat.Pin] ~ { TerminalIO.PutF[" Pin: %6g %5g [%g, %g]\n", IO.rope[SideNames[pin.side]], IO.atom[CD.LayerKey[pin.layer]], IO.int[pin.range.min], IO.int[pin.range.max]]}; SideNames: ARRAY DABasics.Side OF Rope.ROPE _ [bottom: "Bottom", top: "Top", left: "Left", right: "Right"]; END. BCoreRouteFlatImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Don Curry December 2, 1987 12:14:28 pm PST Types Exported Procedures Auxiliary Procedures Attributes, Layout and Decorate ($Hybrid, $GC) Attributes: PWCore.AttributesProc = { layAtom: ATOM _ PWCore.GetLayoutAtom[cellType]; hLayer: Rope.ROPE _ "metal"; vLayer: Rope.ROPE _ "metal2"; rules: GC.DesignRules; structure: Structure; prop: REF _ CoreProperties.GetCellTypeProp[cellType, $VerticalLayer]; IF prop#NIL THEN { name: IO.ROPE _ WITH prop SELECT FROM atom: ATOM => Atom.GetPName[atom], rope: IO.ROPE => rope, ENDCASE => ERROR; IF name.Find["2"]=-1 THEN {hLayer _ "metal2"; vLayer _ "metal"}}; rules _ SELECT layAtom FROM HybridAtom => GC.CreateDesignRules[$cmosB, $Hybrid, hLayer, vLayer], GlobalAtom => GC.CreateDesignRules[$cmosB, $cmosB, hLayer, vLayer], ENDCASE => ERROR; structure _ CoreRouteFlat.FlattenToLayout[cellType, LIST[$w]]; CoreProperties.PutCellTypeProp[cellType, $GCRules, rules]; CoreProperties.PutCellTypeProp[cellType, $GCStruc, structure]}; Layout: PWCore.LayoutProc = { name: Rope.ROPE _ CoreOps.GetCellTypeName[cellType]; result: GC.Result; context: GC.Context; rules: GC.DesignRules _ NARROW[CoreProperties.GetCellTypeProp[cellType, $GCRules]]; struc: Structure _ NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]]; GC.InitialPlace[struc]; context _ GC.CreateContext[name, struc, rules]; GC.DoInitialGlobalRoute[context]; result _ GC.DoDetailRoute[context]; RETURN[result.object]}; Decorate: PWCore.DecorateProc = { CompareFlatInstances: PUBLIC CoreRoute.CompareFlatCTProc = { FOR insts: LIST OF Instance _ struc.instances, insts.rest WHILE insts#NIL DO IF CoreFlat.FlatCellTypeEqualRec[insts.first.flatCell^, flatCT1] THEN RETURN[TRUE]; IF CoreFlat.FlatCellTypeEqualRec[insts.first.flatCell^, flatCT2] THEN RETURN[FALSE]; ENDLOOP; ERROR}; WireToLabels: PROC[wire: Core.Wire] RETURNS [labels: LIST OF Route.Label _ NIL] = { flatWire: CoreFlat.FlatWire = NARROW[RefTab.Fetch[struc.bindings, wire].val]; label: Route.Label = CoreRoute.LabelFlatWire[cellType, flatWire^]; auxLabels: LIST OF Rope.ROPE = NARROW[SymTab.Fetch[struc.auxLabels, label].val]; labels _ CONS [label, auxLabels]}; struc: Structure _ NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]]; CoreRoute.DecorateRoutedArea[ cellType: cellType, obj: obj, wireToLabels: WireToLabels, compareCT: CompareFlatInstances]}; HybridAtom: ATOM _ PWCore.RegisterLayoutAtom[$Hybrid, Layout, Decorate, Attributes]; GlobalAtom: ATOM _ PWCore.RegisterLayoutAtom[$GC, Layout, Decorate, Attributes]; Κ <˜šœ™Jšœ<™˜>Jšœ˜!—Jšœœ!˜5Jšœ;˜;Jšœ&˜&šœœ˜:Jšœ˜Jšœœ˜Jšœ=˜=—šœ œ˜.Jšœ˜Jšœ œ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ —šœœ˜+JšœœŸ-˜>Jšœœ˜Jšœ@˜@šœœœ˜0JšœP˜PJšœR˜RJšœœ&˜FJšœœœ˜#——J˜—šž œœ˜Jšœ˜Jšœ˜Jšœ˜JšœŸ˜$Jšœ˜Jšœ˜Jšœ˜Jšœœ ˜Ašœœœ˜Jšœœ"˜7Jšœ œ:œ˜MJšœ)˜)Jšœœ%˜:Jšœœ#˜8JšœF˜FJšœH˜HJšœ-œ˜@—Jšœ œ˜#J˜—šžœœ˜Jšœ˜Jšœ˜Jšœ˜šœ˜Jšœ˜#—Jšœ œ+˜:šœœ*œœ˜DJšœœ&˜/Jšœ1˜1—J˜—šžœœ>˜UJšœœ˜Jšœœ$˜HJšœ,˜2J˜—šž œœ'œ˜OJšœ$œ˜3šœ#œœ˜7Jšœœ3˜;Jšœœœ5˜DJšœIœ˜R—J˜—šžœœ˜Jšœ˜Jšœ˜Jšœœœ ˜šžœœ.˜