<> <> <> <> <> <> <<>> DIRECTORY BIC, BitOps, Core, CoreFlat, ICTest, IO, Rope, RosemaryUser, Ports; BICSim: CEDAR PROGRAM IMPORTS BIC, BitOps, CoreFlat, ICTest, RosemaryUser, Ports = BEGIN OPEN Ports; <> <<-- mostly inspired by EUSim.mesa>> ROPE: TYPE = Rope.ROPE; nbCycles: INT _ 0; <<-- structure of DBusIn>> nDReset: NAT = BIC.nDReset; nDFreeze: NAT = BIC.nDFreeze; DExecute: NAT = BIC.DExecute; DShiftCK: NAT = BIC.DShiftCK; DAddress: NAT = BIC.DAddress; DSerialIn: NAT = BIC.DSerialIn; HybridSel: NAT = BIC.HybridSel; <<-- other constants>> ScanPath: TYPE = {ReadChipID, AccessDP, ReadExtCK, ReadIntCK, WriteExtCK, WriteIntCK}; dbusAdRegSize: NAT=8; chipIDSize: NAT=16; clockRegSize: NAT=4; Initialize: PROC [p: Ports.Port, public: Core.Wire] RETURNS [bicPorts: BIC.BICPorts]= { OPEN Ports; bicPorts _ BIC.BICBind[public, p]; {OPEN bicPorts; <<-- ignore all outputs, but give them a value to please Rosemary>> PDW[nRqOutB, 0, none]; PDW[nDOutB, 0, none]; PDW[nBOutB, 0, none]; PDW[nOrOutB, 0, none]; PDW[DOutH, 0, none]; PDW[BOutH, 0, none]; PB[ChipCKOut, FALSE, none]; PB[ExtCKOut, FALSE, none]; PB[LocCKOut, FALSE, none]; PB[CKRecAdj, TRUE]; PB[RecAdj, TRUE]; PB[nEClock, TRUE]; PB[Clock, FALSE]; PB[ChipCKIn, FALSE]; PB[ExtCKIn, FALSE]; PDW[nDInB, 0]; PDW[nBInB, 0]; PDW[DInH, 0]; PDW[BInH, 0]; PDW[RqIn, 0]; PDW[OrInH, 0]; PB[nSStop, TRUE]; PB[DOEn, TRUE]; PDW[Name, 7]; PBS[DBusIn, nDReset, TRUE]; PBS[DBusIn, nDFreeze, TRUE]; PBS[DBusIn, DExecute, FALSE]; PBS[DBusIn, DShiftCK, FALSE]; PBS[DBusIn, DAddress, FALSE]; PBS[DBusIn, DSerialIn, FALSE]; PBS[DBusIn, HybridSel, FALSE]; PDW[Send, 0FH]; PD[DBusOut, none]; PDW[DCS, 0, none]; PB[Vdd, TRUE]; PB[Gnd, FALSE]; PB[Gnd2V, FALSE]; }}; ExerciseRose: PUBLIC PROC [ct: Core.CellType, cutSets: LIST OF ROPE _ NIL] RETURNS [tester: RosemaryUser.Tester] = { <> BIC.InitializeTester[ct]; tester _ RosemaryUser.TestProcedureViewer[ cellType: ct, testButtons: LIST["MinimumClockTest", "MinTest", "BtoHTest", "HtoBTest", "StopTest", "ShiftChipIDTest", "NameandDCSTest", "ShiftInDP", "SendandDOEnTest", "DBusTest", "RosemaryGlobalTest", "XTest"], name: "BICTest", displayWires: RosemaryUser.DisplayPortLeafWires[ct], cutSet: CoreFlat.CreateCutSet[labels: cutSets], steady: FALSE]; }; <<-- Wiggle the clock once; must be called after all ports have their value>> <<-- Reset the drive of all tester ports corresponding to output pads to "none">> DoCK: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc] = { OPEN bicPorts; nbCycles _ nbCycles+1; PB[ChipCKIn, FALSE]; Eval[! Ports.CheckError =>RESUME]; PB[ChipCKIn, TRUE]; Eval[]; PD[ChipCKOut, none]; PD[ExtCKOut, none]; PD[LocCKOut, none]; PD[nRqOutB, none]; PD[nDOutB, none]; PD[nBOutB, none]; PD[nOrOutB, none]; PD[DOutH, none]; PD[BOutH, none]; PD[DBusOut, none]; PD[DCS, none]; }; <<-- Enough clock cycles to set all internal flops to a proper value>> DBusState: TYPE = {normal, freeze, reset, execute}; SetDBus: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, state: DBusState _ normal] ~ { OPEN bicPorts; SELECT state FROM normal => { PBS[DBusIn, nDReset, TRUE]; PBS[DBusIn, nDFreeze, TRUE]; PBS[DBusIn, DExecute, FALSE]; }; freeze => { PBS[DBusIn, nDReset, TRUE]; PBS[DBusIn, nDFreeze, FALSE]; PBS[DBusIn, DExecute, FALSE]; }; reset => { PBS[DBusIn, nDReset, FALSE]; PBS[DBusIn, nDFreeze, TRUE]; PBS[DBusIn, DExecute, FALSE]; }; execute => { PBS[DBusIn, nDReset, FALSE]; PBS[DBusIn, nDFreeze, TRUE]; PBS[DBusIn, DExecute, TRUE]; }; ENDCASE => ERROR; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; }; <<-- Loads the DBus address register to access one of the scan path>> <<-- assumes that Name=7>> ShiftInDBusReg: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, scPath: ScanPath, name: NAT _ 7, cs: NAT _ 0] ~ { OPEN bicPorts; val: CARD _ name*32+cs*8+ORD[scPath]; -- was 0E0H+ORD[scPath] PBS[DBusIn, DAddress, TRUE]; PBS[DBusIn, HybridSel, FALSE]; FOR i: NAT IN [0..dbusAdRegSize) DO PBS[DBusIn, DSerialIn, BitOps.EBFD[val, i, dbusAdRegSize]]; -- shift in val[i] PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; DoCK[bicPorts, Eval]; ENDLOOP; PBS[DBusIn, DShiftCK, FALSE]; PBS[DBusIn, DAddress, FALSE]; PBS[DBusIn, HybridSel, TRUE]; }; <<-- Assuming the DBus address register has been loaded properly, this shifts out "size" bits and compares them with "expected">> ShiftOutDBus: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, size: NAT, expected: CARD] ~ { OPEN bicPorts; PBS[DBusIn, DAddress, FALSE]; PBS[DBusIn, HybridSel, TRUE]; PDW[DBusOut, IF BitOps.EBFD[expected, 0, size] THEN 1 ELSE 0, expect]; DoCK[bicPorts, Eval]; FOR i: NAT IN [1..size) DO PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; PDW[DBusOut, IF BitOps.EBFD[expected, i, size] THEN 1 ELSE 0, expect]; DoCK[bicPorts, Eval]; ENDLOOP; PBS[DBusIn, DShiftCK, FALSE]; }; <<-- Shifts a value inside a scan path>> ShiftInDBus: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, size: NAT, val: CARD] ~ { OPEN bicPorts; PBS[DBusIn, DAddress, FALSE]; PBS[DBusIn, HybridSel, TRUE]; FOR i: NAT IN [0..size) DO PBS[DBusIn, DSerialIn, BitOps.EBFD[val, i, size]]; PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; DoCK[bicPorts, Eval]; ENDLOOP; PBS[DBusIn, DShiftCK, FALSE]; }; ShiftInScanPath: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, size: NAT, val: CARD] ~ { OPEN bicPorts; PBS[DBusIn, nDFreeze, FALSE]; <> FOR i: NAT IN [0..2) DO PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; DoCK[bicPorts, Eval]; ENDLOOP; <<-- at this point, the data path receives "shift" for one cycle>> FOR i: NAT IN [0..(size-2)) DO PBS[DBusIn, DSerialIn, BitOps.EBFD[val, i, size]]; PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; DoCK[bicPorts, Eval]; ENDLOOP; PBS[DBusIn, DShiftCK, FALSE]; PBS[DBusIn, DSerialIn, BitOps.EBFD[val, (size-2), size]]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; PBS[DBusIn, DSerialIn, BitOps.EBFD[val, size-1, size]]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; }; <<-- shift the same value back in the DP, so that if you shift the entire length, the content is restored>> ShiftOutDPScanPath: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, size: NAT, val: CARD] ~ { OPEN bicPorts; PBS[DBusIn, nDFreeze, FALSE]; ShiftInDBusReg[bicPorts, Eval, AccessDP]; FOR i: NAT IN [0..2) DO PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; DoCK[bicPorts, Eval]; ENDLOOP; <<-- at this point, the data path receives "shift" for one cycle>> FOR i: NAT IN [0..(size-2)) DO bit: BOOL _ BitOps.EBFD[val, i, size]; PBS[DBusIn, DSerialIn, bit]; PDW[DBusOut, IF bit THEN 1 ELSE 0, expect]; PBS[DBusIn, DShiftCK, FALSE]; DoCK[bicPorts, Eval]; PBS[DBusIn, DShiftCK, TRUE]; DoCK[bicPorts, Eval]; ENDLOOP; PBS[DBusIn, DShiftCK, FALSE]; PBS[DBusIn, DSerialIn, BitOps.EBFD[val, (size-2), size]]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; PBS[DBusIn, DSerialIn, BitOps.EBFD[val, size-1, size]]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; }; CheckInvertingPath: PROC [bicPorts: BIC.BICPorts, Eval: RosemaryUser.TestEvalProc, inPort, outPort: Port, inVal: CARD] ~ { PDW[inPort, inVal]; PDW[outPort, BitOps.DNOT[inVal, Ports.Size[outPort]], expect]; DoCK[bicPorts, Eval]; }; <<>> <<-- Test procs>> <<>> <<-- The minimum expected from a chip: the DBus amplifiers are combinatorial>> MinTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; FOR i: NAT IN [0..8) DO CheckInvertingPath[bicPorts, Eval, nDInB, DOutH, i]; ENDLOOP; }}; <<>> <<-- From board (2V) to hybrid (5V)>> BtoHTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; <<-- Set the DBus>> SetDBus[bicPorts, Eval]; CheckInvertingPath[bicPorts, Eval, nBInB, BOutH, 0]; CheckInvertingPath[bicPorts, Eval, nBInB, BOutH, 0FFFFFFH]; FOR i: NAT IN [0..24) DO -- one running bit CheckInvertingPath[bicPorts, Eval, nBInB, BOutH, BitOps.TwoToThe[i]]; ENDLOOP; FOR i: NAT IN [0..8) DO CheckInvertingPath[bicPorts, Eval, nDInB, DOutH, i]; ENDLOOP; }}; <<>> <<-- From hybrid (5V) to board (2V)>> HtoBTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; SetDBus[bicPorts, Eval]; <<-- DBus from hybrid to board>> FOR i: NAT IN [0..8) DO CheckInvertingPath[bicPorts, Eval, DInH, nDOutB, i]; ENDLOOP; <<-- Data from hybrid to board>> FOR i: NAT IN [0..24) DO CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, BitOps.TwoToThe[i]]; ENDLOOP; <<-- Request and Or from hybrid to board>> FOR i: NAT IN [0..16) DO PDW[OrInH, i]; PDW[nOrOutB, IF i=0 THEN 1 ELSE 0, expect]; PDW[RqIn, 0]; PDW[nRqOutB, 3, expect]; DoCK[bicPorts, Eval]; ENDLOOP; FOR i: NAT IN [0..4) DO PDW[RqIn, i]; PDW[nRqOutB, 3-i, expect]; PDW[OrInH, 0]; PDW[nOrOutB, 1, expect]; DoCK[bicPorts, Eval]; ENDLOOP; }}; <<-- Test Send and DOEn>> SendandDOEnTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; <<-- Set the DBus>> SetDBus[bicPorts, Eval]; PB[DOEn, FALSE]; PDW[DInH, 0]; PDW[nDOutB, 7, expect]; DoCK[bicPorts, Eval]; PDW[DInH, 7]; PDW[nDOutB, 7, expect]; DoCK[bicPorts, Eval]; <<-- Send is latched: it enables the flops one cycle later>> PDW[Send, 0FH]; DoCK[bicPorts, Eval]; FOR i: NAT IN [0..3) DO PDW[Send, BitOps.TwoToThe[i]]; CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, i]; ENDLOOP; <> PDW[Send, 0]; CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0FFFFFFH]; <> PDW[Send, 0]; PDW[BInH, 0FFFFFFH]; PDW[nBOutB, 0FFFFFFH, expect]; DoCK[bicPorts, Eval]; PDW[Send, 0]; PDW[BInH, 0FFFFFFH]; PDW[nBOutB, 0FFFFFFH, expect]; DoCK[bicPorts, Eval]; PDW[Send, 0]; PDW[BInH, 0FFFFFFH]; PDW[nBOutB, 0FFFFFFH, expect]; DoCK[bicPorts, Eval]; }}; <<-- Play with DBus>> DBusTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; SetDBus[bicPorts, Eval]; PBS[DBusIn, nDFreeze, FALSE]; <> CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0AAAAAAH]; CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0BBBBBBH]; CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0CCCCCCH]; PDW[BInH, 0DDDDDDH]; <> PDW[nBOutB, BitOps.DNOT[0CCCCCCH, 24], expect]; DoCK[bicPorts, Eval]; PBS[DBusIn, nDReset, FALSE]; <> PDW[BInH, 0DDDDDDH]; PDW[nBOutB, BitOps.DNOT[0CCCCCCH, 24], expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0DDDDDDH]; PDW[nBOutB, BitOps.DNOT[0CCCCCCH, 24], expect]; DoCK[bicPorts, Eval]; PBS[DBusIn, nDReset, TRUE]; <> PDW[BInH, 0DDDDDDH]; PDW[nBOutB, BitOps.DNOT[0CCCCCCH, 24], expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0888888H]; PDW[nBOutB, 0FFFFFFH, expect]; <> DoCK[bicPorts, Eval]; PDW[BInH, 0888888H]; PDW[nBOutB, 0FFFFFFH, expect]; -- the reset state! PDW[BOutH, 0000000H, expect]; -- the reset state! PDW[OrInH, 0]; PDW[nOrOutB, 1, expect]; -- no longer in scan path PDW[nRqOutB, 3, expect]; -- the reset state! DoCK[bicPorts, Eval]; PDW[BInH, 0888888H]; PDW[nBInB, 0777777H]; PDW[nBOutB, 0FFFFFFH, expect]; PDW[BOutH, 0000000H, expect]; DoCK[bicPorts, Eval]; <> <> ShiftInDBusReg[bicPorts, Eval, AccessDP]; PBS[DBusIn, DExecute, TRUE]; -- now waiting for an edge on DShiftCK DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; -- nothing should move PBS[DBusIn, DShiftCK, TRUE]; PDW[BInH, 0999999H]; PDW[nBInB, 0555555H]; PDW[nBOutB, 0FFFFFFH, expect]; PDW[BOutH, 0000000H, expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0999999H]; PDW[nBInB, 0555555H]; PDW[nBOutB, 0FFFFFFH, expect]; PDW[BOutH, 0000000H, expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0999999H]; PDW[nBInB, 0555555H]; PDW[nBOutB, 0FFFFFFH, expect]; PDW[BOutH, 0000000H, expect]; PDW[nOrOutB, 1, expect]; PDW[nRqOutB, 3, expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0999999H]; PDW[nBInB, 0555555H]; PDW[OrInH, 0]; PDW[RqIn, 0]; PDW[nBOutB, 0666666H, expect]; PDW[BOutH, 0AAAAAAH, expect]; PDW[nOrOutB, 1, expect]; PDW[nRqOutB, 3, expect]; DoCK[bicPorts, Eval]; <> PBS[DBusIn, DSerialIn, TRUE]; -- Shift in a 1 PBS[DBusIn, DExecute, FALSE]; -- ExecuteOff ShiftInDBusReg[bicPorts, Eval, AccessDP]; PBS[DBusIn, DShiftCK, TRUE]; PDW[BInH, 0888888H]; PDW[nBInB, 0777777H]; PDW[nBOutB, 0666666H, expect]; PDW[BOutH, 0AAAAAAH, expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0888888H]; PDW[nBInB, 0777777H]; PDW[nBOutB, 0666666H, expect]; PDW[BOutH, 0AAAAAAH, expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0888888H]; PDW[nBInB, 0777777H]; PDW[nBOutB, 0666666H, expect]; PDW[BOutH, 0AAAAAAH, expect]; DoCK[bicPorts, Eval]; PDW[BInH, 0888888H]; PDW[nBInB, 0777777H]; <> PDW[nBOutB, 0AAAAAAH, expect]; PDW[BOutH, 0CCCCCDH, expect]; PDW[OrInH, 0]; PDW[nOrOutB, 1, expect]; -- no longer in scan path PDW[nRqOutB, 0, expect]; DoCK[bicPorts, Eval]; }}; <<-- Play with the synchronous stop>> StopTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; SetDBus[bicPorts, Eval]; FOR i: NAT IN [0..40) DO PDW[nBInB, i]; SELECT i FROM <15 => { PDW[nSStop, 1]; PDW[BOutH, 0FFFFFFH-i, expect]; }; 15, 16 => { PDW[nSStop, 0]; PDW[BOutH, 0FFFFFFH-i, expect]; }; >= 17 => { PDW[nSStop, 0]; PDW[BOutH, 0FFFFFFH-16, expect]; }; 20, 21 => { PDW[nSStop, 1]; PDW[BOutH, 0FFFFFFH-16, expect]; }; ENDCASE => { PDW[nSStop, 1]; PDW[BOutH, 0FFFFFFH-i, expect]; }; DoCK[bicPorts, Eval]; ENDLOOP; }}; <<-- Read the chip id= 5081; type=2, version=1>> ShiftChipIDTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; SetDBus[bicPorts, Eval]; ShiftInDBusReg[bicPorts, Eval, ReadChipID]; -- we shift in 0E0H=11100000 PDW[DCS, 0, expect]; -- just check if DCS is OK DoCK[bicPorts, Eval]; ShiftOutDBus[bicPorts, Eval, chipIDSize, BIC.chipID+BIC.currentVersion]; <> }}; <<-- Freeze, shift in the data path scan path, check on ports, execute, check on ports>> ShiftInDP: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; <<-- Set the DBus>> SetDBus[bicPorts, Eval]; CheckInvertingPath[bicPorts, Eval, nBInB, BOutH, 0333333H]; CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0777777H]; PDW[OrInH, 0]; PDW[nOrOutB, 1, expect]; PDW[RqIn, 0]; PDW[nRqOutB, 3, expect]; SetDBus[bicPorts, Eval, freeze]; ShiftInDBusReg[bicPorts, Eval, AccessDP]; <<-- the chip is now frozen>> <> ShiftInScanPath[bicPorts, Eval, 4, 5H]; -- rq and 2 ghost flops ShiftInScanPath[bicPorts, Eval, 24, 0555555H]; -- data, in and out interleaved ShiftInScanPath[bicPorts, Eval, 24, 0555555H]; <<-- dp shift register contains 0101..01>> PDW[BOutH, 0FFFFFFH, expect]; PDW[nBOutB, 0H, expect]; PDW[nRqOutB, 0H, expect]; -- the ghost flops are not visible! PDW[OrInH, 0]; PDW[nOrOutB, 1, expect]; -- no longer in scan path DoCK[bicPorts, Eval]; <<-- check that the or path does not care about reset>> PDW[nRqOutB, 0H, expect]; PDW[OrInH, 1]; PDW[nOrOutB, 0, expect]; DoCK[bicPorts, Eval]; }}; NameandDCSTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; SetDBus[bicPorts, Eval]; ShiftInDBusReg[bicPorts, Eval, AccessDP]; PDW[DCS, 0, expect]; -- just check if DCS is OK DoCK[bicPorts, Eval]; <<-- the decoder is a bit tricky>> ShiftInDBusReg[bicPorts, Eval, AccessDP, 7, 1]; PDW[DCS, 4, expect]; DoCK[bicPorts, Eval]; ShiftInDBusReg[bicPorts, Eval, AccessDP, 7, 2]; PDW[DCS, 2, expect]; DoCK[bicPorts, Eval]; ShiftInDBusReg[bicPorts, Eval, AccessDP, 7, 3]; PDW[DCS, 1, expect]; DoCK[bicPorts, Eval]; <<-- if name#7, DCS=0>> FOR i: NAT IN [0..7) DO PDW[Name, i]; ShiftInDBusReg[bicPorts, Eval, AccessDP, i, 0]; PDW[DCS, 0, expect]; DoCK[bicPorts, Eval]; ENDLOOP; }}; <<-- Mimicks a cold start: comments are from DBusDoc.tioga>> ResetTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; <<-- 1. assert nDReset through power on detection or by software>> PBS[DBusIn, nDReset, FALSE]; SetDBus[bicPorts, Eval]; <<-- 2. assert nDFreeze to enable DBus operations>> PBS[DBusIn, nDFreeze, FALSE]; SetDBus[bicPorts, Eval]; <<-- 3. read and verify the hardware configuration by reading all component IDs on the DBus>> ShiftInDBusReg[bicPorts, Eval, ReadChipID]; ShiftOutDBus[bicPorts, Eval, chipIDSize, BIC.chipID+BIC.currentVersion]; ShiftInDBusReg[bicPorts, Eval, AccessDP]; ShiftOutDPScanPath[bicPorts, Eval, 4, 5H]; -- 0101 for Rq ShiftOutDPScanPath[bicPorts, Eval, 24, 555555H]; -- 010101... for data[hi] ShiftOutDPScanPath[bicPorts, Eval, 24, 555555H]; -- 010101... for data[low] <<-- 4. set the DynaBus clock frequency to a reasonable value>> NULL; <<-- 5. tune clock skews in each hybrid to the "best" value>> ShiftInDBusReg[bicPorts, Eval, WriteIntCK]; ShiftInDBus[bicPorts, Eval, clockRegSize, 0]; ShiftInDBusReg[bicPorts, Eval, WriteExtCK]; ShiftInDBus[bicPorts, Eval, clockRegSize, 0]; <<-- 6. load unique DynaBus IDs into each DynaBus partner>> <<-- 7. load chip-dependent initialization constants into chips (arbiters, ...)>> <<-- 8. assert DynaBus StopOut/StopIn signal to prevent arbiters from running>> NULL; <<-- 9. remove nDFreeze, DBus will not be used any more>> PBS[DBusIn, nDFreeze, TRUE]; SetDBus[bicPorts, Eval]; <<-- 10. remove nDReset, allowing chips to start running (except arbiters)>> PBS[DBusIn, nDReset, TRUE]; SetDBus[bicPorts, Eval]; <<-- 11. remove DynaBus StopOut/StopIn to start all arbiters synchronously>> <<-- 12. load Dragon boot code into DynaBus memory through the IOBridge>> <<-- 13. start processors (remove the processor reset bit in caches)>> NULL; }}; <<-- Changes the skew on external clock>> ClockDelayTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; ShiftInDBusReg[bicPorts, Eval, WriteExtCK]; FOR i: NAT IN [0..16) DO ShiftInDBus[bicPorts, Eval, clockRegSize, i]; THROUGH [0..40) DO DoCK[bicPorts, Eval] ENDLOOP; ENDLOOP; <> <> <> <> <> }}; <<-- Test that delay lines are not dead; for Rosemary>> MinimumClockTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; ShiftInDBusReg[bicPorts, Eval, WriteExtCK]; FOR i: NAT IN [0..16) DO ShiftInDBus[bicPorts, Eval, clockRegSize, i]; PB[nEClock, TRUE]; PB[ExtCKOut, FALSE, expect]; DoCK[bicPorts, Eval]; PB[nEClock, FALSE]; PB[ExtCKOut, TRUE, expect]; DoCK[bicPorts, Eval]; ENDLOOP; ShiftInDBusReg[bicPorts, Eval, WriteIntCK]; FOR i: NAT IN [0..16) DO ShiftInDBus[bicPorts, Eval, clockRegSize, i]; PB[nEClock, TRUE]; PB[LocCKOut, FALSE, expect]; DoCK[bicPorts, Eval]; PB[nEClock, FALSE]; PB[LocCKOut, TRUE, expect]; DoCK[bicPorts, Eval]; ENDLOOP; }}; <<-- Tests the Clocks and the Delay Detector not the Delay Function>> ClockTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; <<-- Clock, nEClock, < not ExtCKIn > belong to the same group as ChipCKIn (12)>> <<-- LocCKOut, ChipCKOut, ExtCKOut belong to the same group (11)>> <<>> <<-- First set the delay registers, or the transistor-level simulation will produce X's>> <<-- and for the same price read back the registers>> <> <> <> <> <<>> <> <> <> <> <<>> <<-- Check that ExtCKOut=LocCKOut=~nEClock>> <> FOR i: NAT IN [0..16) DO ShiftInDBus[bicPorts, Eval, clockRegSize, i]; PDW[nEClock, 0]; PDW[ChipCKOut, 1, expect]; -- dumb, but that's IMS! PDW[LocCKOut, 1, expect]; PDW[ExtCKOut, 1, expect]; DoCK[bicPorts, Eval]; PDW[nEClock, 1]; PDW[ChipCKOut, 1, expect]; -- dumb, but that's IMS! PDW[LocCKOut, 0, expect]; PDW[ExtCKOut, 0, expect]; DoCK[bicPorts, Eval]; ENDLOOP; ShiftInDBusReg[bicPorts, Eval, WriteExtCK]; FOR i: NAT IN [0..16) DO ShiftInDBus[bicPorts, Eval, clockRegSize, i]; PDW[nEClock, 0]; PDW[ChipCKOut, 1, expect]; -- dumb, but that's IMS! PDW[LocCKOut, 1, expect]; PDW[ExtCKOut, 1, expect]; DoCK[bicPorts, Eval]; PDW[nEClock, 1]; PDW[ChipCKOut, 1, expect]; -- dumb, but that's IMS! PDW[LocCKOut, 0, expect]; PDW[ExtCKOut, 0, expect]; DoCK[bicPorts, Eval]; ENDLOOP; ShiftInDBusReg[bicPorts, Eval, WriteIntCK]; PDW[Clock, 0]; PDW[DBusOut, 1, expect]; DoCK[bicPorts, Eval]; PDW[Clock, 1]; PDW[DBusOut, 0, expect]; DoCK[bicPorts, Eval]; ShiftInDBusReg[bicPorts, Eval, WriteExtCK]; PDW[Clock, 0]; PDW[DBusOut, 1, expect]; PDW[ExtCKIn, 1]; DoCK[bicPorts, Eval]; PDW[Clock, 1]; PDW[DBusOut, 0, expect]; PDW[ExtCKIn, 1]; DoCK[bicPorts, Eval]; <<-- We cannot test the sampling of ChipCKOut and < ExtCKIn > by Clock since they all belong to the same group, which would create a race ExtCkIn is now part of an In0 signal group so it can be checked>> }}; ZapTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; FOR i: NAT IN [0..8) DO CheckInvertingPath[bicPorts, Eval, nDInB, DOutH, i]; ENDLOOP; }}; XTest: RosemaryUser.TestProc = { bicPorts: BIC.BICPorts _ Initialize[p, cellType.public]; {OPEN bicPorts; PLS[DBusIn, nDReset, X]; PLS[DBusIn, nDFreeze, X]; PLS[DBusIn, DExecute, X]; PLS[DBusIn, DShiftCK, X]; PLS[DBusIn, DAddress, X]; PLS[DBusIn, DSerialIn, X]; PLS[DBusIn, HybridSel, X]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; DoCK[bicPorts, Eval]; SetDBus[bicPorts, Eval, reset]; SetDBus[bicPorts, Eval, normal]; CheckInvertingPath[bicPorts, Eval, RqIn, nRqOutB, 1]; CheckInvertingPath[bicPorts, Eval, RqIn, nRqOutB, 0]; CheckInvertingPath[bicPorts, Eval, RqIn, nRqOutB, 3]; CheckInvertingPath[bicPorts, Eval, RqIn, nRqOutB, 2]; }}; GlobalTest: RosemaryUser.TestProc = { MinTest[simulation, cellType, p, Eval]; BtoHTest[simulation, cellType, p, Eval]; HtoBTest[simulation, cellType, p, Eval]; StopTest[simulation, cellType, p, Eval]; ShiftChipIDTest[simulation, cellType, p, Eval]; NameandDCSTest[simulation, cellType, p, Eval]; ShiftInDP[simulation, cellType, p, Eval]; SendandDOEnTest[simulation, cellType, p, Eval]; DBusTest[simulation, cellType, p, Eval]; <> }; RosemaryGlobalTest: RosemaryUser.TestProc = { MinimumClockTest[simulation, cellType, p, Eval]; XTest[simulation, cellType, p, Eval]; MinTest[simulation, cellType, p, Eval]; BtoHTest[simulation, cellType, p, Eval]; HtoBTest[simulation, cellType, p, Eval]; StopTest[simulation, cellType, p, Eval]; ShiftChipIDTest[simulation, cellType, p, Eval]; NameandDCSTest[simulation, cellType, p, Eval]; ShiftInDP[simulation, cellType, p, Eval]; SendandDOEnTest[simulation, cellType, p, Eval]; DBusTest[simulation, cellType, p, Eval]; }; Register: PROC [usingTester: BOOL] ~ { IF usingTester THEN { -- for IMS tester ICTest.RegisterTestProc["BIC Test", "MinTest", MinTest]; ICTest.RegisterTestProc["BIC Test", "BtoHTest", BtoHTest]; ICTest.RegisterTestProc["BIC Test", "HtoBTest", HtoBTest]; ICTest.RegisterTestProc["BIC Test", "SendandDOEnTest", SendandDOEnTest]; ICTest.RegisterTestProc["BIC Test", "DBusTest", DBusTest]; ICTest.RegisterTestProc["BIC Test", "StopTest", StopTest]; ICTest.RegisterTestProc["BIC Test", "ShiftChipIDTest", ShiftChipIDTest]; ICTest.RegisterTestProc["BIC Test", "NameandDCSTest", NameandDCSTest]; ICTest.RegisterTestProc["BIC Test", "ResetTest", ResetTest]; ICTest.RegisterTestProc["BIC Test", "ClockTest", ClockTest]; ICTest.RegisterTestProc["BIC Test", "ClockDelayTest", ClockDelayTest]; ICTest.RegisterTestProc["BIC Test", "ZapTest", ZapTest]; ICTest.RegisterTestProc["BIC Test", "ShiftInDP", ShiftInDP]; ICTest.RegisterTestProc["BIC Test", "GlobalTest", GlobalTest]; } ELSE { -- for Rosemary simulation RosemaryUser.RegisterTestProc["MinimumClockTest", MinimumClockTest]; RosemaryUser.RegisterTestProc["MinTest", MinTest]; RosemaryUser.RegisterTestProc["BtoHTest", BtoHTest]; RosemaryUser.RegisterTestProc["HtoBTest", HtoBTest]; RosemaryUser.RegisterTestProc["StopTest", StopTest]; RosemaryUser.RegisterTestProc["ShiftChipIDTest", ShiftChipIDTest]; RosemaryUser.RegisterTestProc["NameandDCSTest", NameandDCSTest]; RosemaryUser.RegisterTestProc["ShiftInDP", ShiftInDP]; RosemaryUser.RegisterTestProc["SendandDOEnTest", SendandDOEnTest]; RosemaryUser.RegisterTestProc["DBusTest", DBusTest]; RosemaryUser.RegisterTestProc["RosemaryGlobalTest", RosemaryGlobalTest]; RosemaryUser.RegisterTestProc["XTest", XTest]; }; }; END.