TestBoole.mesa
Copyright Ó 1985, 1986, 1987 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet July 31, 1985 3:03:17 pm PDT
Last edited by Bertrand Serlet September 1, 1987 11:42:59 pm PDT
Barth, April 1, 1987 11:12:52 am PST
Louis Monier April 8, 1986 11:56:33 am PST
Last Edited by: Louis Monier August 8, 1986 11:39:41 am PDT
DIRECTORY
Boole, BooleCore, CD, CDProperties, Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, IO, PW, PWCore, Rope, Rosemary, RosemaryUser, Ports;
TestBoole: CEDAR PROGRAM
IMPORTS Boole, BooleCore, CDProperties, CoreCreate, CoreOps, CoreProperties, IO, PW, PWCore, Rosemary, RosemaryUser, Ports =
BEGIN OPEN Boole, BooleCore;
Basic Test
FromC0: PROC [characteristic: [0 .. 2)] RETURNS [function: Expression] = {
function ← SELECT characteristic FROM
0 => false,
1 => true,
ENDCASE => ERROR;
};
FromC1: PROC [x: Variable, characteristic: [0 .. 4)] RETURNS [function: Expression] = {
function ← If[x, FromC0[characteristic / 2], FromC0[characteristic MOD 2]];
};
FromC2: PROC [x, y: Variable, characteristic: [0 .. 16)] RETURNS [function: Expression] = {
function ← If[x, FromC1[y, characteristic / 4], FromC1[y, characteristic MOD 4]];
};
FromC3: PROC [x, y, z: Variable, characteristic: [0 .. 256)] RETURNS [function: Expression] = {
function ← If[x, FromC2[y, z, characteristic / 16], FromC2[y, z, characteristic MOD 16]];
};
Member: PROC [function: Expression, functions: LIST OF Expression] RETURNS [BOOLFALSE] = {
WHILE functions#NIL DO
IF Equal[functions.first, function] THEN RETURN [TRUE];
functions ← functions.rest;
ENDLOOP;
};
Add: PROC [function: Expression, functions, moreFunctions: LIST OF Expression] RETURNS [newFunctions: LIST OF Expression] = {
IF Member[function, functions] THEN ERROR;
IF moreFunctions#NIL AND NOT Member[function, moreFunctions] THEN ERROR;
newFunctions ← CONS [function, functions];
};
FunctionsOf3: PROC [x, y, z: Variable] = {
functions0, functions1, functions2, functions3: LIST OF Expression ← NIL;
FOR characteristic: INT IN [0 .. 256) DO
functions3 ← Add[FromC3[x, y, z, characteristic], functions3, NIL];
ENDLOOP;
FOR characteristic: INT IN [0 .. 16) DO
functions2 ← Add[FromC2[x, y, characteristic], functions2, functions3];
ENDLOOP;
FOR characteristic: INT IN [0 .. 4) DO
functions1 ← Add[FromC1[x, characteristic], functions1, functions2];
ENDLOOP;
FOR characteristic: INT IN [0 .. 2) DO
functions0 ← Add[FromC0[characteristic], functions0, functions1];
ENDLOOP;
};
Random: PUBLIC PROC [a, b, c, d: Variable] RETURNS [result: Expression] = {
pBar: Expression;
gBar: Expression;
plus, or, and, xor: Expression;
plus ← And[c, d];
xor ← And[Not[c], d];
and ← And[c, Not[d]];
or ← And[Not[c], Not[d]];
pBar ← If[plus, Xor[a, Not[b]], true];
gBar ← If[plus, Or[Not[a], Not[b]], true];
IF NOT HasVar[gBar, a] THEN ERROR;
IF NOT HasVar[gBar, b] THEN ERROR;
IF NOT HasVar[gBar, c] THEN ERROR;
IF NOT HasVar[gBar, d] THEN ERROR;
pBar ← If[or, Nor[a, b], pBar];
pBar ← If[and, Not[And[a, b]], pBar];
pBar ← If[xor, Xor[a, Not[b]], pBar];
result ← And[gBar, pBar];
};
PlainRandom: PROC = {
out: IO.STREAMIO.ROS[];
result: Expression ← Random["aa", "bb", "cc", "dd"];
PutExpr[out, result];
IF NOT Equal[result, GetExpr[IO.RIS[IO.RopeFromROS[out]]]] THEN ERROR;
};
RefIntRandom: PROC = {
a: REF INT = NEW [INT ← 1];
b: REF INT = NEW [INT ← 2];
c: REF INT = NEW [INT ← 3];
d: REF INT = NEW [INT ← 4];
out: IO.STREAMIO.ROS[];
result: Expression = Random[a, b, c, d];
PutExpr[out, result];
IF NOT Equal[result, GetExpr[IO.RIS[IO.RopeFromROS[out]]]] THEN ERROR;
};
RefRealRandom: PROC = {
a: REF REAL = NEW [REAL ← 1.2];
b: REF REAL = NEW [REAL ← 3.4];
c: REF REAL = NEW [REAL ← 5.6];
d: REF REAL = NEW [REAL ← 7.8];
PutReal: PROC [out: IO.STREAM, var: Variable] = {
refReal: REF REAL = NARROW [var];
out.Put1[IO.real[refReal^]];
};
GetReal: PROC [in: IO.STREAM] RETURNS [var: Variable] = {
real: REALIO.GetReal[in];
var ← SELECT TRUE FROM
real>1.1 AND real<1.3 => a,
real>3.3 AND real<3.5 => b,
real>5.5 AND real<5.7 => c,
real>7.7 AND real<7.9 => d,
ENDCASE => ERROR;
};
out: IO.STREAMIO.ROS[];
result: Expression = Random[a, b, c, d];
PutExpr[out, result, LAST [INT], PutReal];
IF NOT Equal[result, GetExpr[IO.RIS[IO.RopeFromROS[out]], GetReal]] THEN ERROR;
};
Test of BooleCore
RandomCellType: PUBLIC PROC [] RETURNS [recordCell: CellType] = {
inputDriver: CellType ← BooleCore.GetCellLibraryCell["InputDriver"];
outputDriver: CellType ← BooleCore.GetCellLibraryCell["ClockedOutputDriver"];
a: Wire ← CoreOps.CreateWire[name: "a"];
b: Wire ← CoreOps.CreateWire[name: "b"];
c: Wire ← CoreOps.CreateWire[name: "c"];
d: Wire ← CoreOps.CreateWire[name: "d"];
recordCell ← AlpsCell[
public: CoreCreate.Wires[a, b, c, d, "r", "ab", "Gnd", "Vdd", "phiA", "phiB", "VRef"],
inputs: LIST [["a", inputDriver], ["b", inputDriver], ["c", inputDriver], ["d", inputDriver]],
outputs: LIST [
["r", Random[a, b, c, d], outputDriver, LIST [["Clock", "phiA"], ["VRef", "VRef"]]],
["ab", And[a, b], outputDriver, LIST [["Clock", "phiB"], ["VRef", "VRef"]]]
],
props: CoreProperties.Props[[$ContactPolyMetal2, NEW [INT ← 3]]]
];
};
a, b, c, d, r, ab, Gnd, Vdd, phiA, phiB, VRef: NAT;
RopeLevel: TYPE = RECORD [rope: ROPE, level: Ports.Level];
Ev: PROC [expr: Expression, rls: LIST OF RopeLevel] RETURNS [Expression] = {
SELECT TRUE FROM
rls=NIL => RETURN [expr];
rls.first.level=X => RETURN [Ev[expr, rls.rest]];
rls.first.level=H => RETURN [Ev[Boole.Eval[rls.first.rope, expr].whenTrue, rls.rest]];
rls.first.level=L => RETURN [Ev[Boole.Eval[rls.first.rope, expr].whenFalse, rls.rest]];
ENDCASE  => ERROR;
};
AlpsTest: RosemaryUser.TestProc = {
rexpr: Expression ← Random["a", "b", "c", "d"];
abexpr: Expression ← And["a", "b"];
InitializePublic[cellType.public];
FOR av: Ports.Level IN Ports.Level DO
p[a].l ← av;
FOR bv: Ports.Level IN Ports.Level DO
p[b].l ← bv;
FOR cv: Ports.Level IN Ports.Level DO
p[c].l ← cv;
FOR dv: Ports.Level IN Ports.Level DO
p[d].l ← dv;
p[r].l ← SELECT Ev[rexpr, LIST[["a", av], ["b", bv], ["c", cv], ["d", dv]]] FROM
Boole.true => H,
Boole.false => L,
ENDCASE  => X;
p[ab].l ← SELECT Ev[abexpr, LIST[["a", av], ["b", bv], ["c", cv], ["d", dv]]] FROM
Boole.true => H,
Boole.false => L,
ENDCASE  => X;
Eval[];
ENDLOOP;
ENDLOOP;
ENDLOOP;
ENDLOOP;
};
InitializePublic: PROC [public: Wire] = {
a ← CoreOps.GetWireIndex[public, "a"];
b ← CoreOps.GetWireIndex[public, "b"];
c ← CoreOps.GetWireIndex[public, "c"];
d ← CoreOps.GetWireIndex[public, "d"];
r ← CoreOps.GetWireIndex[public, "r"];
ab ← CoreOps.GetWireIndex[public, "ab"];
Gnd ← CoreOps.GetWireIndex[public, "Gnd"];
Vdd ← CoreOps.GetWireIndex[public, "Vdd"];
phiA ← CoreOps.GetWireIndex[public, "phiA"];
phiB ← CoreOps.GetWireIndex[public, "phiB"];
VRef ← CoreOps.GetWireIndex[public, "VRef"];
};
ExerciseRose: PUBLIC PROC = {
ct: CellType ← RandomCellType[];
public: Wire ← ct.public;
sim: RosemaryUser.Tester;
design: CD.Design;
InitializePublic[public];
[] ← Rosemary.SetFixedWire[public[Vdd], H];
[] ← Rosemary.SetFixedWire[public[Gnd], L];
[] ← Rosemary.SetFixedWire[public[phiA], H];
[] ← Rosemary.SetFixedWire[public[phiB], H];
[] ← Rosemary.SetFixedWire[public[VRef], H];
FOR i: NAT IN [0..ct.public.size) DO
[] ← Ports.InitPort[wire: ct.public[i], levelType: l];
ENDLOOP;
[] ← Ports.InitTesterDrive[wire: ct.public[a], initDrive: force];
[] ← Ports.InitTesterDrive[wire: ct.public[b], initDrive: force];
[] ← Ports.InitTesterDrive[wire: ct.public[c], initDrive: force];
[] ← Ports.InitTesterDrive[wire: ct.public[d], initDrive: force];
[] ← Ports.InitTesterDrive[wire: ct.public[r], initDrive: expect];
[] ← Ports.InitTesterDrive[wire: ct.public[ab], initDrive: expect];
sim ← RosemaryUser.TestProcedureViewer[name: "Alps Transistor Tester", cellType: ct, testButtons: LIST["AlpsTest"], displayWires: RosemaryUser.DisplayPortLeafWires[ct]];
design ← PW.Draw[PWCore.Layout[ct]];
CDProperties.PutDesignProp[design, $Simulation, sim];
};
Initialization
RosemaryUser.RegisterTestProc["AlpsTest", AlpsTest];
END.