<> <> <> <> <> DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, RefTab, PWCore, Rope, RTBasic, RTCoreUtil; RTCoreUtilImpl: CEDAR PROGRAM IMPORTS CoreFlat, CoreOps, CoreProperties, RefTab, PWCore, Rope, RTBasic EXPORTS RTCoreUtil = BEGIN GetCoreIntProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM, default: INT] RETURNS [num: INT] ~ { <> value: REF _ CoreProperties.GetCellTypeProp[cellType, prop]; IF value=NIL THEN num _ default ELSE WITH value SELECT FROM nat: REF NAT => num _ nat^; int: REF INT => num _ int^; ENDCASE => RTBasic.Error[callingError, "NAT or INT expected"]}; PutCoreIntProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM, num: INT] = { <> CoreProperties.PutCellTypeProp[cellType, prop, NEW[INT _ num]]}; GetCoreRealProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM, default: REAL] RETURNS [num: REAL] ~ { <> value: REF _ CoreProperties.GetCellTypeProp[cellType, prop]; IF value=NIL THEN num _ default ELSE num _ NARROW[value, REF REAL]^}; PutCoreRealProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM, num: REAL] = { <> CoreProperties.PutCellTypeProp[cellType, prop, NEW[REAL _ num]]}; GetCoreBoolProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM, default: BOOL] RETURNS [val: BOOL] ~ { <> value: REF _ CoreProperties.GetCellTypeProp[cellType, prop]; IF value=NIL THEN val _ default ELSE val _ NARROW[value, REF BOOL]^}; PutCoreBoolProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM, val: BOOL] = { <> CoreProperties.PutCellTypeProp[cellType, prop, NEW[BOOL _ val]]}; GetCoreAtomProp: PUBLIC PROC [cellType: Core.CellType, prop: ATOM] RETURNS [ATOM] ~ { <> RETURN[NARROW[CoreProperties.GetCellTypeProp[cellType, prop]]]}; EnumerateInstances: PUBLIC PROC [cellType: Core.CellType, eachInstance: RTCoreUtil.EachInstanceProc] RETURNS [quit: BOOL _ FALSE] = { <> parentRCT: CoreClasses.RecordCellType _ NARROW[cellType.data]; IF parentRCT = NIL THEN RTBasic.Error[callingError, Rope.Cat["Invalid Record Cell: ", CoreOps.GetCellTypeName[cellType]]]; FOR in: NAT IN [0..parentRCT.size) DO instance: CoreClasses.CellInstance _ parentRCT[in]; quit _ eachInstance[instance]; ENDLOOP}; EnumerateFlatWires: PUBLIC PROC [wire: Core.Wire, eachWire: RTCoreUtil.EachWireProc] RETURNS [quit: BOOL _ FALSE] = { DoWire: CoreOps.EachWireProc = { IF wire.size = 0 THEN [subWires, quit] _ eachWire[wire]}; quit _ CoreOps.VisitWire[wire, DoWire]}; EnumerateFlatInstancePins: PUBLIC PROC [cellInstance: CoreClasses.CellInstance, eachInstancePin: RTCoreUtil.EachInstancePinProc] = { DoWire: CoreOps.EachWirePairProc = { <> IF actualWire # NIL AND actualWire.size = 0 AND publicWire.size = 0 THEN [subWires, quit] _ eachInstancePin[actualWire, publicWire]}; [] _ CoreOps.VisitBinding[cellInstance.actual, cellInstance.type.public, DoWire]}; <<-- Flatten until the cellType has a $Layout property>> defaultFlatten: PUBLIC RTCoreUtil.FlattenCellTypeProc = { RETURN[PWCore.GetLayoutAtom[cellType]=NIL]}; -- $Layout Flatten: PUBLIC PROC [root: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc, definePublicWire, defineInternalWire: RTCoreUtil.FlatWireProc, defineInstance: RTCoreUtil.FlatInstanceProc, interestingProperties: RTCoreUtil.PropertyKeys] = { BuildPublic: PROC [wire: Core.Wire] = { flatWire: CoreFlat.FlatWire = NEW [CoreFlat.FlatWireRec _ [wire: wire]]; IF RefTab.Fetch[rootFlatsToInternals, flatWire].val = NIL THEN { -- public not seen [] _ RefTab.Store[rootFlatsToInternals, flatWire, wire]; [] _ defineInternalWire[flatWire^]; [] _ definePublicWire[flatWire^]}}; EachInstance: CoreFlat.BoundFlatCellProc = { <> BuildActual: PROC [public: Core.Wire] RETURNS [actual: Core.Wire] = { IF public.size=0 THEN { flatWire: CoreFlat.FlatWire _ NARROW [RefTab.Fetch[bindings, public].val]; actual _ NARROW [RefTab.Fetch[rootFlatsToInternals, flatWire].val]; IF actual = NIL THEN { actual _ CoreOps.CopyWire[flatWire.wire]; actual.properties _ CopyProps[flatWire.wire.properties, interestingProperties]; [] _ RefTab.Store[rootFlatsToInternals, flatWire, actual]; [] _ defineInternalWire[flatWire^]}} ELSE { actual _ CoreOps.CreateWires[size: public.size]; FOR i: NAT IN [0 .. public.size) DO actual[i] _ BuildActual[public[i]]; ENDLOOP}}; IF instance=NIL OR (flattenCellType # NIL AND flattenCellType[cell]) OR (PWCore.GetLayoutAtom[cell]=NIL AND cell.class.recast#NIL) THEN CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, EachInstance] ELSE { IF cell.public.size>0 THEN [] _ BuildActual[cell.public]; [] _ defineInstance[flatCell, cell, bindings, instance.properties]}}; rootFlatsToInternals: CoreFlat.Bindings _ RefTab.Create[equal: CoreFlat.FlatWireEqual, hash: CoreFlat.FlatWireHash]; CoreOps.VisitRootAtomics[root.public, BuildPublic]; EachInstance[cell: root, bindings: CoreFlat.InitialBindingTable[root]]}; CopyProps: PUBLIC PROC [sourceProperties: Core.Properties, interestingProperties: RTCoreUtil.PropertyKeys] RETURNS [destProperties: Core.Properties _ NIL] ~ { <> Consume: PROC [prop: ATOM, value: REF ANY] ~ { FOR index: NAT IN [0 .. interestingProperties.size) DO IF prop = interestingProperties[index] THEN { destProperties _ CoreProperties.PutProp[destProperties, prop, value]; EXIT}; ENDLOOP}; CoreProperties.Enumerate[sourceProperties, Consume]}; END.