<> <> <> DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDInstances, CoreName, CDOps, CDSymbolicObjects, CDProperties, CDViewer, Core, CoreLibrary, CoreBlock, CoreFrame, CoreProperties, HashTable, IO, PW, PWCore, PWPins, Rope, RopeList, ViewerClasses; CoreLibraryImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDInstances, CDSymbolicObjects, CDProperties, CoreBlock, CoreName, CoreProperties, HashTable, IO, PW, PWCore, PWPins, Rope, RopeList EXPORTS CoreLibrary = BEGIN Signal: SIGNAL = CODE; ROPE: TYPE = CoreLibrary.ROPE; Library: TYPE = CoreLibrary.Library; LibraryRec: TYPE = CoreLibrary.LibraryRec; RenamePinsProc: TYPE = CoreLibrary.RenamePinsProc; designArchive: LIST OF CD.Design _ NIL; -- prevent garbage collection OpenLibrary: PUBLIC PROC[name: ROPE] RETURNS[lib: Library] = { lib _ NEW[LibraryRec _ [ design: PW.OpenDesign[name], table: HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope] ] ]; IF lib.design=NIL THEN Signal[]; designArchive _ CONS[lib.design, designArchive]}; Get: PUBLIC PROC[ lib: Library, name: ROPE, removeNamed: BOOL _ TRUE, conds: LIST OF ROPE _ NIL] RETURNS[cell: Core.CellType] = { obj: CD.Object; refName: ROPE _ name; IF name.Length[]=0 THEN Signal[]; IF conds#NIL THEN { conds _ RopeList.Sort[conds, RopeList.Compare]; refName _ refName.Cat[IF removeNamed THEN "-Remove" ELSE "-Keep"]; FOR list: LIST OF ROPE _ conds, list.rest WHILE list#NIL DO refName _ refName.Cat["-", (IF list.first=NIL THEN "NONE" ELSE list.first)] ENDLOOP }; name _ CoreName.RopeNm[name]; refName _ CoreName.RopeNm[refName]; cell _ NARROW[HashTable.Fetch[lib.table, refName].value]; IF cell#NIL THEN RETURN[cell]; obj _ CDDirectory.Fetch[lib.design, name].object; IF obj=NIL THEN RETURN[NIL]; IF conds#NIL THEN obj _PW.Inst[obj, conds, removeNamed]; cell _ ObjCell[obj, refName]; Set[lib, refName, cell]}; Set: PUBLIC PROC[ lib: Library, name: ROPE, cell: Core.CellType ] = { old: Core.CellType; name _ CoreName.CellNm[cell, name].n; IF name.Length[]=0 THEN Signal[]; old _ NARROW[HashTable.Fetch[lib.table, name].value]; IF old#NIL AND old#cell THEN Signal[]; [ ] _ HashTable.Store[lib.table, name, cell]}; ObjCell: PUBLIC PROC[ obj: CD.Object, name: ROPE, rename: RenamePinsProc _ NIL] RETURNS[cell: Core.CellType] = { PW.WriteF["\nDefine Core Cell: %g", IO.rope[name]]; obj _ Flatten[obj, rename]; -- New independent object cell _ PWCore.FromLayoutWithoutPublic[obj]; IF name.Length[]=0 THEN Signal[]; [ ] _ CoreName.CellNm[cell, name]; <> <<[cell, NIL, NIL, TRUE, $PWCoreLayout, $SinixCMosBInstance, $SinixCMosBWireGeometry];>> CoreBlock.MarkSides[cell] }; Flatten: PUBLIC PROC [cell: CD.Object, rename: RenamePinsProc_NIL] RETURNS [new: CD.Object] = { flat: BOOL _ FALSE; new _ Crystallize[cell]; PW.WriteF["\nFlatten cell: %g ", IO.rope[NARROW[new.specificRef, CD.CellPtr].name]]; FOR pass: INT IN [0..10) WHILE NOT flat DO PW.WriteF["."]; [new, flat] _ FlattenOneLevel[new, rename] ENDLOOP; PW.WriteF[" done\n"]}; FlattenOneLevel: PUBLIC PROC [cell: CD.Object, rename: RenamePinsProc_NIL] RETURNS [new: CD.Object, flat: BOOL _ TRUE] = { IncludeInNew: PROC[child: CD.Instance] = { baby: CD.Instance; IF CDSymbolicObjects.IsPin[child.ob] AND rename#NIL THEN { name: ROPE _ CDSymbolicObjects.GetName[child]; side: CoreFrame.Side5 _ PWPins.GetSide[cell, child]; SELECT side FROM left, right => name _ rename[name, side, child.location.y-iBase.y]; top, bottom => name _ rename[name, side, child.location.x-iBase.x]; ENDCASE => RETURN; IF name=NIL THEN RETURN; CDSymbolicObjects.SetName[child, name]}; baby _ CDCells.IncludeOb[ design: NIL, cell: new, ob: child.ob, position: child.location, -- iBase, orientation: child.orientation, cellCSystem: cdCoords, -- interrestCoords, obCSystem: cdCoords, -- interrestCoords, mode: dontPropagate ].newInst; CDProperties.CopyProps[child.properties, baby] }; list0, list1: CD.InstanceList; iBase: CD.Position _ CDBasics.BaseOfRect[CD.InterestRect[cell]]; IF NOT ISTYPE[cell.specificRef, CD.CellPtr] THEN ERROR; new _ CDCells.CreateEmptyCell[]; CDCells.SetInterestRect[new, CD.InterestRect[cell]]; list0 _ NARROW [cell.specificRef, CD.CellPtr].contents; FOR list0 _ list0, list0.rest WHILE list0 # NIL DO inst: CD.Instance _ NEW[CD.InstanceRep _ list0.first^]; inst.ob _ Crystallize[inst.ob]; IF NOT ISTYPE[inst.ob.specificRef, CD.CellPtr] THEN IncludeInNew[inst] ELSE { list1 _ NARROW [inst.ob.specificRef, CD.CellPtr].contents; list1 _ CDInstances.ComposedList[list1, inst.location, inst.ob.size, inst.orientation]; FOR list1 _ list1, list1.rest WHILE list1 # NIL DO flat _ flat AND NOT inst.ob.class.inDirectory; IncludeInNew[list1.first] ENDLOOP }; ENDLOOP; [ ] _ CDCells.RepositionCell[new, NIL] }; hardLayout: PUBLIC ATOM _ CoreProperties.RegisterProperty[$CoreLibraryHardLayout]; HardLayout: PUBLIC PROC [cell: Core.CellType] RETURNS [obj: CD.Object] = { IF cell=NIL THEN RETURN[NIL]; obj _ NARROW[CoreProperties.GetCellTypeProp[cell, hardLayout]]; IF obj=NIL THEN obj _ Crystallize[PWCore.Layout[cell]]; CoreProperties.PutCellTypeProp[cell, hardLayout, obj]}; Crystallize: PUBLIC PROC [cell: CD.Object] RETURNS [new: CD.Object] = { new _ cell; WHILE cell.class.inDirectory AND NOT ISTYPE[new.specificRef, CD.CellPtr] DO new _ CDDirectory.Expand[new, NIL, NIL].new; IF new=NIL THEN Signal[]; ENDLOOP}; FlattenAll: PROC [cell: CD.Object] RETURNS [new: CD.Object] = { cell _ Crystallize[cell]; PW.WriteF["\nFlatten cell: %g ", IO.rope[NARROW[cell.specificRef, CD.CellPtr].name]]; new _ FlattenAllLevels[cell]}; FlattenAllLevels: PROC [cell: CD.Object] RETURNS [new: CD.Object] = { IncludeInNew: PROC[child: CD.Instance] = { baby: CD.Instance; baby _ CDCells.IncludeOb[ design: NIL, cell: new, ob: child.ob, position: child.location, -- iBase, orientation: child.orientation, cellCSystem: cdCoords, -- interrestCoords, obCSystem: cdCoords, -- interrestCoords, mode: dontPropagate ].newInst; CDProperties.CopyProps[child.properties, baby] }; list0, list1: CD.InstanceList; iBase: CD.Position _ CDBasics.BaseOfRect[CD.InterestRect[cell]]; IF NOT cell.class.inDirectory THEN RETURN[cell]; cell _ Crystallize[cell]; new _ CDCells.CreateEmptyCell[]; CDCells.SetInterestRect[new, CD.InterestRect[cell]]; list0 _ NARROW [cell.specificRef, CD.CellPtr].contents; FOR list0 _ list0, list0.rest WHILE list0 # NIL DO inst: CD.Instance _ NEW[CD.InstanceRep _ list0.first^]; inst.ob _ FlattenAllLevels[inst.ob]; IF NOT ISTYPE[inst.ob.specificRef, CD.CellPtr] THEN IncludeInNew[inst] ELSE { list1 _ NARROW [inst.ob.specificRef, CD.CellPtr].contents; list1 _ CDInstances.ComposedList[list1, inst.location, inst.ob.size, inst.orientation]; FOR list1 _ list1, list1.rest WHILE list1 # NIL DO IncludeInNew[list1.first] ENDLOOP }; ENDLOOP; [ ] _ CDCells.RepositionCell[new, NIL] }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <<>> END.