<> <> <> DIRECTORY Basics, BitOps, CD, Core, CoreFlat, DRam, DynaBusInterface, IO, MCUtils, MTSVector, Ports, Random, Rope, Rosemary, RosemaryUser, ResponseChecker, TerminalIO; TestMC: CEDAR PROGRAM IMPORTS Basics, BitOps, CoreFlat, DRam, DynaBusInterface, IO, MCUtils, MTSVector, Ports, Random, Rosemary, RosemaryUser, ResponseChecker, TerminalIO ~ BEGIN nSStopIn, DReqTP, DGrantTP, SharedIn, OwnerIn, HeaderCycleIn, Clock, DataIn, DBus, TestIn, Vdd, Gnd: NAT; dSerialOut: NAT _ 0; dSerialIn: NAT _ 1; nDReset: NAT _ 2; nDFreeze: NAT _ 3; dExecute: NAT _ 4; dAddress: NAT _ 5; dShiftCK: NAT _ 6; ROPE: TYPE = Core.ROPE; Port: TYPE = Ports.Port; Quad: TYPE = DynaBusInterface.Quad; Cmd: TYPE = DynaBusInterface.Cmd; ModeError: TYPE = DynaBusInterface.ModeError; Shared: TYPE = DynaBusInterface.Shared; DeviceID: TYPE = DynaBusInterface.DeviceID; Address: TYPE = DynaBusInterface.Address; qZero: Quad = BitOps.BitQWordZero; REProc: TYPE = RosemaryUser.TestEvalProc; <<--PROC [memory: BOOL _ TRUE, clockEval: BOOL _ FALSE, checkPorts: BOOL _ TRUE]-->> TProc: TYPE = PROC [h: Handle, Eval: REProc]; ownerDelay: CARDINAL = 7; SHIFT: PROC [value: WORD, count: INTEGER] RETURNS [WORD] = Basics.BITSHIFT; BITAND: Basics.BitOp = Basics.BITAND; BITNOT: PROC [WORD] RETURNS [WORD] = Basics.BITNOT; Log2: PROC [n: INT] RETURNS [INT] = BitOps.Log2; dBusPrefix: NAT = 20h; dBusPrefixBits: NAT = 13; dBusRegAddBits: NAT = 3; dBusWidth: NAT = 9; dBusRegAdd: TYPE = [0..8); arbiterTimeout: CARDINAL _ 200; ownerDelayBuf: ARRAY [0..ownerDelay] OF RECORD [owner, shared: BOOL]; cmdCount: INT _ 0; seed: INT _ 1234; ramdomOps: INT _ 100; cutSet : LIST OF ROPE _ LIST["Logic", "LogicMacro", "DPMacro", "FSM"]; logOn: BOOL _ TRUE; CallIOWrite: TProc ~ {IOWrite0[h, Eval, 7, TRUE, TRUE, 0, 28, 28, 28, 22, 30]}; CallWB: TProc ~ {WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]}; CallRB: TProc ~ {ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]}; CallRBSh: TProc ~ {ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0], FALSE, TRUE]}; CallRBOwn: TProc ~ {ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0], TRUE, FALSE]}; CallRBOwnSh: TProc ~ {ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0], TRUE, TRUE]}; CallFB: TProc ~ {FlushBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]}; CallWS: TProc ~ {WriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah]]}; CallWSSh: TProc ~ {WriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah], TRUE]}; CallCWS: TProc ~ {CondWriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah]]}; CallCWSSh: TProc ~ {CondWriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah], TRUE]}; CallIOR: TProc ~ {IORRqst[h, Eval, [0,0,30h, 0], 0]}; CallBIOW: TProc ~ {BIOWRqst[h, Eval, [0,0,0,0], [0,0,0,0Bh]]}; CallDeMap: TProc ~ {DeMapRqst[h, Eval, [0,0,0,0], [0,0,0,0Ch]]}; opProcs: INT = 13; op: ARRAY [0..opProcs) OF TProc _ [CallIOWrite, CallWB, CallRB, CallRBSh, CallRBOwn, CallRBOwnSh, CallFB, CallWS, CallWSSh, CallCWS, CallCWSSh, CallBIOW, CallDeMap]; Handle: TYPE = REF HandleRec; HandleRec: TYPE = RECORD[ capture: MTSVector.Capture _ NIL, rootCT: Core.CellType _ NIL, captureVectors: BOOL _ FALSE, port: Port _ NIL, rcState: REF ANY --state record of the response checker ]; MCTest: RosemaryUser.TestProc = { DoSimpleTest: TProc ~ { InitPortIndicies[cellType]; h.rcState _ GetState[h, "/ResponseChecker"]; cmdCount _ 0; Reset[h, Eval]; <> <> CmdTest[h, Eval]; <> <> <> <> <> <> <> <> FlushPipe[h, Eval]; }; h: Handle _ NEW[HandleRec]; h.rootCT _ cellType; h.port _ p; h.capture _ MTSVector.CreateCapture[h.rootCT]; h.captureVectors _ TRUE; DoSimpleTest[h, Eval]; MTSVector.CloseCapture[h.capture]; }; ReadID: TProc ~ { ENABLE Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME; DBusRegRead[h, Eval, 0, [0, 0, 0, 5180h], 16]; --header=5, type=6, version=0 }; Reset: TProc ~ { ENABLE Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME; p: Port _ h.port; TerminalIO.PutRope["***Reset***\n"]; p[DBus].bs[nDReset] _ FALSE; p[DBus].ds[dSerialIn] _ drive; p[DBus].ds[nDReset] _ drive; p[DBus].ds[nDFreeze] _ drive; p[DBus].ds[dExecute] _ drive; p[DBus].ds[dAddress] _ drive; p[DBus].ds[dShiftCK] _ drive; p[TestIn].b _ FALSE; p[TestIn].d _ drive; p[nSStopIn].b _ TRUE; p[nSStopIn].d _ drive; p[DBus].bs[dShiftCK] _ FALSE; p[dShiftCK].d _ drive; Cycle[h, Eval, 1]; DBusRegWrite[h, Eval, 1, 0, 10]; p[SharedIn].b _ FALSE; p[SharedIn].d _ drive; p[OwnerIn].b _ FALSE; p[OwnerIn].d _ drive; p[HeaderCycleIn].b _ FALSE; p[HeaderCycleIn].d _ drive; p[DataIn].q _ qZero; p[DataIn].d _ drive; p[DReqTP].c _ 0; -- no request p[DReqTP].d _ drive; Cycle[h, Eval, 7]; p[nSStopIn].b _ FALSE; Cycle[h, Eval, 5]; p[DBus].bs[nDReset] _ TRUE; Cycle[h, Eval, 5]; p[nSStopIn].b _ TRUE; Cycle[h, Eval, 5]; p[DGrantTP].d _ expect; p[DGrantTP].b _ FALSE; IOWrite0[h, Eval, 7, TRUE, TRUE, 0, 28, 28, 28, 22, 30]; IOWrite1[h, Eval, 1, 10]; IOWrite2[h, Eval, 1, 10]; FlushPipe[h, Eval]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; WriteBlockRqst[h, Eval, [0,0,0,0], [0,0,0,0], [1,1,1,1], [2,2,2,2], [3,3,3,3]]; FlushPipe[h, Eval]; }; CircularAccessTest: TProc ~ { <> TerminalIO.PutRope["***Circular Access Test***\n"]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; ReadBlockRqst[h, Eval, [0,0,0,2], [2,2,2,2], [1,1,1,1], [0,0,0,0], [3,3,3,3]]; ReadBlockRqst[h, Eval, [0,0,0,4], [1,1,1,1], [0,0,0,0], [3,3,3,3], [2,2,2,2]]; ReadBlockRqst[h, Eval, [0,0,0,6], [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1]]; ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; }; BankTest: TProc ~ { <> TerminalIO.PutRope["***Bank Test***\n"]; IOWrite1[h, Eval, 2, 10, 1]; --two banks, one megabit drams, bank add=1, IOWrite2[h, Eval, 2, 10, 1]; FlushPipe[h, Eval]; WriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah], FALSE, TRUE]; WriteSingleRqst[h, Eval, [0,0,0,8], [0,0,0,0Ah], FALSE, FALSE]; CondWriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah], FALSE, TRUE]; CondWriteSingleRqst[h, Eval, [0,0,0,8], [0,0,0,0Ah], FALSE, FALSE]; BIOWRqst[h, Eval, [0,0,0,0], [0,0,0,0Bh], TRUE]; BIOWRqst[h, Eval, [0,0,0,8], [0,0,0,0Bh], FALSE]; DeMapRqst[h, Eval, [0,0,0,0], [0,0,0,0Ch], TRUE]; DeMapRqst[h, Eval, [0,0,0,8], [0,0,0,0Ch], FALSE]; IOWrite1[h, Eval, 1, 10]; --single bank, one megabit drams IOWrite2[h, Eval, 1, 10]; Cycle[h, Eval, 10]; }; AddressTest: TProc ~ { <> quad: Quad; TerminalIO.PutRope["***Address Test***\n"]; IOWrite1[h, Eval, 1, 10]; --single bank, one megabit drams IOWrite2[h, Eval, 1, 10]; Cycle[h, Eval, 10]; WriteBlockRqst[h, Eval, [0,0,0,00h], [0,0,0,00h], [0,0,0,00h], [0,0,0,00h], [0,0,0,00h]]; <<--Ignore the low order bit: it signifies the 32-bit address>> <<--Don't test the next two low order bits: they signify the nibble rotatation address>> <<--Test the next 18 bits>> FOR i: NAT DECREASING IN [43..60] DO quad _ BitOps.BitQWordZero; quad _ BitOps.IBIQ[TRUE, quad, i]; WriteBlockRqst[h, Eval, quad, quad, quad, quad, quad]; ENDLOOP; ReadBlockRqst[h, Eval, [0,0,0,00h], [0,0,0,00h], [0,0,0,00h], [0,0,0,00h], [0,0,0,00h]]; FOR i: NAT DECREASING IN [43..60] DO quad _ BitOps.BitQWordZero; quad _ BitOps.IBIQ[TRUE, quad, i]; ReadBlockRqst[h, Eval, quad, quad, quad, quad, quad]; ENDLOOP; }; GetState: PROC [h: Handle, rope: Rope.ROPE] RETURNS [REF] ~ { display: RosemaryUser.RoseDisplay _ RosemaryUser.RoseDisplayFor[h.rootCT]; RETURN[Rosemary.GetState[display.simulation, NEW[CoreFlat.FlatCellTypeRec _ CoreFlat.ParseCellTypePath[display.cellType, rope, NIL]]]]; }; SingleErrorTest: TProc ~ { <> lowBitsState: REF _ GetState[h,"/Ram/Bits63to71"]; TerminalIO.PutRope["***Single Error Test***\n"]; IOWrite3[h, Eval]; --clear error status WriteBlockRqst[h, Eval, [0,0,0,0f0h], [9,9,9,9], [8,8,8,8], [7,7,7,7], [6,6,6,6]]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FlushPipe[h, Eval]; DRam.SingleBitError[lowBitsState, 03Ch, 8]; ReadBlockRqst[h, Eval, [0,0,0,0f0h], [9,9,9,9], [8,8,8,8], [7,7,7,7], [6,6,6,6]]; ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FlushPipe[h, Eval]; IORRqst[h, Eval, [0, 0, 30h, 0], 0f0h]; IORRqst[h, Eval, [0, 0, 30h, 1], 2 + SHIFT[62,5]]; --single bit error, bit 62 ReadBlockRqst[h, Eval, [0,0,0,0f0h], [9,9,9,9], [8,8,8,8], [7,7,7,7], [6,6,6,6]]; FlushPipe[h, Eval]; IORRqst[h, Eval, [0, 0, 30h, 0], 0f0h]; IORRqst[h, Eval, [0, 0, 30h, 1], 3 + SHIFT[62,5]]; --single bit error, mult. mem errors, bit 62 FlushPipe[h, Eval]; <<-- syndrome is XOR[62], error reg is 3 (One Bit, Mult. Mem Err), add is 0f0h>> DBusRegRead[h, Eval, 2, [0, SHIFT[62,5] + 3, 0, 0f0h], 44]; }; DoubleErrorTest: TProc ~ { <> lowBitsState: REF _ GetState[h,"/Ram/Bits63to71"]; TerminalIO.PutRope["***Double Error Test***\n"]; IOWrite3[h, Eval]; --clear error status WriteBlockRqst[h, Eval, [0,0,0,0f0h], [9,9,9,9], [8,8,8,8], [7,7,7,7], [6,6,6,6]]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FlushPipe[h, Eval]; DRam.DoubleBitError[lowBitsState, 03Ch, 6, 8]; ReadBlockRqst[h, Eval, [0,0,0,0f0h], [9,9,9,9], [8,8,8,8], [7,7,7,7], [6,6,6,6], FALSE, FALSE, [TRUE, FALSE, FALSE, FALSE]]; ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FlushPipe[h, Eval]; IORRqst[h, Eval, [0, 0, 30h, 0], 0f0h]; IORRqst[h, Eval, [0, 0, 30h, 1], 8 + SHIFT[Basics.BITXOR[62, 66], 5]]; --two bit error, bits 62, 66 ReadBlockRqst[h, Eval, [0,0,0,0f0h], [9,9,9,9], [8,8,8,8], [7,7,7,7], [6,6,6,6], FALSE, FALSE, [TRUE, FALSE, FALSE, FALSE]]; FlushPipe[h, Eval]; IORRqst[h, Eval, [0, 0, 30h, 0], 0f0h]; IORRqst[h, Eval, [0, 0, 30h, 1], 9 + SHIFT[Basics.BITXOR[62, 66], 5]]; --two bit error, mult. mem errors, bits 62, 66 FlushPipe[h, Eval]; <<-- syndrome is XOR[62, 66], error reg is 9 (Two Bit, Mult. Mem Err), add is 0f0h>> DBusRegRead[h, Eval, 2, [0, SHIFT[Basics.BITXOR[62, 66], 5] + 9, 0, 0f0h], 44]; }; wordSize: NAT = 72; SingleErrorTestExtended: TProc ~ { <> ramState: ARRAY [0..8) OF REF; TerminalIO.PutRope["***Single Error Test Extended***\n"]; ramState[0] _ GetState[h, "/Ram/Bits63to71"]; ramState[1] _ GetState[h, "/Ram/Bits54to62"]; ramState[2] _ GetState[h, "/Ram/Bits45to53"]; ramState[3] _ GetState[h, "/Ram/Bits36to44"]; ramState[4] _ GetState[h, "/Ram/Bits27to35"]; ramState[5] _ GetState[h, "/Ram/Bits18to26"]; ramState[6] _ GetState[h, "/Ram/Bits9to17"]; ramState[7] _ GetState[h, "/Ram/Bits0to8"]; FOR i: NAT _ 0, i+4 WHILE i> a: (i MOD 2 * 400h) + 040h + (IF i MOD 4 >1 THEN 1 ELSE 0) + (i/4)*2, d: 8-(i MOD 9) ]; ENDLOOP; FOR i: NAT _ 0, i+4 WHILE i> rs: Random.RandomStream _ Random.Create[opProcs, seed]; TerminalIO.PutRope["***Random Test***\n"]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FOR i: INT IN [0..count) DO op[Random.NextInt[rs]][h, Eval]; ENDLOOP; FlushPipe[h, Eval]; }; CrossProdTest: TProc ~ { <> TerminalIO.PutRope["***Cross Product Test***\n"]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FOR i: INT IN [0..opProcs) DO FOR j: INT IN [0..opProcs) DO op[i][h, Eval]; op[j][h, Eval]; ENDLOOP; ENDLOOP; FlushPipe[h, Eval]; }; OwnerTest: TProc ~ { <> TerminalIO.PutRope["***Owner Test***\n"]; WriteBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; ReadBlockRqst[h, Eval, [0,0,0,0], qZero, qZero, qZero, qZero, TRUE, FALSE]; WriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah], TRUE]; CondWriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah], TRUE]; ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0], FALSE, TRUE]; }; CmdTest: TProc ~ { <> TerminalIO.PutRope["***Command Test***\n"]; <> <> <> <> ReadBlockRqst[h, Eval, [0,0,0,0], [3,3,3,3], [2,2,2,2], [1,1,1,1], [0,0,0,0]]; FlushPipe[h, Eval]; <> WriteSingleRqst[h, Eval, [0,0,0,0], [0,0,0,0Ah]]; <> <> <> <> }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<>> ReadBlockRqst: PROC [h: Handle, Eval: REProc, add: Address, data0, data1, data2, data3: Quad, owner, shared: BOOL _ FALSE, doubleError: ARRAY [0..4) OF BOOL _ ALL[FALSE], noReply: BOOL _ FALSE] ~ { p: Port _ h.port; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) RBRqst, owner: %g, shared: %g\n", IO.int[cmdCount], IO.bool[owner], IO.bool[shared]]]; p[DataIn].q _ MakeHeader[cmd: RBRqst, add: add]; p[HeaderCycleIn].b _ TRUE; ownerDelayBuf[ownerDelay] _ [owner, shared]; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; FinalCycle[h, Eval]; IF ~owner AND ~noReply THEN ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: RBRply, add: add, sh: shared], [data0, data1, data2, data3], doubleError]; }; WriteBlockRqst: PROC [h: Handle, Eval: REProc, add: Address, data0, data1, data2, data3: Quad, noReply: BOOL _ FALSE] ~ { WBorFBRqst[h, Eval, WBRqst, add, data0, data1, data2, data3, noReply]; }; FlushBlockRqst: PROC [h: Handle, Eval: REProc, add: Address, data0, data1, data2, data3: Quad, noReply: BOOL _ FALSE] ~ { WBorFBRqst[h, Eval, FBRqst, add, data0, data1, data2, data3, noReply]; }; WBorFBRqst: PROC [h: Handle, Eval: REProc, cmd: Cmd, add: Address, data0, data1, data2, data3: Quad, noReply: BOOL _ FALSE] ~ { reqHeader: Quad _ MakeHeader[cmd: cmd, add: add]; p: Port _ h.port; AcquireBus[h, Eval, 5]; TerminalIO.PutRope[IO.PutFR["%g) %g\n", IO.int[cmdCount], IO.rope[IF cmd=WBRqst THEN "WBRqst" ELSE "FBRqst"]]]; p[DataIn].q _ reqHeader; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; p[DataIn].q _ data0; Cycle[h, Eval, 1]; p[DataIn].q _ data1; Cycle[h, Eval, 1]; p[DataIn].q _ data2; Cycle[h, Eval, 1]; p[DataIn].q _ data3; FinalCycle[h, Eval]; p[DataIn].q _ qZero; IF ~noReply THEN ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: SUCC[cmd], add: add], [reqHeader, qZero, qZero, qZero]]; }; WriteSingleRqst: PROC [h: Handle, Eval: REProc, add: Address, data0: Quad, shared: BOOL _ FALSE, noReply: BOOL _ FALSE] ~ { p: Port _ h.port; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) WSRqst, shared: %g\n", IO.int[cmdCount], IO.bool[shared]]]; p[DataIn].q _ MakeHeader[cmd: WSRqst, add: add]; p[HeaderCycleIn].b _ TRUE; ownerDelayBuf[ownerDelay] _ [FALSE, shared]; Cycle[h, Eval, 1]; p[DataIn].q _ data0; p[HeaderCycleIn].b _ FALSE; FinalCycle[h, Eval]; IF ~noReply THEN ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: WSRply, add: add, sh: shared], [data0, qZero, qZero, qZero]]; }; CondWriteSingleRqst: PROC [h: Handle, Eval: REProc, add: Address, data0: Quad, shared: BOOL _ FALSE, noReply: BOOL _ FALSE] ~ { p: Port _ h.port; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) CWSRqst, shared: %g\n", IO.int[cmdCount], IO.bool[shared]]]; p[DataIn].q _ MakeHeader[cmd: CWSRqst, add: add]; p[HeaderCycleIn].b _ TRUE; ownerDelayBuf[ownerDelay] _ [FALSE, shared]; Cycle[h, Eval, 1]; p[DataIn].q _ data0; p[HeaderCycleIn].b _ FALSE; FinalCycle[h, Eval]; IF ~noReply THEN ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: CWSRply, add: add, sh: shared], [data0, data0, data0, data0]]; }; IORRqst: PROC [h: Handle, Eval: REProc, add: Address, data: LONG CARDINAL] ~ { p: Port _ h.port; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) IORRqst\n", IO.int[cmdCount]]]; p[DataIn].q _ MakeHeader[cmd: IORRqst, add: add]; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; FinalCycle[h, Eval]; ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: IORRply, add: add], [[0, 0, Basics.HighHalf[data], Basics.LowHalf[data]], qZero, qZero, qZero]]; }; IOWrite0: PROC [h: Handle, Eval: REProc, ownerFifoDelay: [0..8), enbCorr: BOOL, enbOpReflect: BOOL _ TRUE, selRefCk: [0..4), gntDelay, pchgDelay, refDelay, wrDelay, rdDelay: [0..32)] ~ { data: LONG CARDINAL _ MCUtils.ComposeIOWrite0[ownerFifoDelay, enbCorr, enbOpReflect, selRefCk, gntDelay, pchgDelay, refDelay, wrDelay, rdDelay]; address: Quad _ [0,0,30h,0]; p: Port _ h.port; reqHeader: Quad _ MakeHeader[cmd: IOWRqst, add: address, mode: FALSE]; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) IOW0Rqst\n", IO.int[cmdCount]]]; p[DataIn].q _ reqHeader; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; p[DataIn].q _ [0, 0, Basics.HighHalf[data], Basics.LowHalf[data]]; FinalCycle[h, Eval]; p[DataIn].q _ qZero; ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: IOWRply, add: address, mode: FALSE], [reqHeader, qZero, qZero, qZero]]; }; IOWrite1: PROC [h: Handle, Eval: REProc, banks: [1..16], ramAddWires: [9..14], bankAdd: [0..16) _ 0, pageAdd: CARDINAL _ 0] ~ { data: LONG CARDINAL _ MCUtils.ComposeIOWrite1[banks, ramAddWires, bankAdd, pageAdd]; address: Quad _ [0,0,30h,1]; p: Port _ h.port; reqHeader: Quad _ MakeHeader[cmd: IOWRqst, add: address, mode: FALSE]; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) IOW1Rqst\n", IO.int[cmdCount]]]; p[DataIn].q _ reqHeader; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; p[DataIn].q _ [0, 0, Basics.HighHalf[data], Basics.LowHalf[data]]; FinalCycle[h, Eval]; p[DataIn].q _ qZero; ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: IOWRply, add: address, mode: FALSE], [reqHeader, qZero, qZero, qZero]]; }; IOWrite2: PROC [h: Handle, Eval: REProc, banks: [1..16], ramAddWires: [9..14], bankAdd: [0..16) _ 0] ~ { data: LONG CARDINAL _ MCUtils.ComposeIOWrite2[banks, ramAddWires, bankAdd]; address: Quad _ [0,0,30h,2]; p: Port _ h.port; reqHeader: Quad _ MakeHeader[cmd: IOWRqst, add: address, mode: FALSE]; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) IOW2Rqst\n", IO.int[cmdCount]]]; p[DataIn].q _ reqHeader; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; p[DataIn].q _ [0, 0, Basics.HighHalf[data], Basics.LowHalf[data]]; FinalCycle[h, Eval]; p[DataIn].q _ qZero; ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: IOWRply, add: address, mode: FALSE], [reqHeader, qZero, qZero, qZero]]; }; IOWrite3: TProc ~ { p: Port _ h.port; address: Quad _ [0,0,30h,3]; reqHeader: Quad _ MakeHeader[cmd: IOWRqst, add: address, mode: FALSE]; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) IOW3Rqst\n", IO.int[cmdCount]]]; p[DataIn].q _ reqHeader; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[HeaderCycleIn].b _ FALSE; p[DataIn].q _ qZero; FinalCycle[h, Eval]; p[DataIn].q _ qZero; ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: IOWRply, add: address, mode: FALSE], [reqHeader, qZero, qZero, qZero]]; }; BIOWRqst: PROC [h: Handle, Eval: REProc, add: Address, data0: Quad, noReply: BOOL_FALSE] ~ { p: Port _ h.port; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) BIOWRqst\n", IO.int[cmdCount]]]; p[DataIn].q _ MakeHeader[cmd: BIOWRqst, add: add]; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[DataIn].q _ data0; p[HeaderCycleIn].b _ FALSE; FinalCycle[h, Eval]; IF ~noReply THEN ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: BIOWRply, add: add], [data0, qZero, qZero, qZero]]; }; DeMapRqst: PROC [h: Handle, Eval: REProc, add: Address, data0: Quad, noReply: BOOL_FALSE] ~ { p: Port _ h.port; AcquireBus[h, Eval]; TerminalIO.PutRope[IO.PutFR["%g) DeMapRqst\n", IO.int[cmdCount]]]; p[DataIn].q _ MakeHeader[cmd: DeMapRqst, add: add]; p[HeaderCycleIn].b _ TRUE; Cycle[h, Eval, 1]; p[DataIn].q _ data0; p[HeaderCycleIn].b _ FALSE; FinalCycle[h, Eval]; IF ~noReply THEN ResponseChecker.ExpectReply[h.rcState, MakeHeader[cmd: DeMapRply, add: add], [data0, qZero, qZero, qZero]]; }; DBusRegSel: PROC [h: Handle, Eval: REProc, add: dBusRegAdd] ~ { bits: CARDINAL _ dBusPrefix; p: Port _ h.port; p[DBus].bs[dAddress] _ TRUE; FOR i: NAT IN [0..dBusPrefixBits) DO p[DBus].bs[dSerialIn] _ Basics.BITAND[bits, Basics.BITSHIFT[1, dBusPrefixBits-1]]#0; --send MSB first bits _ Basics.BITSHIFT[bits, 1]; DBusCycle[h, Eval]; ENDLOOP; bits _ add; FOR i: NAT IN [0..dBusRegAddBits) DO p[DBus].bs[dSerialIn] _ Basics.BITAND[bits, Basics.BITSHIFT[1, dBusRegAddBits-1]]#0; --send MSB first bits _ Basics.BITSHIFT[bits, 1]; DBusCycle[h, Eval]; ENDLOOP; p[DBus].bs[dAddress] _ FALSE; }; DBusRegRead: PROC [h: Handle, Eval: REProc, add: dBusRegAdd, data: BitOps.BitQWord, regWidth: [1..BitOps.bitsPerQWord]] ~ { p: Port _ h.port; DBusRegSel[h, Eval, add]; p[DBus].bs[dExecute] _ TRUE; p[DBus].ds[dSerialOut] _ expect; p[DBus].bs[dSerialOut] _ BitOps.EBFQ[data, 0, regWidth]; DBusCycle[h, Eval]; p[DBus].bs[dExecute] _ FALSE; FOR i: NAT IN [1..regWidth) DO p[DBus].bs[dSerialOut] _ BitOps.EBFQ[data, i, regWidth]; DBusCycle[h, Eval]; ENDLOOP; p[DBus].ds[dSerialOut] _ none; }; DBusRegWrite: PROC [h: Handle, Eval: REProc, add: dBusRegAdd, data: BitOps.BitDWord, regWidth: [1..BitOps.bitsPerDWord]] ~ { p: Port _ h.port; DBusRegSel[h, Eval, add]; FOR i: NAT IN [0..regWidth) DO p[DBus].bs[dSerialIn] _ BitOps.EBFD[data, i, regWidth]; DBusCycle[h, Eval]; ENDLOOP; }; Cycle: PROC [h: Handle, Eval: REProc, n: CARDINAL _ 1] ~ { p: Port _ h.port; THROUGH [0..n) DO p[OwnerIn].b _ ownerDelayBuf[0].owner; p[SharedIn].b _ ownerDelayBuf[0].shared; FOR i: NAT IN [0..ownerDelay) DO ownerDelayBuf[i] _ ownerDelayBuf[i+1]; ENDLOOP; ownerDelayBuf[ownerDelay] _ [FALSE, FALSE]; p[Clock].b _ FALSE; MTSVector.EvalAndCapture[capture: h.capture, Eval: Eval, memory: TRUE, useClockEval: TRUE, checkPorts: FALSE]; p[Clock].b _ TRUE; MTSVector.EvalAndCapture[capture: h.capture, Eval: Eval, memory: TRUE, useClockEval: TRUE, checkPorts: TRUE]; ENDLOOP; }; DBusCycle: TProc ~ { p: Port _ h.port; p[DBus].bs[dShiftCK] _ FALSE; MTSVector.EvalAndCapture[capture: h.capture, Eval: Eval, memory: TRUE, useClockEval: TRUE, checkPorts: FALSE]; p[DBus].bs[dShiftCK] _ TRUE; MTSVector.EvalAndCapture[capture: h.capture, Eval: Eval, memory: TRUE, useClockEval: TRUE, checkPorts: TRUE]; }; FlushPipe: TProc ~ { WHILE ~ResponseChecker.IsEmpty[h.rcState] DO Cycle[h, Eval, 1]; ENDLOOP; }; AcquireBus: PROC [h: Handle, Eval: REProc, cycles: NAT _ 2 ] ~ { timer: CARDINAL _ arbiterTimeout; p: Port _ h.port; p[DReqTP].c _ (SELECT cycles FROM 2 => 2, 5 => 3, ENDCASE => ERROR); Cycle[h, Eval, 1]; p[DReqTP].c _ 0; -- no further request p[DGrantTP].d _ inspect; -- p[DGrantTP].b = FALSE WHILE NOT p[DGrantTP].b DO Cycle[h, Eval, 1]; timer _ timer-1; IF timer=0 THEN ERROR; --bus timeout ENDLOOP; p[DGrantTP].d _ expect; -- p[DGrantTP].b = TRUE }; FinalCycle: TProc ~ { p: Port _ h.port; p[DGrantTP].b _ FALSE; Cycle[h, Eval, 1]; cmdCount _ cmdCount+1; }; MakeHeader: PROC [cmd: Cmd, mode: ModeError _ FALSE, sh: Shared _ FALSE, id: DeviceID _ 0, add: Address _ qZero] RETURNS [header: Quad] ~ { header _ qZero; header _ DynaBusInterface.InsertCmd[header, cmd]; header _ DynaBusInterface.InsertModeError[header, mode]; header _ DynaBusInterface.InsertShared[header, sh]; header _ DynaBusInterface.InsertDeviceID[header, id]; header _ DynaBusInterface.InsertAddress[header, add]; }; InitPortIndicies: PROC [ct: Core.CellType] ~ { [nSStopIn, SharedIn, OwnerIn, DBus, DReqTP, DGrantTP, TestIn] _ Ports.PortIndexes[ct.public, "nSStopIn", "SharedIn", "OwnerIn", "DBus", "DReqTP", "DGrantTP", "TestIn"]; [HeaderCycleIn, Clock, DataIn] _ Ports.PortIndexes[ct.public, "HeaderCycleIn", "Clock", "DataIn"]; Vdd _ Ports.PortIndex[ct.public, "Vdd"]; Gnd _ Ports.PortIndex[ct.public, "Gnd"]; }; RosemaryUser.RegisterTestProc["MCTest", MCTest]; END.