SloIODeviceTest.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Created by Neil Gunther, August 18, 1986 1:02:28 am PDT
Last Edited by: Neil Gunther August 22, 1986 6:42:55 pm PDT
DIRECTORY
Core, Ports, Rosemary, RosemaryUser, SloIODevice, TerminalIO;
SloIODeviceTest: CEDAR PROGRAM
IMPORTS Ports, RosemaryUser, SloIODevice, TerminalIO
= BEGIN
ENCTest: RosemaryUser.TestProc = {
junkAddr: CARDINAL ← 0;
iopAddrReg: CARDINAL ← 0;
iopDataReg: CARDINAL ← 0;
CycleClock: PROC [n: NAT ← 1] = { --always returns low
THROUGH [0..n) DO
p[Clock].d ← drive;
p[Clock].l ← L;
Eval[];
p[Clock].d ← drive;
p[Clock].l ← H;
Eval[! Ports.CheckError => RESUME];
ENDLOOP;
p[Clock].d ← drive;
p[Clock].l ← L;
Eval[];
};
ClkLevel: TYPE = {hi, lo};
SetClock: PROC [cl: ClkLevel] = {
p[Clock].d ← drive;
p[Clock].l ← SELECT TRUE FROM cl=hi=> H, ENDCASE=> L;
Eval[! Ports.CheckError => RESUME];
};
Assert: PROC [signal: NAT, strength: Ports.Drive ← drive, cycles: NAT] = {
THROUGH [0..cycles) DO
p[signal].d ← strength;
p[signal].l ← H;
SetClock[lo]; --calls Eval
p[signal].d ← strength;
p[signal].l ← H;
SetClock[hi];
ENDLOOP;
p[signal].d ← strength;
p[signal].l ← H;
SetClock[lo];
};
ResetENC: PROC = {
Assumes clock is low on entry.
SetClock[hi];
Assert[signal: Reset, strength: drive, cycles: 4];
SetClock[hi];
p[Reset].l ← L;
SetClock[lo]; --deassert it
SetClock[hi];
CycleClock[10];
};
WriteIOP: PROC [] = {
NoteState["Interrupt from Ethernet"];
Assert[signal: SerialDataReceived, strength: force, cycles: 1]; --returns low
ENC requests SloBus
NoteState["ENC sent interrupt to IOP"];
p[SerialDataReceived].l ← L; --expected (only in test mode)
SetClock[hi];
SetClock[lo];
p[IntrptReq].l ← H; --expected
SetClock[hi];
SetClock[lo];
p[HoldReq].l ← H; --expected
Simulate IOP busy; burn some cycles before granting SloBus
NoteState["SloBus busy (1 cycles)"];
SetClock[hi];
SetClock[lo];
NoteState["Grant SloBus"];
p[HoldAck].l ← H;
Write transfer starts here
Tri-state IOP drivers
p[ADBus].d ← none;
NoteState["IOP is addressed"];
SetClock[hi];
SetClock[lo];
p[ADBus].d ← expect;
iopAddrReg ← p[ADBus].c ← 60000;
NoteState["IOP busy (2 cycles)"];
SetClock[hi];
SetClock[lo];
SetClock[hi];
SetClock[lo];
p[Ready].l ← H;
SetClock[hi];
SetClock[lo]; --t1
p[ADBus].d ← none; --tri-state IOP drivers
ENC writes valid data out
SetClock[hi];
SetClock[lo]; --t2
NoteState["Data available from ENC"];
p[ADBus].d ← expect;
iopDataReg ← p[ADBus].c ← 4000;
p[ADBus].d ← none; --tri-state ENC drivers
SetClock[hi];
SetClock[lo]; --t3
SetClock[hi];
SetClock[lo]; --t4
Finalize DMA transfer
NoteState["Releasing SloBus"];
SetClock[hi];
SetClock[lo];
p[HoldReq].l ← L; --expected
SetClock[hi];
p[HoldAck].l ← L;
p[Ready].l ← L;
SetClock[lo];
}; --WriteIOP
ReadIOP: PROC = {
NoteState["Interrupt Ethernet controller"];
Assert[signal: ChanAttn, strength: force, cycles: 1]; --returns low
ENC acknowledges & requests SloBus
NoteState["Request SloBus"];
SetClock[hi];
SetClock[lo];
Both of these lines deasserted by ENC
p[ChanAttn].l ← L; --expected
p[IntrptReq].l ← L; --expected
SetClock[hi];
SetClock[lo];
p[HoldReq].l ← H; --expected
Simulate IOP busy; burn some cycles before granting SloBus
NoteState["SloBus Busy (2 cycles)"];
SetClock[hi];
CycleClock[1];
SetClock[hi];
NoteState["Grant SloBus"];
p[HoldAck].l ← H;
SetClock[lo];
Read transfer starts here
NoteState["Generate address"];
SetClock[hi];
Tri-state IOP drivers
p[ADBus].d ← none;
SetClock[lo];
Address is available
p[ADBus].d ← expect;
iopAddrReg ← p[ADBus].c ← 60000;
p[ADBus].d ← none; --tri-state
SetClock[hi];
SetClock[lo]; --t1
NoteState["Address ready"];
IOP drivers enabled
SetClock[hi];
p[ADBus].d ← force;
SetClock[lo]; --t2
NoteState["IOP data drivers enabled"];
Force wait-state insertions
NoteState["SloBus Busy (3 cycles) => ENC Wait States"];
SetClock[hi];
CycleClock[2]; --t3
SetClock[hi];
IOP puts valid data out
NoteState["Data available"];
p[ADBus].c ← iopDataReg;
p[Ready].l ← H;
SetClock[lo];
ENC samples data
NoteState["Data sampled"];
SetClock[hi];
SetClock[lo]; --t4
Finalize DMA transfer
p[HoldReq].l ← L; --expect
SetClock[hi];
p[HoldAck].l ← L;
p[Ready].l ← L; -- drop this line too
SetClock[lo];
}; -- ReadIOP
-- Initialization --
p[Vdd].l ← H;
p[Reset].l ← L;
p[ChanAttn].l ← L;
p[IntrptReq].l ← L;
p[HoldReq].l ← L;
p[HoldAck].l ← L;
p[Ready].l ← L;
p[Clock].l ← L;
p[ADBus].c ← junkAddr;
--Test commences here
IMPORTANT: Ensure that asynchBehaviour is disabled in ENetMaxModeSimple
NoteState["... START "];
CycleClock[2];
SetClock[hi];
WriteIOP[]; --returns low
SetClock[hi];
ReadIOP[]; --returns low
SetClock[hi];
NoteState["Initiate reset cycling"];
ResetENC[];
}; --ENCTest
Vdd, Gnd, Reset, ChanAttn, IntrptReq, HoldReq, HoldAck, Ready, SerialDataReceived, Clock, ADBus: NAT;
testeeName: Core.ROPE = "Ethernet Controller";
enc: Core.CellType ← SloIODevice.EthernetController[];
InitPorts: PROC [public: Core.Wire] = {
Vdd ← Ports.PortIndex[wire: public, name: "Vdd"];
Gnd ← Ports.PortIndex[wire: public, name: "Gnd"];
Reset ← Ports.PortIndex[wire: public, name: "RESET"];
ChanAttn ← Ports.PortIndex[wire: public, name: "CA"];
IntrptReq ← Ports.PortIndex[wire: public, name: "INT"];
HoldReq ← Ports.PortIndex[wire: public, name: "HOLD"];
HoldAck ← Ports.PortIndex[wire: public, name: "HLDA"];
Ready ← Ports.PortIndex[wire: public, name: "READY"];
SerialDataReceived ← Ports.PortIndex[wire: public, name: "RxD"];
Clock ← Ports.PortIndex[wire: public, name: "CLK"];
ADBus ← Ports.PortIndex[wire: public, name: "ADBus"];
IOP Outputs
Ports.InitTesterDrive[wire: public[Reset], initDrive: drive];
Ports.InitTesterDrive[wire: public[HoldAck], initDrive: drive];
Ports.InitTesterDrive[wire: public[Ready], initDrive: drive];
Ports.InitTesterDrive[wire: public[Clock], initDrive: drive];
IOP BiDirectional
Ports.InitTesterDrive[wire: public[ChanAttn], initDrive: force];
Ports.InitTesterDrive[wire: public[SerialDataReceived], initDrive: force]; --fake test wire
Ports.InitTesterDrive[wire: public[ADBus], initDrive: force];
IOP Inputs
Ports.InitTesterDrive[wire: public[IntrptReq], initDrive: expect];
Ports.InitTesterDrive[wire: public[HoldReq], initDrive: expect];
};
NoteState: PROC [msg: Core.ROPE] = {
IF debugOn THEN TerminalIO.WriteRopes["\nTester: ", msg, " ..."];
};
debugOn: BOOLTRUE; --global
InitPorts[enc.public];
[] ← RosemaryUser.TestProcedureViewer[
cellType: enc,
testButtons: LIST[testeeName],
name: testeeName,
displayWires: RosemaryUser.DisplayCellTypePortLeafWires[enc],
flatten: FALSE
];
RosemaryUser.RegisterTestProc[testeeName, ENCTest];
END.