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];
Sos.CheckDesignRules
[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] };
Test: PROC[design, name: ROPE] = {
lib: Library ← OpenLibrary[design];
cell: Core.CellType ← Get[lib, name];
ref: CD.Object ← PW.Get[lib.design, name];
obj: CD.Object ← PWCore.Layout[cell];
iRect: CD.Rect ← CD.InterestRect[obj];
viewer: ViewerClasses.Viewer;
CoreOps.PrintCellType[cell];
IF ref=NIL OR obj=NIL THEN Signal[];
CDOps.IncludeObjectI[lib.design, obj, [0, 0]];
CDCleanUp.CleanUp[lib.design];
viewer ← CDViewer.CreateViewer[lib.design];
CDViewer.ShowAndScale[viewer, iRect];
Signal[]};
Test["IFUCore", "Junk"];
END.