add test 3006
[fleet.git] / testCode / com / sun / vlsi / chips / marina / test / MarinaTest.java
1 package com.sun.vlsi.chips.marina.test;
2 /* -*- tab-width: 4 -*- */
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import com.sun.async.test.BitVector;
7 import com.sun.async.test.ChainControl;
8 import com.sun.async.test.ChainTest;
9 import com.sun.async.test.ChipModel;
10 import com.sun.async.test.HP34401A;
11 import com.sun.async.test.Infrastructure;
12 import com.sun.async.test.JtagTester;
13 import com.sun.async.test.ManualPowerChannel;
14 import com.sun.async.test.NanosimModel;
15 import com.sun.async.test.Netscan4;
16 import com.sun.async.test.PowerChannel;
17 import com.sun.async.test.Pst3202Channel;
18 import com.sun.async.test.SiliconChip;
19 import com.sun.async.test.SimulationModel;
20 import com.sun.async.test.VoltageReadable;
21 import com.sun.vlsi.chips.marina.test.MarinaUtils.CmdArgs;
22 import com.sun.vlsi.chips.marina.test.MarinaUtils.Station;
23 import com.sun.vlsi.chips.marina.test.MarinaUtils.CmdArgs.Mode;
24
25 import edu.berkeley.fleet.api.Dock;
26 import edu.berkeley.fleet.api.Instruction;
27 import edu.berkeley.fleet.api.Predicate;
28 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
29 import edu.berkeley.fleet.api.Instruction.Set.SetSource;
30
31 /**
32  * Tests for Marina
33  */
34 public class MarinaTest {
35         //--------------------------  constants -----------------------------------
36         public static final int INSTR_SZ = 36;
37         
38         public static final Dock DOCK = InstructionStopper.DOCK;
39     public static final Instruction.Set.FlagFunction CLEAR_FLAG 
40         = Instruction.Set.FlagFunction.ZERO;
41     public static final Instruction.Set.FlagFunction SET_FLAG 
42         = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA)
43                                            .add(Predicate.NotFlagA);
44     public static final Instruction.Set.FlagFunction A_FLAG 
45         = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA);
46
47     public static final Instruction.Set.FlagFunction B_FLAG 
48         = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB);
49     
50         // COLUMN_LATENCY is a delay that is larger than the latency through an Infinity column
51         private static final int COLUMN_LATENCY = 10; // nanoseconds
52
53
54     // Officially, this should be the number of requeueing no-ops that
55     // can be inserted into an idle dock whose OLC is nonzero.
56     //
57     // Less formally, this is roughly the number of stages of
58     // buffering between the instruction insertion point and the
59     // instruction ring, plus the capacity of the instruction ring.
60     private static final int SATURATION_AMOUNT = 19;
61
62     // This is some number which is significantly greater than
63     // SATURATION_AMOUNT.  Increasing it may slow the tests down, but
64     // will never cause them to operate incorrectly.
65     private static final int MORE_THAN_SATURATION_AMOUNT = 25;
66         
67         // Nominal cycle time assuming 4 GHz throughput
68         private static final double CYCLE_TIME_NS = 0.250;
69
70         //--------------------------------  types ---------------------------------
71
72         //--------------------------  private data --------------------------------
73         private static long startTime;
74
75         private Indenter indenter = new Indenter();
76         private Marina marina;
77         private ChipModel model;
78         private ChainControl cc;
79         private JtagTester tester;
80         private CmdArgs cmdArgs;
81         private PowerChannel corePowerSupply, padsPowerSupply;
82     private VoltageReadable coreVoltmeter, voltmeterForCurrent;
83         
84         //--------------------------  private methods -----------------------------
85     /** @return true if simulation. Return false if we're testing silicon. */
86         private boolean sim() {return model instanceof SimulationModel;}
87         
88         private void prln(String msg) {indenter.prln(msg);}
89         private void pr(String msg) {indenter.pr(msg);}
90         private void adjustIndent(int n) {indenter.adjustIndent(n);}
91         
92         private static void fatal(boolean pred, String msg) {
93                 if (pred) {
94                         System.out.println("Test Failed");
95                         printTestTime();
96                         Infrastructure.fatal(msg);
97                 }
98         }
99         private static void printTestTime() {
100         long endTime = System.currentTimeMillis();
101         System.out.println("Test took: "+(endTime-startTime)/1000.0+"  sec");
102         }
103     
104         // Tell user what we're about to do
105         private static void reportTask(CmdArgs args) {
106                 System.out.println("Begin testing Marina");
107         switch (args.mode) {
108         case WHOLE_CHIP_SCHEMATIC_PARASITICS:
109                 System.out.println("  Simulate whole chip, schematic parasitics");
110                 break;
111         case WHOLE_CHIP_LAYOUT_PARASITICS:
112                 System.out.println("  Simulate whole chip, layout parasitics");
113                 break;
114         case TEST_SILICON:
115                 System.out.println("  Test silicon");
116                 break;
117         default:
118                 fatal(true, "unrecognized CmdArgs.Mode");
119                 return;
120         }
121         }
122         private void setUpSuppliesAndMeters(Station station) {
123                 // set up power supplies and meters
124                 if (!sim()) {
125                         prln("Testing station: "+station);
126                   Infrastructure.gpibControllers = new int[] {0};
127                   switch (cmdArgs.station) {
128                   case ONE:
129                                 corePowerSupply = new Pst3202Channel("ch1", "HPST3202", 1);
130                             padsPowerSupply = new Pst3202Channel("ch2", "HPST3202", 2);
131                             break;
132                   case TWO:
133                                 corePowerSupply = new Pst3202Channel("ch1", "HPST3202B", 1);
134                             padsPowerSupply = new Pst3202Channel("ch2", "HPST3202B", 2);
135                         break;
136                   default:
137                         fatal(true, "Unrecognized station: "+cmdArgs.station);
138                   }
139                   corePowerSupply.setCurrent((float)1.7);
140                   corePowerSupply.setVoltageWait((float)1.0);
141                   
142                   padsPowerSupply.setCurrent((float)0.100);
143                   padsPowerSupply.setVoltageWait((float)1.8);
144                   
145                   coreVoltmeter = new HP34401A(station.coreVoltmeter);
146                   voltmeterForCurrent = new HP34401A(station.currentVoltmenter);
147                 }
148         }
149         
150         private MarinaTest(String[] args) {
151         cmdArgs = new MarinaUtils.CmdArgs(args);
152         reportTask(cmdArgs);
153         boolean sim = cmdArgs.mode != Mode.TEST_SILICON;
154         if (sim) {
155                 model = new NanosimModel();
156                 tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
157         } else {
158                 model = new SiliconChip();
159                 String ip = cmdArgs.station.ipAddr;
160                 tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
161         }
162         tester.printInfo = false;
163         int khz = sim ? 1000000 : 1000;
164
165         String netListName;
166         switch (cmdArgs.mode) {
167         case WHOLE_CHIP_SCHEMATIC_PARASITICS:
168                 netListName = "marina.spi"; 
169             cc = new ChainControl("marina.xml", tester, 1.8f, khz);
170             marina = new Marina(cc, model, indenter);
171                 break;
172         case WHOLE_CHIP_LAYOUT_PARASITICS:
173                 netListName = "marina_pads_guts.spi"; 
174             cc = new ChainControl("???", tester, 1.8f, khz);
175             marina = null;
176                 break;
177         case TEST_SILICON:
178                 netListName = "marina_pads_guts.spi"; 
179             cc = new ChainControl("???", tester, 1.8f, khz);
180             marina = null;
181                 break;
182         default:
183                 fatal(true, "unrecognized CmdArgs.Mode");
184                 return;
185         }
186         cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
187         
188         PowerChannel pc = new ManualPowerChannel("pc", false);
189         ChainTest ct = new ChainTest(cc, pc);
190         
191         setUpSuppliesAndMeters(cmdArgs.station);
192         
193         if (sim) ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, true);
194         ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
195
196         doOneTest(cmdArgs.testNum);
197         
198         if (sim) ((SimulationModel)model).finish();
199 }
200
201         /** In the absence of looping, the longest path through Infinity is 4 column delays */
202         private void waitUntilQuiescent() {
203                 model.waitNS(4*COLUMN_LATENCY);
204         }
205     
206     private double readCurrent() {
207         return voltmeterForCurrent.readVoltage() / cmdArgs.station.ammeterShuntResistance;
208     }
209     
210     /** Generate List of BitVectors where Token=true, high 25 data bits  
211      * are alternating ones and zeros, low 12 data bits increment from 
212      * zero, and address is given by addr. */
213     private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
214         List<BitVector> ans = new ArrayList<BitVector>();
215         BitVector dHi = new BitVector(25, "dataHi");
216         BitVector dLo = new BitVector(12, "dataLo");
217         BitVector t = new BitVector("1", "token");
218         BitVector a = new BitVector(14, "addr");
219         dHi.setFromLong(0x00aaaaa);
220         a.setFromLong(addr);
221         for (int i=0; i<num; i++) {
222                 dLo.setFromLong(i);
223                 ans.add(dHi.cat(dLo).cat(t).cat(a));
224                 dHi = dHi.not();
225         }
226         return ans;
227     }
228     private void stopToStop(ProperStopper s1, ProperStopper s2, 
229                                 Counter ctr,
230                                 List<BitVector> din) {
231         prln("Begin stopToStop");
232         adjustIndent(2);
233         
234         s1.stop();
235         
236         long ctrStart = ctr==null ? 0 : ctr.getCount();
237         
238         s1.fillMany(din);
239         waitUntilQuiescent();
240         
241         List<BitVector> dout = s2.drainMany();
242         
243         MarinaUtils.compareItemsOrdered(din, dout);
244         
245         if (ctr!=null) {
246                 long ctrEnd = ctr.getCount();
247                 long delta = ctrEnd - ctrStart;
248             long expect = din.size();
249             fatal(delta!=expect, 
250                   "counter delta wrong: expected delta: "+expect+
251                   " counter before:"+ctrStart+" counter after:"+ctrEnd);
252         }
253         
254         adjustIndent(-2);
255         prln("End stopToStop");
256     }
257     /** Burst data from src to dst. gate is stopped while loading src. gate
258      * is then run to allow the burst to flow. */
259     private void stopToStopBurst(ProperStopper src, ProperStopper gate, 
260                                      ProperStopper dst,
261                                      Counter ctr,
262                                      List<BitVector> din) {
263                 prln("Begin stopToStopBurst test");
264                 adjustIndent(2);
265                 
266                 src.stop();
267                 gate.stop();
268                 
269         long ctrStart = ctr==null ? 0 : ctr.getCount();
270                 
271                 src.fillMany(din);
272                 waitUntilQuiescent();
273
274                 // open the gate to start the burst
275                 gate.run();
276                 waitUntilQuiescent();
277                 
278                 List<BitVector> dout = dst.drainMany();
279                 
280                 MarinaUtils.compareItemsOrdered(din, dout);
281                 
282                 if (ctr!=null) {
283                 long ctrEnd = ctr.getCount();
284                 long delta = ctrEnd - ctrStart;
285                 
286                 long expectA = din.size();
287                 fatal(delta!=expectA, 
288                           "counter delta wrong: expected delta: "+expectA+
289                           " counter before:"+ctrStart+" counter after:"+ctrEnd);
290                 }
291                 
292                 adjustIndent(-2);
293                 prln("End stopToStopBurst test");
294 }
295
296     private void stopToStopOne(ProperStopper s1, ProperStopper s2, 
297                                    Counter ctr, int adr) {
298         prln("Begin stopToStopOne");
299         adjustIndent(2);
300         
301         List<BitVector> din = makeIncrDataConstAdr(1, adr);
302         stopToStop(s1, s2, ctr, din);
303
304         adjustIndent(-2);
305         prln("End stopToStopOne");
306     }
307     
308     private void stopToStopThree(ProperStopper s1, ProperStopper s2, 
309                                      Counter ctr, int adr) {
310         prln("Begin stopToStopOne");
311         adjustIndent(2);
312         
313         List<BitVector> din = makeIncrDataConstAdr(3, adr);
314         stopToStop(s1, s2, ctr, din);
315
316         adjustIndent(-2);
317         prln("End stopToStopOne");
318     }
319
320     private int indexOf(BitVector o, List<BitVector> dIn) {
321                 for (int i=0; i<dIn.size(); i++) {
322                         if (o.equals(dIn.get(i)))  return i;
323                 }
324                 return -1;
325     }
326     private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
327         StringBuffer sb = new StringBuffer();
328         sb.append("  ring dump: ");
329         for (BitVector o : dOut) {
330                 sb.append(indexOf(o, dIn)+" ");
331         }
332         return sb.toString();
333     }
334
335     private int[][] makeIntArray2D(int a, int b) {
336         int[][] ans = new int[a][];
337         for (int i=0; i<a; i++) ans[i] = new int[b];
338         return ans;
339     }
340
341     //=========================================================================
342     // Put top level tests here
343     private void stopToStopOneItem(Marina marina) {
344         stopToStopOne(marina.data, marina.tokOut, null, -1);
345     }
346     private void stopToStopThreeItems(Marina marina) {
347         stopToStopThree(marina.data, marina.tokOut, null, -1);
348     }
349     private void sendInstructions(Marina marina) {
350         prln("Begin sendInstructions");
351         adjustIndent(2);
352         
353         List<BitVector> din = new ArrayList<BitVector>();
354
355         BitVector count = new BitVector(36,"count");
356         BitVector one = new BitVector(36, "one");
357         count.setFromLong(0);
358         one.setFromLong(1);
359         for (int i=0; i<3; i++) {
360                 din.add(count);
361                 count = count.add(one);
362         }
363
364         marina.instrIn.fillMany(din);
365
366         adjustIndent(-2);
367         prln("End sendInstructions");
368     }
369
370     private void sendToken(Marina marina) {
371         prln("Begin sendToken");
372         adjustIndent(2);
373         
374         prln("ILC=1");
375         marina.instrIn.fill(
376                 new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, 1));
377
378         getCtrsFlags(marina);
379         
380         prln("send token");
381         marina.instrIn.fill(
382             new Instruction.Move(DOCK,
383                                  false,                 /* requeueing  */
384                                  Predicate.IgnoreOLC,   /* predicate   */
385                                  false,                 /* torpedoable */
386                                  null,                  /* path        */
387                                  false,                 /* tokenIn     */
388                                  false,                 /* dataIn      */
389                                  false,                 /* latchData   */
390                                  false,                 /* latchPath   */
391                                  false,                 /* dataOut     */
392                                  true                   /* tokenOut    */
393                                  ));
394         
395         getCtrsFlags(marina);
396         
397         List<BitVector> toks = marina.tokOut.drainMany();
398         fatal(toks.size()!=1, "Expected one token to emerge but got: "+toks.size()+" tokens");
399         
400         prln("Token="+MarinaUtils.formatDataTokAddr(toks.get(0)));
401
402         adjustIndent(-2);
403         prln("End sendToken");
404     }
405
406     private void sendData(Marina marina) {
407         prln("Begin sendToken");
408         adjustIndent(2);
409         
410         prln("ILC=1");
411         marina.instrIn.fill(
412                 new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, 1));
413
414         getCtrsFlags(marina);
415         
416         prln("send data");
417         marina.instrIn.fill(
418             new Instruction.Move(DOCK,
419                                  false,                 /* requeueing  */
420                                  Predicate.IgnoreOLC,   /* predicate   */
421                                  false,                 /* torpedoable */
422                                  null,                  /* path        */
423                                  false,                 /* tokenIn     */
424                                  false,                 /* dataIn      */
425                                  false,                 /* latchData   */
426                                  false,                 /* latchPath   */
427                                  true,                  /* dataOut     */
428                                  false                  /* tokenOut    */
429                                  ));
430         
431         getCtrsFlags(marina);
432         
433         List<BitVector> dataItems = marina.data.drainMany();
434         fatal(dataItems.size()!=1, "Expected one token to emerge but got: "+dataItems.size()+" tokens");
435         
436         prln("Datum="+MarinaUtils.formatDataTokAddr(dataItems.get(0)));
437
438         adjustIndent(-2);
439         prln("End sendData");
440     }
441
442     private void testFlagZ(Marina marina) {
443         prln("Begin testFlagZ");
444         adjustIndent(2);
445         
446         List<BitVector> toks;
447
448         Predicate only_if_olc_zero    = Predicate.OLCZero;
449         Predicate only_if_olc_nonzero = Predicate.Default;
450
451         for(int olc : new int[] { 1, 0 }) {
452             for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
453                 prln("Attempting send token with "+
454                      "olc=="+olc+" and "+
455                      "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
456                 adjustIndent(2);
457                 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, 1));
458                 if (olc==0)
459                     marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC, SetDest.OuterLoopCounter, SetSource.Decrement));
460                 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, 1));
461                 marina.instrIn.fill(new Instruction.Move(DOCK,
462                                                          false,                 /* requeueing  */
463                                                          predicate_olc_nonzero  /* predicate   */
464                                                          ? only_if_olc_nonzero
465                                                          : only_if_olc_zero
466                                                          ,
467                                                          false,                 /* torpedoable */
468                                                          null,                  /* path        */
469                                                          false,                 /* tokenIn     */
470                                                          false,                 /* dataIn      */
471                                                          false,                 /* latchData   */
472                                                          false,                 /* latchPath   */
473                                                          false,                 /* dataOut     */
474                                                          true                   /* tokenOut    */
475                                                          ));
476                 toks = marina.tokOut.drainMany();
477                 int expected = (predicate_olc_nonzero == (olc!=0)) ? 1 : 0;
478                 fatal(toks.size()!=expected, "Expected "+expected+" token to emerge but got: "+toks.size()+" token(s)");
479                 adjustIndent(-2);
480             }
481         }
482         adjustIndent(-2);
483         prln("End testFlagZ");
484     }
485
486     private void testPredicationOnAB(Marina marina) {
487         prln("Begin testPredicationOnAB");
488         adjustIndent(2);
489         
490         List<BitVector> toks;
491
492         prln("Setting OLC=63");
493         marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, 63));
494
495         for(boolean flag_a : new boolean[] { false, true }) {
496             for(boolean flag_b : new boolean[] { false, true }) {
497                 prln("Setting flags, a="+flag_a+" b="+flag_b);
498                 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,
499                                                         flag_a
500                                                         ? Instruction.Set.FlagFunction.ONE
501                                                         : Instruction.Set.FlagFunction.ZERO,
502                                                         flag_b
503                                                         ? Instruction.Set.FlagFunction.ONE
504                                                         : Instruction.Set.FlagFunction.ZERO
505                                                         ));
506                 getCtrsFlags(marina);
507
508                 adjustIndent(2);
509                 for(Predicate predicate : new Predicate[] {
510                         Predicate.Default,
511                         Predicate.FlagA,
512                         Predicate.FlagB,
513                         Predicate.NotFlagA,
514                         Predicate.NotFlagB,
515                     }) {
516
517                     prln("Attempting send token with a="+flag_a+", b="+flag_b+", predicate="+predicate.getClass().getName());
518                     adjustIndent(2);
519                     marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, 1));
520                     marina.instrIn.fill(new Instruction.Move(DOCK,
521                                                              false,                 /* requeueing  */
522                                                              predicate,             /* predicate   */
523                                                              false,                 /* torpedoable */
524                                                              null,                  /* path        */
525                                                              false,                 /* tokenIn     */
526                                                              false,                 /* dataIn      */
527                                                              false,                 /* latchData   */
528                                                              false,                 /* latchPath   */
529                                                              false,                 /* dataOut     */
530                                                              true                   /* tokenOut    */
531                                                              ));
532                     adjustIndent(-2);
533                     toks = marina.tokOut.drainMany();
534                     int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
535                     fatal(toks.size()!=expected, "Expected "+expected+" token to emerge but got: "+
536                           toks.size()+" token(s)");
537                 }
538                 adjustIndent(-2);
539             }
540         }
541         adjustIndent(-2);
542         prln("End testPredicationOnAB");
543     }
544
545     private void getCtrsFlags(Marina marina) {
546         prln("begin getCtrsFlags");
547         adjustIndent(2);
548         
549         int olc = marina.getOLC();
550         prln("OLC=="+olc);
551         
552         prln("ILC.zero=="+marina.getIlcZero()+
553                  " ILC.count=="+marina.getIlcCount());
554         
555         boolean a = marina.getFlagA();
556         prln("flagA=="+a);
557         
558         boolean b = marina.getFlagB();
559         prln("flagB=="+b);
560         
561         boolean c = marina.getFlagC();
562         prln("flagC=="+c);
563         
564         adjustIndent(-2);
565         prln("end getCtrsFlags");
566     }
567     private void walkOneOLC(Marina marina) {
568         prln("Begin walkOneOLC");
569         adjustIndent(2);
570         for (int i=0; i<7; i++) {
571                 int inOlc = 0x20 >> i;
572                 prln("inOlc="+inOlc);
573                 marina.instrIn.fill(new 
574                         Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, inOlc));
575                 int outOlc = marina.getOLC();
576                 fatal(outOlc!=inOlc, "walkOneOLC: got="+outOlc+" expected="+inOlc);
577         }
578         adjustIndent(-2);
579         prln("End walkOneOLC");
580     }
581     private void walkOneILC(Marina marina) {
582         prln("Begin walkOneILC");
583         adjustIndent(2);
584         for (int i=0; i<7; i++) {
585                 // Mask off the "zero" bit position
586                 int inIlc = 0x20 >> i;
587                         prln("inIlc="+inIlc);
588
589                 marina.instrIn.fill(new 
590                         Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, inIlc));
591
592                 int outIlc = marina.getIlcCount();
593                 fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+outIlc);
594                 
595                 boolean inZero = inIlc==0;
596                 boolean outZero = marina.getIlcZero();
597                 fatal(outZero!=inZero, "bad ILC zero: "+outZero);
598         }
599         adjustIndent(-2);
600         prln("End walkOneILC");
601     }
602     private void countIlc(Marina marina) {
603         final int maxIlc = 63;
604         prln("Begin countIlc");
605         adjustIndent(2);
606         
607                 marina.instrIn.fill(new 
608                         Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, maxIlc));
609
610                 int ilc = marina.getIlcCount();
611                 fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
612                 
613                 // execute a move instruction that does nothing except decrement the ILC to zero
614         marina.instrIn.fill(
615             new Instruction.Move(DOCK,
616                                  false,                                 /* requeueing */
617                                  Predicate.IgnoreOLC,   /* predicate   */
618                                  false,                 /* torpedoable */
619                                  null,                  /* path        */
620                                  false,                 /* tokenIn     */
621                                  false,                 /* dataIn      */
622                                  false,                 /* latchData   */
623                                  false,                 /* latchPath   */
624                                  false,                 /* dataOut     */
625                                  false                  /* tokenOut    */
626                                  ));
627         
628                 // wait for ILC to count from 63 to 0
629         model.waitNS(64 * CYCLE_TIME_NS);
630
631                 ilc = marina.getIlcCount();
632                 fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
633         
634         adjustIndent(-2);
635         prln("End countIlc");
636     }
637     // Note: countOlc takes 44 minutes to run on nanosim
638     private void countOlc(Marina marina) {
639         final int maxOlc = 63;
640         prln("Begin countOlc");
641         adjustIndent(2);
642         
643                 marina.instrIn.fill(new 
644                         Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, maxOlc));
645                 for (int i=maxOlc; i>=0; i--) {
646                         prln("OLC should be: "+i);
647                         int olc = marina.getOLC();
648                         fatal(olc!=i, "bad OLC: "+olc+" expected: "+i);
649                         marina.instrIn.fill(new 
650                                 Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, SetSource.Decrement));
651                 }
652
653         adjustIndent(-2);
654         prln("End countOlc");
655     }
656
657     private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
658         prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
659         adjustIndent(2);
660         int i=0;
661         for(i=0; i<quantity; i++) {
662             prln("Inserting instruction " + (i+1) +"/"+ quantity);
663             marina.instrIn.fill(instruction);
664             boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
665             if (jammed && expect_it_to_jam_up) {
666                 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
667                 adjustIndent(-2);
668                 return;
669             }
670             fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
671         }
672         fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
673         adjustIndent(-2);
674         prln("Successfully inserted " + i + " instructions");
675     }
676
677     private static final Instruction REQUEUEING_NOP =
678         new Instruction.Move(DOCK,
679                              true,                  /* requeueing  */
680                              Predicate.IgnoreOLC,   /* predicate   */
681                              false,                 /* torpedoable */
682                              null,                  /* path        */
683                              false,                 /* tokenIn     */
684                              false,                 /* dataIn      */
685                              false,                 /* latchData   */
686                              false,                 /* latchPath   */
687                              false,                 /* dataOut     */
688                              false                  /* tokenOut    */
689                              );
690
691     private void testRequeueStage0(Marina marina) {
692         prln("Begin testRequeueStage0");
693         adjustIndent(2);
694
695         prln("Executing Set OLC=1");
696         marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter,1));
697         prln("Executing Set OLC--");
698         marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter,SetSource.Decrement));
699         saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_SATURATION_AMOUNT, false);
700         adjustIndent(-2);
701         prln("End testRequeueStage0");
702     }
703
704     private void testRequeueStage0to1(Marina marina) {
705         prln("Begin testRequeueStage0to1");
706         adjustIndent(2);
707
708         prln("Executing Set OLC=63");
709         marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter,63));
710         saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_SATURATION_AMOUNT, true);
711         adjustIndent(-2);
712         prln("End testRequeueStage0to1");
713     }
714
715     private void testFlagAB(Marina marina) {
716         prln("Begin testFlagAB");
717         adjustIndent(2);
718
719         Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
720         Instruction.Set.FlagFunction one  = zero;
721
722         
723         // we should be able to use any pair of FlagX+NotFlagX,
724         // but we toss them all in to maximize the chances of the
725         // test passing (later we will try the individual
726         // combinations to maximize the chances of failure).
727         one = one.add(Predicate.FlagA);
728         one = one.add(Predicate.NotFlagA);
729         one = one.add(Predicate.FlagB);
730         one = one.add(Predicate.NotFlagB);
731         one = one.add(Predicate.FlagC);
732         one = one.add(Predicate.NotFlagC);
733
734         // clear the flags to a known state, then check both 0->1 and 1->0 transitions
735         for(boolean b : new boolean[] { false, true, false }) {
736             prln((b?"Setting":"Clearing")+" flags");
737
738             marina.instrIn.fill(new 
739                                 Instruction.Set(DOCK,false,Predicate.IgnoreOLC,
740                                                 b ? one : zero,
741                                                 b ? one : zero
742                                                 ));
743             fatal(marina.getFlagA()!=b, "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
744             fatal(marina.getFlagB()!=b, "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
745         }
746
747         adjustIndent(-2);
748         prln("End testFlagAB");         
749     }
750     private void sendTorpedo(Marina marina) {
751         prln("Begin sendTorpedo");
752         adjustIndent(2);
753         
754         prln("OLC = 63");
755                 marina.instrIn.fill(new 
756                 Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, 63));
757
758                 int olc = marina.getOLC();
759                 fatal(olc!=63, "bad OLC: "+olc+" expected: 63");
760
761                 prln("A=0, B=0");
762                 marina.instrIn.fill(new 
763             Instruction.Set(DOCK,false,Predicate.IgnoreOLC, CLEAR_FLAG, CLEAR_FLAG));
764
765                 fatal(marina.getFlagA(), "bad A flag: true");
766                 fatal(marina.getFlagB(), "bad B flag: true");
767                 
768                 prln("ILC = Infinity");
769                 marina.instrIn.fill(new 
770                 Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.InnerLoopCounter, SetSource.Infinity));
771                 
772                 prln("execute a move instruction that does nothing but loops until torpedo arrives"); 
773         marina.instrIn.fill(
774             new Instruction.Move(DOCK,
775                                      false,                             /* requeueing */
776                                  Predicate.IgnoreOLC,   /* predicate   */
777                                  true,                 /* torpedoable */
778                                  null,                  /* path        */
779                                  false,                 /* tokenIn     */
780                                  false,                 /* dataIn      */
781                                  false,                 /* latchData   */
782                                  false,                 /* latchPath   */
783                                  false,                 /* dataOut     */
784                                  false                  /* tokenOut    */
785                                  ));
786         
787                 prln("NOP This instruction can't predicate on OLC because of a hardware bug");
788                 marina.instrIn.fill(new 
789             Instruction.Set(DOCK,false,Predicate.Default, A_FLAG, B_FLAG));
790
791                 prln("A=1, B=1 This instruction should get torpedoed along with the Move");
792                 marina.instrIn.fill(new 
793                 Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG));
794
795                 prln("send torpedo. This should clear the OLC");
796                 marina.instrIn.fill(InstructionStopper.TORPEDO);
797                 
798                 getCtrsFlags(marina);
799                 
800                 prln("A and B should remain false");
801                 fatal(marina.getFlagA(), "bad A flag: true");
802                 fatal(marina.getFlagB(), "bad B flag: true");
803         
804         prln("OLC = 63. Reload OLC after torpedo");
805                 marina.instrIn.fill(new 
806                 Instruction.Set(DOCK,false,Predicate.IgnoreOLC,SetDest.OuterLoopCounter, 63));
807
808                 olc = marina.getOLC();
809                 fatal(olc!=63, "bad OLC: "+olc+" expected: 63");
810                 
811                 prln("A=1, B=1 This instruction should execute because OLC!=0");
812                 marina.instrIn.fill(new 
813                         Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG));
814
815                 prln("A and B should be true");
816                 fatal(!marina.getFlagA(), "bad A flag: false");
817                 fatal(!marina.getFlagB(), "bad B flag: false");
818                 
819                 adjustIndent(-2);
820         prln("End sendTorpedo");        
821     }    
822         private void doOneTest(int testNum) {
823         prln("MarinaTest: performing test: "+testNum);
824         marina.masterClear(tester);
825         
826         marina.enableInstructionSend(true);
827         
828                 switch (testNum) {
829                 case 2:                 sendInstructions(marina);               break;
830                 case 3:                 sendToken(marina);                              break;
831                 case 4:                 getCtrsFlags(marina);                   break;
832                 case 5:                 walkOneOLC(marina);                             break;
833                 
834                 // Russell's tests begin with 1000
835                 case 1000:              walkOneILC(marina);                     break;
836                 case 1001:              countIlc(marina);                               break;
837                 case 1002:              countOlc(marina);                               break;
838                 case 1003:              sendTorpedo(marina);                    break;
839                 
840                 // Bill's tests begin with 2000
841                 case 2000: break;
842                     
843                 // Adam's tests begin with 3000
844                 case 3000: sendToken(marina); break;
845                 case 3001: testFlagAB(marina); break;
846                 case 3002: testRequeueStage0(marina); break;
847                 case 3003: testRequeueStage0to1(marina); break;
848                 case 3004: testFlagZ(marina); break;
849                 case 3005: testPredicationOnAB(marina); break;
850                 case 3006: sendData(marina); break;
851
852                 default:
853                         fatal(true, "Test number: "+testNum+" doesn't exist.");
854                         break;
855                 }
856                 // If we get here then test passed
857                 prln("Passed");
858         }
859
860
861     //============================ for public use =============================
862
863         
864     public static void main(String[] args) {
865         startTime = System.currentTimeMillis();
866                 new MarinaTest(args);
867                 printTestTime();
868     }
869
870 }