IFUTests.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
Curry, August 13, 1986 6:59:12 am PDT
DIRECTORY CCDUtils, CD, Core, CoreClasses, CoreFrame, CoreGlue, CoreOps, CoreName, CoreWire, CoreXform, IFUCoreData, IO, Ports, PW, PWC, PWCore, Rosemary, RosemaryUser;
IFUTests: CEDAR PROGRAM
IMPORTS CCDUtils, CoreClasses, CoreFrame, CoreGlue, CoreOps, CoreName, CoreWire, CoreXform, IFUCoreData, IO, Ports, PW, PWC, Rosemary, RosemaryUser =
BEGIN
CellType:  TYPE = Core.CellType;
Wire:   TYPE = Core.Wire;
ROPE:   TYPE = Core.ROPE;
adder:  Core.CellType;
adderObj: CD.Object;
decoObj: CD.Object;
AdderTest: PROC[size: INT] = {
xform: CoreXform.Xform ← CoreXform.GenXform[ LIST[ [size, 0] ] ];
sb: CellType = IFUCoreData.CellProc[
subClass: "SwitchBox",
name:  "SB",
top:  "( Ina. Inb. )",
left:  "( Junk )",
right:  "( Junk )",
bot:  "( Ina. Inb. )",
xform:  xform ];
adderMain: CellType = IFUCoreData.CellProc[
subClass: "Adder",
name:  "AdderMain",
top:  "( Ina. Inb. )",
right:  "( GND )",
in:   "( Ina. Inb. )",
out:  "( Out. )",
bot:  "( Out. )",
xform:  xform ];
adder ← CoreFrame.NewFrameCells[name: "Adder", rec: [first:top], cells:LIST[sb, adderMain]];
CoreFrame.Expand[hard, adder];
CoreFrame.NameFrame[adder];
[ ] ← CoreGlue.RouteHard[adder];
adderObj ← CCDUtils.Layout[ adder];
[ ] ← PW.Draw[ adderObj];
decoObj ← CCDUtils.OrnateFrame[ adder];
[ ] ← PW.Draw[decoObj];
TestAdder[size, CoreFrame.FCT[adder].cell]};
TestAdder: PROC[size: INT, cell: CellType] = {
UpdateDisplay: PROC = {
RosemaryUser.UpdateDisplay[display]};
DisplayAndSignal: PROC = {
RosemaryUser.UpdateDisplay[display];
Signal[]};
twoToPwrSize: CARDINAL ← 1;
ina:  NAT = 0;
inb:  NAT = 1;
out:  NAT = 2;
VDD:  NAT = 3;
GND:  NAT = 4;
junk:  NAT = 5;
pubSize: NAT = 6;
testerWire: CoreWire.CWire;
testerPort:  Ports.Port;
display:  RosemaryUser.RoseDisplay;
simulation: Rosemary.Simulation;
newCell: CellType;
public: Wire ← CoreOps.CreateWires[pubSize];
public[ina]   ← CoreOps.CreateWires[size, "Ina"];
public[inb]   ← CoreOps.CreateWires[size, "Inb"];
public[out]   ← CoreOps.CreateWires[size, "Out"];
public[VDD]   ← CoreOps.CreateWires[0, "VDD"];
public[GND]   ← CoreOps.CreateWires[0, "GND"];
public[junk]   ← CoreOps.CreateWires[0, "Junk"];
FOR bit: INT IN [0..size) DO
public[ina][bit] ← CoreOps.CreateWires[0, IO.PutFR["Ina.%g", IO.int[bit]]];
public[inb][bit] ← CoreOps.CreateWires[0, IO.PutFR["Inb.%g", IO.int[bit]]];
public[out][bit] ← CoreOps.CreateWires[0, IO.PutFR["Out.%g", IO.int[bit]]];
ENDLOOP;
newCell ← RestructuredCell[public, cell];
PWC.SetAbutX[newCell]; [] ← PWC.Layout[newCell];
testerWire ← [newCell.public];
[]←Ports.InitPort[wire: testerWire.i[ina].w, levelType: c];
[]←Ports.InitPort[wire: testerWire.i[inb].w, levelType: c];
[]←Ports.InitPort[wire: testerWire.i[out].w, levelType: c];
[]←Ports.InitTesterDrive[wire: testerWire.i[ina].w, initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[inb].w, initDrive: force];
[]←Ports.InitTesterDrive[wire: testerWire.i[out].w, initDrive: none];
FOR bit: INT IN [0..size) DO twoToPwrSize ← twoToPwrSize*2 ENDLOOP;
[ ] ← Rosemary.SetFixedWire[testerWire.w[VDD], H];
[ ] ← Rosemary.SetFixedWire[testerWire.w[GND], L];
[ ] ← Rosemary.SetFixedWire[testerWire.w[junk], L];
testerPort  ← Ports.CreatePort[testerWire.w, TRUE];
simulation ← Rosemary.InstantiateInstances[newCell, testerPort];
display  ← RosemaryUser.DisplayViewer[simulation, newCell, "IFU Test", RosemaryUser.DisplayCellTypePortLeafWires[newCell]];
FOR arga: CARDINAL IN [0..twoToPwrSize) DO
FOR argb: CARDINAL IN [0..twoToPwrSize) DO -- check for hidden state
testerPort[ina].c ← arga;
testerPort[inb].c ← argb;
Rosemary.Settle[simulation];
UpdateDisplay[];
IF (testerPort[out].c#((arga+argb) MOD twoToPwrSize)) THEN DisplayAndSignal[];
ENDLOOP;
ENDLOOP };
Signal: SIGNAL = CODE;
Uses short wire names to generate corresponding actual
RestructuredCell: PROC[public: Wire, cell: CellType] RETURNS[new: CellType]= {
data:  CoreClasses.RecordCellType ← NEW[CoreClasses.RecordCellTypeRec[1]];
context: CoreName.Context ← CoreName.NewContext[];
actual: Core.Wire ← CoreOps.CreateWires[cell.public.size];
count:  NAT ← 0;
addToCtx: PROC[wire: Wire] =
{IF NOT CoreName.CtxRegisterWire[context, wire] THEN Signal[]; count ← count+1};
[ ] ← CoreOps.VisitAtomicWires[public, addToCtx];
IF count#cell.public.size THEN Signal[]; -- new public has extras
FOR i: INT IN [0..cell.public.size) DO
name: ROPE ← CoreName.WireNm[cell.public[i]].n;
actual[i] ← CoreName.CtxNameToWire[context, name];
IF actual[i]=NIL THEN Signal[]; -- incomplete new public
ENDLOOP;
data.internal ← public;
data[0] ← NEW[CoreClasses.CellInstanceRec ← [actual, cell]];
new ← NEW[Core.CellTypeRec ← [
class:  CoreClasses.recordCellClass,
public: public,
data:  data ]]};
END.