<> <> <> <<>> DIRECTORY CD, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, RefTab, IO, PWCore, Rope, Rosemary, Sinix, SourceFromLayout, TerminalIO; SourceFromLayoutImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreGeometry, CoreOps, CoreProperties, RefTab, IO, PWCore, Rope, Rosemary, Sinix, TerminalIO EXPORTS SourceFromLayout = BEGIN Wire: TYPE = Core.Wire; CellType: TYPE = Core.CellType; ROPE: TYPE = Core.ROPE; Object: TYPE = CD.Object; Signal: SIGNAL = CODE; LayoutSource: PUBLIC PROC[obj: Object, name: ROPE] RETURNS[cell: CellType] = { ect: CellType; root: ROPE _ name.Substr[0, name.Index[0, "."]]; TerminalIO.PutF["Define Core Cell: %g\n", IO.rope[name]]; IF name.Length[]=0 THEN Signal[]; ect _ NARROW [Sinix.Extract[obj, PWCore.extractMode].result]; [] _ CoreOps.SetCellTypeName[ect, name]; MarkWeakTransistors[ect]; FixUpPublic[ect]; cell _ CopyCell[ect]; PWCore.SetLayout[cell, $Value, $PWCoreValue, obj]; []_PWCore.Layout[cell]}; MarkWeakTransistors: PROC [cell: CellType] = { SELECT cell.class FROM CoreClasses.transistorCellClass => ERROR; CoreClasses.recordCellClass => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; FOR child: NAT IN [0..data.size) DO IF data.instances[child].type.class # CoreClasses.transistorCellClass THEN MarkWeakTransistors[ data.instances[child].type] ELSE { name: ROPE _ NARROW [CoreProperties.GetCellInstanceProp[data.instances[child], $CoreName]]; IF Rope.Equal[name, "driveWeak"] THEN [] _ Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]}; ENDLOOP }; ENDCASE => ERROR}; SortFlatWire: PROC[wire: Wire] = { FOR i: NAT IN [0.. wire.size-1) DO FOR j: NAT IN (i.. wire.size) DO TwoWires: TYPE = RECORD [w1, w2: Wire]; n1: ROPE _ CoreOps.GetShortWireName[wire[i]]; n2: ROPE _ CoreOps.GetShortWireName[wire[j]]; IF Rope.Compare[n1, n2]=greater THEN [wire[i], wire[j]] _ TwoWires[wire[j], wire[i]] ENDLOOP ENDLOOP}; FixUpPublic: PROC[cell: CellType] = { pubs: Core.Wires _ NIL; rec: CoreClasses.RecordCellType _ NARROW[cell.data]; PWCore.SortInstances[PWCore.extractMode.decoration, cell, PWCore.SortInY]; FOR i: INT DECREASING IN [0..cell.public.size) DO IF GetWireSides[ cell, cell.public[i] ]#CoreGeometry.noSide THEN pubs _ CONS[ cell.public[i], pubs] ELSE TerminalIO.PutF["\nRemoving pseudo public: %g", IO.rope[ CoreOps.GetShortWireName[cell.public[i] ] ] ]; ENDLOOP; cell.public _ CoreOps.CreateWire[pubs]; SortFlatWire[cell.public]; SortFlatWire[rec.internal]}; GetWireSides: PROC[cell: CellType, wire: Wire] RETURNS[sides: CoreGeometry.Sides _ CoreGeometry.noSide] = { eachPin: CoreGeometry.EachPinProc = {sides[side] _ TRUE}; []_CoreGeometry.EnumerateSides[PWCore.extractMode.decoration, cell, wire, eachPin]}; CopyCell: PROC[old: CellType] RETURNS[new: CellType] = { Copy: PROC[oldWire: Wire] RETURNS[newWire: Wire] = { IF (newWire_NARROW[RefTab.Fetch[table, oldWire].val])=NIL THEN { newWire _ CoreOps.CreateWires[oldWire.size, CoreOps.GetShortWireName[oldWire]]; []_RefTab.Store[table, oldWire, newWire]; FOR i: NAT IN [0..newWire.size) DO newWire[i] _ Copy[oldWire[i]] ENDLOOP}}; table: RefTab.Ref _ RefTab.Create[]; name: ROPE _ CoreOps.GetCellTypeName[old]; oldRec: CoreClasses.RecordCellType _ NARROW[old.data]; newRec: CoreClasses.RecordCellType _ NEW[CoreClasses.RecordCellTypeRec[oldRec.size]]; new _ CoreOps.CreateCellType [old.class, Copy[old.public], newRec, Rope.Cat["Src", name]]; newRec.internal _ Copy[oldRec.internal]; FOR i: NAT IN [0..newRec.size) DO newRec[i] _ NEW[CoreClasses.CellInstanceRec _ [ actual: Copy[oldRec[i].actual], type: oldRec[i].type ]]; ENDLOOP }; END.