<> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDInstances, CDOps, CDProperties, CDSymbolicObjects, CDViewer, Core, CoreBlock, CoreClasses, CoreGeometry, CoreLibrary, CoreName, CoreProperties, HashTable, IO, PW, PWC, Rope, RopeList, Rosemary, ViewerClasses, WriteCapa; CoreLibraryImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDInstances, CDProperties, CDSymbolicObjects, CoreBlock, CoreClasses, CoreGeometry, CoreName, CoreProperties, HashTable, IO, PW, PWC, Rope, RopeList, Rosemary, WriteCapa EXPORTS CoreLibrary = BEGIN Signal: SIGNAL = CODE; ROPE: TYPE = Core.ROPE; CellType: TYPE = Core.CellType; 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, flatten: INT _ -1, merge: BOOL _ FALSE] 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, NIL, flatten]; IF merge THEN CoreBlock.MergeCell[cell]; 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, flatten: INT _ -1] RETURNS[cell: Core.CellType] = { PW.WriteF["Define Core Cell: %g\n", IO.rope[name]]; IF flatten=-1 THEN obj _ Flatten[obj, rename] -- New independent object ELSE THROUGH [0..flatten) DO obj _ FlattenOneLevel[obj, rename].new ENDLOOP; IF name.Length[]=0 THEN Signal[]; IF CDDirectory.Name[obj]=NIL THEN PWC.SetObjName[obj, name]; cell _ PWC.Extract[obj]; < >> <<{IF CheckMismatch[name, prop, value1, value2].ok THEN RESUME}];>> IF CoreProperties.GetCellTypeProp[cell, $CoreIOGlobal]#NIL THEN RETURN[cell]; [] _ CoreProperties.PutCellTypeProp[cell, $CoreIOGlobal, $CoreIOGlobal]; [] _ CoreName.CellNm[cell, name]; CoreBlock.MarkSides[cell]; CoreBlock.DeletePseudoPublics[cell]; WriteCapa.WriteWireCapa[cell]; -- put capacitance on all leaf cells MarkWeakTransistors[cell]; <> <<[cell, NIL, NIL, TRUE, $PWCLayout, $SinixCMosBInstance, $SinixCMosBWireGeometry];>> }; <> <> <> <> <> <> <> <> <> <0 THEN nv _ TRUE;>> <0 THEN ng _ TRUE;>> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[] _ CoreName.WireNm[cell.public[i], "VDD"];>> <> <> <> <> <> <> <> Flatten: PUBLIC PROC [cell: CD.Object, rename: RenamePinsProc_NIL] RETURNS [new: CD.Object] = { flat: BOOL _ FALSE; new _ Crystallize[cell]; PW.WriteF["Flatten 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]; sides: CoreGeometry.Sides _ CoreGeometry.GetSides[iRect, child]; SELECT TRUE FROM sides[left] => name _ rename[name, left, child.location.y-iBase.y]; sides[right] => name _ rename[name, right, child.location.y-iBase.y]; sides[top] => name _ rename[name, top, child.location.x-iBase.x]; sides[bottom] => name _ rename[name, bottom, 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; iRect: CD.Rect _ CD.InterestRect[cell]; iBase: CD.Position _ CDBasics.BaseOfRect[iRect]; IF NOT CDCells.IsCell[cell] 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 CDCells.IsCell[inst.ob] THEN { 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 } ELSE IncludeInNew[inst]; ENDLOOP; [ ] _ CDCells.RepositionCell[new, NIL] }; Crystallize: PUBLIC PROC [cell: CD.Object] RETURNS [new: CD.Object] = { new _ cell; WHILE cell.class.inDirectory AND NOT CDCells.IsCell[new] 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["Flatten cell: %g \n", 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 CDCells.IsCell[inst.ob] 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] }; 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}; <> <