DIRECTORY Commander, CommandTool, Convert, Core, IO, Ports, Random, Rosemary, RosemaryUser, MTSVector; ALS652: CEDAR PROGRAM IMPORTS Commander, CommandTool, Convert, IO, Ports, Random, Rosemary, RosemaryUser, MTSVector = BEGIN controlledClocks: BOOL _ FALSE; ALS652Wires: TYPE = {A, B, nGBA, GAB, CBA, CAB, SBA, SAB}; ALS652WireNames: ARRAY ALS652Wires OF IO.ROPE = ["A", "B", "nGBA", "GAB", "CBA", "CAB", "SBA", "SAB"]; State: TYPE = REF StateRec _ NIL; StateRec: TYPE = RECORD [ cellType: Core.CellType _ NIL, p: Ports.Port _ NIL, pi: ARRAY ALS652Wires OF NAT _ ALL[0], -- indexes in cellType.public Vdd, Gnd: NAT _ 0, AVal, BVal: ARRAY [0..8) OF Ports.Level _ ALL[X] ]; CreateState: PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [ st: State ] = { st _ NEW[StateRec _ [cellType: cellType, p: p]]; [st.Vdd, st.Gnd] _ Ports.PortIndexes[st.cellType.public, "Vdd", "Gnd"]; FOR aw: ALS652Wires IN ALS652Wires DO [st.pi[aw]] _ Ports.PortIndexes[st.cellType.public, ALS652WireNames[aw]]; ENDLOOP; }; RunTest: PROC [st: State, eval: RosemaryUser.TestEvalProc, mts: MTSVector.Capture ] = { ENABLE UNWIND => MTSVector.CloseCapture[mts]; Eval: PROC = { MTSVector.EvalAndCapture[capture: mts, Eval: eval, memory: FALSE]; }; EvalIgnoreX: PROC = { Eval[ ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT ]; }; st.p[st.pi[CAB]].d _ st.p[st.pi[CBA]].d _ drive; st.p[st.pi[CAB]].b _ st.p[st.pi[CBA]].b _ FALSE; st.p[st.pi[nGBA]].d _ st.p[st.pi[GAB]].d _ drive; st.p[st.pi[nGBA]].b _ TRUE; st.p[st.pi[GAB]].b _ FALSE; st.p[st.pi[SAB]].d _ st.p[st.pi[SBA]].d _ drive; st.p[st.pi[SAB]].b _ st.p[st.pi[SBA]].b _ FALSE; st.p[st.pi[A]].d _ st.p[st.pi[B]].d _ drive; FOR i: NAT IN [0..8) DO st.p[st.pi[A]].ls[i] _ st.p[st.pi[B]].ls[i] _ st.AVal[i] _ st.BVal[i] _ L; ENDLOOP; EvalIgnoreX[]; st.p[st.pi[CAB]].b _ st.p[st.pi[CBA]].b _ TRUE; -- clear internal flipflops EvalIgnoreX[]; st.p[st.pi[CAB]].b _ st.p[st.pi[CBA]].b _ FALSE; EvalIgnoreX[]; st.p[st.pi[A]].d _ st.p[st.pi[B]].d _ force; Eval[]; FOR i: NAT IN [0..8) DO st.p[st.pi[A]].ls[i] _ st.p[st.pi[B]].ls[i] _ st.AVal[i] _ st.BVal[i] _ H; ENDLOOP; Eval[]; FOR i: NAT IN [0..8) DO st.p[st.pi[A]].ls[i] _ st.p[st.pi[B]].ls[i] _ st.AVal[i] _ st.BVal[i] _ L; ENDLOOP; st.p[st.pi[A]].d _ st.p[st.pi[B]].d _ drive; Eval[]; FOR i: NAT IN [0..2000) DO SimulateALS652Data: PROC = { FOR i: NAT IN [0..8) DO baMux: Ports.Level _ (SELECT TRUE FROM st.p[st.pi[SBA]].b => st.BVal[i], NOT st.p[st.pi[GAB]].b => st.p[st.pi[B]].ls[i], st.p[st.pi[SAB]].b => st.AVal[i], st.p[st.pi[nGBA]].b => st.p[st.pi[A]].ls[i], ENDCASE => ERROR -- logical loop -- ); abMux: Ports.Level _ (SELECT TRUE FROM st.p[st.pi[SAB]].b => st.AVal[i], st.p[st.pi[nGBA]].b => st.p[st.pi[A]].ls[i], st.p[st.pi[SBA]].b => st.BVal[i], NOT st.p[st.pi[GAB]].b => st.p[st.pi[B]].ls[i], ENDCASE => ERROR -- logical loop -- ); IF st.p[st.pi[GAB]].b THEN st.p[st.pi[B]].ls[i] _ abMux; IF NOT st.p[st.pi[nGBA]].b THEN st.p[st.pi[A]].ls[i] _ baMux; ENDLOOP; }; gba, gab, sba, sab, cba, cab: BOOL; didEval: BOOL _ FALSE; DO gba _ NOT st.p[st.pi[nGBA]].b; gab _ st.p[st.pi[GAB]].b; sba _ st.p[st.pi[SBA]].b; sab _ st.p[st.pi[SAB]].b; cba _ st.p[st.pi[CBA]].b; cab _ st.p[st.pi[CAB]].b; SELECT genRS.ChooseInt[max: 8] FROM 0 => gba _ NOT gba; 1 => gab _ NOT gab; 2 => sba _ NOT sba; 3 => sab _ NOT sab; 4 => cba _ NOT cba; 5 => cab _ NOT cab; ENDCASE => NULL; IF NOT gba OR NOT gab OR sba OR sab THEN EXIT; -- it's OK ENDLOOP; SELECT TRUE FROM st.p[st.pi[GAB]].b AND NOT gab => { -- device port B turning off, tester drives the same value for one vector st.p[st.pi[GAB]].b _ FALSE; st.p[st.pi[B]].d _ drive; Eval[]; }; NOT st.p[st.pi[GAB]].b AND gab => { -- device port B turning on st.p[st.pi[GAB]].b _ TRUE; SimulateALS652Data[]; st.p[st.pi[GAB]].b _ FALSE; Eval[]; st.p[st.pi[GAB]].b _ TRUE; -- now turn device port B on Eval[]; st.p[st.pi[B]].d _ expect; -- now disable tester drive }; NOT st.p[st.pi[nGBA]].b AND NOT gba => { -- device port A turning off, tester drives the same value for one vector st.p[st.pi[nGBA]].b _ NOT FALSE; st.p[st.pi[A]].d _ drive; Eval[]; }; st.p[st.pi[nGBA]].b AND gba => { -- device port A turning on st.p[st.pi[nGBA]].b _ NOT TRUE; SimulateALS652Data[]; st.p[st.pi[nGBA]].b _ NOT FALSE; Eval[]; st.p[st.pi[nGBA]].b _ NOT TRUE; -- now turn device port A on Eval[]; st.p[st.pi[A]].d _ expect; -- now disable tester drive }; NOT st.p[st.pi[CAB]].b AND cab => { -- clock A->B rising st.p[st.pi[CAB]].b _ TRUE; FOR i: NAT IN [0..8) DO st.AVal[i] _ st.p[st.pi[A]].ls[i]; ENDLOOP; SimulateALS652Data[]; Eval[]; IF controlledClocks THEN { st.p[st.pi[CAB]].b _ FALSE; -- for clock edge noise immunity Eval[]; }; }; NOT st.p[st.pi[CBA]].b AND cba => { -- clock B->A rising st.p[st.pi[CBA]].b _ TRUE; FOR i: NAT IN [0..8) DO st.BVal[i] _ st.p[st.pi[B]].ls[i]; ENDLOOP; SimulateALS652Data[]; Eval[]; IF controlledClocks THEN { st.p[st.pi[CBA]].b _ FALSE; -- for clock edge noise immunity Eval[]; }; }; ENDCASE => { st.p[st.pi[SAB]].b _ sab; st.p[st.pi[SBA]].b _ sba; st.p[st.pi[CAB]].b _ cab; st.p[st.pi[CBA]].b _ cba; FOR i: NAT IN [0..8) DO IF st.p[st.pi[A]].d = drive THEN -- tester is driving port A st.p[st.pi[A]].ls[i] _ (IF genRS.ChooseInt[max: 1] < 1 THEN H ELSE L); IF st.p[st.pi[B]].d = drive THEN -- tester is driving port B st.p[st.pi[B]].ls[i] _ (IF genRS.ChooseInt[max: 1] < 1 THEN H ELSE L); ENDLOOP; SimulateALS652Data[]; Eval[]; }; ENDLOOP; MTSVector.CloseCapture[mts]; }; RandomCapture: RosemaryUser.TestProc ~ { RunTest[CreateState[cellType, p], Eval, MTSVector.CreateCapture[cellType]]; }; RandomTest: RosemaryUser.TestProc ~ { RunTest[CreateState[cellType, p], Eval, NIL]; }; lastGenSeed: INT _ 1354117939; genRS: Random.RandomStream _ NIL; SetupSeed: PROC [ seed: INT _ 0 ] RETURNS [ IO.ROPE ] = { IF seed = 0 THEN seed _ lastGenSeed; genRS _ Random.Create[seed: seed]; lastGenSeed _ genRS.seed; RETURN[IO.PutFR["New ALS652 random number seed is %d.\n", IO.int[lastGenSeed]]]; }; ALS652RandSeedProc: PROC [ cmd: Commander.Handle ] RETURNS [ result: REF _ NIL, msg: IO.ROPE _ NIL ] -- Commander.CommandProc -- = { seed: INT _ 0; argv: CommandTool.ArgumentVector = CommandTool.Parse[cmd]; IF argv.argc > 1 THEN seed _ Convert.IntFromRope[ argv[1] ! Convert.Error => CONTINUE ]; cmd.out.PutRope[SetupSeed[seed]]; }; Commander.Register["ALS652RandSeed", ALS652RandSeedProc, "Reseeds the random number generator for the ALS652 simulation. Usage is\n ALS652RandSeed n\n where n is an integer. 0 recovers the previous seed."]; RosemaryUser.RegisterTestProc["ALS652Random", RandomTest]; RosemaryUser.RegisterTestProc["ALS652RandomCapture", RandomCapture]; END. ήALS652.mesa Copyright Σ 1987, 1988 by Xerox Corporation. All rights reserved. E. McCreight, May 15, 1987 4:28:01 pm PDT Jean-Marc Frailong September 30, 1988 11:26:48 am PDT st.p[st.Vdd].d _ st.p[st.Gnd].d _ inspect; st.p[st.Vdd].b _ TRUE; st.p[st.Gnd].b _ FALSE; -- -- -- -- -- -- Choose at most one random thing to do next.... Check that it's legal... To avoid complications of high-impedance buses oscillating, we overlap drive of tester and DUT by one test vector. figure out what device port B would be saying if it were on now, and drive that from the tester before turning device port B on. figure out what device port A would be saying if it were on now, and drive that from the tester before turning device port A on. Κ Ό– "cedar" style˜šœ ™ JšœB™BJšœ&Οk™)Icode™5J˜—š ˜ Jšœ'œ3˜\J˜—šΠblœœ˜Jšœ"œ2˜]J˜Jš˜J˜Jšœœœ˜J˜Jš œ œœœœœœ˜:Jš Οnœœ œœœ9˜fJ˜Jšœœœ œ˜!šœ œœ˜Jšœœ˜Jšœœ˜Jš œœ œœœΟc˜DJšœ œ˜Jšœ œœœ˜0J˜J˜—šŸ œœ*œ˜TJšœœ(˜0JšœG˜Gšœœ ˜%JšœI˜IJšœ˜—J˜J˜—šŸœœJ˜WJšœœ ˜-šŸœœ˜Jšœ;œ˜BJšœ˜—šŸ œœ˜Jš œœœœœœ˜MJšœ˜—Jšœ*™*Jšœœ™Jšœœ™Jšœ œœ ˜0Jšœ œœœ˜0Jšœ!œ ˜1Jšœœ˜Jšœ œœ˜Jšœ œœ ˜0Jšœ œœœ˜0Jšœ,˜,šœœœ˜JšœJ˜JJšœ˜—Jšœ˜J™Jšœ œœœ ˜KJšœ˜J™Jšœ œœœ˜0Jšœ˜J™Jšœ,˜,Jšœ˜J™šœœœ˜JšœJ˜JJšœ˜—Jšœ˜J™šœœœ˜JšœJ˜JJšœ˜—Jšœ,˜,Jšœ˜J™šœœœ ˜šŸœœ˜šœœœ˜šœœœ˜&Jšœ œ˜!Jšœ œ˜/Jšœ œ˜!Jšœ,˜,Jšœœ œ˜&—šœœœ˜&Jšœ œ˜!Jšœ,˜,Jšœ œ˜!Jšœ œ˜/Jšœœ œ˜&—Jšœ œœ˜8Jšœœœ˜=Jšœ˜—Jšœ˜—Jšœœ˜#Jšœ œœ˜Jšœ.™.š˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜šœ˜#Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœœ˜—Jšœ™Jšœœœœœœœœ  ˜9Jšœ˜—Jšœ[œ™ršœœ˜šœ œœœ  I˜mJšœ œœ˜Jšœ˜Jšœ˜Jšœ˜—šœ œœ  ˜?Jšœ œœ˜šœ˜Jšœ€™€—Jšœ œœ˜Jšœ˜Jšœ œœ ˜7Jšœ˜Jšœ ˜6Jšœ˜—šœœœ  I˜rJšœœœ˜ Jšœ˜Jšœ˜Jšœ˜—šœœ  ˜