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];
PWCore.SetAbutX[newCell]; [] ← PWCore.Layout[newCell];
testerWire ← [newCell.public];
[]←Ports.InitPort[wire: testerWire.i[ina].w, initType: c];
[]←Ports.InitPort[wire: testerWire.i[inb].w, initType: c];
[]←Ports.InitPort[wire: testerWire.i[out].w, initType: 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 };
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 ]]};