<> <> <> <> 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; <> 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 []_CoreOps.SetShortWireName[public[in][bit], IO.PutFR["StateBA.%g", IO.int[bit]]]; []_CoreOps.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] ]; }; <> <> 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[]}; <> RotateSReg: PROC[in: INT] = { inverts: LIST OF BOOL _ LIST[TRUE, FALSE]; FOR pass: INT IN [0..2) DO expVals: LIST OF INT _ LIST[(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; <> 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]; <> 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.