<> <> <> 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"]; <> <> <> <> <> <> <> <> <> <> < Atom.GetPName[atom],>> < rope,>> < ERROR;>> <> <> < GC.CreateDesignRules[$cmosB, $Hybrid, hLayer, vLayer],>> < GC.CreateDesignRules[$cmosB, $cmosB, hLayer, vLayer],>> < ERROR;>> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <<>> END.