TestCore.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Bertrand Serlet, March 28, 1987 11:20:07 pm PST
Barth, April 16, 1987 4:20:20 pm PDT
Mike Spreitzer February 27, 1987 4:42:32 pm PST
DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, GList, RefTab;
TestCore: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, GList, RefTab = BEGIN OPEN Core;
CreateInverter: PROC [] RETURNS [cellType: CellType] = {
In: Wire ← CoreOps.CreateWire[name: "In"];
Out: Wire ← CoreOps.CreateWire[name: "Out"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
Vdd: Wire ← CoreOps.CreateWire[name: "Vdd"];
ntrans: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Out, Gnd]],
type: CoreClasses.CreateTransistor[nE]
]];
ptrans: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Out, Vdd, Vdd]],
type: CoreClasses.CreateTransistor[pE]
]];
cellType ← CoreClasses.CreateRecordCell[
public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
instances: LIST [ntrans, ptrans],
name: "Inverter"
];
};
Create2Inverter: PROC [] RETURNS [cellType: CellType] = {
In: Wire ← CoreOps.CreateWire[name: "In"];
Out: Wire ← CoreOps.CreateWire[name: "Out"];
Gnd: Wire ← CoreCreate.Seq[size:2, name: "Gnd"];
Vdd: Wire ← CoreCreate.Seq[size:2, name: "Vdd"];
Intern: Wire ← CoreOps.CreateWire[name: "Intern"];
inverter: CellType ← CreateInverter[];
first: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Intern, Gnd[0], Vdd[0]]],
type: inverter
]];
second: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [Intern, Out, Gnd[1], Vdd[1]]],
type: inverter
]];
cellType ← CoreClasses.CreateRecordCell[
public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd, Intern]],
instances: LIST [first, second],
name: "Inverter2"
];
};
CreateInverters: PROC [n: NAT] RETURNS [cellType: CellType] = {
args: CoreClasses.SequenceCellType ← NEW [CoreClasses.SequenceCellTypeRec ← [base: CreateInverter[], count: n, sequence: NEW [CoreClasses.SequenceSetRec[2]]]];
args.sequence[0] ← 0;
args.sequence[1] ← 1;
cellType ← CoreClasses.CreateSequence[name: "ALotOfInverters", args: args];
};
CreateInvertersPlusOne: PROC [n: NAT] RETURNS [cellType: CellType] = {
public: Wire ← CoreCreate.Wires["SameIn", CoreCreate.Seq["Outs", n+1], "Gnd", "Vdd"];
pas: LIST OF CoreCreate.PANIL;
FOR i: NAT IN [0 .. n) DO pas ← CONS [[CoreCreate.Index["In", i], "SameIn"], pas] ENDLOOP;
pas ← CONS [["Out", CoreCreate.Range[public[1], 1, n]], pas];
cellType ← CoreCreate.Cell[
public: public,
instances: LIST [
CoreCreate.Instance[CreateInverter[], ["In", "SameIn"], ["Out", public[1][0]], ["Gnd", CoreOps.CreateWire[name: "Gnd"]], ["Vdd", CoreCreate.FindWire[public, "Vdd"]]],
CoreCreate.InstanceList[CreateInverters[n], pas]
],
name: "InvertersPlusOne"
];
};
CreateUnNamed2Inverter: PROC [] RETURNS [cellType: CellType] = {
In: Wire ← CoreOps.CreateWire[];
Out: Wire ← CoreOps.CreateWire[];
Gnd: Wire ← CoreCreate.Seq[size:2];
Vdd: Wire ← CoreCreate.Seq[size:2];
Intern: Wire ← CoreOps.CreateWire[];
inverter: CellType ← CreateInverter[];
first: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Intern, Gnd[0], Vdd[0]]],
type: inverter
]];
second: CoreClasses.CellInstance ← NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [Intern, Out, Gnd[1], Vdd[1]]],
type: inverter
]];
cellType ← CoreClasses.CreateRecordCell[
public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd, Intern]],
instances: LIST [first, second],
name: "Inverter2",
giveNames: TRUE
];
};
Test: PROC [] = {
AllTheWay: FlattenCellTypeProc = {flatten ← cellType.class#CoreClasses.transistorCellClass};
cellType, ct, unspec: CellType;
data: CoreClasses.RecordCellType;
public, wire: Wire;
wires: Wires;
table: RefTab.Ref;
wirePath: ROPE;
flatWire: CoreFlat.FlatWireRec;
cellType ← CreateInverter[];
data ← NARROW [cellType.data];
IF CoreClasses.InstanceIndex[cellType, data[1]]#1 THEN ERROR;
cellType ← Create2Inverter[];
IF CoreClasses.InstanceIndex[cellType, data[1]]#-1 THEN ERROR;
cellType ← CreateInverters[6];
cellType ← CreateInvertersPlusOne[6];
cellType ← CreateUnNamed2Inverter[];
IF CoreOps.FindWire[cellType.public, "In"]=NIL THEN ERROR;
IF CoreOps.FindWire[cellType.public, "Out"]=NIL THEN ERROR;
IF CoreOps.FindWire[cellType.public, "Gnd"]#NIL THEN ERROR;
IF CoreOps.FindWire[cellType.public, "Vdd"]#NIL THEN ERROR;
IF CoreOps.FindWire[cellType.public, "Intern"]#NIL THEN ERROR;
wire ← cellType.public[2]; -- Gnd
wires ← LIST [wire];
IF NOT GList.EqLists[CoreOps.ParentWires[cellType.public, wire[0]], wires] THEN ERROR;
wires ← LIST [cellType.public];
IF NOT GList.EqLists[CoreOps.ParentWires[cellType.public, wire], wires] THEN ERROR;
IF NOT GList.EqLists[CoreOps.ParentWires[cellType.public, cellType.public], NIL] THEN ERROR;
Test for CoreFlat
cellType ← Create2Inverter[];
cellType ← Flatten[cellType, AllTheWay];
IF cellType.public.size#6 THEN ERROR;
data ← NARROW [cellType.data];
IF data.internal.size#7 THEN ERROR;
IF data.size#4 THEN ERROR;
cellType ← Create2Inverter[];
flatWire ← CoreFlat.ParseWirePath[cellType, "Intern"];
wirePath ← CoreFlat.WirePathRope[cellType, flatWire];
flatWire ← CoreFlat.ParseWirePath[cellType, "/0.actual.In"];
wirePath ← CoreFlat.WirePathRope[cellType, flatWire];
Test for CoreClasses.CreatePermutedRecordCell
cellType ← Create2Inverter[];
public ← CoreCreate.Wires[CoreCreate.Seq["Gnd", 2], "Out"]; -- no Vdd and In and Out collapsed
unspec ← CoreClasses.CreateUnspecified[public];
table ← RefTab.Create[];
[] ← RefTab.Store[table, CoreOps.FindWire[cellType.public, "Gnd"], CoreOps.FindWire[public, "Gnd"]];
[] ← RefTab.Store[table, CoreOps.FindWire[cellType.public, "In"], CoreOps.FindWire[public, "Out"]];
[] ← RefTab.Store[table, CoreOps.FindWire[cellType.public, "Out"], CoreOps.FindWire[public, "Out"]];
ct ← CoreClasses.CreatePermutedRecordCell[public, cellType, table];
Test for Properties inheritance
cellType ← Create2Inverter[];
IF CoreProperties.InheritCellTypeProp[cellType, $foo]#NIL THEN ERROR;
CoreProperties.PutCellTypeProp[cellType, $foo, $bar];
IF CoreProperties.InheritCellTypeProp[cellType, $foo]#$bar THEN ERROR;
CoreProperties.PutCellTypeProp[cellType, $foo, NIL];
CoreProperties.PutCellClassProp[cellType.class, $foo, $bar];
IF CoreProperties.InheritCellTypeProp[cellType, $foo]#$bar THEN ERROR;
CoreProperties.PutCellTypeProp[cellType, $foo, $zob];
IF CoreProperties.InheritCellTypeProp[cellType, $foo]#$zob THEN ERROR;
CoreProperties.PutCellTypeProp[cellType, $foo, NIL];
CoreProperties.PutCellClassProp[cellType.class, $foo, NIL];
IF CoreProperties.InheritCellTypeProp[cellType, $foo]#NIL THEN ERROR;
CoreProperties.PutWireProp[CoreOps.FindWire[cellType.public, "Gnd"], $bip, $bop];
IF CoreProperties.InheritPublicProp[cellType, CoreOps.FindWire[cellType.public, "Gnd"], $bip]#$bop THEN ERROR;
IF CoreProperties.InheritPublicProp[cellType, CoreOps.FindWire[cellType.public, "Gnd"], $burp]#NIL THEN ERROR;
};
FlattenCellTypeProc: TYPE = PROC [cellType: CellType] RETURNS [flatten: BOOL];
Flatten: PUBLIC PROC [root: CellType, flattenCellType: FlattenCellTypeProc] RETURNS [flat: CellType] = {
BuildPublic: PROC [wire: Wire] = {
flatWire: CoreFlat.FlatWire = NEW [CoreFlat.FlatWireRec ← [wire: wire, flatCell: CoreFlat.rootCellType]];
newPublic: Wire;
IF RefTab.Fetch[rootFlatsToInternals, flatWire].val#NIL THEN RETURN; -- public already seen
newPublic ← CoreOps.CreateWire[];
[] ← RefTab.Store[rootFlatsToInternals, flatWire, newPublic];
internal ← CONS [newPublic, internal];
publics ← CONS [newPublic, publics];
};
BuildActual: PROC [public: Wire, bindings: CoreFlat.Bindings] RETURNS [actual: Wire] = {
IF public.size=0 THEN {
flatWire: CoreFlat.FlatWire ← NARROW [RefTab.Fetch[bindings, public].val];
IF flatWire=NIL THEN flatWire ← NEW[CoreFlat.FlatWireRec ← [
flatCell: CoreFlat.rootCellType,
wire: public]];
actual ← NARROW [RefTab.Fetch[rootFlatsToInternals, flatWire].val];
IF actual#NIL THEN RETURN;
actual ← CoreOps.CreateWire[];
[] ← RefTab.Store[rootFlatsToInternals, flatWire, actual];
internal ← CONS [actual, internal];
}
ELSE {
actual ← CoreOps.CreateWires[size: public.size];
FOR i: NAT IN [0 .. actual.size) DO
actual[i] ← BuildActual[public[i], bindings];
ENDLOOP;
};
};
FlattenCell: CoreFlat.BoundFlatCellProc = {
[cell: CellType, target: FlatCellTypeRec ← allFlatCells, flatCell: FlatCellTypeRec ← [], bindings: Bindings ← NIL, instance: CellInstance ← NIL, parent: CellType ← NIL, flatParent: FlatCellTypeRec ← []]
actual: Wire;
IF flattenCellType[cell] THEN CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCell]
ELSE {
actual ← BuildActual[cell.public, bindings];
FOR i: NAT IN [0 .. actual.size) DO
IF NOT CoreOps.Member[internal, actual[i]] THEN internal ← CONS [actual[i], internal];
ENDLOOP;
instances ← CONS [
CoreClasses.CreateInstance[actual: actual, type: cell],
instances];
};
};
rootFlatsToInternals: CoreFlat.Bindings ← RefTab.Create[equal: CoreFlat.FlatWireEqual, hash: CoreFlat.FlatWireHash];
publics: LIST OF Wire ← NIL;
internal: LIST OF Wire ← NIL;
instances: LIST OF CoreClasses.CellInstance ← NIL;
CoreOps.VisitRootAtomics[root.public, BuildPublic];
FlattenCell[root];
flat ← CoreClasses.CreateRecordCell[
public: CoreOps.CreateWire[publics],
internal: CoreOps.CreateWire[internal],
instances: instances,
giveNames: TRUE];
};
END.