<> <> <> <> <> <> <> <<>> 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; <> 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 [BOOL _ FALSE] = { 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.STREAM _ IO.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.STREAM _ IO.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: REAL _ IO.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.STREAM _ IO.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; }; <> 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"]]] ], name: "RandomTestBoole", 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] = { 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]; }; <<>> <> RosemaryUser.RegisterTestProc["AlpsTest", AlpsTest]; END.