IFUTestLibrary.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
Last Edited by Curry, September 30, 1986 10:39:00 am PDT
Don Curry October 30, 1986 9:38:01 pm PST
DIRECTORY Core, CoreClasses, CoreFlat, CoreFrame, CoreLibrary, CoreName, CoreOps, CoreProperties, CoreWire, IFUCoreCells, IFUCoreDrive, IFUSim, IFUTest, Ports, Rosemary, RosemaryUser;
IFUTestLibrary: CEDAR PROGRAM
IMPORTS CoreClasses, CoreFlat, CoreFrame, CoreLibrary, CoreName, CoreOps, CoreProperties, CoreWire, IFUCoreCells, IFUCoreDrive, IFUSim, Ports, Rosemary, RosemaryUser
EXPORTS IFUTest =
BEGIN
ROPE:  TYPE = Core.ROPE;
CellType: TYPE = Core.CellType;
Wire:  TYPE = Core.Wire;
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: CellType ← Extract[name];
Simulate[cell, vectors]};
Extract: PROC[name: ROPE] RETURNS[cell: 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: CellType, vectors: TestVectors, cutLabels: LIST OF ROPENIL] = {
cuts: CoreFlat.CutSet ← CoreFlat.CreateCutSet[labels: cutLabels];
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, levelType: l, initDrive: force];
IF ctl1#-1 THEN []←Ports.InitPort[wire: testerWire.i[ctl1].w, levelType: l, initDrive: force];
IF in0#-1 THEN []←Ports.InitPort[wire: testerWire.i[in0].w, levelType: l, initDrive: force];
IF in1#-1 THEN []←Ports.InitPort[wire: testerWire.i[in1].w, levelType: l, initDrive: force];
     []←Ports.InitPort[wire: testerWire.i[out].w, levelType: 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[cell, TRUE];
simulation ← Rosemary.Instantiate[cell, testerPort, cuts];
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:   CellType ← Extract["DpAdderSerial"];
testerWire ← [cell.public];
cyI   ← CoreOps.GetWireIndex[testerWire.w, "in2"];
cyO   ← CoreOps.GetWireIndex[testerWire.w, "out2"];
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, levelType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[cyO].w, levelType: l, initDrive: none];
[]←Ports.InitPort[wire: testerWire.i[in0].w, levelType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[in1].w, levelType: l, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[out].w, levelType: 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[cell, TRUE];
simulation ← Rosemary.Instantiate[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 };
TestGPC: PROC[gpLRNeg: BOOL] = {
UpdateDisplay: PROC = {
RosemaryUser.UpdateDisplay[display]};
DisplayAndSignal: PROC = {
RosemaryUser.UpdateDisplay[display];
Signal[]};
gl, pl, cl, gm, pm, cm, gr, pr, cr, VDD, GND: INT;
cell:   CellType;
testerWire: CoreWire.CWire;
testerPort:  Ports.Port;
simulation: Rosemary.Simulation;
display:  RosemaryUser.RoseDisplay;
IF gpLRNeg
THEN {
cell   ← CoreLibrary.Get[ library, "DpAdderGPC0", FALSE, LIST["Cry"]];
testerWire ← [cell.public];
gl  ← CoreOps.GetWireIndex[testerWire.w, "nGL"];
pl  ← CoreOps.GetWireIndex[testerWire.w, "nPL"];
cl  ← CoreOps.GetWireIndex[testerWire.w, "CL"];
gm ← CoreOps.GetWireIndex[testerWire.w, "GM"];
pm ← CoreOps.GetWireIndex[testerWire.w, "PM"];
cm ← CoreOps.GetWireIndex[testerWire.w, "nCM"];
gr  ← CoreOps.GetWireIndex[testerWire.w, "nGR"];
pr  ← CoreOps.GetWireIndex[testerWire.w, "nPR"];
cr  ← CoreOps.GetWireIndex[testerWire.w, "CR"]}
ELSE {
cell   ← CoreLibrary.Get[ library, "DpAdderGPC1", FALSE, LIST["Cry"]];
testerWire ← [cell.public];
gl  ← CoreOps.GetWireIndex[testerWire.w, "GL"];
pl  ← CoreOps.GetWireIndex[testerWire.w, "PL"];
cl  ← CoreOps.GetWireIndex[testerWire.w, "nCL"];
gm ← CoreOps.GetWireIndex[testerWire.w, "nGM"];
pm ← CoreOps.GetWireIndex[testerWire.w, "nPM"];
cm ← CoreOps.GetWireIndex[testerWire.w, "CM"];
gr  ← CoreOps.GetWireIndex[testerWire.w, "GR"];
pr  ← CoreOps.GetWireIndex[testerWire.w, "PR"];
cr  ← CoreOps.GetWireIndex[testerWire.w, "nCR"]};
VDD ← CoreOps.GetWireIndex[testerWire.w, "VDD"];
GND ← CoreOps.GetWireIndex[testerWire.w, "GND"];
[]←Ports.InitPort[wire: testerWire.i[gl].w,  levelType: b, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[pl].w,  levelType: b, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[cl].w,  levelType: b, initDrive: none];
[]←Ports.InitPort[wire: testerWire.i[gm].w, levelType: b, initDrive: none];
[]←Ports.InitPort[wire: testerWire.i[pm].w, levelType: b, initDrive: none];
[]←Ports.InitPort[wire: testerWire.i[cm].w,  levelType: b, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[gr].w,  levelType: b, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[pr].w,  levelType: b, initDrive: force];
[]←Ports.InitPort[wire: testerWire.i[cr].w,  levelType: b, initDrive: none];
[]←Ports.InitTesterDrive[wire: testerWire.i[gl].w,    initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[pl].w,    initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[cl].w,    initDrive: none];
[]←Ports.InitTesterDrive[wire: testerWire.i[gm].w,   initDrive: none];
[]←Ports.InitTesterDrive[wire: testerWire.i[pm].w,   initDrive: none];
[]←Ports.InitTesterDrive[wire: testerWire.i[cm].w,   initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[gr].w,    initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[pr].w,    initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[cr].w,    initDrive: none];
[ ] ← Rosemary.SetFixedWire[testerWire.w[VDD], H];
[ ] ← Rosemary.SetFixedWire[testerWire.w[GND], L];
testerPort  ← Ports.CreatePort[cell, TRUE];
simulation ← Rosemary.Instantiate[cell, testerPort];
display  ← RosemaryUser.DisplayViewer[simulation, cell, "IFU Test", RosemaryUser.DisplayPortLeafWires[cell]];
FOR gL: BOOL IN BOOL DO
FOR pL: BOOL IN BOOL DO
FOR gR: BOOL IN BOOL DO
FOR pR: BOOL IN BOOL DO
FOR cM: BOOL IN BOOL DO
gM: BOOL;
pM: BOOL;
cL: BOOL;
cR: BOOL;
testerPort[gl].b ← gpLRNeg # gL;
testerPort[pl].b ← gpLRNeg # pL;
testerPort[gr].b ← gpLRNeg # gR;
testerPort[pr].b ← gpLRNeg # pR;
testerPort[cm].b ← gpLRNeg # cM;
Rosemary.Settle[simulation ! Rosemary.Stop => UpdateDisplay[]];
gM ← gpLRNeg = testerPort[gm].b;
pM ← gpLRNeg = testerPort[pm].b;
cL  ← gpLRNeg = testerPort[cl].b;
cR  ← gpLRNeg = testerPort[cr].b;
IF    cM    #  cR  THEN DisplayAndSignal[];
IF (gR OR (cM AND pR)) #  cL  THEN DisplayAndSignal[];
IF (gL OR (pL AND gR)) # gM THEN DisplayAndSignal[];
IF    (pL AND pR)  # pM THEN DisplayAndSignal[];
ENDLOOP ENDLOOP ENDLOOP 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];
};
TestLatchOld: PROC = {
cell:   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 {
transistorSizeRef: REF Ports.Drive ← NARROW
[CoreProperties.GetCellInstanceProp[from: rec[ii], prop: $RoseTransistorSize]];
IF transistorSizeRef=NIL THEN Signal[];
[ ] ← Rosemary.SetTransistorInstanceSize[rec[ii], driveWeak]};
ENDLOOP;
Simulate[cell, latchVectors]};
TestLatch: PROC = {
cell:   CellType;
out0:  ROPE ← CoreName.RopeNm["out0"];
ctl1:  ROPE ← CoreName.RopeNm["1"];
XNode: ROPE ← CoreName.RopeNm["XNode"];
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"];
IFUSim.SetUp[cell];
Simulate[cell, latchVectors];
Simulate[cell, latchVectors, LIST["DpLatch", "DpLatchCtl"]]};
dpins: RECORD[
in, out, PhA, PhB, DShA, DShB, DShWt, DShRd, DShIn, DShOut, GND, VDD: INT ← -1];
DriverTest: RosemaryUser.TestProc = {
T: BOOL = TRUE; F: BOOL = FALSE;
vec: REF DrVecSeq ← NEW[DrVecSeq[9]];
DrVecSeq: TYPE = RECORD[SEQUENCE size: CARDINAL OF DrVec];
DrVec: TYPE = RECORD[
in, out, PhA, PhB, DShA, DShB, DShWt, DShRd, DShIn, DShOut: BOOLFALSE];
vec[0] ← [in:TRUE, PhB:TRUE, out:TRUE,  DShIn:F, DShA:T, DShB:T, DShOut:F];
vec[1] ← [in:TRUE, PhB:TRUE, out:TRUE,  DShIn:F, DShA:T, DShOut:F];
vec[2] ← [in:TRUE, PhB:TRUE, out:TRUE,  DShIn:F, DShA:F, DShOut:F];
vec[3] ← [in:TRUE, PhB:TRUE, out:TRUE,  DShIn:F, DShB:T, DShOut:F];
vec[4] ← [in:TRUE, PhB:TRUE, out:TRUE,  DShIn:F, DShB:F, DShOut:F];
vec[5] ← [in:TRUE, PhB:TRUE, out:TRUE];
vec[6] ← [in:TRUE, PhB:F,  out:TRUE];
vec[7] ← [in:F,  PhB:F,  out:TRUE];
vec[8] ← [in:F,  PhB:TRUE, out:F];
FOR index: CARDINAL IN [0..vec.size) DO
p[dpins.in].b   ← vec[index].in;
p[dpins.PhA].b  ← vec[index].PhA;
p[dpins.PhB].b  ← vec[index].PhB;
p[dpins.DShA].b  ← vec[index].DShA;
p[dpins.DShB].b  ← vec[index].DShB;
p[dpins.DShWt].b ← vec[index].DShWt;
p[dpins.DShRd].b ← vec[index].DShRd;
p[dpins.DShIn].b ← vec[index].DShIn;
p[dpins.out].b  ← vec[index].out;
p[dpins.DShOut].b ← vec[index].DShOut;
Eval[];
ENDLOOP };
DriverSimTestDo: PROC = {
testName: ROPE ← "DriverTest";
drive:   IFUCoreDrive.Drive;
driver:  CellType;
cell:   CellType;
tester:   RosemaryUser.Tester;
drive ← IFUCoreDrive.SpecificDrive[
dir:  in,
in:   "InAB",
out:  "OutBA",
inverted: FALSE,
dual:  FALSE];
drive.inSh ← "DShIn";
drive.outSh ← "DShOut";
driver ← IFUCoreDrive.CellProc["DrTest", drive];
CoreFrame.Expand[hard, driver];
cell    ← CoreOps.Recast[CoreFrame.FCT[driver].cell];
IFUSim.SetUp[cell];
dpins.GND  ← CoreOps.GetWireIndex[cell.public, "GND"];
dpins.VDD  ← CoreOps.GetWireIndex[cell.public, "VDD"];
dpins.PhA  ← CoreOps.GetWireIndex[cell.public, "PhA"];
dpins.PhB  ← CoreOps.GetWireIndex[cell.public, "PhB"];
dpins.in   ← CoreOps.GetWireIndex[cell.public, "InAB"];
dpins.out   ← CoreOps.GetWireIndex[cell.public, "OutBA"];
dpins.DShA  ← CoreOps.GetWireIndex[cell.public, "DShA"];
dpins.DShB  ← CoreOps.GetWireIndex[cell.public, "DShB"];
dpins.DShWt  ← CoreOps.GetWireIndex[cell.public, "DShWt"];
dpins.DShRd  ← CoreOps.GetWireIndex[cell.public, "DShRd"];
dpins.DShIn  ← CoreOps.GetWireIndex[cell.public, "DShIn"];
dpins.DShOut ← CoreOps.GetWireIndex[cell.public, "DShOut"];
[] ← Rosemary.SetFixedWire[ cell.public[dpins.GND],   L];
[] ← Rosemary.SetFixedWire[ cell.public[dpins.VDD],   H];
[] ← Ports.InitPort[wire: cell.public[dpins.PhA],     levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.PhB],     levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.in],     levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.out],     levelType: b, initDrive: force];
[] ← Ports.InitPort[wire: cell.public[dpins.DShA],    levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.DShB],    levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.DShWt],    levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.DShRd],    levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.DShIn],    levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: cell.public[dpins.DShOut],    levelType: b, initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.PhA],   initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.PhB],   initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.in],   initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.out],   initDrive: expect];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.DShA],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.DShB],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.DShWt],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.DShRd],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.DShIn],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: cell.public[dpins.DShOut],  initDrive: expect];
testerPort  ← Ports.CreatePort[cell, TRUE];
simulation ← Rosemary.Instantiate[cell, testerPort];
display  ← RosemaryUser.DisplayViewer[
simulation,
cell,
"Driver Simulation Test",
RosemaryUser.DisplayPortLeafWires[cell]];
RosemaryUser.RegisterTestProc[testName, DriverTest];
tester ← RosemaryUser.TestProcedureViewer[
cellType:   cell,
testButtons:  LIST[testName],
name:    testName,
displayWires: RosemaryUser.DisplayPortLeafWires[cell],
cutSet:   CoreFlat.CreateCutSet[labels: LIST["DrLatch"]]]};
library: CoreLibrary.Library ← IFUCoreCells.library;
Library: PUBLIC PROC = {
DriverSimTestDo[];
TestAllSimples[];
TestLatchOld[];
TestLatch[];
TestSAdder[];
TestGPC[TRUE];
TestGPC[FALSE]};
END.