DIRECTORY CDCommandOps, CDSequencer, CDProperties, Core, CoreCreate, CoreFlat, Ports, Rope, Rosemary, RosemaryUser, Sisyph, CoreClasses, Basics, BitOps, MIPadFrame, Random; TestMI: CEDAR PROGRAM IMPORTS -- CoreFlat, CDCommandOps, CDSequencer, CDProperties, CoreCreate, CoreClasses, Ports, Rosemary, RosemaryUser, Sisyph, Basics, BitOps, MIPadFrame, Random = BEGIN XA, XD, XIOWbar, XIORbar, XCEbar, XIORDY, XHOSTRESET, XLPRESET, XHOLD, XHOLDA, XPIRQ, XXIRQ0, XPA, XWENTbar, XWENWbar, XCASbar, XRASbar, XRASXbar, XMEMRDY, XCLOCK2, XHINT, XPD, XPDTAG, XPDHI, XPDWP, XPDTP, Vdd, Gnd, PadVdd, PadGnd: NAT _ LAST[NAT]; memoryoffset: NAT _ 4000H; statusregreset: NAT _ 1300H; statusregnorm: NAT _ 0000H; laststatus: CARD _ 0; addrlatch: NAT _ 5004H; lastaddr, curriopaddr: CARD _ 0; refreshlatch: NAT _ 5002H; lastrefresh, refreshcount: CARD _ 0; refreshcycle, refreshhold, refreshrq, refreshinprogress: BOOL _ FALSE; statuslatch: NAT _ 5000H; ILIST: TYPE = LIST OF CARD; oddclock, statusignore: BOOL; lastpd: CARD _ 0; innerCell: Core.CellType; outerCell: Core.CellType; outerset: BOOL _ FALSE; rs: Random.RandomStream; MIInitPortIndicies: PROC [p: Core.Wire] ~ { [XA, XD, XIOWbar, XIORbar, XCEbar, XIORDY, XHOSTRESET, XLPRESET, XHOLD, XHOLDA, XPIRQ, XXIRQ0] _ Ports.PortIndexes[p, "XA", "XD", "XIOW'", "XIOR'", "XCE'", "XIORDY", "XHOSTRESET", "XLPRESET", "XHOLD", "XHOLDA", "XPIRQ", "XXIRQ0"]; [XPA, XWENTbar, XWENWbar, XCASbar, XRASbar, XRASXbar, XMEMRDY,] _ Ports.PortIndexes[p, "XPA", "XWENT'", "XWENW'", "XCAS'", "XRAS'", "XRASX'", "XMEMRDY"]; [XCLOCK2, XHINT] _ Ports.PortIndexes[p, "XCLOCK2", "XHINT"]; [XPD, XPDTAG, XPDHI, XPDWP, XPDTP] _ Ports.PortIndexes[p, "XPD", "XPDTAG", "XPDHI", "XPDWP", "XPDTP"]; [Vdd, Gnd, PadVdd, PadGnd] _ Ports.PortIndexes[p, "Vdd", "Gnd", "PadVdd", "PadGnd"]; }; MISetupInit: PROC [public: Core.Wire] = { MIInitPortIndicies[public]; IPList[public, LIST[XCLOCK2], l, force]; IPList[public, LIST[ XIOWbar, XIORbar, XCEbar, XIORDY, XHOSTRESET, XLPRESET, XHOLD, XHOLDA, XPIRQ, XXIRQ0, XWENTbar, XWENWbar, XCASbar, XRASXbar, XMEMRDY, XPDWP, XPDTP], l, none]; IPList[public, LIST[ XA, XPA, XRASbar, XD, XPDTAG, XPDHI, XPD], ls, none]; [] _ Rosemary.SetFixedWire[public[Vdd], H]; [] _ Rosemary.SetFixedWire[public[Gnd], L]; [] _ Rosemary.SetFixedWire[public[PadGnd], L]; [] _ Rosemary.SetFixedWire[public[PadVdd], H]; }; MI: PUBLIC PROC RETURNS [cellType: CoreCreate.CellType] = { public: Core.Wire _ CoreCreate.WireList[LIST[ "XA", "XD", "XIOW'", "XIOR'", "XCE'", "XIORDY", "XHOSTRESET", "XLPRESET", "XHOLD", "XHOLDA", "XPIRQ", "XXIRQ0", "XPA", "XWENT'", "XWENW'", "XCAS'", "XRAS'", "XRASX'", "XMEMRDY", "XCLOCK2", "XHINT", "XPDWP", "XPDTP", CoreCreate.Seq["XA", 16], CoreCreate.Seq["XD", 16], CoreCreate.Seq["XPA", 12], CoreCreate.Seq["XRAS", 4], CoreCreate.Seq["XPD", 32], CoreCreate.Seq["XPDTAG", 2], CoreCreate.Seq["XPDHI", 6], "Vdd", "Gnd"]]; cellType _ CoreClasses.CreateUnspecified[name: "MI", public: public]; }; InitializeTest: PROC ~ { outerset _ FALSE; CDSequencer.ImplementCommand[key: $MIExtractAndSimulate, proc: MIExtractAndSimulate, queue: doQueue]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "Extract *& Simulate MI", key: $MIExtractAndSimulate]; CDSequencer.ImplementCommand[key: $MISimulate, proc: MISetCellMISimulate, queue: doQueue]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "Simulate MI", key: $MISimulate]; RosemaryUser.RegisterTestProc["MITest", MITest]; }; RemakePads: PROC = {outerCell_ MIPadFrame.CreateWholeChip[innerCell];}; MISetOuter: PROC [ct: Core.CellType] = { outerCell _ ct; outerset _ TRUE; }; MISetCellMISimulate: PROC [comm: CDSequencer.Command] ~ { IF ~outerset THEN ERROR; CDProperties.PutDesignProp[comm.design, $DAUserRoseDisplay, MISimulate[outerCell, "MI Layout Simulate"].display]; }; MIExtractAndSimulate: PROC [comm: CDSequencer.Command] ~ { innerCell _ Sisyph.ExtractSchematicByName["MIInner.sch", Sisyph.Create[comm.design]]; RemakePads[]; CDProperties.PutDesignProp[comm.design, $DAUserRoseDisplay, MISimulate[outerCell, "MI Schematic Simulate"].display]; }; MISimulate: PROC [cellType: Core.CellType, title: Rope.ROPE] RETURNS [tester: RosemaryUser.Tester]~ { public: Core.Wire _ cellType.public; MISetupInit[public]; tester _ RosemaryUser.TestProcedureViewer[ cellType: cellType, testButtons: LIST["MITest"], name: title, displayWires: RosemaryUser.DisplayPortLeafWires[cellType] ]; }; MITest: RosemaryUser.TestProc ~ { SwapBits: PROC[value: BitOps.BitWord] RETURNS [newvalue: BitOps.BitWord] = { oldc: BitOps.BitWord _ value; newvalue _ 0; FOR i: NAT _ 0, i+1 WHILE i < 16 DO newvalue _ BitOps.IBIW[BitOps.EBFW[oldc, i, 16], newvalue, 15-i, 16]; ENDLOOP; }; Parityof: PROC [value: CARD, size: NAT] RETURNS [bit: NAT] = { p: BitOps.BitWord _ 0; FOR i: NAT _ 0, i + 1 WHILE i < size DO p _ BitOps.WXOR[p, BitOps.ECFD[value, i, 1, size]]; ENDLOOP; bit _ p; }; HiParity: PROC[hival: CARD] RETURNS [p: NAT] = { p _ Parityof[hival, 6]; }; DataParity: PROC[data, tag: CARD]RETURNS [p: NAT] = { p _ BitOps.WXOR[Parityof[data, 32], Parityof[tag, 2]]; }; SetPVal: PROC [port, value: CARD] = { IF (port = XA) OR (port = XD) THEN value _ SwapBits[value]; SELECT p[port].levelType FROM l => p[port].l _ IF value=0 THEN L ELSE H; ls => Ports.LCToLS[value, p[port].ls]; c => p[port].c _ value; lc => p[port].lc _ value; b => SELECT value FROM 0 => p[port].b _ FALSE; 1 => p[port].b _ TRUE; ENDCASE => ERROR; ENDCASE => ERROR; }; RasDecode: PROC [rasval: NAT] RETURNS [NAT] = { RETURN[ IF refreshinprogress THEN 0 ELSE SELECT rasval FROM 0 => 0EH, 1 => 0DH, 2 => 0BH, 3 => 07H, 7 => 0FH, ENDCASE => ERROR]; }; RasXDecode: PROC [rasval: NAT] RETURNS [NAT] = { RETURN[ IF refreshinprogress THEN 1 ELSE SELECT rasval FROM 0 => 01H, 1 => 01H, 2 => 01H, 3 => 01H, 7 => 00H, ENDCASE => ERROR]; }; SetP: PROC [port, value: CARD] = { SetPVal[port, value]; p[port].d _ force; IF port = XA THEN curriopaddr _ value; IF port = XPD THEN lastpd _ value; }; ClrP: PROC [port: CARD] = { SELECT p[port].levelType FROM l => p[port].l _ X; ls => Ports.SetLS[p[port].ls, X]; c => p[port].c _ 0; lc => p[port].lc _ 0; b => p[port].b _ FALSE; ENDCASE => ERROR; p[port].d _ none; }; ChkP: PROC [port, value: CARD] = { SetPVal[port, value]; p[port].d _ expect; }; ChkX: PROC [port: CARD] = { ClrP[port]; p[port].d _ expect; }; GoClock: PROC [cycles: NAT _ 1, extraEval: BOOL _ FALSE] = { saveddrives: ARRAY [0..50] OF Ports.Drive; ExpectsOff: PROC = { FOR i: NAT _ 0, i + 1 WHILE i < p.size DO { -- Turn off Expects saveddrives[i] _ p[i].d; IF p[i].d = expect THEN p[i].d _ none; }; ENDLOOP; }; ExpectsOn: PROC = { FOR i: NAT _ 0, i + 1 WHILE i < p.size DO -- Turn on Expects p[i].d _ saveddrives[i]; ENDLOOP; }; FOR i: NAT _ 0, i + 1 WHILE i < cycles DO { -- Do clock cycles IF refreshcycle AND ~refreshhold THEN { refreshhold _ TRUE; refreshinprogress _ TRUE; ClockMemory1[3, 2, 0, 0]; ClockMemory2[FALSE, FALSE]; ClockMemory3[0]; ClockMemory4[]; GoClock[3]; refreshcycle _ FALSE; refreshhold _ FALSE; refreshrq _ FALSE; refreshinprogress _ FALSE; }; ExpectsOff[]; -- checks off IF extraEval THEN Eval[]; -- Setup Values extraEval _ FALSE; SetP[XCLOCK2,0]; -- clock 0 Eval[]; -- Setup Values ExpectsOn[]; -- Turn on expects SetP[XCLOCK2,1]; -- clock 1 Eval[]; oddclock _ ~oddclock; IF refreshrq AND ~refreshcycle THEN refreshcycle _ TRUE; IF (BitOps.WAND[lastrefresh, 8000H] # 0) AND ~oddclock THEN { refreshcount _ refreshcount - 1; IF refreshcount = 0 THEN { refreshrq _ TRUE; refreshcount _ BitOps.WAND[lastrefresh, 0FFFH] + 1; }; }; }; ENDLOOP; }; SyncClock: PROC = { IF oddclock THEN GoClock[]; }; WriteLatch: PROC [addr, value: CARD] = { SetP[XA, addr]; SetP[XIOWbar, 1]; SetP[XD, value]; SetP[XIORDY, 1]; GoClock[1, addr = statuslatch]; SetP[XIOWbar, 0]; SetP[XCEbar, 0]; ChkP[XIORDY, 1]; GoClock[]; SetP[XIOWbar, 1]; SetP[XCEbar, 1]; ClrP[XIORDY]; GoClock[]; ClrP[XD]; ClrP[XA]; IF addr = statuslatch THEN laststatus _ value; -- save last status IF addr = addrlatch THEN lastaddr _ value; -- save last addr IF addr = refreshlatch THEN { lastrefresh _ value; -- save last refresh refreshcount _ BitOps.WAND[lastrefresh, 0FFFH] + 1; -- init refresh counter refreshrq _ BitOps.WAND[lastrefresh, 8000H] # 0; }; }; ReadLatch: PROC [addr, value: CARD] = { SetP[XA, addr]; SetP[XIORbar,1]; SetP[XIORDY,1]; GoClock[]; SetP[XIORbar,0]; SetP[XCEbar, 0]; ChkP[XD,value]; IF (addr = statuslatch) AND statusignore THEN FOR i: NAT IN [14..15] DO p[XD].ls[i] _ X; ENDLOOP; ChkP[XIORDY, 1]; GoClock[]; ClrP[XD]; ClrP[XA]; SetP[XIORbar,1]; SetP[XCEbar, 1]; ClrP[XIORDY]; GoClock[]; }; ClockMemory1: PROC [delay1, delay2, holddelay: NAT, casval: NAT _ 1] = { ChkP[XWENTbar, 1]; ChkP[XWENWbar, 1]; GoClock[delay1-1]; ChkP[XHOLD, 1]; GoClock[]; IF Basics.BITAND[laststatus, 8] = 0 THEN { FOR i: NAT _ holddelay, i - 1 WHILE i > 0 DO GoClock[]; ENDLOOP; SetP[XHOLDA, 1]; }; GoClock[delay2-1]; ChkP[XCASbar, casval]; GoClock[]; }; CasPA: PROC RETURNS[CARD] = { RETURN[ Basics.DoubleOr[ Basics.DoubleAnd[ Basics.DoubleShiftRight[[lc[curriopaddr]], 2], [li[01FFH]]], Basics.DoubleAnd[ Basics.DoubleShiftLeft[[lc[lastaddr]], 9], [li[0200H]]] ].lc]; }; RasPA: PROC RETURNS[CARD] = { RETURN[ Basics.DoubleAnd[ Basics.DoubleShiftRight[[lc[lastaddr]], 1], [li[03FFH]]].lc]; }; ClockMemory2: PROC [checkwe: BOOL _ FALSE, do2ndclock: BOOL _ TRUE] = { rasval: NAT _ Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[lastaddr]], 11], [li[07H]]].lc; rasdecodedval: NAT _ RasDecode[rasval]; ChkP[XRASbar, rasdecodedval]; ChkP[XRASXbar, RasXDecode[rasval]]; ChkP[XPA, IF rasval = 7 THEN CasPA[] ELSE RasPA[]]; GoClock[]; ClrP[XPA]; -- PA only on 1st RAS' IF checkwe THEN -- Check WE on a write { ChkP[XWENTbar, 0]; ChkP[XWENWbar, 0]; }; IF do2ndclock THEN GoClock[]; }; ClockMemory3: PROC [memdelay: NAT] = { ChkP[XCASbar, 0]; ChkP[XPA, CasPA[]]; SetP[XMEMRDY, IF memdelay = 0 THEN 1 ELSE 0]; GoClock[]; IF p[XRASXbar].l = H THEN ClrP[XPA]; -- Only 1 PA on CAS' IF memdelay # 0 THEN { FOR i: NAT _ memdelay, i - 1 WHILE i > 0 DO GoClock[]; ENDLOOP; SetP[XMEMRDY, 1]; IF BitOps.WAND[memdelay, 1] = 1 THEN GoClock[]; }; ClrP[XIORDY]; ClrP[XCASbar]; ClrP[XRASbar]; ClrP[XRASXbar]; ClrP[XPD]; ClrP[XPDTAG]; ClrP[XPDHI]; ClrP[XPA]; ClrP[XPDTP]; ClrP[XPDWP]; ClrP[XWENTbar]; ClrP[XWENWbar]; ClrP[XHOLD]; GoClock[]; }; ClockMemory4: PROC = { SetP[XIORDY, 1]; SetP[XIORbar, 1]; SetP[XIOWbar, 1]; SetP[XCEbar, 1]; ClrP[XD]; ClrP[XA]; SetP[XHOLDA, 0]; GoClock[]; ChkP[XWENTbar, 1]; ChkP[XWENWbar, 1]; ChkP[XIORDY, 1]; GoClock[]; ClrP[XIORDY]; ClrP[XWENTbar]; ClrP[XWENWbar]; }; ReadMemory: PROC [addr, memval, hival: CARD, hibyte, badhiparity, baddataparity: BOOL _ FALSE, holddelay, memdelay: NAT _ 0] = { wordsel: CARD _ Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[addr]], 1], [li[1]]].lc; rsltval: CARD _ IF hibyte THEN hival ELSE Basics.DoubleAnd[ Basics.DoubleShiftRight[[lc[memval]], IF wordsel = 1 THEN 16 ELSE 0], [lc[0FFFFH]]].lc; tagval: CARD _ Basics.DoubleAnd[[lc[hival]], [li[3]]].lc; delay1: NAT _ 4 + Basics.BITAND[holddelay, 1]; delay2: NAT _ 2; newaddr: CARD _ Basics.DoubleShiftRight[[lc[addr]], 11].lc; hival _ Basics.DoubleShiftRight[[lc[hival]], 2].lc; IF lastaddr # newaddr THEN WriteLatch[addrlatch, newaddr]; IF hibyte THEN WriteLatch[statuslatch, Basics.DoubleOr[[lc[laststatus]], [lc[1]]].lc] ELSE WriteLatch[statuslatch, Basics.DoubleAnd[[lc[laststatus]], [lc[0FFFEH]]].lc]; SyncClock[]; SetP[XHOLDA, 0]; SetP[XCEbar, 0]; SetP[XA, Basics.DoubleAnd[[lc[addr]],[li[07FFH]]].lc]; GoClock[]; SetP[XIORbar, 0]; ChkP[XIORDY, 0]; refreshhold _ TRUE; ClockMemory1[delay1, delay2, holddelay]; ClockMemory2[]; SetP[XPD, memval]; SetP[XPDTAG, tagval]; SetP[XPDHI, hival]; SetP[XPDTP, BitOps.WXOR[HiParity[hival], LOOPHOLE[badhiparity]]]; SetP[XPDWP, BitOps.WXOR[DataParity[memval, tagval], LOOPHOLE[baddataparity]]]; ClockMemory3[memdelay]; ChkP[XD, rsltval]; GoClock[2]; ClockMemory4[]; refreshhold _ FALSE; }; WriteMemory: PROC [addr, memval, hival, writeval: CARD, hibyte, badhiparity, baddataparity: BOOL _ FALSE, holddelay, memdelay: NAT _ 0] = { wordsel: CARD _ Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[addr]], 1], [li[1]]].lc; newmemval: CARD; newhival, newtagval: CARD; ioop: BOOL _ FALSE; tagval: CARD _ Basics.DoubleAnd[[lc[hival]], [li[3]]].lc; delay1: NAT _ 4 + Basics.BITAND[holddelay, 1]; delay2: NAT _ 2; newaddr: CARD _ Basics.DoubleShiftRight[[lc[addr]], 11].lc; hival _ Basics.DoubleShiftRight[[lc[hival]], 2].lc; newhival _ hival; newtagval _ tagval; IF hibyte THEN { newhival _ Basics.DoubleShiftRight[ Basics.DoubleAnd[ [lc[writeval]], [lc[0FCH]]], 2].lc; newtagval _ Basics.DoubleAnd[ [lc[writeval]], [lc[3H]]].lc; }; IF lastaddr # newaddr THEN WriteLatch[addrlatch, newaddr]; IF hibyte THEN WriteLatch[statuslatch, Basics.DoubleOr[[lc[laststatus]], [lc[1]]].lc] ELSE WriteLatch[statuslatch, Basics.DoubleAnd[[lc[laststatus]], [lc[0FFFEH]]].lc]; ioop _ RasXDecode[Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[lastaddr]], 11], [li[07H]]].lc] # 1; SyncClock[]; SetP[XCEbar, 0]; SetP[XHOLDA, 0]; SetP[XA, Basics.DoubleAnd[[lc[addr]],[li[07FFH]]].lc]; GoClock[]; ChkP[XIORDY, 0]; SetP[XIOWbar,0]; SetP[XD, writeval]; refreshhold _ TRUE; ClockMemory1[delay1, delay2, holddelay]; IF~ ioop THEN { ClockMemory2[]; SetP[XPD, memval]; SetP[XPDTAG, tagval]; SetP[XPDHI, hival]; SetP[XPDTP, BitOps.WXOR[HiParity[hival], LOOPHOLE[badhiparity]]]; SetP[XPDWP, BitOps.WXOR[DataParity[memval, tagval], LOOPHOLE[baddataparity]]]; ClockMemory3[memdelay]; GoClock[2]; }; ClockMemory2[TRUE]; newmemval _ IF hibyte THEN lastpd ELSE Basics.DoubleOr[ Basics.DoubleAnd[ [lc[lastpd]], Basics.DoubleShiftLeft[[lc[0FFFFH]], IF wordsel = 1 THEN 0 ELSE 16]], Basics.DoubleShiftLeft[[lc[writeval]], IF wordsel = 1 THEN 16 ELSE 0]].lc; ChkP[XPD, newmemval]; IF ~ ioop THEN { ChkP[XPDTAG, newtagval]; ChkP[XPDHI, newhival]; ChkP[XPDTP, HiParity[newhival]]; ChkP[XPDWP, DataParity[newmemval, newtagval]]; }; ClockMemory3[memdelay]; ClockMemory4[]; GoClock[3]; refreshhold _ FALSE; }; ChipReady: PROC = { oddclock _ FALSE; statusignore _ TRUE; refreshcycle _ FALSE; refreshhold _ FALSE; refreshrq _ FALSE; refreshinprogress _ FALSE; lastrefresh _ 0; refreshcount _ 0; SetP[Gnd, 0]; SetP[Vdd, 1]; SetP[PadGnd, 0]; SetP[PadVdd, 1]; p[Vdd].b _ TRUE; p[PadVdd].b _ TRUE; SetP[XA, 0]; SetP[XD, 0]; SetP[XIOWbar, 1]; SetP[XIORbar, 1]; SetP[XCEbar, 1]; ClrP[XIORDY]; SetP[XHOSTRESET, 1]; ClrP[XHINT]; ClrP[XLPRESET]; ClrP[XHOLD]; SetP[XHOLDA, 0]; SetP[XPIRQ, 0]; ClrP[XXIRQ0]; ClrP[XPDWP]; ClrP[XPDTP]; ClrP[XPDTAG]; ClrP[XPDHI]; ClrP[XPD]; ClrP[XCASbar]; ClrP[XRASbar]; ClrP[XRASXbar]; ClrP[XPA]; SetP[XMEMRDY, 1]; ClrP[XWENTbar]; ClrP[XWENWbar]; GoClock[4]; WriteLatch[statuslatch, 0800H]; GoClock[2]; SetP[XHOSTRESET, 0]; GoClock[12, TRUE]; ChkP[XLPRESET, 1]; -- Check for LPRESET = 1 WriteLatch[refreshlatch, 0]; -- Clear refresh counter WriteLatch[addrlatch, 0]; -- Clear address latch ClrP[XLPRESET]; -- Don't for LPRESET WriteLatch[statuslatch, 1000H]; -- Clear LPRESET GoClock[4]; ChkP[XLPRESET, 0]; -- Check for LPRESET = 0 WriteLatch[statuslatch, statusregreset]; ClrP[XLPRESET]; -- Don't for LPRESET statusignore _ FALSE; ReadLatch[statuslatch, statusregreset]; -- Read Status Reg ReadLatch[refreshlatch, 0]; -- Read refreshcounter ReadLatch[addrlatch, 0]; -- Read address latch ReadMemory[0, 0, 0]; -- Clear Parity Errors ReadMemory[1C00010H, 0, 0]; -- Read IO port WriteMemory[1C00010H, 0, 0, 0]; -- Write IO port WriteLatch[statuslatch, statusregreset]; -- Write Status Reg }; ChkNClk: PROC [port, value: CARD] = { ChkP[port, value]; GoClock[]; ClrP[port]; }; TestStatReg: PROC = { WriteLatch[statuslatch, statusregreset]; WriteLatch[statuslatch, 2]; -- Set XIRQ0 ChkP[XXIRQ0, 1]; -- Check for XIRQ0 = 1 GoClock[]; ClrP[XXIRQ0]; WriteLatch[statuslatch, statusregreset]; ChkP[XXIRQ0, 0]; -- Check for XIRQ0 = 0 GoClock[]; ClrP[XXIRQ0]; SetP[XPIRQ, 0]; WriteLatch[statuslatch, 0200H]; -- Clr PIRQ bit ReadLatch[statuslatch, 0200H]; -- Latch should be clear WriteLatch[statuslatch, 0080H]; -- Enable PIRQ SetP[XPIRQ, 1]; -- Set PIRQ GoClock[]; ChkP[XHINT, 1]; ReadLatch[statuslatch, 2080H]; -- Should have PIRQ & HINT ClrP[XHINT]; SetP[XPIRQ, 0]; GoClock[]; ReadLatch[statuslatch, 2080H]; -- Should Still have PIRQ & HINT WriteLatch[statuslatch, 0200H]; -- Clr PIRQ bit ChkP[XHINT, 0]; GoClock[]; ReadLatch[statuslatch, 0200H]; -- Latch & HINT should be clear WriteLatch[statuslatch, 0000H]; -- Clr Latch SetP[XPIRQ, 1]; -- Set PIRQ GoClock[]; ReadLatch[statuslatch, 2000H]; -- Should have PIRQ but no HINT SetP[XPIRQ, 0]; ClrP[XHINT]; WriteLatch[statuslatch, statusregreset]; }; TestRefresh: PROC = { WriteLatch[refreshlatch, 8010H]; GoClock[100]; WriteLatch[refreshlatch, 0000H]; WriteLatch[refreshlatch, 8040H]; FOR i: NAT _ 0, i+1 WHILE i < 10 DO { ReadMemory[0, 0, 0]; GoClock[30]; }; ENDLOOP; }; TestLatches: PROC = { ReadMemory[0, 0, 0]; WriteLatch[statuslatch, statusregreset]; FOR val: ILIST _ LIST [0, 1, 2, 4, 8, 16, 32, 64, 128, 100H, 200H, 400H, statusregreset], val.rest WHILE val # NIL DO WriteLatch[statuslatch, val.first]; ReadLatch[statuslatch, val.first]; ENDLOOP; FOR val: ILIST _ LIST[0, 1, 2, 4, 8, 16, 32, 64, 128, 255, 100H, 200H, 400H, 800H], val.rest WHILE val # NIL DO WriteLatch[refreshlatch, val.first]; ReadLatch[refreshlatch, val.first]; ENDLOOP; FOR val: ILIST _ LIST[0, 1, 2, 4, 8, 16, 32, 64, 128, 255, 100H, 200H, 400H, 800H, 1000H, 2000H, 4000H, 8000H, 0FF00H, 0FFFFH], val.rest WHILE val # NIL DO WriteLatch[addrlatch, val.first]; ReadLatch[addrlatch, val.first]; ENDLOOP; TestStatReg[]; WriteLatch[statuslatch, statusregreset]; ReadMemory[0, 0, 0]; WriteLatch[statuslatch, statusregreset]; TestRefresh[]; WriteLatch[statuslatch, statusregreset]; WriteLatch[statuslatch, statusregnorm]; WriteLatch[refreshlatch, 0]; }; RandomMemoryTest: PROC = { addr: CARD; RandomBool: PROC RETURNS [BOOL] = { RETURN[IF Random.ChooseInt[rs, 0, 1] = 0 THEN FALSE ELSE TRUE]}; RandomCard: PROC [hi: CARD, alt: CARD _ 0] RETURNS [CARD] = { IF (alt # 0) AND (Random.ChooseInt[rs, 0, 15] = 15) THEN RETURN[alt] ELSE RETURN[ Basics.DoubleOr[ Basics.DoubleShiftLeft[ [lc[Random.ChooseInt[rs, 0, Basics.DoubleShiftRight[ [lc[hi]], 16].lc ] ]], 16], Basics.DoubleAnd[ [lc[Random.ChooseInt[rs, 0, Basics.DoubleAnd[ [lc[hi]], [lc[0FFFFH]] ].lc] ]], [lc[0FFFFH]] ] ].lc ] }; rs _ Random.Create[]; FOR i: CARD _ 0, i + 1 WHILE i < 100 DO addr _ RandomCard[08FFFFFH, 1C00000H]; IF RandomBool[] THEN ReadMemory[ addr, RandomCard[0FFFFFFFFH], RandomCard[0FFH], IF addr = 1C00000H THEN FALSE ELSE RandomBool[], FALSE, FALSE, RandomCard[10], RandomCard[10]] ELSE WriteMemory[ addr, RandomCard[0FFFFFFFFH], RandomCard[0FFH], RandomCard[0FFFFH], IF addr = 1C00000H THEN FALSE ELSE RandomBool[], FALSE, FALSE, RandomCard[10], RandomCard[10]]; ENDLOOP; }; TestMemory: PROC = { MemoryReadTest: PROC = { ReadMemory[0, 0, 0, FALSE, FALSE, FALSE, 6, 9]; FOR addr: ILIST _ LIST [1C00000H, 0, 1, 2, 4, 8, 16, 32, 64, 128, 100H, 200H, 400H, 800H, 1000H, 2000H, 4000H, 8000H, 10000H, 20000H, 40000H, 80000H, 100000H, 200000H, 400000H, 800000H, 100000H, 200000H, 400000H, 800000H, 7FFFFFH ], addr.rest WHILE addr # NIL DO ReadMemory[addr.first ,0, 0, FALSE]; ReadMemory[addr.first ,0FFFFH, 0, FALSE]; ReadMemory[addr.first ,0, 3, FALSE, FALSE, FALSE, 7]; ReadMemory[addr.first ,0, 003FH, FALSE]; ReadMemory[addr.first ,0FFFFH, 003FH, FALSE]; ReadMemory[addr.first , 0, 0FFH, TRUE]; ReadMemory[addr.first , 0, 0AAH, TRUE]; ENDLOOP; }; MemoryWriteTest: PROC = { WriteMemory[0, 0, 0, 0, FALSE]; WriteMemory[0, 0, 0, 0, FALSE, FALSE, FALSE, 6]; FOR addr: ILIST _ LIST [1C00000H, 0, 1, 2, 4, 8, 16, 32, 64, 128, 100H, 200H, 400H, 800H, 1000H, 2000H, 4000H, 8000H, 10000H, 20000H, 40000H, 80000H, 100000H, 200000H, 400000H, 800000H, 100000H, 200000H, 400000H, 800000H, 7FFFFFH ], addr.rest WHILE addr # NIL DO WriteMemory[addr.first ,0, 0, 0FFFFH, FALSE]; WriteMemory[addr.first ,0FFFFH, 0, 0AAAAH, FALSE]; WriteMemory[addr.first ,0, 3, 5555H, FALSE, FALSE, FALSE, 2]; WriteMemory[addr.first ,0, 003FH, 055AA, FALSE]; WriteMemory[addr.first ,0FFFFH, 003FH, 0AA55H, FALSE]; IF addr.first # 1C00000H THEN { WriteMemory[addr.first , 0, 0FFH, 55H, TRUE]; WriteMemory[addr.first , 0, 0AAH, 0FFH, TRUE]; }; ENDLOOP; }; ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 6]; ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 7]; ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 0, 3]; ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 0, 4]; ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 3, 4]; ReadMemory[1C00000H ,0, 0, FALSE, FALSE, FALSE, 4, 5]; WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 4, 0]; WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 5, 0]; WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 0, 6]; WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 0, 7]; WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 5, 6]; WriteMemory[1C00000H ,0, 0, 0, FALSE, FALSE, FALSE, 6, 7]; MemoryWriteTest[]; MemoryReadTest[]; }; ParityTest: PROC = { WriteLatch[statuslatch, statusregreset]; WriteLatch[statuslatch, statusregnorm]; ChkP[XHINT, 0]; ReadLatch[statuslatch, statusregnorm]; ReadMemory[0,0,0, FALSE, TRUE, FALSE]; ReadLatch[statuslatch, statusregnorm + 8000H]; ClrP[XHINT]; WriteLatch[statuslatch, statusregnorm + 0400H]; ChkP[XHINT, 1]; ReadLatch[statuslatch, statusregnorm + 8400H]; ClrP[XHINT]; WriteLatch[statuslatch, statusregnorm]; ChkP[XHINT, 0]; GoClock[]; ReadMemory[0,0,0]; WriteLatch[statuslatch, statusregnorm + 0100H]; ReadLatch[statuslatch, laststatus]; WriteLatch[statuslatch, statusregnorm]; ReadMemory[0,0,0, FALSE, FALSE, TRUE]; ReadLatch[statuslatch, statusregnorm + 4000H]; ClrP[XHINT]; WriteLatch[statuslatch, statusregnorm + 0400H]; ChkP[XHINT, 1]; ReadLatch[statuslatch, statusregnorm + 4400H]; ClrP[XHINT]; WriteLatch[statuslatch, statusregnorm]; ChkP[XHINT, 0]; GoClock[]; ReadMemory[0,0,0]; WriteLatch[statuslatch, statusregnorm + 0100H]; ReadLatch[statuslatch, laststatus]; WriteLatch[statuslatch, statusregnorm]; ClrP[XHINT]; }; MISetupInit[cellType.public]; ChipReady[]; RandomMemoryTest[]; TestMemory[]; TestLatches[]; ParityTest[]; }; ITDList: PROC [public: CoreCreate.Wire, indicies: LIST OF NAT, initDrive: Ports.Drive] ~ { FOR l: LIST OF NAT _ indicies, l.rest WHILE l#NIL DO [] _ Ports.InitTesterDrive[wire: public[l.first], initDrive: initDrive]; ENDLOOP; }; IPList: PROC [public: CoreCreate.Wire, indicies: LIST OF NAT, levelType: Ports.LevelType, initDrive: Ports.Drive _ none] ~ { FOR l: LIST OF NAT _ indicies, l.rest WHILE l#NIL DO [] _ Ports.InitPort[wire: public[l.first], levelType: levelType, initDrive: initDrive]; ENDLOOP; }; InitializeTest[]; END. ¨TestMI.mesa Copyright c 1987 by Xerox Corporation. All rights reserved. Krivacic, March 5, 1987 1:33:42 pm PST Last Edited by: Krivacic March 30, 1987 12:47:59 pm PST Last Edited by: Bell March 10, 1987 12:28:56 pm PST Binding -- Special Constants & Addresses Structure Test -- graphWires: x CoreFlat.CreateFlatWires -- cutSet: CoreFlat.CreateCutSet[labels: LIST["Logic","LogicMacro"]] PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC] -- Write value to the indicated MI latch -- Read value from the indicated MI latch & compare with expected value -- Clock Through the sequencer of a memory operation -- Get to Hold logic & delay HOLDA for holddelay -- Check for RAS & Ras Address Check for CAS & Cas Address -- Test for MEMRDY delay -- Clear CAS' / RAS' / PA / RASX' / PD -- Set Latch with Upper part of address & Status Reg Sync Clock -- Do Memory Read, Setup Chip Select & Address -- Get through 1st clocking sequence Set up values to read -- Get through Cas' clocking sequence -- Check for returned data -- Set Latch with Upper part of address & Status Reg Sync Clock -- Do Memory Read -- Read Word Before Writing, unless an IO operation -- Set Values to Read -- Check for CAS & Cas Address -- 3. WRITE Merged word ------------------------------------ -- Check for RAS & Ras Address -- Check for CAS & Cas Address, data written 4. Clear time --------------------------------------------- -- Set all pads of the chip so it is ready for input & remove x's from the chip. -- Set IOP side 1st -- Set MI to LP pins -- Set Memory Pins -- Set Memory Control Pins -- Clock Pins clear reset Set the Latches -- Test Bits in Status Regs bits: 0 - Tag Parity Error 1 - Data Parity Error 2 - PIRQ 3 - Reset LPRESET 4 - Set LPRESET 5 - Enable Parity IRQ 6 - Reset PIRQ 7 - Reset Parity Error 8 - Enable PIRQ 12- Hold Ignore 13- Dint2 (XIRQ1) 14- XIRQ0 15- Hi Byte Select -- Test XIRQ0 Test PIRQ logic -- Refresh Count Register: Bit: 0 - Enale Refresh Counter 4-15 Refresh Counter Test Refresh Cycles -- WriteLatch[refreshlatch, 0000H]; -- Test Ability to Read / Write Internal Latches -- Test Status Reg -- Test Refresh Count Reg -- Test Address Latch Test Bits in Status Regs Test Memory Reads Go through some specific locations -- Write Memroy Test Go through some specific locations -- Test the parity error detection & interrupt lines -- Setup / clear status reg -- Read with Tag Parity Error -- Turn on Interrupt Enable & check HINT -- Clear Interrupt Enable & check HINT cleared -- Clear Tag Parity Error -- Read with Data Parity Error -- Turn on Interrupt Enable & check HINT -- Clear Interrupt Enable & check HINT cleared -- Clear Data Parity Error Belongs in Ports Start Code Κ$ϊ˜code– "cedar" stylešœ ™ šœ Οmœ1™Kšœ˜K˜šžœžœ žœ žœ˜(Kšœ žœ žœ˜3Kšžœ˜—Kšœ˜K˜—K˜K˜š Ÿœžœžœžœžœ˜0Kšœ˜Kšœ˜—K˜š Ÿ œžœ žœžœžœ˜5Kšœ žœ'˜6Kšœ˜—K˜šŸœžœžœ˜%Kš žœ žœžœ žœžœ˜;K˜šžœž˜Kšœžœ žœžœ˜*Kšœ&˜&K˜K˜˜šžœž˜Kšœžœ˜Kšœžœ˜Kšžœžœ˜——Kšžœžœ˜—Kšœ˜K˜—š Ÿ œžœ žœžœžœ˜/šžœ˜šžœžœ˜Kšž˜šžœž˜Kšœ‘œ˜ Kšœ‘œ˜ Kšœ‘œ˜ Kšœ‘œ˜ Kšœ‘œ˜ Kšžœžœ˜———K˜—K˜š Ÿ œžœ žœžœžœ˜0šžœ˜šžœžœ˜šž˜šžœž˜Kšœ‘œ˜ Kšœ‘œ˜ Kšœ‘œ˜ Kšœ‘œ˜ Kšœ‘œ˜ —Kšžœžœ˜———K˜—K˜šŸœžœžœ˜"Kšœ˜K˜Kšžœžœžœ˜&Kšžœžœžœ˜"K˜—K˜šŸœžœžœ˜šžœž˜Kšœ˜Kšœ!˜!K˜K˜Kšœžœ˜Kšžœžœ˜—K˜K˜—K˜šŸœžœžœ˜"Kšœ˜K˜K˜—K˜šŸœžœžœ˜Kšœ ˜ K˜K˜—K˜š Ÿœžœ žœžœžœ˜K˜šžœžœžœ˜'Kšœžœ˜Kšœžœ˜Kšœ˜Kšœ žœžœ˜Kšœ˜Kšœ˜K˜ Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœžœ˜K˜K˜—Kšœ  ˜Kšžœ žœ  ˜*Kšœ žœ˜Kšœ  ˜Kšœ  ˜K˜Kšœ ˜!Kšœ  ˜Kšœ˜Kšœ˜K˜šžœ žœžœžœ˜8K˜—š žœ žœ‘œžœ žœ˜>K˜ šžœžœ˜Kšœ žœ˜Kšœžœ‘œ˜3Kšœ˜—Kšœ˜—K˜K˜Kšžœ˜—K˜—K˜šŸ œžœ˜Kšžœ žœ ˜Kšœ˜—K˜šŸ œžœžœ˜(K˜Kš (™(K˜Kšœžœ˜Kšœ˜Kšœžœ ˜Kšœžœ˜K˜Kšœ˜K˜Kšœ˜Kšœ˜Kšœžœ˜K˜ Kšœ˜Kšœ˜Kšœžœ˜ K˜ Kšœžœ˜ Kšœžœ˜ K˜Kšžœžœ ˜BK˜Kšžœžœ ˜