<> <> <> <> <<>> 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 = { <> 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 <> 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 <> NoteState["SloBus busy (1 cycles)"]; SetClock[hi]; SetClock[lo]; NoteState["Grant SloBus"]; p[HoldAck].l _ H; <> <> 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 <> 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 <> 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 <> NoteState["Request SloBus"]; SetClock[hi]; SetClock[lo]; <> p[ChanAttn].l _ L; --expected p[IntrptReq].l _ L; --expected SetClock[hi]; SetClock[lo]; p[HoldReq].l _ H; --expected <> NoteState["SloBus Busy (2 cycles)"]; SetClock[hi]; CycleClock[1]; SetClock[hi]; NoteState["Grant SloBus"]; p[HoldAck].l _ H; SetClock[lo]; <> NoteState["Generate address"]; SetClock[hi]; <> p[ADBus].d _ none; SetClock[lo]; <
> p[ADBus].d _ expect; iopAddrReg _ p[ADBus].c _ 60000; p[ADBus].d _ none; --tri-state SetClock[hi]; SetClock[lo]; --t1 NoteState["Address ready"]; <<>> <> SetClock[hi]; p[ADBus].d _ force; SetClock[lo]; --t2 NoteState["IOP data drivers enabled"]; <> NoteState["SloBus Busy (3 cycles) => ENC Wait States"]; SetClock[hi]; CycleClock[2]; --t3 SetClock[hi]; <<>> <> NoteState["Data available"]; p[ADBus].c _ iopDataReg; p[Ready].l _ H; SetClock[lo]; <> NoteState["Data sampled"]; SetClock[hi]; SetClock[lo]; --t4 <> 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>> <> 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"]; <> 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]; <> Ports.InitTesterDrive[wire: public[ChanAttn], initDrive: force]; Ports.InitTesterDrive[wire: public[SerialDataReceived], initDrive: force]; --fake test wire Ports.InitTesterDrive[wire: public[ADBus], initDrive: force]; <> 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: BOOL _ TRUE; --global InitPorts[enc.public]; [] _ RosemaryUser.TestProcedureViewer[ cellType: enc, testButtons: LIST[testeeName], name: testeeName, displayWires: RosemaryUser.DisplayCellTypePortLeafWires[enc], flatten: FALSE ]; RosemaryUser.RegisterTestProc[testeeName, ENCTest]; END. <<>>