CoreLibraryImpl.mesa
Copyright c 1985 by Xerox Corporation. All rights reserved.
Curry May 14, 1986 12:46:15 pm PDT
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];
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: BOOLTRUE] = {
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.