DIRECTORY Basics, BitOps, Core, CoreFlat, CRProcs, Ports, Rosemary, RosemaryUser; CRTest: CEDAR PROGRAM IMPORTS Basics, BitOps, CoreFlat, Ports, Rosemary, RosemaryUser = BEGIN OPEN CRProcs; Vdd: NAT; Gnd: NAT; PadVdd: NAT; PadGnd: NAT; nPrecharge: NAT; Access: NAT; Write: NAT; Read: NAT; Address: NAT; Data: NAT; Size: NAT = 4*rowQuads*8; InitPortIndicies: PROC [p: Core.Wire] ~ { Vdd _ Ports.PortIndex[p, "Vdd"]; Gnd _ Ports.PortIndex[p, "Gnd"]; PadVdd _ Ports.PortIndex[p, "PadVdd"]; PadGnd _ Ports.PortIndex[p, "PadGnd"]; nPrecharge _ Ports.PortIndex[p, "nPrecharge"]; Access _ Ports.PortIndex[p, "Access"]; Write _ Ports.PortIndex[p, "Write"]; Read _ Ports.PortIndex[p, "Read"]; Address _ Ports.PortIndex[p, "Address"]; Data _ Ports.PortIndex[p, "Data"]; }; Init: PROC [ct: Core.CellType, flatten: BOOL _ FALSE] = { InitPortIndicies[ct.public]; [] _ Rosemary.SetFixedWire[ct.public[Vdd], H]; [] _ Rosemary.SetFixedWire[ct.public[Gnd], L]; [] _ Rosemary.SetFixedWire[ct.public[PadVdd], H]; [] _ Rosemary.SetFixedWire[ct.public[PadGnd], L]; [] _ Ports.InitTesterDrive[wire: ct.public[nPrecharge], initDrive: force]; [] _ Ports.InitTesterDrive[wire: ct.public[Access], initDrive: force]; [] _ Ports.InitTesterDrive[wire: ct.public[Write], initDrive: force]; [] _ Ports.InitTesterDrive[wire: ct.public[Read], initDrive: force]; [] _ Ports.InitTesterDrive[wire: ct.public[Address], initDrive: force]; [] _ Ports.InitTesterDrive[wire: ct.public[Data], initDrive: none]; [] _ RosemaryUser.TestProcedureViewer[name: "CrossRAM Tester", cellType: ct, testButtons: LIST["Write2Read2", "Illinois"], displayWires: RosemaryUser.DisplayPortLeafWires[ct], steady: FALSE, cutSet: CoreFlat.CreateCutSet[cellTypes: IF flatten THEN NIL ELSE LIST["CrossRAM"]], recordDeltas: FALSE]; }; InitRAM: PROC [p: Ports.Port, Eval: PROC [memory: BOOL _ TRUE]] = { p[Vdd].b _ TRUE; p[Gnd].b _ FALSE; p[PadVdd].b _ TRUE; p[PadGnd].b _ FALSE; p[nPrecharge].b _ TRUE; p[Access].b _ FALSE; p[Write].b _ FALSE; p[Read].b _ FALSE; p[Data].d _ force; Eval[! Rosemary.Stop => RESUME]; p[Data].d _ none; }; AccessRAM: PROC [address: CARDINAL, data: CARDINAL, write: BOOL, p: Ports.Port, Eval: PROC [memory: BOOL _ TRUE]] = { data _ Basics.BITAND[Basics.LowHalf[BitOps.TwoToThe[CRProcs.dataBits]-1], data]; p[Address].c _ address; p[nPrecharge].b _ FALSE; Eval[]; p[nPrecharge].b _ TRUE; Eval[]; p[Access].b _ TRUE; IF write THEN { p[Data].d _ force; p[Write].b _ TRUE; } ELSE { p[Data].d _ expect; p[Read].b _ TRUE; }; p[Data].c _ data; Eval[ ! Rosemary.Stop => IF reason = $BoolWireHasX THEN SIGNAL FindX[]]; p[Access].b _ p[Write].b _ p[Read].b _ FALSE; p[Data].d _ none; Eval[]; }; Write2Read2: RosemaryUser.TestProc = { InitPortIndicies[cellType.public]; InitRAM[p, Eval]; AccessRAM[write: TRUE, address: 0, data: 0, p: p, Eval: Eval]; AccessRAM[write: TRUE, address: 1, data: 0FFH, p: p, Eval: Eval]; AccessRAM[write: FALSE, address: 0, data: 0, p: p, Eval: Eval]; AccessRAM[write: FALSE, address: 1, data: 0FFH, p: p, Eval: Eval]; }; Illinois: RosemaryUser.TestProc = { CycleRAM: PROC [address: CARDINAL, data: CARDINAL, write: BOOL] = { AccessRAM[write: write, address: address, data: data, p: p, Eval: Eval]; }; HalfStep: PROC [upper: BOOL, data: BOOL, write: BOOL] = { address: CARDINAL _ IF upper THEN halfBit ELSE 0; addressMod: CARDINAL; DO CycleRAM[address, IF data THEN LAST[CARDINAL] ELSE 0, write]; address _ address + 1; addressMod _ address MOD (2*halfBit); IF (upper AND addressMod=0) OR (NOT upper AND addressMod=halfBit) THEN address _ address + halfBit; IF address>=Size THEN EXIT; ENDLOOP; }; StepIndex: TYPE = [0..8); complementUpper: ARRAY StepIndex OF BOOL = [TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,TRUE,FALSE]; writeData: ARRAY StepIndex OF BOOL = [TRUE,FALSE,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE]; readData: ARRAY StepIndex OF BOOL = [FALSE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE]; halfBit: CARDINAL _ BitOps.TwoToThe[BitOps.NBits[Size]]; InitPortIndicies[cellType.public]; InitRAM[p, Eval]; FOR address: CARDINAL IN [0..Size) DO CycleRAM[address, 0, TRUE]; ENDLOOP; UNTIL (halfBit _ halfBit/2) = 4 DO FOR step: StepIndex IN StepIndex DO HalfStep[upper: complementUpper[step], data: writeData[step], write: TRUE]; HalfStep[upper: NOT complementUpper[step], data: readData[step], write: FALSE]; ENDLOOP; ENDLOOP; }; FindX: SIGNAL = CODE; CrossRAMInit: Rosemary.InitProc = { stateAny _ NEW[CrossRAMStateRec[Size]]; IF dataBits>16 OR addressBits>16 THEN ERROR; }; CrossRAMSimple: Rosemary.EvalProc = { state: CrossRAMState _ NARROW[stateAny]; IF NOT p[Vdd].b OR p[Gnd].b OR NOT p[PadVdd].b OR p[PadGnd].b THEN SIGNAL Rosemary.Stop[]; IF (NOT p[nPrecharge].b AND p[Access].b) OR (p[Write].b AND p[Read].b) OR (NOT p[nPrecharge].b AND p[Write].b) THEN SIGNAL Rosemary.Stop[]; IF NOT p[nPrecharge].b THEN state.precharged _ TRUE; p[Data].d _ none; IF p[Access].b THEN { IF NOT state.precharged THEN SIGNAL Rosemary.Stop[]; IF state.accessOccured AND state.address#p[Address].c THEN SIGNAL Rosemary.Stop[]; state.accessOccured _ TRUE; state.address _ p[Address].c; IF p[Read].b THEN { p[Data].c _ state.memory[state.address].data; p[Data].d _ drive; }; IF p[Write].b THEN state.memory[state.address].data _ p[Data].c; }; IF NOT p[Access].b AND state.accessOccured THEN { state.accessOccured _ FALSE; state.precharged _ FALSE; }; }; [] _ Rosemary.Register[roseClassName: "CrossRAM", init: CrossRAMInit, evalSimple: CrossRAMSimple]; RosemaryUser.RegisterTestProc["Write2Read2", Write2Read2]; RosemaryUser.RegisterTestProc["Illinois", Illinois]; END. ΤCRTest.mesa Barth, March 13, 1987 11:47:37 am PST precharge enable select line if write then enable write drivers disable select line write zero to all locations divide RAM by columns instead of rows ΚL˜codešœ ™ K™%—K˜KšΟk œH˜QK˜šΟnœœ˜Kšœ:˜AKšœœ ˜—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˜—šžœœœœ˜9Kšœ˜Kšœ.˜.Kšœ.˜.Kšœ1˜1Kšœ1˜1KšœJ˜JKšœF˜FKšœE˜EKšœD˜DKšœG˜GKšœC˜CK˜KšœZœZœ+œ œœœœœ˜©K˜K˜—š žœœžœœ œœ˜CJšœ œ œ˜"Jšœœœ˜(Jšœœœ˜,Jšœ œœ˜&J˜Jšœ˜Jšœœ˜ Jšœ˜J˜J˜—šž œœ œœ œžœœ œœ˜uJšœœ<˜PJ˜J™J™ Jšœœ˜J˜Jšœœ˜J˜J™J™Jšœœ˜J™J™"šœœ˜Jšœ˜Jšœ œ˜—šœœ˜Jšœ˜Jšœ œ˜J˜—Jšœ˜Jšœœœœ ˜HJ™J™Jšœ'œ˜-J™Jšœ˜J˜J˜J˜J˜—šž œ˜&Kšœ"˜"K˜Jšœœ)˜>Jšœœ,˜AJšœœ)˜?Jšœœ,˜BKšœ˜—˜K˜—šžœ˜#K˜š žœœ œœ œ˜CKšœH˜HK˜K˜—š žœœ œœ œ˜9Kš œ œœœ œ˜1Kšœ œ˜š˜Kš œœœœœœ ˜=Kšœ˜Kšœœ ˜%Kš œœœœœœ˜cKšœœœ˜Kšœ˜—K˜K˜—Kšœ œ ˜Kšœœ œœœœœœœœœœ˜YKšœ œ œœœœœœœœœœ˜SKšœ œ œœœœœœœœœœ˜RKšœ œ'˜8Kšœ"˜"K˜K™K™%šœ œœ ˜%Kšœœ˜Kšœ˜—šœ˜"šœœ ˜#KšœEœ˜KKšœœ5œ˜OKšœ˜—Kšœ˜—K˜K˜—šžœœœ˜K˜—šž œ˜#Kšœ œ˜'Kšœ œœœ˜,Kšœ˜—K˜šžœ˜%Kšœœ ˜(Kšœœ œ œœ œ œœ˜ZKšœœœœ œ œœœ œœ˜‹Kšœœœœ˜4Kšœ˜šœ œ˜Kšœœœœ˜4Kšœœœœ˜RKšœœ˜Kšœ˜šœ œ˜Kšœ-˜-Kšœ˜Kšœ˜—Kšœ œ.˜@K˜—šœœ œœ˜1Kšœœ˜Kšœœ˜Kšœ˜—Kšœ˜—K˜Kšœb˜bKšœ:˜:Kšœ4˜4K˜Kšœ˜—…—ͺΚ