IFUTestPLA.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
Curry, October 10, 1986 8:48:18 am PDT
Don Curry November 4, 1986 11:25:42 am PST
DIRECTORY CD, Commander, CommandTool, Core, CoreClasses, CoreCreate, CoreFrame, CoreName, CoreOps, IFUCoreCtl, IFUCoreDrive, IO, PLAOps, IFUSim, IFUTest, Ports, PWCore, Rope, Rosemary, RosemaryUser, TerminalIO;
IFUTestPLA: CEDAR PROGRAM
IMPORTS Commander, CommandTool, CoreClasses, CoreCreate, CoreFrame, CoreName, CoreOps, IFUCoreCtl, IFUCoreDrive, IFUSim, IO, PLAOps, Ports, Rope, Rosemary, RosemaryUser, TerminalIO
EXPORTS IFUTest =
BEGIN
CellType:  TYPE = Core.CellType;
Wire:   TYPE = Core.Wire;
Wires:   TYPE = Core.Wires;
ROPE:   TYPE = Core.ROPE;
TestIn:  TYPE = IFUTest.PLATestIn;  -- RECORD = [state:  INT[0..16) ← 0];
TestOut:  TYPE = IFUTest.PLATestOut; -- RECORD = [next:  INT[0..16) ← 0];
IFUTestPLAInit: Commander.CommandProc = {
TestPLA: PLAOps.PLA ← PLAOps.NewPLA["IFUTest.PLATestIn", "IFUTest.PLATestOut"];
Set: PROC [m, d: TestIn ← [], out: TestOut]={
res: REF TestOut ← NARROW[TestPLA.out];
res^ ← out; PLAOps.SetOutForBE[TestPLA, Be[m,d]]};
Be: PROC [m, d: TestIn] RETURNS[PLAOps.BoolExpr] = {
mRef:  REF TestIn ← NARROW[TestPLA.mask];
dRef:  REF TestIn ← NARROW[TestPLA.data];
mRef^ ← m; dRef^ ← d; RETURN[PLAOps.GetBEForDataMask[TestPLA]]};
FOR state: INT IN [0..16) DO
next: CARDINAL [0..16) ← (state+1) MOD 16;
Set[m:[state: 15], d:[state: state], out:[next: next]];
ENDLOOP;
[] ←PLAOps.ConvertTermListToCompleteSum[TestPLA.termList, FALSE,FALSE,cmd.out];
[] ←PLAOps.FindAMinimalCover[TestPLA.termList,  120, cmd.out];
PLAOps.WritePLAFile[ "TestPLA.ttt", cmd.out,    TestPLA] };
PLAType:     TYPE = IFUCoreCtl.PLAType; -- precharged, hot
MakeTestPLA: PROC[type: PLAType] RETURNS[cellType: CellType] = {
IF (cellType ← CoreFrame.ReadFrameCache[ testNames[type] ])=NIL THEN {
plaDesc: IFUCoreCtl.PLADescription ←
NEW[IFUCoreCtl.PLADescriptionRec ←
[name: "TestPLA", plaPhs: [BA, A, AB, B, BA] ]];
plaDesc.inSh   ← "ShiftIn";
plaDesc.plaType  ← type; -- A Precharge, B Fire
plaDesc.nPreChg  ← "NotPhA";
plaDesc.fire   ← "PhB";
plaDesc.fireV  ← "PhB1";
plaDesc.capSides  ← top;
IF type=precharged THEN plaDesc.termsPerHeader ← 6;
IFUCoreCtl.MakePLA1[plaDesc];
IFUCoreCtl.MakePLA2[plaDesc];
cellType ← IFUCoreCtl.CellProc[ complete, plaDesc];
[ ] ← CoreName.CellNm[cellType, testNames[type]];
IFUCoreDrive.SetDShiftIO[cellType, plaDesc.inSh, plaDesc.outSh];
CoreFrame.WriteFrameCache[cellType]};
cellType ← CoreFrame.FCT[cellType].cell;
cellType ← IFUSim.SubstituteRecasted[cellType];
IFUSim.SetUp[cellType]};
GND:   NAT = 0;
VDD:   NAT = 1;
PhA:   NAT = 2;
PhB:   NAT = 3;
PhB1:  NAT = 4;
NotPhA:  NAT = 5;
NotPhB:  NAT = 6;
in:    NAT = 7;
out:   NAT = 8;
DShA:  NAT = 9;
DShB:  NAT = 10;
DShWt:  NAT = 11;
DShRd:  NAT = 12;
DShIn:  NAT = 13;
DShOut:  NAT = 14;
pubSize:  NAT = 15;
size:   NAT = 4;
Globals
plaType:  PLAType;
tester:   RosemaryUser.Tester;
IFUTestPLADo: Commander.CommandProc = {
pla:   CellType;
cell:   CellType;
args:   LIST OF ROPE ← CommandTool.ParseToList[cmd].list;
public:  Wire ← CoreOps.CreateWires[pubSize];
public[GND]   ← CoreCreate.Seq["GND",     0];
public[VDD]   ← CoreCreate.Seq["VDD",     0];
public[PhA]   ← CoreCreate.Seq["PhA",     0];
public[PhB]   ← CoreCreate.Seq["PhB",     0];
public[PhB1]   ← CoreCreate.Seq["PhB1",     0];
public[NotPhA]  ← CoreCreate.Seq["NotPhA",    0];
public[NotPhB]  ← CoreCreate.Seq["NotPhB",     0];
public[in]   ← CoreCreate.Seq["StateBA",    size];
public[out]   ← CoreCreate.Seq["NextBA",    size];
public[DShA]  ← CoreCreate.Seq["DShA",     0];
public[DShB]  ← CoreCreate.Seq["DShB",     0];
public[DShWt]  ← CoreCreate.Seq["DShWt",     0];
public[DShRd]  ← CoreCreate.Seq["DShRd",     0];
public[DShIn]  ← CoreCreate.Seq["ShiftIn",     0];
public[DShOut]  ← CoreCreate.Seq["drShOutNotNextB.3", 0];
plaType    ← IF args=NIL OR args.first.Fetch[]='h OR args.first.Fetch[]='H
THEN hot
ELSE precharged;
pla ← MakeTestPLA[plaType];
FOR bit: INT IN [0..size) DO
[]𡤌oreOps.SetShortWireName[public[in][bit], IO.PutFR["StateBA.%g",  IO.int[bit]]];
[]𡤌oreOps.SetShortWireName[public[out][bit], IO.PutFR["NextBA.%g",  IO.int[bit]]];
ENDLOOP;
cell ← RestructuredCell[public, pla];
[] ← Rosemary.SetFixedWire[ public[GND],  L];
[] ← Rosemary.SetFixedWire[ public[VDD],  H];
[] ← Ports.InitPort[wire: public[PhA],  levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[PhB],  levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[PhB1], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[NotPhA], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[NotPhB], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[in],  levelType: c, initDrive: none];
[] ← Ports.InitPort[wire: public[out],  levelType: c, initDrive: drive];
[] ← Ports.InitPort[wire: public[DShA], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[DShB], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[DShWt], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[DShRd], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[DShIn], levelType: b, initDrive: none];
[] ← Ports.InitPort[wire: public[DShOut], levelType: b, initDrive: drive];
[] ← Ports.InitTesterDrive[wire: public[PhA],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[PhB],   initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[PhB1],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[NotPhA], initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[NotPhB],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[in],   initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[out],   initDrive: expect];
[] ← Ports.InitTesterDrive[wire: public[DShA],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[DShB],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[DShWt],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[DShRd],  initDrive: force];
[] ← Ports.InitTesterDrive[wire: public[DShIn],  initDrive: driveStrong];
[] ← Ports.InitTesterDrive[wire: public[DShOut], initDrive: expect];
RosemaryUser.RegisterTestProc[testNames[plaType], IFUTestPLATestProc];
tester ← RosemaryUser.TestProcedureViewer[
cellType:   cell,
testButtons:  LIST[testNames[plaType]],
name:    testNames[plaType],
displayWires: RosemaryUser.DisplayPortLeafWires[cell] ];
};
cutSet:   CoreFlat.CreateCutSet[labels: LIST["SimplePLA"]]]};
cutSet:   CoreFlat.CreateCutSet[labels: LIST["SimplePLA", "UpOneLevel"]]]};
IFUTestPLATestProc: RosemaryUser.TestProc = {
DoQPh: PROC[quadPh: {A, ab, B, ba}] = {
p[PhA].b  ← quadPh=A;
p[PhB].b  ← quadPh=B;
p[NotPhA].b ← quadPh#A;
p[NotPhB].b ← quadPh#B;
Eval[]};
DoQPhSh: PROC[quadPh: {A, ab, B, ba}] = {
p[DShA].b  ← quadPh=A;
p[DShB].b  ← quadPh=B;
Eval[]};
Shifts through twice, inverting and writing both times.
RotateSReg: PROC[in: INT] = {
inverts: LIST OF BOOLLIST[TRUE, FALSE];
FOR pass: INT IN [0..2) DO
expVals: LIST OF INTLIST[(in+1) MOD 16, in];
p[DShRd].b ← TRUE; Eval[]; p[DShRd].b ← FALSE; Eval[];
FOR expVals ← expVals, expVals.rest WHILE expVals#NIL DO
FOR arg: CARDINAL IN [0..size) DO
TerminalIO.WriteF["%g ", IO.int[arg]];
p[DShOut].b ← ((expVals.first MOD 2) = 0) = (pass=0);
expVals.first ← expVals.first/2;
DoQPhSh[B];
DoQPhSh[ba];
p[DShIn].b  ← NOT p[DShOut].b;
RosemaryUser.UpdateDisplay[tester.display];
DoQPhSh[A];
DoQPhSh[ab];
ENDLOOP;
TerminalIO.WriteF["- "];
ENDLOOP;
TerminalIO.WriteF[" "];
p[out].c  ← ((in+1) MOD 16);
IF (pass=0) THEN p[out].c ← 15 - p[out].c;
p[DShWt].b ← TRUE; Eval[]; p[DShWt].b ← FALSE; Eval[];
RosemaryUser.UpdateDisplay[tester.display];
ENDLOOP};
p[DShWt].b ← TRUE;
p[DShRd].b ← FALSE;
p[DShOut].b ← TRUE;
p[DShA].b ← TRUE;
p[DShB].b ← TRUE;
p[DShIn].b ← TRUE;
p[in].c  ← 0;
p[out].c  ← 0;
p[PhA].b  ← FALSE;
p[PhB].b  ← FALSE;
p[PhB1].b ← FALSE;
p[NotPhA].b ← TRUE;
p[NotPhB].b ← TRUE;
Eval[];
p[DShWt].b ← FALSE;
Eval[];
p[DShA].b ← FALSE;
Eval[];
p[DShB].b ← FALSE;
Eval[];
FOR arg: CARDINAL IN [0..18] DO
next: INT ← (arg+1) MOD 16;
TerminalIO.WriteF["%2g: ", IO.int[arg]];
p[in].c  ← arg;
DoQPh[A];
DoQPh[ab];
IF plaType=hot
THEN {
p[out].c ← next; DoQPh[B]}
ELSE {
p[out].c ← 0; DoQPh[B];
p[out].c ← next; p[PhB1].b ← TRUE;
Eval[];   p[PhB1].b ← FALSE};
RosemaryUser.UpdateDisplay[tester.display];
DoQPh[ba];
RotateSReg[in: arg];
TerminalIO.WriteF["\n"];
ENDLOOP;
TerminalIO.WriteF["\nDone\n"]};
testNames: ARRAY PLAType OF ROPE ← ["IFUTestPLAPreCharged", "IFUTestPLAHot"];
Signal: SIGNAL = CODE;
Uses short wire names to generate corresponding actual
RestructuredCell: PUBLIC PROC[public: Wire, cell: CellType] RETURNS[new: CellType]= {
data:  CoreClasses.RecordCellType ← NEW[CoreClasses.RecordCellTypeRec[1]];
context: CoreName.Context ← CoreName.NewContext[];
actual: Wire ← CoreOps.CreateWires[cell.public.size];
count:  NAT ← 0;
internals: Wires ← NIL;
addToCtx: PROC[wire: Wire] =
{IF NOT CoreName.CtxRegisterWire[context, wire] THEN Signal[]; count ← count+1};
[ ] ← CoreOps.VisitRootAtomics[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 {
TerminalIO.WriteF["Internal Only: %g\n", IO.rope[name]];
actual[i] ← CoreCreate.Seq[name, 0];
internals ← CONS[actual[i], internals]};
ENDLOOP;
data.internal ← IF internals#NIL
THEN CoreOps.CreateWire[ LIST[public, CoreOps.CreateWire[internals]] ]
ELSE public;
data[0] ← NEW[CoreClasses.CellInstanceRec ← [actual, cell]];
new ← NEW[Core.CellTypeRec ← [
class:  CoreClasses.recordCellClass,
public: public,
data:  data ]]};
Commander.Register[key: "IFUTestPLAInit", proc: IFUTestPLAInit];
Commander.Register[key: "IFUTestPLA",  proc: IFUTestPLADo];
END.