IFUTest:
CEDAR
PROGRAM
IMPORTS CoreClasses, CoreLibrary, CoreName, CoreOps, CoreWire, Ports, Rosemary =
BEGIN
ROPE: TYPE = Core.ROPE;
Signal: SIGNAL = CODE;
TestVectors: TYPE = REF TestVectorSeq;
TestVectorSeq: TYPE = RECORD[SEQUENCE size: CARDINAL OF TestRec];
TestRec: TYPE = RECORD[c0, c1, i0, i1, out: Ports.Level ← X];
GeneralPurposeTest:
PROC[name:
ROPE, vectors: TestVectors] = {
cell: Core.CellType ← Extract[name];
Simulate[cell, vectors]};
Extract:
PROC[name:
ROPE]
RETURNS[cell: Core.CellType]={
cell ← CoreLibrary.Get[library, name];
SoS.CheckDesignRules[
cell, library.design, NIL, TRUE,
$PWCoreLayout, $SinixCMosBInstance, $SinixCMosBWireGeometry];
IF CoreProperties.GetProp[cell.properties, SoS.DRVkey].value#NIL THEN Signal[];
};
Simulate:
PROC[cell: Core.CellType, vectors: TestVectors] = {
DoSim:
PROC[index:
CARDINAL] = {
v: TestRec ← vectors[index];
IF (v.c0=X) # (ctl0=-1) THEN Signal[];
IF (v.c1=X) # (ctl1=-1) THEN Signal[];
IF (v.i0=X) # (in0=-1) THEN Signal[];
IF (v.i1=X) # (in1=-1) THEN Signal[];
IF v.c0#X THEN testerPort[ctl0].l ← v.c0;
IF v.c1#X THEN testerPort[ctl1].l ← v.c1;
IF v.i0#X THEN testerPort[in0].l ← v.i0;
IF v.i1#X THEN testerPort[in1].l ← v.i1;
Rosemary.Settle[simulation];
IF testerPort[out].l#v.out THEN Signal[]};
ctl0, ctl1, in0, in1, out, VDD, GND: INT;
testerWire: CoreWire.CWire;
testerPort: Ports.Port;
simulation: Rosemary.Simulation;
testerWire ← [cell.public];
ctl0 ← CoreOps.GetWireIndex[testerWire.w, "0"];
ctl1 ← CoreOps.GetWireIndex[testerWire.w, "1"];
in0 ← CoreOps.GetWireIndex[testerWire.w, "in0"];
in1 ← CoreOps.GetWireIndex[testerWire.w, "in1"];
out ← CoreOps.GetWireIndex[testerWire.w, "out0"];
VDD ← CoreOps.GetWireIndex[testerWire.w, "VDD"];
GND ← CoreOps.GetWireIndex[testerWire.w, "GND"];
IF ctl0#-1 THEN []←Ports.InitPort[wire: testerWire.i[ctl0].w, initType: l, initDrive: force];
IF ctl1#-1 THEN []←Ports.InitPort[wire: testerWire.i[ctl1].w, initType: l, initDrive: force];
IF in0#-1 THEN []←Ports.InitPort[wire: testerWire.i[in0].w, initType: l, initDrive: force];
IF in1#-1 THEN []←Ports.InitPort[wire: testerWire.i[in1].w, initType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[out].w, initType: l, initDrive: none];
IF ctl0#-1 THEN []←Ports.InitTesterDrive[wire: testerWire.i[ctl0].w, initDrive: force];
IF ctl1#-1 THEN []←Ports.InitTesterDrive[wire: testerWire.i[ctl1].w, initDrive: force];
IF in0#-1 THEN []←Ports.InitTesterDrive[wire: testerWire.i[in0].w, initDrive: force];
IF in1#-1 THEN []←Ports.InitTesterDrive[wire: testerWire.i[in1].w, initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[out].w, initDrive: none];
[ ] ← Rosemary.SetFixedWire[testerWire.w[VDD], H];
[ ] ← Rosemary.SetFixedWire[testerWire.w[GND], L];
testerPort ← Ports.CreatePort[testerWire.w, TRUE];
simulation ← Rosemary.InstantiateInstances[cell, testerPort];
FOR index1:
CARDINAL
IN [0..vectors.size)
DO
DoSim[index1];
ENDLOOP };
TestSAdder:
PROC = {
DoSim:
PROC[index:
CARDINAL] = {
carry: BOOL ← ((index/1) MOD 2) = 1;
ain: BOOL ← ((index/2) MOD 2) = 1;
bin: BOOL ← ((index/4) MOD 2) = 1;
testerPort[cyI].l ← IF carry THEN H ELSE L;
testerPort[in0].l ← IF ain THEN H ELSE L;
testerPort[in1].l ← IF bin THEN H ELSE L;
Rosemary.Settle[simulation];
IF (carry#ain)#(bin#(testerPort[out].l=H)) THEN Signal[];
IF (carry AND (ain OR bin) OR ain AND bin)#(testerPort[cyO].l=H) THEN Signal[]};
cyI, cyO, in0, in1, out, VDD, GND: INT;
testerWire: CoreWire.CWire;
testerPort: Ports.Port;
simulation: Rosemary.Simulation;
cell: Core.CellType ← Extract["DpAdderSerial"];
testerWire ← [cell.public];
cyI ← CoreOps.GetWireIndex[testerWire.w, "rt0"];
cyO ← CoreOps.GetWireIndex[testerWire.w, "0"];
in0 ← CoreOps.GetWireIndex[testerWire.w, "in0"];
in1 ← CoreOps.GetWireIndex[testerWire.w, "in1"];
out ← CoreOps.GetWireIndex[testerWire.w, "out0"];
VDD ← CoreOps.GetWireIndex[testerWire.w, "VDD"];
GND ← CoreOps.GetWireIndex[testerWire.w, "GND"];
[]←Ports.InitPort[wire: testerWire.i[cyI].w, initType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[cyO].w, initType: l, initDrive: none];
[]←Ports.InitPort[wire: testerWire.i[in0].w, initType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[in1].w, initType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[out].w, initType: l, initDrive: none];
[]←Ports.InitTesterDrive[wire: testerWire.i[cyI].w, initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[cyO].w, initDrive: none];
[]←Ports.InitTesterDrive[wire: testerWire.i[in0].w, initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[in1].w, initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[out].w, initDrive: none];
[ ] ← Rosemary.SetFixedWire[testerWire.w[VDD], H];
[ ] ← Rosemary.SetFixedWire[testerWire.w[GND], L];
testerPort ← Ports.CreatePort[testerWire.w, TRUE];
simulation ← Rosemary.InstantiateInstances[cell, testerPort];
FOR index1:
CARDINAL
IN [0..8)
DO
FOR index2:
CARDINAL
IN [0..8)
DO
-- check for hidden state
DoSim[index1];
DoSim[index2];
ENDLOOP;
ENDLOOP };
TestAllSimples:
PROC = {
bufVectors: TestVectors ← NEW[TestVectorSeq[2]];
invVectors: TestVectors ← NEW[TestVectorSeq[2]];
orVectors: TestVectors ← NEW[TestVectorSeq[4]];
norVectors: TestVectors ← NEW[TestVectorSeq[4]];
andVectors: TestVectors ← NEW[TestVectorSeq[4]];
nandVectors: TestVectors ← NEW[TestVectorSeq[4]];
xorVectors: TestVectors ← NEW[TestVectorSeq[4]];
xnorVectors: TestVectors ← NEW[TestVectorSeq[4]];
example[0] ← [c0: X, c1: X, i0: X, i1: X, out: X];
bufVectors[0] ← [i0: L, i1: X, out: L];
bufVectors[1] ← [i0: H, i1: X, out: H];
invVectors[0] ← [i0: L, i1: X, out: H];
invVectors[1] ← [i0: H, i1: X, out: L];
orVectors[0] ← [i0: L, i1: L, out: L];
orVectors[1] ← [i0: L, i1: H, out: H];
orVectors[2] ← [i0: H, i1: L, out: H];
orVectors[3] ← [i0: H, i1: H, out: H];
norVectors[0] ← [i0: L, i1: L, out: H];
norVectors[1] ← [i0: L, i1: H, out: L];
norVectors[2] ← [i0: H, i1: L, out: L];
norVectors[3] ← [i0: H, i1: H, out: L];
andVectors[0] ← [i0: L, i1: L, out: L];
andVectors[1] ← [i0: L, i1: H, out: L];
andVectors[2] ← [i0: H, i1: L, out: L];
andVectors[3] ← [i0: H, i1: H, out: H];
nandVectors[0] ← [i0: L, i1: L, out: H];
nandVectors[1] ← [i0: L, i1: H, out: H];
nandVectors[2] ← [i0: H, i1: L, out: H];
nandVectors[3] ← [i0: H, i1: H, out: L];
xorVectors[0] ← [i0: L, i1: L, out: L];
xorVectors[1] ← [i0: L, i1: H, out: H];
xorVectors[2] ← [i0: H, i1: L, out: H];
xorVectors[3] ← [i0: H, i1: H, out: L];
xnorVectors[0] ← [i0: L, i1: L, out: H];
xnorVectors[1] ← [i0: L, i1: H, out: L];
xnorVectors[2] ← [i0: H, i1: L, out: L];
xnorVectors[3] ← [i0: H, i1: H, out: H];
GeneralPurposeTest["DpBuf", bufVectors];
GeneralPurposeTest["DpInv", invVectors];
GeneralPurposeTest["DpOr", orVectors];
GeneralPurposeTest["DpNor", norVectors];
GeneralPurposeTest["DpAnd", andVectors];
GeneralPurposeTest["DpNand", nandVectors];
GeneralPurposeTest["DpXor", xorVectors];
GeneralPurposeTest["DpXNor", xnorVectors];
GeneralPurposeTest["DpPreChg", bufVectors];
GeneralPurposeTest["DpInvDr", bufVectors];
GeneralPurposeTest["DpTriDr", bufVectors];
GeneralPurposeTest["DpSelect", bufVectors];
GeneralPurposeTest["DpAdderGPC0", bufVectors];
GeneralPurposeTest["DpAdderGPC1", bufVectors];
GeneralPurposeTest["DpAdderSum", bufVectors];
GeneralPurposeTest["DpAdderSerial", bufVectors];
GeneralPurposeTest["DpStackBit", bufVectors];
GeneralPurposeTest["DpStackBitSeparation", bufVectors];
GeneralPurposeTest["DpFetchBufferBit", bufVectors];
GeneralPurposeTest["DrInPosSing", bufVectors];
GeneralPurposeTest["DrInNegSing", bufVectors];
GeneralPurposeTest["DrInPosDual", bufVectors];
GeneralPurposeTest["DrInNegDual", bufVectors];
GeneralPurposeTest["DrLatch", bufVectors];
GeneralPurposeTest["DrInA", bufVectors];
GeneralPurposeTest["DrInB", bufVectors];
GeneralPurposeTest["DrInInPos", bufVectors];
GeneralPurposeTest["DrInInNeg", bufVectors];
GeneralPurposeTest["DrOutPosSing", bufVectors];
GeneralPurposeTest["DrOutNegSing", bufVectors];
GeneralPurposeTest["DrOutPosDual", bufVectors];
GeneralPurposeTest["DrOutNegDual", bufVectors];
GeneralPurposeTest["DrOutAc", bufVectors];
GeneralPurposeTest["DrOutBc", bufVectors];
GeneralPurposeTest["DrOutPos", bufVectors];
GeneralPurposeTest["DrOutNeg", bufVectors];
GeneralPurposeTest["DrOutLatchA", bufVectors];
GeneralPurposeTest["DrOutLatchB", bufVectors];
GeneralPurposeTest["DrOutInPos", bufVectors];
GeneralPurposeTest["DrOutInNeg", bufVectors];
};
TestLatch:
PROC = {
cell: Core.CellType;
out0: ROPE ← CoreName.RopeNm["out0"];
ctl1: ROPE ← CoreName.RopeNm["1"];
XNode: ROPE ← CoreName.RopeNm["XNode"];
rec: CoreClasses.RecordCellType;
latchVectors: TestVectors ← NEW[TestVectorSeq[8]];
latchVectors[0] ← [c1: H, c0: H, i0: L, out: L];
latchVectors[1] ← [c1: H, c0: L, i0: L, out: L];
latchVectors[2] ← [c1: H, c0: L, i0: H, out: L];
latchVectors[3] ← [c1: H, c0: H, i0: H, out: H];
latchVectors[4] ← [c1: H, c0: L, i0: H, out: H];
latchVectors[5] ← [c1: H, c0: L, i0: L, out: H];
latchVectors[6] ← [c1: H, c0: H, i0: L, out: L];
latchVectors[7] ← [c1: H, c0: L, i0: L, out: L];
cell ← Extract["DpLatch"];
rec ← NARROW[cell.data];
FOR ii:
INT
IN [0..rec.size)
DO
gate, ch1, ch2: ROPE;
IF rec[ii].type.class#CoreClasses.transistorCellClass THEN Signal[];
gate ← CoreName.WireNm[rec[ii].actual[0]].n;
ch1 ← CoreName.WireNm[rec[ii].actual[1]].n;
ch2 ← CoreName.WireNm[rec[ii].actual[2]].n;
IF (gate=ctl1
OR gate=out0)
AND (ch1=XNode
OR ch2=XNode)
THEN
[ ] ← Rosemary.SetTransistorInstanceSize[rec[ii], driveWeak];
ENDLOOP;
Simulate[cell, latchVectors]};
library: CoreLibrary.Library ← CoreLibrary.OpenLibrary["IFUCore"];
TestAllSimples[];
TestLatch[];
TestSAdder[];
END.