BICSim.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reversed.
Created by Louis Monier February 1, 1987 7:31:08 pm PST
Bertrand Serlet May 30, 1987 4:32:46 pm PDT
Last Edited by: Louis Monier November 13, 1987 2:29:28 pm PST
Last Edited by: RBruce September 9, 1987 1:38:12 pm PDT
DIRECTORY
BIC, BitOps, Core, CoreFlat, ICTest, IO, Rope, Rosemary, RosemaryUser, Ports;
BICSim: CEDAR PROGRAM
IMPORTS BIC, BitOps, CoreFlat, ICTest, Rosemary, RosemaryUser, Ports =
BEGIN OPEN Ports;
Test of the Bus Interface Chip
-- 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];
}};
InitializePublic: PROC [public: Core.Wire] = {
Vdd, Gnd, Gnd2V, CKRecAdj, RecAdj,
nEClock, Clock, ChipCKIn, ExtCKIn,
ChipCKOut, ExtCKOut, LocCKOut,
nDInB, nBInB,
nRqOutB, nDOutB, nBOutB, nOrOutB,
DInH, BInH, RqIn, OrInH,
DOutH, BOutH,
nSStop, DOEn, Name, DBusIn, Send,
DBusOut, DCS: NATLAST [NAT];
[Vdd, Gnd, Gnd2V, CKRecAdj, RecAdj] ←
Ports.PortIndexes[public, "Vdd", "Gnd", "Gnd2V", "CKRecAdj", "RecAdj"];
[nEClock, Clock, ChipCKIn, ExtCKIn] ←
Ports.PortIndexes[public, "nEClock", "Clock", "ChipCKIn", "ExtCKIn"];
[ChipCKOut, ExtCKOut, LocCKOut] ←
Ports.PortIndexes[public, "ChipCKOut", "ExtCKOut", "LocCKOut"];
[nDInB, nBInB] ←
Ports.PortIndexes[public, "nDInB", "nBInB"];
[nRqOutB, nDOutB, nBOutB, nOrOutB] ←
Ports.PortIndexes[public, "nRqOutB", "nDOutB", "nBOutB", "nOrOutB"];
[DInH, BInH, RqIn, OrInH] ←
Ports.PortIndexes[public, "DInH", "BInH", "RqIn", "OrInH"];
[DOutH, BOutH] ←
Ports.PortIndexes[public, "DOutH", "BOutH"];
[nSStop, DOEn, Name, DBusIn, Send] ←
Ports.PortIndexes[public, "nSStop", "DOEn", "Name", "DBusIn", "Send"];
[DBusOut, DCS] ←
Ports.PortIndexes[public, "DBusOut", "DCS"];
[] ← Rosemary.SetFixedWire[public[Vdd], H];
[] ← Rosemary.SetFixedWire[public[Gnd], L];
[] ← Rosemary.SetFixedWire[public[Gnd2V], L];
[] ← Ports.InitTesterDrive[public[Vdd], drive];
[] ← Ports.InitTesterDrive[public[Gnd], drive];
[] ← Ports.InitTesterDrive[public[Gnd2V], drive];
[] ← Ports.InitTesterDrive[public[CKRecAdj], drive];
[] ← Ports.InitTesterDrive[public[RecAdj], drive];
[] ← Ports.InitTesterDrive[public[nEClock], drive];
[] ← Ports.InitTesterDrive[public[Clock], drive];
[] ← Ports.InitTesterDrive[public[ChipCKIn], drive];
[] ← Ports.InitTesterDrive[public[ExtCKIn], drive];
[] ← Ports.InitTesterDrive[public[ChipCKOut], drive];
[] ← Ports.InitTesterDrive[public[ExtCKOut], drive];
[] ← Ports.InitTesterDrive[public[LocCKOut], drive];
[] ← Ports.InitTesterDrive[public[nDInB], drive];
[] ← Ports.InitTesterDrive[public[nBInB], drive];
[] ← Ports.InitTesterDrive[public[nRqOutB], expect];
[] ← Ports.InitTesterDrive[public[nDOutB], expect];
[] ← Ports.InitTesterDrive[public[nBOutB], expect];
[] ← Ports.InitTesterDrive[public[nOrOutB], expect];
[] ← Ports.InitTesterDrive[public[DInH], drive];
[] ← Ports.InitTesterDrive[public[BInH], drive];
[] ← Ports.InitTesterDrive[public[RqIn], drive];
[] ← Ports.InitTesterDrive[public[OrInH], drive];
[] ← Ports.InitTesterDrive[public[DOutH], expect];
[] ← Ports.InitTesterDrive[public[BOutH], expect];
[] ← Ports.InitTesterDrive[public[nSStop], drive];
[] ← Ports.InitTesterDrive[public[DOEn], drive];
[] ← Ports.InitTesterDrive[public[Name], drive];
[] ← Ports.InitTesterDrive[public[DBusIn], drive];
[] ← Ports.InitTesterDrive[public[Send], drive];
[] ← Ports.InitTesterDrive[public[DBusOut], expect];
[] ← Ports.InitTesterDrive[public[DCS], expect];
};
ExerciseRose: PUBLIC PROC [ct: Core.CellType, cutSets: LIST OF ROPENIL] RETURNS [tester: RosemaryUser.Tester] = {
InitializePublic[ct.public];
tester ← RosemaryUser.TestProcedureViewer[
cellType: ct,
testButtons: LIST["XTest", "MinTest", "BtoHTest", "HtoBTest", "StopTest", "ShiftChipIDTest", "NameandDCSTest", "ShiftInDP", "SendandDOEnTest", "DBusTest", "GlobalTest"],
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];
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
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;
-- this one OK, but we set Send so that during next cycle, it should not drive
PDW[Send, 0];
CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0FFFFFFH];
-- this one should not drive
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];
FreezeSet
CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0AAAAAAH];
CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0BBBBBBH];
CheckInvertingPath[bicPorts, Eval, BInH, nBOutB, 0CCCCCCH];
PDW[BInH, 0DDDDDDH];
FreezeOn
PDW[nBOutB, BitOps.DNOT[0CCCCCCH, 24], expect];
DoCK[bicPorts, Eval];
PBS[DBusIn, nDReset, FALSE];
ResetSet
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];
ResetUnset
PDW[BInH, 0DDDDDDH];
PDW[nBOutB, BitOps.DNOT[0CCCCCCH, 24], expect];
DoCK[bicPorts, Eval];
PDW[BInH, 0888888H];
PDW[nBOutB, 0FFFFFFH, expect];
ResetOn
DoCK[bicPorts, Eval];
PDW[BInH, 0888888H];
PDW[nBOutB, 0FFFFFFH, expect]; -- the reset state!
PDW[BOutH, 0000000H, expect]; -- the reset state!
PDW[nOrOutB, 1, expect];  -- fix!
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];
ResetOff
ExecuteSet
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];
Shift Set
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];
Shift On
PDW[nBOutB, 0AAAAAAH, expect];
PDW[BOutH, 0CCCCCDH, expect];
PDW[nOrOutB, 0, expect]; -- fix!
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];
PD[DCS, none];
}};
-- 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, 2, 1H]; -- or and 1 ghost flop
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[nOrOutB, 0H, expect];  -- idem
DoCK[bicPorts, Eval];
-- check that the or path does not care about reset
PDW[OrInH, 0];
PDW[nOrOutB, 1, expect];
DoCK[bicPorts, Eval];
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;
ShiftInDBusReg[bicPorts, Eval, WriteIntCK]; 
FOR i: NAT IN [0..16) DO
ShiftInDBus[bicPorts, Eval, clockRegSize, i];
THROUGH [0..40) DO DoCK[bicPorts, Eval] ENDLOOP;
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
ShiftInDBusReg[bicPorts, Eval, WriteIntCK];
ShiftInDBus[bicPorts, Eval, clockRegSize, 1];
ShiftInDBusReg[bicPorts, Eval, ReadIntCK];
ShiftOutDBus[bicPorts, Eval, clockRegSize, 1];
ShiftInDBusReg[bicPorts, Eval, WriteExtCK];
ShiftInDBus[bicPorts, Eval, clockRegSize, 4];
ShiftInDBusReg[bicPorts, Eval, ReadExtCK];
ShiftOutDBus[bicPorts, Eval, clockRegSize, 4];
-- Check that ExtCKOut=LocCKOut=~nEClock
ShiftInDBusReg[bicPorts, Eval, WriteIntCK];
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[cellType, p, Eval];
BtoHTest[cellType, p, Eval];
HtoBTest[cellType, p, Eval];
StopTest[cellType, p, Eval];
ShiftChipIDTest[cellType, p, Eval];
NameandDCSTest[cellType, p, Eval];
ShiftInDP[cellType, p, Eval];
SendandDOEnTest[cellType, p, Eval];
DBusTest[cellType, p, Eval];
ClockTest[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["XTest", XTest];
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["GlobalTest", GlobalTest];
};
};
END.