SinixFlattenImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Bertrand Serlet January 30, 1986 1:22:24 pm PST
Barth, January 13, 1986 1:40:28 pm PST
DIRECTORY Core, CoreClasses, CoreOps, CoreProperties, HashTable, Sinix, SinixFlatten;
SinixFlattenImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreOps, CoreProperties, HashTable, Sinix
EXPORTS SinixFlatten =
BEGIN OPEN SinixFlatten;
Wire: TYPE = Core.Wire;
CellType: TYPE = Core.CellType;
Flatten: PUBLIC PROC [cellType: CellType, expand: ExpandProc] RETURNS [flat: CellType, isRecordCell: BOOLTRUE] = {
WHILE (isRecordCell ← expand[cellType]) AND cellType.class#CoreClasses.recordCellClass DO
cellType ← CoreOps.Recast[cellType];
IF cellType=NIL THEN ERROR;
ENDLOOP;
IF ~isRecordCell THEN RETURN[cellType, FALSE];
BEGIN
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
flatInterns: LIST OF Wire ← NIL;
flatInstances: LIST OF CoreClasses.CellInstance ← NIL;
correspondindFlatWires: HashTable.Table ← HashTable.Create[];
FOR i: NAT IN [0 .. data.internal.size) DO
thisFlat: Wire ← CoreOps.CopyWire[data.internal[i]];
flatInterns ← CONS [thisFlat, flatInterns];
[] ← HashTable.Store[correspondindFlatWires, data.internal[i], thisFlat];
ENDLOOP;
FOR i: NAT IN [0 .. data.size) DO
instance: CoreClasses.CellInstance ← data[i];
subCell: CellType; isSubRecordCell: BOOL;
[subCell, isSubRecordCell] ← Flatten[instance.type, expand];
IF ~isSubRecordCell THEN {
thisInstance: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: MakeFlattenedWire[correspondindFlatWires, instance.actual],
type: subCell,
properties: CoreProperties.CopyProps[instance.properties]]];
flatInstances ← CONS [thisInstance, flatInstances];
} ELSE {
The game is now to mark each of the internal wires of the instance. Some are derived from the actual, others must be added to flatInterns;
subData: CoreClasses.RecordCellType ← NARROW [subCell.data];
subCorrespondingFlatWires: HashTable.Table ← HashTable.Create[];
FOR i: NAT IN [0 .. subCell.public.size) DO
val: REF ← HashTable.Fetch[correspondindFlatWires, instance.actual[i]].value;
IF val=NIL THEN ERROR;
[] ← HashTable.Store[subCorrespondingFlatWires, subCell.public[i], val];
ENDLOOP;
FOR i: NAT IN [0 .. subData.internal.size) DO
IF HashTable.Fetch[subCorrespondingFlatWires, subData.internal[i]].value=NIL THEN {
thisFlat: Wire ← CoreOps.CopyWire[subData.internal[i]];
flatInterns ← CONS [thisFlat, flatInterns];
[] ← HashTable.Store[subCorrespondingFlatWires, subData.internal[i], thisFlat];
Sinix.PutWireGeometryProp[
thisFlat,
Sinix.TransformList[NARROW[CoreProperties.GetCellInstanceProp[instance, Sinix.instanceProp]], Sinix.GetWireGeometryProp[subData.internal[i]]]];
};
ENDLOOP;
FOR i: NAT IN [0 .. subData.size) DO
subInstance: CoreClasses.CellInstance ← subData[i];
thisInstance: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: MakeFlattenedWire[subCorrespondingFlatWires, subInstance.actual],
type: subInstance.type,
properties: CoreProperties.CopyProps[subInstance.properties]]];
CoreProperties.PutCellInstanceProp[
thisInstance,
Sinix.instanceProp,
Sinix.Transform[
NARROW [CoreProperties.GetCellInstanceProp[instance, Sinix.instanceProp]],
NARROW [CoreProperties.GetCellInstanceProp[subInstance, Sinix.instanceProp]]]];
flatInstances ← CONS [thisInstance, flatInstances];
ENDLOOP;
};
ENDLOOP;
flat ← CoreClasses.CreateRecordCell[
public: MakeFlattenedWire[correspondindFlatWires, cellType.public],
internal: CoreOps.CreateWire[flatInterns],
instances: flatInstances,
name: CoreOps.GetCellTypeName[cellType],
props: CoreProperties.CopyProps[cellType.properties]
];
END;
};
NonTransistorsExpand: PUBLIC ExpandProc = {
expand ← cellType.class#CoreClasses.transistorCellClass;
};
MakeFlattenedWire: PROC [table: HashTable.Table, oldWire: Wire] RETURNS [newWire: Wire] = {
newWire ← CoreOps.CreateWires[size: oldWire.size];
FOR i: NAT IN [0 .. oldWire.size) DO
newWire[i] ← NARROW [HashTable.Fetch[table, oldWire[i]].value];
IF newWire[i]=NIL THEN ERROR;
ENDLOOP;
};
END.