remember to re-set ILC in MarinaTest.loadEveryValueOLC()
[fleet.git] / src / 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.ChainG;
9 import com.sun.async.test.ChainTest;
10 import com.sun.async.test.ChipModel;
11 import com.sun.async.test.HP34401A;
12 import com.sun.async.test.Infrastructure;
13 import com.sun.async.test.JtagSubchainTesterModel;
14 import com.sun.async.test.JtagTester;
15 import com.sun.async.test.ManualPowerChannel;
16 import com.sun.async.test.NanosimModel;
17 import com.sun.async.test.HsimModel;
18 import com.sun.async.test.VerilogModel;
19 import com.sun.async.test.Netscan4;
20 import com.sun.async.test.PowerChannel;
21 import com.sun.async.test.Pst3202Channel;
22 import com.sun.async.test.SiliconChip;
23 import com.sun.async.test.SimulationModel;
24 import com.sun.async.test.VoltageReadable;
25 import com.sun.vlsi.chips.marina.test.Marina.Ilc;
26 import com.sun.vlsi.chips.marina.test.CmdArgs;
27 import com.sun.vlsi.chips.marina.test.CmdArgs.Mode;
28
29 import edu.berkeley.fleet.api.Dock;
30 import edu.berkeley.fleet.api.Instruction;
31 import edu.berkeley.fleet.api.Predicate;
32 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
33 import edu.berkeley.fleet.api.Instruction.Set.SetSource;
34 import edu.berkeley.fleet.marina.MarinaFleet;
35 import edu.berkeley.fleet.marina.MarinaPath;
36
37 /**
38  * Tests for Marina
39  */
40 public class MarinaTest {
41     public static final MarinaFleet marinaFleet = new MarinaFleet();
42     public static final Dock dock = marinaFleet.getOnlyInputDock();
43
44     //--------------------------  constants -----------------------------------
45     private static final String SCAN_CHAIN_XML = "marina.xml";
46     private static final String NET_LIST = "marina.spi";
47
48     public static final int INSTR_SZ = 36;
49
50        
51     public static final Instruction.Set.FlagFunction CLEAR_FLAG 
52         = Instruction.Set.FlagFunction.ZERO;
53     public static final Instruction.Set.FlagFunction SET_FLAG 
54         = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA)
55         .add(Predicate.NotFlagA);
56     public static final Instruction.Set.FlagFunction A_FLAG 
57         = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA);
58
59     public static final Instruction.Set.FlagFunction B_FLAG 
60         = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB);
61     
62     // COLUMN_LATENCY is a delay that is larger than the latency through an Infinity column
63     private static final int COLUMN_LATENCY = 10; // nanoseconds
64
65
66     // Officially, this should be the number of requeueing no-ops that
67     // can be inserted into an idle dock whose OLC is nonzero.
68     //
69     // Less formally, this is roughly the number of stages of
70     // buffering between the instruction insertion point and the
71     // instruction ring, plus the capacity of the instruction ring.
72     private static final int INSTRUCTION_IN_SATURATION_AMOUNT = 19;
73
74     // This is some number which is significantly greater than
75     // INSTRUCTION_IN_SATURATION_AMOUNT.  Increasing it may slow the tests down, but
76     // will never cause them to operate incorrectly.
77     private static final int MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT = 25;
78         
79     // This is the number of items which can be in the instruction
80     // fifo ring WITHOUT causing it to stop circulating.
81     private static final int INSTRUCTION_RING_CAPACITY = 13;
82         
83     // Officially, this should be the number of data items which can
84     // be sent from the dock while the "data" proper stopper is in
85     // the "stopped" state
86     //
87     // Less formally, this is roughly the number of stages of
88     // buffering between the dock's data successor and the "data"
89     // proper stopper
90     /*
91       FIXME: what is the correct value here?
92       private static final int DATA_OUT_SATURATION_AMOUNT = XXX;
93     */
94
95     // This is some number which is greater than
96     // DATA_OUT_SATURATION_AMOUNT, but less than the capacity of the
97     // instruction fifo.
98     private static final int MORE_THAN_DATA_OUT_SATURATION_AMOUNT = 10;
99         
100     // Nominal cycle time assuming 4 GHz throughput
101     public static double CYCLE_TIME_NS;
102
103     //--------------------------------  types ---------------------------------
104
105     //--------------------------  private data --------------------------------
106     private static long startTime;
107
108     public static Indenter indenter = new Indenter();
109     private Marina marina;
110     private ChipModel model;
111     //private ChainControl cc;
112     //private JtagTester tester;
113     private CmdArgs cmdArgs;
114     private PowerChannel corePowerSupply, padsPowerSupply;
115     private VoltageReadable coreVoltmeter, voltmeterForCurrent;
116
117     private ChainTest ctD, ctR, ctC, ct;
118     private ChainControl ccD, ccR, ccC, cc;
119         
120     //--------------------------  private methods -----------------------------
121     /** @return true if simulation. Return false if we're testing silicon. */
122     private boolean sim() {return model instanceof SimulationModel;}
123         
124     private void prln(String msg) {indenter.prln(msg);}
125     private void pr(String msg) {indenter.pr(msg);}
126     private void adjustIndent(int n) {indenter.adjustIndent(n);}
127         
128     public static void fatal(boolean pred, String msg) { MarinaUtils.fatal(pred, msg); }
129
130     public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
131         // FIXME: better error reporting needed here
132
133         fatal(bv1.getNumBits()!=bv2.getNumBits(), "lengths do not match");
134
135         boolean mismatch = false;
136         String err = "";
137         for(int i=0; i<bv1.getNumBits(); i++) {
138             if (bv1.get(i) != bv2.get(i)) {
139                 mismatch = true;
140                 err += ""+i+", ";
141             }
142         }
143         fatal(mismatch, "bit vectors do not match on bits " + err + "\n  "+bv1+"\n  "+bv2);
144     }
145
146     private static void printTestTime() {
147         long endTime = System.currentTimeMillis();
148         System.out.println("Test took: "+(endTime-startTime)/1000.0+"  sec");
149     }
150     
151     // Tell user what we're about to do
152     private static void reportTask(CmdArgs args) {
153         System.out.println("Begin testing Marina");
154         switch (args.mode) {
155             case WHOLE_CHIP_SCHEMATIC_PARASITICS:
156                 System.out.println("  Simulate whole chip, schematic parasitics");
157                 break;
158             case WHOLE_CHIP_LAYOUT_PARASITICS:
159                 System.out.println("  Simulate whole chip, layout parasitics");
160                 break;
161             case TEST_SILICON:
162                 System.out.println("  Test silicon");
163                 break;
164             default:
165                 fatal(true, "unrecognized CmdArgs.Mode");
166                 return;
167         }
168     }
169     private void setUpSuppliesAndMeters(Station station) {
170         // set up power supplies and meters
171         if (!sim()) {
172             prln("Testing station: "+station);
173             Infrastructure.gpibControllers = new int[] {0};
174             switch (cmdArgs.station) {
175                 case ONE:
176                     corePowerSupply = new Pst3202Channel("ch1", "HPST3202", 1);
177                     padsPowerSupply = new Pst3202Channel("ch2", "HPST3202", 2);
178                     break;
179                 case TWO:
180                     corePowerSupply = new Pst3202Channel("ch1", "HPST3202B", 1);
181                     padsPowerSupply = new Pst3202Channel("ch2", "HPST3202B", 2);
182                     break;
183                 default:
184                     fatal(true, "Unrecognized station: "+cmdArgs.station);
185             }
186             corePowerSupply.setCurrent((float)1.7);
187             corePowerSupply.setVoltageWait((float)1.0);
188                   
189             padsPowerSupply.setCurrent((float)0.100);
190             padsPowerSupply.setVoltageWait((float)1.8);
191                   
192             coreVoltmeter = new HP34401A(station.coreVoltmeter);
193             voltmeterForCurrent = new HP34401A(station.currentVoltmenter);
194         }
195     }
196         
197     private MarinaTest(String[] args) {
198         cmdArgs = new CmdArgs(args);
199         reportTask(cmdArgs);
200         if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim();
201     }
202         
203     private void doSim() {
204         String netListName;
205         switch (cmdArgs.mode) {
206             case WHOLE_CHIP_SCHEMATIC_PARASITICS:
207                 netListName = NET_LIST; 
208                 break;
209             case WHOLE_CHIP_LAYOUT_PARASITICS:
210                 netListName = "marina_pads_guts.spi"; 
211                 break;
212             default:
213                 fatal(true, "unrecognized CmdArgs.Mode");
214                 return;
215         }
216         model = cmdArgs.useVerilog
217             ? new VerilogModel()
218             : cmdArgs.useHsim
219             ? new HsimModel()
220             : new NanosimModel();
221             
222         ((SimulationModel)model).setOptimizedDirectReadsWrites(true);
223
224         CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250;
225         int khz   = model instanceof VerilogModel ? 100000 : cmdArgs.jtagShift ? 20000 : 1000000;
226
227         prln("constructing jtag controller");
228         JtagTester tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
229         tester.printInfo = false;
230
231         ChainControls ccs = new ChainControls();
232         PowerChannel pc = new ManualPowerChannel("pc", false);
233         /*
234         JtagTester testerD, testerR, testerC;
235         testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null); 
236         testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null); 
237         testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null); 
238         testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
239
240         ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
241         ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
242         ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
243         ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
244
245         
246         ctD = new ChainTest(ccD, pc);
247         ctR = new ChainTest(ccR, pc);
248         ctC = new ChainTest(ccC, pc);
249         */        
250         /*
251         ccs.addChain(Marina.DATA_CHAIN, ccD);
252         ccs.addChain(Marina.REPORT_CHAIN, ccR);
253         ccs.addChain(Marina.CONTROL_CHAIN, ccC);
254         */
255
256         cc = new ChainControl(SCAN_CHAIN_XML, tester, 1.8f, khz);
257         cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
258         ct = new ChainTest(cc, pc);
259         ccs.addChain(Marina.DATA_CHAIN, cc);
260         ccs.addChain(Marina.REPORT_CHAIN, cc);
261         ccs.addChain(Marina.CONTROL_CHAIN, cc);
262
263         marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter);
264
265         if (model instanceof VerilogModel)
266             ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift);
267         else if (model instanceof HsimModel)
268             ((SimulationModel)model).start("hsim64", netListName, 0, !cmdArgs.jtagShift);
269         else
270             ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
271
272         /*
273         ccC.resetInBits();
274         ccC.shift(Marina.CONTROL_CHAIN, false, true);
275         */
276
277         cc.resetInBits();
278         cc.shift(Marina.CONTROL_CHAIN, false, true);
279         
280         doOneTest(cmdArgs.testNum);
281         
282         ((SimulationModel)model).finish();
283     }
284     private void doSilicon() {
285         model = new SiliconChip();
286         String ip = cmdArgs.station.ipAddr;
287         JtagTester tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
288         tester.printInfo = false;
289         int khz = 1000;
290         ChainControl cc = new ChainControl("???", tester, 1.8f, khz);
291         cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
292         ChainControls ccs = new ChainControls();
293         ccs.addChain(Marina.DATA_CHAIN, cc);
294         ccs.addChain(Marina.REPORT_CHAIN, cc);
295         ccs.addChain(Marina.CONTROL_CHAIN, cc);
296         marina = new Marina(ccs, model, false, indenter);
297         PowerChannel pc = new ManualPowerChannel("pc", false);
298         ChainTest ct = new ChainTest(cc, pc);
299         ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
300         doOneTest(cmdArgs.testNum);
301         setUpSuppliesAndMeters(cmdArgs.station);
302     }
303
304     /** In the absence of looping, the longest path through Infinity is 4 column delays */
305     private void waitUntilQuiescent() {
306         model.waitNS(4*COLUMN_LATENCY);
307     }
308     
309     private double readCurrent() {
310         return voltmeterForCurrent.readVoltage() / cmdArgs.station.ammeterShuntResistance;
311     }
312     
313     /** Generate List of BitVectors where Token=true, high 25 data bits  
314      * are alternating ones and zeros, low 12 data bits increment from 
315      * zero, and address is given by addr. */
316     private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
317         List<BitVector> ans = new ArrayList<BitVector>();
318         BitVector dHi = new BitVector(25, "dataHi");
319         BitVector dLo = new BitVector(12, "dataLo");
320         BitVector t = new BitVector("1", "token");
321         BitVector a = new BitVector(14, "addr");
322         dHi.setFromLong(0x00aaaaa);
323         a.setFromLong(addr);
324         for (int i=0; i<num; i++) {
325             dLo.setFromLong(i);
326             ans.add(dHi.cat(dLo).cat(t).cat(a));
327             dHi = dHi.not();
328         }
329         return ans;
330     }
331     private void stopToStop(ProperStopper s1, ProperStopper s2, 
332                             Counter ctr,
333                             List<BitVector> din) {
334         prln("Begin stopToStop");
335         adjustIndent(2);
336         
337         s1.stop();
338         
339         long ctrStart = ctr==null ? 0 : ctr.getCount();
340         
341         s1.fillMany(din);
342         waitUntilQuiescent();
343         
344         List<BitVector> dout = s2.drainMany();
345         
346         MarinaUtils.compareItemsOrdered(din, dout);
347         
348         if (ctr!=null) {
349             long ctrEnd = ctr.getCount();
350             long delta = ctrEnd - ctrStart;
351             long expect = din.size();
352             fatal(delta!=expect, 
353                   "counter delta wrong: expected delta: "+expect+
354                   " counter before:"+ctrStart+" counter after:"+ctrEnd);
355         }
356         
357         adjustIndent(-2);
358         prln("End stopToStop");
359     }
360     /** Burst data from src to dst. gate is stopped while loading src. gate
361      * is then run to allow the burst to flow. */
362     private void stopToStopBurst(ProperStopper src, ProperStopper gate, 
363                                  ProperStopper dst,
364                                  Counter ctr,
365                                  List<BitVector> din) {
366         prln("Begin stopToStopBurst test");
367         adjustIndent(2);
368                 
369         src.stop();
370         gate.stop();
371                 
372         long ctrStart = ctr==null ? 0 : ctr.getCount();
373                 
374         src.fillMany(din);
375         waitUntilQuiescent();
376
377         // open the gate to start the burst
378         gate.run();
379         waitUntilQuiescent();
380                 
381         List<BitVector> dout = dst.drainMany();
382                 
383         MarinaUtils.compareItemsOrdered(din, dout);
384                 
385         if (ctr!=null) {
386             long ctrEnd = ctr.getCount();
387             long delta = ctrEnd - ctrStart;
388                 
389             long expectA = din.size();
390             fatal(delta!=expectA, 
391                   "counter delta wrong: expected delta: "+expectA+
392                   " counter before:"+ctrStart+" counter after:"+ctrEnd);
393         }
394                 
395         adjustIndent(-2);
396         prln("End stopToStopBurst test");
397     }
398
399     private void stopToStopOne(ProperStopper s1, ProperStopper s2, 
400                                Counter ctr, int adr) {
401         prln("Begin stopToStopOne");
402         adjustIndent(2);
403         
404         List<BitVector> din = makeIncrDataConstAdr(1, adr);
405         stopToStop(s1, s2, ctr, din);
406
407         adjustIndent(-2);
408         prln("End stopToStopOne");
409     }
410     
411     private void stopToStopThree(ProperStopper s1, ProperStopper s2, 
412                                  Counter ctr, int adr) {
413         prln("Begin stopToStopOne");
414         adjustIndent(2);
415         
416         List<BitVector> din = makeIncrDataConstAdr(3, adr);
417         stopToStop(s1, s2, ctr, din);
418
419         adjustIndent(-2);
420         prln("End stopToStopOne");
421     }
422
423     private int indexOf(BitVector o, List<BitVector> dIn) {
424         for (int i=0; i<dIn.size(); i++) {
425             if (o.equals(dIn.get(i)))  return i;
426         }
427         return -1;
428     }
429     private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
430         StringBuffer sb = new StringBuffer();
431         sb.append("  ring dump: ");
432         for (BitVector o : dOut) {
433             sb.append(indexOf(o, dIn)+" ");
434         }
435         return sb.toString();
436     }
437
438     private int[][] makeIntArray2D(int a, int b) {
439         int[][] ans = new int[a][];
440         for (int i=0; i<a; i++) ans[i] = new int[b];
441         return ans;
442     }
443
444     //=========================================================================
445     // Put top level tests here
446
447     private void testChains(Marina marina) {
448         if (ctC!=null) {
449             prln("Testing control chain...");
450             ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
451             ccC.resetInBits();
452             ccC.shift(Marina.CONTROL_CHAIN, false, true);
453         }
454         
455         if (ctD!=null) {
456             prln("Testing data chain...");
457             ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
458             //ccD.resetInBits();
459             //ccD.shift(Marina.DATA_CHAIN, false, true);
460         }
461         
462         if (ctR!=null) {
463             prln("Testing report chain...");            
464             ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
465             //ccR.resetInBits();
466             //ccR.shift(Marina.REPORT_CHAIN, false, true);
467         }
468
469         if (ct!=null) {
470             prln("Testing control chain...");
471             ct.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
472             cc.resetInBits();
473             cc.shift(Marina.CONTROL_CHAIN, false, true);
474             prln("Testing data chain...");
475             ct.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
476             prln("Testing report chain...");            
477             ct.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
478         }
479     }
480
481     private void testProperStoppers(Marina marina) {
482         prln("Begin testProperStoppers");
483         adjustIndent(2);
484
485         for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) {
486
487             prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper");
488             adjustIndent(2);
489
490             prln("un-stopping stopper");
491             ps.run();
492             fatal( ps.getStopped(), "stopper should not have been stopped, but was");
493
494             prln("stopping stopper");
495             ps.stop();
496             fatal( !ps.getStopped(), "stopper should have been stopped, but was not");
497
498             adjustIndent(-2);
499         }
500
501         adjustIndent(-2);
502     }
503
504     private void sendInstructions(Marina marina) {
505         prln("Begin sendInstructions");
506         adjustIndent(2);
507         
508         List<BitVector> din = new ArrayList<BitVector>();
509
510         BitVector count = new BitVector(MarinaPacket.WORD_WIDTH,"count");
511         BitVector one = new BitVector(MarinaPacket.WORD_WIDTH, "one");
512         count.setFromLong(0);
513         one.setFromLong(1);
514         for (int i=0; i<3; i++) {
515             din.add(count);
516             count = count.add(one);
517         }
518
519         for(BitVector d : din)
520             marina.instrIn.fill(new MarinaPacket(d, false, MarinaPacket.null_path));
521
522         adjustIndent(-2);
523         prln("End sendInstructions");
524     }
525
526     private void sendToken(Marina marina) {
527         prln("Begin sendToken");
528         adjustIndent(2);
529         
530         //getCtrsFlags(marina);
531         
532         int nbToks = marina.getNumTokens();
533         fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens");
534
535         marina.instrIn.fill(setIlc(1));
536         marina.instrIn.fill(SEND_TOKEN);
537         nbToks = marina.getNumTokens();
538         fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
539         
540         adjustIndent(-2);
541         prln("End sendToken");
542     }
543
544     private void sendData(Marina marina) {
545         prln("Begin sendData");
546         adjustIndent(2);
547         
548         edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
549         for(int i=0; i<bv.length(); i+=2) bv.set(i, false);
550         MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
551
552         marina.instrIn.fill(setIlc(1));
553         marina.instrIn.fill(SEND_DATA);
554         
555         List<BitVector> dataItems = marina.data.drainMany();
556         fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
557
558         MarinaPacket mp = new MarinaPacket(dataItems.get(0));
559         fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token");
560
561         adjustIndent(-2);
562         prln("End sendData");
563     }
564
565     private void sendDataIlcInfinite(Marina marina) {
566         prln("Begin sendDataIlcInfinite");
567         adjustIndent(2);
568         
569         marina.fillSouthProperStopper(new Instruction[] {
570                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
571                 SEND_DATA,
572             });
573         
574         // more than MAX_ILC
575         int howmany = 70;
576         List<BitVector> dataItems = marina.data.drainMany(howmany);
577         fatal(dataItems.size()!=howmany,
578               "Expected an unending supply of data items to emerge but only got got: "+dataItems.size());
579
580         adjustIndent(-2);
581         prln("End sendDataIlcInfinite");
582     }
583
584     private Instruction setOlc(int olc) {
585         return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc);
586     }
587     private Instruction setOlcIfZero(int olc) {
588         return new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, olc);
589     }
590     private Instruction setIlc(int ilc) {
591         return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, ilc);
592     }
593
594     private void testFlagD(Marina marina) {
595         prln("Begin testFlagD");
596         adjustIndent(2);
597         
598         List<BitVector> toks;
599
600         Predicate only_if_olc_zero    = Predicate.FlagD;
601         Predicate only_if_olc_nonzero = Predicate.Default;
602
603         marina.instrIn.fill(setIlc(1));
604
605         for(int olc : new int[] { 1, 0 }) {
606             for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
607                 prln("Attempting send data item with "+
608                      "olc=="+olc+" and "+
609                      "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
610                 adjustIndent(2);
611
612                 marina.fillSouthProperStopper(new Instruction[] {
613                         setOlc(olc),
614                         new Instruction.Move(dock,
615                                              predicate_olc_nonzero  // predicate   
616                                              ? only_if_olc_nonzero
617                                              : only_if_olc_zero
618                                              ,
619                                              false,                 // torpedoable 
620                                              null,                  // path        
621                                              false,                 // tokenIn     
622                                              false,                 // dataIn      
623                                              false,                 // latchData   
624                                              false,                 // latchPath   
625                                              true,                  // dataOut     
626                                              false                  // tokenOut    
627                                              ),
628                     });
629                 expectNorthFifoExactly((predicate_olc_nonzero == (olc!=0)) ? 1 : 0);
630
631                 for(int i=0; i<olc; i++)
632                     marina.instrIn.fill(DEC);
633
634                 adjustIndent(-2);
635             }
636         }
637         adjustIndent(-2);
638         prln("End testFlagD");
639     }
640
641     private void testPredicationOnAB(Marina marina) {
642         prln("Begin testPredicationOnAB");
643         adjustIndent(2);
644         
645         List<BitVector> dItems;
646
647         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
648         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
649
650         for(boolean flag_a : new boolean[] { false, true }) {
651             for(boolean flag_b : new boolean[] { false, true }) {
652                 prln("Setting flags, a="+flag_a+" b="+flag_b);
653                 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
654                                                         flag_a
655                                                         ? Instruction.Set.FlagFunction.ONE
656                                                         : Instruction.Set.FlagFunction.ZERO,
657                                                         flag_b
658                                                         ? Instruction.Set.FlagFunction.ONE
659                                                         : Instruction.Set.FlagFunction.ZERO
660                                                         ));
661                 getCtrsFlags(marina);
662
663                 adjustIndent(2);
664                 for(Predicate predicate : new Predicate[] {
665                         Predicate.Default,
666                         Predicate.FlagA,
667                         Predicate.FlagB,
668                         Predicate.NotFlagA,
669                         Predicate.NotFlagB,
670                     }) {
671
672                     prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate);
673                     adjustIndent(2);
674                     marina.instrIn.fill(new Instruction.Move(dock,
675                                                              predicate,  // predicate   
676                                                              false,      // torpedoable 
677                                                              null,       // path        
678                                                              false,      // tokenIn     
679                                                              false,      // dataIn      
680                                                              false,      // latchData   
681                                                              false,      // latchPath   
682                                                              true,       // dataOut     
683                                                              false       // tokenOut    
684                                                              ));
685                     adjustIndent(-2);
686                     dItems = marina.data.drainMany();
687                     int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
688                     fatal(dItems.size()!=expected, "Expected "+expected+" data items to emerge but got: "+
689                           dItems.size()+" items(s)");
690                 }
691                 adjustIndent(-2);
692             }
693         }
694         adjustIndent(-2);
695         prln("End testPredicationOnAB");
696     }
697
698
699     private void showOlc() {
700         prln("OLC=="+marina.getOLC());
701     }
702     private void expectOlc(int x) {
703         int olc = marina.getOLC();
704         fatal(x!=olc, "expected OLC=="+x+", but scanned out OLC=="+olc);
705     }
706
707     private void getCtrsFlags(Marina marina) {
708         prln("begin getCtrsFlags");
709         adjustIndent(2);
710         
711         showOlc();
712         Ilc ilc = marina.getILC();
713         prln("ILC.done=="+ilc.getDone()+
714              " ILC.infinity=="+ilc.getInfinity()+
715              " ILC.count=="+ilc.getCount());
716         prln("flagA=="+marina.getFlagA());
717         prln("flagB=="+marina.getFlagB());
718         adjustIndent(-2);
719         prln("end getCtrsFlags");
720     }
721
722     private void walkOneOLC(Marina marina) {
723         prln("Begin walkOneOLC");
724         adjustIndent(2);
725         for (int i=0; i<6; i++) {
726
727             if (marina.kesselsCounter) {
728                 System.out.println("master-clearing...");
729                 // master clear on each iteration; otherwise we'd need to "run down" the olc
730                 marina.masterClear();
731                 marina.enableInstructionSend(true);
732             }
733
734             int inOlc = i==-1 ? 0 : (1<<i);
735             marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
736
737             model.waitNS(128 * CYCLE_TIME_NS);
738
739             expectOlc(inOlc);
740             prln("walkOneOLC: "+inOlc+" checks out");
741         }
742         adjustIndent(-2);
743         prln("End walkOneOLC");
744     }
745     private void walkOneILC(Marina marina) {
746         prln("Begin walkOneILC");
747         adjustIndent(2);
748         for (int i=0; i<6; i++) {
749             // Mask off the "zero" bit position
750             int inIlc = 1 << i;
751             prln("inIlc="+inIlc);
752             marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
753             Ilc ilc = marina.getILC();
754             int outIlc = ilc.getCount();
755             fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc);
756             fatal(ilc.getInfinity(), "bad Infinity bit: true");
757         }
758         prln("Now test the infinity bit");
759         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
760         Ilc ilc = marina.getILC();
761         fatal(!ilc.getInfinity(), "bad Infinity bit: false");
762         adjustIndent(-2);
763         prln("End walkOneILC");
764     }
765     private void countIlc(Marina marina) {
766         final int maxIlc = 63;
767         prln("Begin countIlc");
768         adjustIndent(2);
769         
770         marina.instrIn.fill(new 
771                             Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
772
773         int ilc = marina.getILC().getCount();
774         fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
775                 
776         prln("execute a move instruction that does nothing except decrement the ILC to zero");
777         marina.instrIn.fill(
778                             new Instruction.Move(dock,
779                                                  Predicate.IgnoreFlagD, // predicate   
780                                                  false,                 // torpedoable 
781                                                  null,                  // path        
782                                                  false,                 // tokenIn     
783                                                  false,                 // dataIn      
784                                                  false,                 // latchData   
785                                                  false,                 // latchPath   
786                                                  false,                 // dataOut     
787                                                  false                  // tokenOut    
788                                                  ));
789         
790         // wait for ILC to count from 63 to 0
791         model.waitNS(128 * CYCLE_TIME_NS);
792         //model.waitNS(10000);
793
794         prln("Check that ILC==0");
795         ilc = marina.getILC().getCount();
796         fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
797         
798         adjustIndent(-2);
799         prln("End countIlc");
800     }
801     // Note: countOlc takes 44 minutes to run on nanosim
802     private void countOlc(Marina marina) {
803         int maxOlc = 63;
804         prln("Begin countOlc");
805         adjustIndent(2);
806
807         marina.instrIn.fill(setOlc(maxOlc));
808
809         for (int i=maxOlc; i>=0; i--) {
810             model.waitNS(128 * CYCLE_TIME_NS);
811             prln("OLC should be: "+i);
812             expectOlc(i);
813             marina.instrIn.fill(new 
814                                 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
815         }
816
817         adjustIndent(-2);
818         prln("End countOlc");
819     }
820     private void loadEveryValueOLC(Marina marina) {
821         adjustIndent(2);
822         for (int i=0; i<(1<<6); i++) {
823
824             if (marina.kesselsCounter) {
825                 System.out.println("master-clearing...");
826                 // master clear on each iteration; otherwise we'd need to "run down" the olc
827                 marina.masterClear();
828                 marina.enableInstructionSend(true);
829             }
830
831             int inOlc = i;
832             marina.fillSouthProperStopper(new Instruction[] {
833
834                     setIlc(1),
835
836                     // to ensure that instruction is bubble-limited
837                     RECV_DATA,
838
839                     // the Set-OLC instruction
840                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc),
841
842                     // put a Set-ILC instruction right behind it with inverted bits to be sure we're
843                     // not capturing the instruction-latch value too late in the cycle
844                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, (inOlc ^ (~(-1<<6)))),
845                     
846                 });
847
848             model.waitNS(128 * CYCLE_TIME_NS);
849             marina.fillNorthProperStopper();
850             model.waitNS(128 * CYCLE_TIME_NS);
851
852             expectOlc(inOlc);
853             prln("loadEveryValueOLC: "+inOlc+" checks out");
854         }
855         adjustIndent(-2);
856     }
857
858     private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
859         prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
860         adjustIndent(2);
861         int i=0;
862         for(i=0; i<quantity; i++) {
863             prln("Inserting instruction " + (i+1) +"/"+ quantity);
864             marina.instrIn.fill(instruction);
865             boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
866             if (jammed && expect_it_to_jam_up) {
867                 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
868                 adjustIndent(-2);
869                 return;
870             }
871             fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
872         }
873         fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
874         adjustIndent(-2);
875         prln("Successfully inserted " + i + " instructions");
876     }
877
878     private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(),
879                                                          MarinaUtils.sunToBerk(MarinaPacket.null_path));
880
881     private static final Instruction DEC = 
882         new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, SetSource.Decrement);
883
884     private static final Instruction FLAG_NOP =
885         new Instruction.Set(dock, Predicate.IgnoreFlagD,
886                             CLEAR_FLAG.add(Predicate.FlagA),
887                             CLEAR_FLAG.add(Predicate.FlagB));
888
889     private static final Instruction NOP =
890         new Instruction.Move(dock,
891                              Predicate.IgnoreFlagD,   /* predicate   */
892                              false,                 /* torpedoable */
893                              null,                  /* path        */
894                              false,                 /* tokenIn     */
895                              false,                 /* dataIn      */
896                              false,                 /* latchData   */
897                              false,                 /* latchPath   */
898                              false,                 /* dataOut     */
899                              false                  /* tokenOut    */
900                              );
901
902     private static final Instruction SEND_DATA =
903         new Instruction.Move(dock,
904                              Predicate.IgnoreFlagD,   /* predicate   */
905                              false,                 /* torpedoable */
906                              null_path,                  /* path        */
907                              false,                 /* tokenIn     */
908                              false,                 /* dataIn      */
909                              false,                 /* latchData   */
910                              false,                 /* latchPath   */
911                              true,                  /* dataOut     */
912                              false                  /* tokenOut    */
913                              );
914
915     private static final Instruction SEND_DATA_IF_D_NOT_SET =
916         new Instruction.Move(dock,
917                              Predicate.Default,     /* predicate   */
918                              false,                 /* torpedoable */
919                              null_path,             /* path        */
920                              false,                 /* tokenIn     */
921                              false,                 /* dataIn      */
922                              false,                 /* latchData   */
923                              false,                 /* latchPath   */
924                              true,                  /* dataOut     */
925                              false                  /* tokenOut    */
926                              );
927
928     private static final Instruction SEND_DATA_IF_D_SET =
929         new Instruction.Move(dock,
930                              Predicate.FlagD,       /* predicate   */
931                              false,                 /* torpedoable */
932                              null_path,             /* path        */
933                              false,                 /* tokenIn     */
934                              false,                 /* dataIn      */
935                              false,                 /* latchData   */
936                              false,                 /* latchPath   */
937                              true,                  /* dataOut     */
938                              false                  /* tokenOut    */
939                              );
940
941     private static final Instruction TORPEDOABLE_RECV_DATA =
942         new Instruction.Move(dock,
943                              Predicate.IgnoreFlagD, /* predicate   */
944                              true,                  /* torpedoable */
945                              null,                  /* path        */
946                              false,                 /* tokenIn     */
947                              true,                  /* dataIn      */
948                              true,                  /* latchData   */
949                              false,                 /* latchPath   */
950                              false,                 /* dataOut     */
951                              false                  /* tokenOut    */
952                              );
953
954     private static final Instruction RECV_DATA =
955         new Instruction.Move(dock,
956                              Predicate.IgnoreFlagD,   /* predicate   */
957                              false,                 /* torpedoable */
958                              null,                  /* path        */
959                              false,                 /* tokenIn     */
960                              true,                  /* dataIn      */
961                              true,                  /* latchData   */
962                              false,                 /* latchPath   */
963                              false,                 /* dataOut     */
964                              false                  /* tokenOut    */
965                              );
966
967     private static final Instruction SEND_TOKEN =
968         new Instruction.Move(dock,
969                              Predicate.IgnoreFlagD,   /* predicate   */
970                              false,                 /* torpedoable */
971                              null_path,                  /* path        */
972                              false,                 /* tokenIn     */
973                              false,                 /* dataIn      */
974                              false,                 /* latchData   */
975                              false,                 /* latchPath   */
976                              false,                 /* dataOut     */
977                              true                   /* tokenOut    */
978                              );
979
980     private static final Instruction RECV_TOKEN =
981         new Instruction.Move(dock,
982                              Predicate.IgnoreFlagD,   /* predicate   */
983                              false,                 /* torpedoable */
984                              null,                  /* path        */
985                              true,                  /* tokenIn     */
986                              false,                 /* dataIn      */
987                              false,                 /* latchData   */
988                              false,                 /* latchPath   */
989                              false,                 /* dataOut     */
990                              false                  /* tokenOut    */
991                              );
992
993
994     private void expectNorthFifoNoMoreThan(int num) {
995         model.waitNS(128 * CYCLE_TIME_NS);
996         List<BitVector> dataItems = marina.data.drainMany(num+1);
997         fatal(dataItems.size()>num,
998               "Expected no more than "+num+
999               " data items to emerge but got at least: "+dataItems.size());
1000     }
1001     private void expectNorthFifoExactly(int num) {
1002         model.waitNS(128 * CYCLE_TIME_NS);
1003         List<BitVector> dataItems = marina.data.drainMany(num+1);
1004         fatal(dataItems.size()!=num,
1005               "Expected exactly "+num+
1006               " data items to emerge but got at least: "+dataItems.size());
1007     }
1008     private void expectNorthFifoAtLeast(int num) {
1009         model.waitNS(128 * CYCLE_TIME_NS);
1010         List<BitVector> dataItems = marina.data.drainMany(num);
1011         fatal(dataItems.size()<num,
1012               "Expected at least "+num+
1013               " data items to emerge but got only: "+dataItems.size());
1014     }
1015     private void expectTokensNoMoreThan(int num) {
1016         int x = marina.getNumTokens();
1017         List<BitVector> dataItems = marina.data.drainMany(num+1);
1018         fatal(x>num,
1019               "Expected no more than "+num+
1020               " tokens to emerge but got at least: "+x);
1021     }
1022     private void expectTokensExactly(int num) {
1023         int x = marina.getNumTokens();
1024         fatal(x!=num,
1025               "Expected exactly "+num+
1026               " tokens but got at least: "+x);
1027     }
1028
1029     private void testFlagDRecomputationTime(Marina marina) {
1030         marina.instrIn.fill(setIlc(1));
1031         marina.fillSouthProperStopper(new Instruction[] {
1032                 RECV_DATA,
1033                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
1034                 SEND_DATA_IF_D_NOT_SET
1035             });
1036         marina.fillNorthProperStopper();
1037         expectNorthFifoNoMoreThan(0);
1038
1039         marina.fillSouthProperStopper(new Instruction[] {
1040                 RECV_DATA,
1041                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
1042                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
1043                 SEND_DATA_IF_D_NOT_SET
1044             });
1045         marina.fillNorthProperStopper();
1046         expectNorthFifoNoMoreThan(0);
1047
1048         marina.fillSouthProperStopper(new Instruction[] {
1049                 RECV_DATA,
1050                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1051                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
1052                 SEND_DATA_IF_D_NOT_SET
1053             });
1054         marina.fillNorthProperStopper();
1055         expectNorthFifoExactly(1);
1056         marina.instrIn.fill(DEC);
1057
1058         marina.fillSouthProperStopper(new Instruction[] {
1059                 RECV_DATA,
1060                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
1061                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
1062                 SEND_DATA_IF_D_NOT_SET
1063             });
1064         marina.fillNorthProperStopper();
1065         expectNorthFifoExactly(1);
1066     }
1067
1068     private void testTailWaitsForHead(Marina marina) {
1069         marina.instrIn.fill(setIlc(1));
1070         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1071         
1072         marina.enableInstructionSend(false);
1073         marina.enableInstructionRecirculate(true);
1074         
1075         marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1076         marina.instrIn.fill(new Instruction.Head(dock));
1077         marina.instrIn.fill(SEND_DATA);
1078         marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1079         marina.instrIn.fill(SEND_TOKEN);
1080         marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1081         marina.instrIn.fill(new Instruction.Tail(dock));
1082         marina.instrIn.fillTorpedo();
1083         
1084         marina.enableInstructionRecirculate(false);
1085         marina.enableInstructionSend(true);
1086         marina.instrIn.run();
1087         
1088         expectNorthFifoNoMoreThan(0);
1089         prln("inserting into north proper stopper");
1090         marina.fillNorthProperStopper();
1091         expectNorthFifoExactly(1);
1092         int nbToks = marina.getNumTokens();
1093         fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
1094     }
1095
1096         /*
1097         marina.instrIn.fill(setIlc(1));
1098         marina.instrIn.fill(setOlc(1));
1099
1100         // this makes the head wait for the torpedo
1101         marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1102
1103         // the head should wait for the tail
1104         marina.instrIn.fill(new Instruction.Head(dock));
1105         marina.instrIn.fill(NOP);
1106         marina.instrIn.fill(SEND_DATA);
1107         marina.instrIn.fill(RECV_DATA);
1108
1109         expectNorthFifoNoMoreThan(0);
1110
1111         marina.instrIn.fillTorpedo();
1112         expectNorthFifoNoMoreThan(0);
1113
1114         marina.instrIn.fill(new Instruction.Tail(dock));
1115         expectNorthFifoExactly(1);
1116         */
1117
1118     private void testTailWithoutHead(Marina marina) {
1119         marina.instrIn.fill(setIlc(1));
1120         marina.fillSouthProperStopper(new Instruction[] {
1121                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
1122                 new Instruction.Tail(dock),
1123                 SEND_DATA,
1124             });
1125         List<BitVector> dataItems = marina.data.drainMany(1);
1126         fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
1127     }
1128
1129     private void testHeadWaitsForTail(Marina marina) {
1130         List<BitVector> dataItems;
1131
1132         prln("Begin testHeadWaitsForTail");
1133         adjustIndent(2);
1134
1135         marina.instrIn.fill(setIlc(1));
1136         marina.fillSouthProperStopper(new Instruction[] {
1137                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
1138                 new Instruction.Head(dock),
1139                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1140                 SEND_DATA,
1141             });
1142
1143         expectNorthFifoExactly(0);
1144         marina.instrIn.fill(new Instruction.Tail(dock));
1145         expectNorthFifoAtLeast(1);
1146
1147         adjustIndent(-2);
1148         prln("End testHeadWaitsForTail");
1149     }
1150
1151     private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) {
1152         marina.instrIn.fill(setIlc(1));
1153         marina.fillSouthProperStopper(new Instruction[] {
1154                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,63),
1155                 new Instruction.Move(dock,
1156                                      Predicate.IgnoreFlagD, // predicate   
1157                                      true,                  // torpedoable 
1158                                      null,                  // path        
1159                                      true,                  // tokenIn     
1160                                      false,                 // dataIn      
1161                                      false,                 // latchData   
1162                                      false,                 // latchPath   
1163                                      false,                 // dataOut     
1164                                      false                  // tokenOut    
1165                                      ),
1166                 new Instruction.Move(dock,
1167                                      Predicate.FlagD,       // predicate   
1168                                      false,                 // torpedoable 
1169                                      null,                  // path        
1170                                      false,                 // tokenIn     
1171                                      false,                 // dataIn      
1172                                      false,                 // latchData   
1173                                      false,                 // latchPath   
1174                                      true,                  // dataOut     
1175                                      false                  // tokenOut    
1176                                      ),
1177             });
1178         marina.instrIn.fillTorpedo();
1179         expectNorthFifoExactly(1);
1180         marina.fillSouthProperStopper(new Instruction[] {
1181                 new Instruction.Move(dock,
1182                                      Predicate.Default,     // predicate   
1183                                      false,                 // torpedoable 
1184                                      null,                  // path        
1185                                      false,                 // tokenIn     
1186                                      false,                 // dataIn      
1187                                      false,                 // latchData   
1188                                      false,                 // latchPath   
1189                                      true,                  // dataOut     
1190                                      false                  // tokenOut    
1191                                      ),
1192             });
1193         expectNorthFifoNoMoreThan(0);
1194     }
1195
1196     private void testAbort(Marina marina) {
1197         
1198         marina.instrIn.fill(setIlc(1));
1199         marina.fillSouthProperStopper(new Instruction[] {
1200                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1),
1201                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1202                 SEND_DATA_IF_D_NOT_SET,
1203                 new Instruction.Head(dock),
1204                 SEND_DATA_IF_D_NOT_SET,
1205                 new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2),
1206                 new Instruction.Abort(dock, Predicate.FlagD),
1207                 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement),
1208                 new Instruction.Tail(dock),
1209             }, true);
1210         
1211         for(int i=0; i<4; i++) {
1212             BitVector bv;
1213             
1214             model.waitNS(128 * CYCLE_TIME_NS);
1215             bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1216             fatal(bv==null, "no data item found");
1217             prln("got " + bv.toLong());
1218             fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1219             
1220             model.waitNS(128 * CYCLE_TIME_NS);
1221             bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1222             fatal(bv==null, "no data item found");
1223             prln("got " + bv.toLong());
1224             fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1225             
1226             model.waitNS(128 * CYCLE_TIME_NS);
1227             bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1228             fatal(bv==null, "no data item found");
1229             prln("got " + bv.toLong());
1230             fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong());
1231             
1232         }
1233     }
1234
1235     private void testAbortOutsideOfLoop(Marina marina) {
1236         marina.instrIn.fill(setIlc(1));
1237         marina.fillSouthProperStopper(new Instruction[] {
1238                 // ensure that an abort doesn't cause problems if no loop is in progress
1239                 new Instruction.Abort(dock, Predicate.IgnoreFlagD),
1240                 SEND_DATA,
1241             });
1242         expectNorthFifoExactly(1);
1243     }
1244
1245     private void testFlagAB(Marina marina) {
1246         prln("Begin testFlagAB");
1247         adjustIndent(2);
1248
1249         Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1250         Instruction.Set.FlagFunction one  = zero;
1251
1252         
1253         // we should be able to use any pair of FlagX+NotFlagX,
1254         // but we toss them all in to maximize the chances of the
1255         // test passing (later we will try the individual
1256         // combinations to maximize the chances of failure).
1257         one = one.add(Predicate.FlagA);
1258         one = one.add(Predicate.NotFlagA);
1259         one = one.add(Predicate.FlagB);
1260         one = one.add(Predicate.NotFlagB);
1261         one = one.add(Predicate.FlagC);
1262         one = one.add(Predicate.NotFlagC);
1263
1264         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1265         for(boolean fast : new boolean[] { true, false }) {
1266             // clear the flags to a known state, then check both 0->1 and 1->0 transitions
1267             for(boolean b : new boolean[] { false, true, false }) {
1268                 prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
1269                 prln((b?"Setting":"Clearing")+" flags");
1270                 
1271                 Instruction inst = new Instruction.Set(dock,Predicate.IgnoreFlagD,
1272                                                        b ? one : zero,
1273                                                        b ? one : zero
1274                                                        );
1275                 if (fast) {
1276                     marina.fillSouthProperStopper(new Instruction[] {
1277                             RECV_DATA,
1278                             inst,
1279                             NOP,
1280                         });
1281                     model.waitNS(64 * CYCLE_TIME_NS);
1282                     marina.fillNorthProperStopper();
1283                 } else {
1284                     marina.instrIn.fill(inst);
1285                 }
1286
1287                 fatal(marina.getFlagA()!=b,
1288                       "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
1289                 fatal(marina.getFlagB()!=b,
1290                       "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
1291             }
1292         }
1293
1294         adjustIndent(-2);
1295         prln("End testFlagAB");         
1296     }
1297
1298     /**
1299      *  WARNING: this is a very, very, very long test case -- it goes
1300      *  through 216 iterations.
1301      */
1302     private void testFlagTruthTable(Marina marina) {
1303         prln("Begin testFlagTruthTable");
1304         adjustIndent(2);
1305
1306         marina.instrIn.fill(setIlc(1));
1307         Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1308         Instruction.Set.FlagFunction one  = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
1309
1310         for(Predicate a_input : new Predicate[] { null, Predicate.FlagA, Predicate.NotFlagA })
1311             for(Predicate b_input : new Predicate[] { null, Predicate.FlagB, Predicate.NotFlagB })
1312                 for(Predicate c_input : new Predicate[] { null, Predicate.FlagC, Predicate.NotFlagC })
1313                     for(boolean a_state : new boolean[] { false, true })
1314                         for(boolean b_state : new boolean[] { false, true })
1315                             for(boolean c_state : new boolean[] { false, true }) {
1316                                 for(boolean which : new boolean[] { false, true }) {
1317
1318                                     prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
1319                                     // set A,B flags to a_state and b_state
1320                                     marina.instrIn.fill(new 
1321                                                         Instruction.Set(dock,Predicate.IgnoreFlagD,
1322                                                                         a_state ? one : zero,
1323                                                                         b_state ? one : zero
1324                                                                         ));
1325                                     
1326                                     // set C flag to c_state
1327                                     BitVector data = new BitVector(37, "empty");
1328                                     BitVector addr = new BitVector(14, "empty");
1329                                     for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1330                                     for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1331                                     addr.set(Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
1332                                     marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1333                                     marina.instrIn.fill(RECV_DATA);
1334                                     
1335                                     Instruction.Set.FlagFunction func = zero;
1336                                     if (a_input!=null) func = func.add(a_input);
1337                                     if (b_input!=null) func = func.add(b_input);
1338                                     if (c_input!=null) func = func.add(c_input);
1339
1340                                     Instruction inst = new 
1341                                         Instruction.Set(dock,Predicate.IgnoreFlagD,
1342                                                         !which ? func : zero.add(Predicate.FlagA),
1343                                                         which  ? func : zero.add(Predicate.FlagB)
1344                                                         );
1345
1346                                     marina.instrIn.fill(inst);
1347
1348                                     boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
1349                                     boolean expected_b =  which ? func.evaluate(a_state, b_state, c_state, false) : b_state;
1350                                     fatal(expected_a != marina.getFlagA(),
1351                                           "expected A="+expected_a+", but got "+marina.getFlagA());
1352                                     fatal(expected_b != marina.getFlagB(),
1353                                           "expected B="+expected_b+", but got "+marina.getFlagB());
1354                                 }
1355                             }
1356         adjustIndent(-2);
1357         prln("End testFlagTruthTable");         
1358     }
1359
1360     private void recvData(Marina marina) {
1361         prln("Begin recvData");
1362         adjustIndent(2);
1363
1364         marina.instrIn.fill(setIlc(1));
1365         marina.fillSouthProperStopper(new Instruction[] {
1366                 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1367                 new Instruction.Move(dock,
1368                                      Predicate.IgnoreFlagD, // predicate   
1369                                      false,                 // torpedoable 
1370                                      null,                  // path        
1371                                      false,                 // tokenIn     
1372                                      true,                  // dataIn      
1373                                      false,                 // latchData   
1374                                      false,                 // latchPath   
1375                                      false,                 // dataOut     
1376                                      false                  // tokenOut    
1377                                      ),
1378                 new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG),
1379             });
1380         model.waitNS(64 * CYCLE_TIME_NS);
1381
1382         prln("checking to confirm that A flag is cleared");
1383         fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1384         
1385         prln("inserting data item in north fifo ring");
1386         BitVector data = new BitVector(37, "empty");
1387         BitVector addr = new BitVector(14, "empty");
1388         for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1389         for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1390         marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1391         model.waitNS(64 * CYCLE_TIME_NS);
1392
1393         prln("checking to see if A flag got set");
1394         fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1395
1396         adjustIndent(-2);
1397         prln("End recvData");           
1398     }
1399
1400
1401     private void testRecvAndSendWalkingOne(Marina marina) {
1402         prln("Begin testRecvAndSendWalkingOne");
1403         adjustIndent(2);
1404
1405         marina.instrIn.fill(setIlc(1));
1406
1407         List<BitVector> dataItems;
1408         for(int bit=0; bit<37; bit++) {
1409
1410             BitVector data = new BitVector(37, "empty");
1411             BitVector addr = new BitVector(14, "empty");
1412             for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1413             for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1414             data.set(bit, true);
1415             prln("testing with bit pattern " + data);
1416
1417             prln("inserting data item into north fifo ring");
1418             marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1419
1420             prln("stopping the north proper stopper");
1421             marina.data.stop();
1422
1423             dataItems = marina.data.drainMany(1);
1424             fatal(dataItems.size()!=0,
1425                   "found a data item waiting in the north proper stopper, but should not have");
1426
1427             marina.instrIn.fill(new Instruction.Move(dock,
1428                                                      Predicate.IgnoreFlagD,  // predicate   
1429                                                      false,                  // torpedoable 
1430                                                      null_path,              // path        
1431                                                      false,                  // tokenIn     
1432                                                      true,                   // dataIn      
1433                                                      true,                   // latchData   
1434                                                      false,                  // latchPath   
1435                                                      true,                   // dataOut     
1436                                                      false                   // tokenOut    
1437                                                      ));
1438
1439             dataItems = marina.data.drainMany(2);
1440             fatal(dataItems.size()!=1,
1441                   "found "+dataItems.size()+" data items in north fifo; expected one");
1442             MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1443             fatalIfBitVectorsDoNotMatch(mp.data, data);
1444         }
1445
1446         adjustIndent(-2);
1447         prln("End testRecvAndSendWalkingOne");          
1448     }
1449
1450
1451
1452     private void setOlcFromDataLatch(Marina marina) {
1453         prln("Begin setOlcFromDataLatch");
1454         adjustIndent(2);
1455
1456         marina.instrIn.fill(setIlc(1));
1457
1458         // walk a bit from 0 to 5
1459         for(int bit=0; bit<6; bit++) {
1460             prln("inserting data item in north fifo ring");
1461             BitVector data = new BitVector(37, "empty");
1462             BitVector addr = new BitVector(14, "empty");
1463             for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1464             for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1465             data.set(bit, true);
1466             marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1467
1468             marina.fillSouthProperStopper(new Instruction[] {
1469                     RECV_DATA,
1470                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch),
1471                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,-1),
1472                 });
1473
1474             model.waitNS(CYCLE_TIME_NS * 64);
1475
1476             expectOlc(1<<bit);
1477
1478             if (marina.kesselsCounter) {
1479                 // master clear on each iteration; otherwise we'd need to "run down" the olc
1480                 marina.masterClear();
1481                 marina.enableInstructionSend(true);
1482             }
1483         }
1484
1485         adjustIndent(-2);
1486         prln("End setOlcFromDataLatch");        
1487     }
1488
1489     private void setIlcFromDataLatch(Marina marina) {
1490         prln("Begin setIlcFromDataLatch");
1491         adjustIndent(2);
1492
1493         marina.instrIn.fill(setIlc(1));
1494
1495         // walk a bit from 0 to 5
1496         for(int bit=5; bit>=0; bit--) {
1497             prln("inserting data item in north fifo ring");
1498             BitVector data = new BitVector(37, "empty");
1499             BitVector addr = new BitVector(14, "empty");
1500             for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1501             for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1502             data.set(bit, true);
1503             marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1504
1505             marina.fillSouthProperStopper(new Instruction[] {
1506                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1507                     RECV_DATA,
1508                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch),
1509                 });
1510             model.waitNS(CYCLE_TIME_NS * 64);
1511
1512             int ilc = marina.getILC().getCount();
1513             fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc); 
1514         }
1515
1516         adjustIndent(-2);
1517         prln("End setIlcFromDataLatch");        
1518     }
1519
1520     private void testSendAndRecvToken(Marina marina) {
1521         prln("Begin testSendAndRecvToken");
1522         adjustIndent(2);
1523
1524         marina.instrIn.fill(setIlc(1));
1525         marina.fillSouthProperStopper(new Instruction[] {
1526                 SEND_TOKEN,
1527                 RECV_TOKEN,
1528                 SEND_DATA,
1529             });
1530         expectNorthFifoExactly(1);
1531
1532         adjustIndent(-2);
1533         prln("End testSendAndRecvToken");       
1534     }
1535
1536     private void testSignExtendedLiteral(Marina marina) {
1537         prln("Begin testSignExtendedLiteral");
1538         adjustIndent(2);
1539
1540         marina.instrIn.fill(setIlc(1));
1541         for(long val : new long[] { (-1L << 14), -1, 0, 1 }) {
1542
1543             marina.fillSouthProperStopper(new Instruction[] {
1544                     new Instruction.Set(dock,Predicate.IgnoreFlagD,
1545                                         Instruction.Set.SetDest.DataLatch,
1546                                         val),
1547                     SEND_DATA,
1548                 });
1549             model.waitNS(CYCLE_TIME_NS * 64);
1550
1551             List<BitVector> dataItems = marina.data.drainMany(3);
1552             fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1553
1554             MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1555             BitVector bv = mp.data;
1556             prln("got back " + mp);
1557
1558             boolean mismatch = false;
1559             String err = "";
1560             for(int i=0; i<37; i++) {
1561                 if (bv.get(i) != ( (val & (1L << i)) != 0 )) {
1562                     mismatch = true;
1563                     err += ""+i+", ";
1564                 }
1565             }
1566             fatal(mismatch, "data read back did not match inserted literal; mismatch on bits " + err);
1567         }
1568                 
1569         adjustIndent(-2);
1570         prln("End testSignExtendedLiteral");            
1571     }
1572
1573     private void testShiftedLiteral(Marina marina) {
1574         prln("Begin testShiftedLiteral");
1575         adjustIndent(2);
1576
1577         marina.instrIn.fill(setIlc(1));
1578         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
1579                                                 Instruction.Set.SetDest.DataLatch,
1580                                                 0));
1581
1582         BitVector dreg = new BitVector(37, "what we think is in the d-register");
1583         for(int i=0; i<37; i++) dreg.set(i, false);
1584
1585         for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
1586
1587             edu.berkeley.fleet.api.BitVector immediate =
1588                 new edu.berkeley.fleet.api.BitVector(19);
1589             for(int i=0; i<immediate.length(); i++)
1590                 immediate.set(i, (val & (1L << i)) != 0);
1591
1592             // shift over 19 LSB's towards MSB
1593             for(int i=0; i<19; i++)
1594                 if (i+19 <= 36)  dreg.set(i+19, dreg.get(i));
1595             for(int i=0; i<19; i++)
1596                 dreg.set(i, immediate.get(i));
1597
1598             marina.fillSouthProperStopper(new Instruction[] {
1599                     new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate),
1600                     SEND_DATA,
1601                 });
1602
1603             model.waitNS(CYCLE_TIME_NS * 64);
1604             List<BitVector> dataItems = marina.data.drainMany(3);
1605             fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1606
1607             BitVector bv = new MarinaPacket(dataItems.get(0)).data;
1608             fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" +
1609                   "got:     "+bv.bitReverse().getState()+"\n"+
1610                   "expected:"+dreg.bitReverse().getState());
1611         }
1612                 
1613         adjustIndent(-2);
1614         prln("End testShiftedLiteral");         
1615     }
1616
1617     private void testFlagC(Marina marina) {
1618         prln("Begin testFlagC");
1619         adjustIndent(2);
1620
1621         // Russell says:
1622         // addr[14] == sigS
1623         // addr[1]  == sigA
1624         //
1625         // Adam says:
1626         // Dc=1 => sigS is copied into C-flag
1627         // Dc=0 => sigA is copied into C-flag
1628        
1629         marina.instrIn.fill(setIlc(1));
1630         for(boolean dc : new boolean[] { false, true }) {
1631             for(boolean c_flag : new boolean[] { true, false, true }) {
1632
1633                 prln("");
1634                 prln("****** checking case where dc="+dc+", cflag="+c_flag);
1635                 BitVector data = new BitVector(37, "empty");
1636                 BitVector addr = new BitVector(14, "empty");
1637                 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1638                 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1639
1640                 int whichbit = dc
1641                     ? Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
1642                     : Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
1643                 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
1644                 addr.set(whichbit, c_flag);
1645
1646                 prln("... and filling north fifo proper stopper");
1647                 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1648                 
1649                 prln("clearing flags");
1650                 prln("executing recv data with Dc="+dc);
1651                 prln("copying c-flag to a-flag");
1652                 marina.fillSouthProperStopper(new Instruction[] {
1653                         new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1654                         new Instruction.Move(dock,
1655                                              Predicate.IgnoreFlagD,   /* predicate   */
1656                                              true,                  /* torpedoable */
1657                                              null,                  /* path        */
1658                                              false,                 /* tokenIn     */
1659                                              true,                  /* dataIn      */
1660                                              dc,                    /* latchData   */
1661                                              false,                 /* latchPath   */
1662                                              false,                 /* dataOut     */
1663                                              false                  /* tokenOut    */
1664                                              ),
1665                         FLAG_NOP,
1666                         new Instruction.Set(dock,Predicate.IgnoreFlagD,
1667                                             Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
1668                                             CLEAR_FLAG
1669                                             ),
1670                     });
1671
1672                 model.waitNS(CYCLE_TIME_NS * 64);
1673                 
1674                 prln("checking to confirm that A flag is " + c_flag);
1675                 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
1676             }
1677         }
1678         adjustIndent(-2);
1679         prln("End testFlagC");          
1680     }
1681
1682     private void sendDataWithPath(Marina marina) {
1683         prln("Begin sendDataWithPath");
1684         adjustIndent(2);
1685
1686         edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
1687         marina.instrIn.fill(setIlc(1));
1688
1689         // alternating ones and zeroes
1690         for(int i=0; i<bv.length(); i+=2)
1691             bv.set(i, true);
1692         // and then ones in the lower four bits so it's not symmetric
1693         for(int i=0; i<4; i++)
1694             bv.set(i, true);
1695
1696         MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
1697
1698         marina.fillSouthProperStopper(new Instruction[] {
1699                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1700                 new Instruction.Move(dock,
1701                                      Predicate.IgnoreFlagD, /* predicate   */
1702                                      false,                 /* torpedoable */
1703                                      path,                  /* path        */
1704                                      false,                 /* tokenIn     */
1705                                      false,                 /* dataIn      */
1706                                      false,                 /* latchData   */
1707                                      false,                 /* latchPath   */
1708                                      true,                  /* dataOut     */
1709                                      false                  /* tokenOut    */
1710                                      ),
1711             });
1712
1713         List<BitVector> dataItems;
1714         MarinaPacket mp;
1715
1716         dataItems = marina.data.drainMany();
1717         fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1718         mp = new MarinaPacket(dataItems.get(0));
1719
1720         // the 14th bit of the outbound address cannot be set by the
1721         // ship, so we don't care about it
1722         fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1723
1724         prln("send data with no change to path");
1725         marina.instrIn.fill(new Instruction.Move(dock,
1726                                                  Predicate.IgnoreFlagD, /* predicate   */
1727                                                  false,                 /* torpedoable */
1728                                                  null,                  /* path        */
1729                                                  false,                 /* tokenIn     */
1730                                                  false,                 /* dataIn      */
1731                                                  false,                 /* latchData   */
1732                                                  false,                 /* latchPath   */
1733                                                  true,                  /* dataOut     */
1734                                                  false                  /* tokenOut    */
1735                                                  ));
1736
1737         dataItems = marina.data.drainMany();
1738         fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1739         mp = new MarinaPacket(dataItems.get(0));
1740
1741         // the 14th bit of the outbound address cannot be set by the
1742         // ship, so we don't care about it
1743         fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1744
1745         adjustIndent(-2);
1746         prln("End sendDataWithPath");
1747     }
1748
1749     private void recvPath(Marina marina) {
1750         prln("Begin recvPath");
1751         adjustIndent(2);
1752
1753         marina.instrIn.fill(setIlc(1));
1754         for(int bit=0; bit<11; bit++) {
1755             BitVector packet_data = new BitVector(37, "inbound data item");
1756             for(int i=0; i<37; i++) packet_data.set(i, false);
1757             packet_data.set(27+bit, true);
1758             BitVector packet_path = new BitVector(14, "inbound data item");
1759             for(int i=0; i<14; i++) packet_path.set(i, false);
1760
1761             marina.fillNorthProperStopper(new MarinaPacket(packet_data, false, packet_path));
1762                                            
1763             prln("recv path, send data (using recv'd path)");
1764             marina.instrIn.fill(new Instruction.Move(dock,
1765                                                      Predicate.IgnoreFlagD,   /* predicate   */
1766                                                      false,                 /* torpedoable */
1767                                                      null,                  /* path        */
1768                                                      false,                 /* tokenIn     */
1769                                                      true,                  /* dataIn      */
1770                                                      true,                  /* latchData   */
1771                                                      true,                  /* latchPath   */
1772                                                      true,                  /* dataOut     */
1773                                                      false                  /* tokenOut    */
1774                                                      ));
1775
1776             List<BitVector> dataItems = marina.data.drainMany();
1777             fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1778             MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1779             
1780             fatalIfBitVectorsDoNotMatch(packet_data.get(25,11), mp.path.get(0,11));
1781             fatalIfBitVectorsDoNotMatch(packet_data, mp.data);
1782         }
1783
1784         adjustIndent(-2);
1785         prln("End recvPath");
1786     }
1787
1788     private void testILC(Marina marina) {
1789         prln("Begin testILC");
1790         adjustIndent(2);
1791
1792         for(int bit=0; bit<6; bit++) {
1793             int ilc = bit<0 ? 0 : (1<<bit);
1794             marina.fillSouthProperStopper(new Instruction[] {
1795                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc),
1796                     SEND_DATA,
1797                 });
1798             List<BitVector> dataItems = marina.data.drainMany();
1799             fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
1800         }
1801
1802         adjustIndent(-2);
1803         prln("End testILC");
1804     }
1805
1806     private void testILCZero(Marina marina) {
1807         adjustIndent(2);
1808         marina.fillSouthProperStopper(new Instruction[] {
1809                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0),
1810                 SEND_DATA,
1811                 SEND_TOKEN,
1812             });
1813         expectNorthFifoNoMoreThan(0);
1814         expectTokensExactly(1);
1815         adjustIndent(-2);
1816     }
1817
1818     private void sendTorpedo(Marina marina) {
1819         prln("Begin sendTorpedo");
1820         adjustIndent(2);
1821         marina.instrIn.fill(setIlc(1));
1822         marina.instrIn.fill(setOlc(63));
1823
1824         model.waitNS(128 * CYCLE_TIME_NS);
1825         expectOlc(63);
1826
1827         marina.instrIn.fill(new 
1828                             Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1829         fatal(marina.getFlagA(), "bad A flag: true");
1830         fatal(marina.getFlagB(), "bad B flag: true");
1831
1832         prln("execute a move instruction that does nothing but loops until torpedo arrives"); 
1833         prln("A=1, B=B This instruction should not execute because D-flag is set");
1834         prln("Set A=A, B=1 This instruction should execute because D-flag is set");
1835
1836         model.waitNS(128 * CYCLE_TIME_NS);
1837
1838         marina.fillSouthProperStopper(new Instruction[] {
1839                 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity),
1840                 new Instruction.Move(dock,
1841                                      Predicate.IgnoreFlagD, // predicate   
1842                                      true,                  // torpedoable 
1843                                      null,                  // path        
1844                                      false,                 // tokenIn     
1845                                      true,                  // dataIn      
1846                                      false,                 // latchData   
1847                                      false,                 // latchPath   
1848                                      false,                 // dataOut     
1849                                      false                  // tokenOut    
1850                                      ),
1851                 new Instruction.Set(dock,Predicate.Default,
1852                                     SET_FLAG,
1853                                     Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB)
1854                                     ),
1855                 new Instruction.Set(dock, Predicate.FlagD,
1856                                     Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA),
1857                                     SET_FLAG
1858                                     ),
1859             });
1860
1861         model.waitNS(128 * CYCLE_TIME_NS);
1862
1863         prln("send torpedo. This should clear the OLC");
1864         marina.instrIn.fillTorpedo();
1865         model.waitNS(128 * CYCLE_TIME_NS);
1866
1867         model.waitNS(128 * CYCLE_TIME_NS);
1868                 
1869         prln("A should remain false, B should be true");
1870         fatal(marina.getFlagA(), "bad A flag: true");
1871         fatal(!marina.getFlagB(), "bad B flag: false");
1872         
1873         model.waitNS(128 * CYCLE_TIME_NS);
1874
1875         prln("Reload OLC after torpedo, clears D-flag");
1876         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1877
1878         // FIXME: find another way to test this
1879         model.waitNS(128 * CYCLE_TIME_NS);
1880         expectOlc(63);
1881                 
1882         prln("Set A=1, B=1 This instruction should execute because OLC!=0");
1883         marina.instrIn.fill(new 
1884                             Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
1885
1886         prln("A and B should be true");
1887         fatal(!marina.getFlagA(), "bad A flag: false");
1888         fatal(!marina.getFlagB(), "bad B flag: false");
1889                 
1890         adjustIndent(-2);
1891         prln("End sendTorpedo");        
1892     }    
1893
1894     private void testTorpedoOnAnInfinite(Marina marina) {
1895         prln("Begin testTorpedoOnAnInfinite");
1896         adjustIndent(2);
1897
1898         List<BitVector> dataItems;
1899
1900         marina.instrIn.fill(setIlc(1));
1901         for(boolean torpedoable : new boolean[] { true, false }) {
1902             
1903             marina.fillSouthProperStopper(new Instruction[] {
1904                     new Instruction.Move(dock,
1905                                          Predicate.IgnoreFlagD, // predicate   
1906                                          false,                 // torpedoable 
1907                                          null,                  // path        
1908                                          false,                 // tokenIn     
1909                                          false,                 // dataIn      
1910                                          false,                 // latchData   
1911                                          false,                 // latchPath   
1912                                          false,                 // dataOut     
1913                                          true                   // tokenOut    
1914                                          ),
1915                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
1916                     new Instruction.Move(dock,
1917                                          Predicate.IgnoreFlagD, // predicate   
1918                                          torpedoable,           // torpedoable 
1919                                          null,                  // path        
1920                                          true,                  // tokenIn     
1921                                          false,                 // dataIn      
1922                                          false,                 // latchData   
1923                                          false,                 // latchPath   
1924                                          false,                 // dataOut     
1925                                          true                   // tokenOut    
1926                                          ),
1927                     // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior
1928                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1929
1930                     SEND_DATA,
1931                 });
1932             
1933             // expect nothing to come out, because the NOP is executing
1934             dataItems = marina.data.drainMany(2);
1935             fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
1936             
1937             marina.instrIn.fillTorpedo();
1938             
1939             int expected = torpedoable?1:0;
1940             dataItems = marina.data.drainMany(2);
1941             fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1942
1943             fatal(!marina.getILC().getDone(), "Expected ilc=done, but got "+marina.getILC());
1944         }
1945
1946         adjustIndent(-2);
1947         prln("End testTorpedoOnAnInfinite");
1948     }
1949
1950     private void testDFlagWhenTorpedoLyingInWait(Marina marina) {
1951         marina.fillSouthProperStopper(new Instruction[] {
1952                 RECV_DATA,
1953                 TORPEDOABLE_RECV_DATA,
1954                 marina.kesselsCounter ? null : FLAG_NOP,
1955                 SEND_DATA_IF_D_SET,
1956             });
1957         marina.instrIn.fillTorpedo();
1958         model.waitNS(64 * CYCLE_TIME_NS);
1959         marina.fillNorthProperStopper();
1960         model.waitNS(64 * CYCLE_TIME_NS);
1961         expectNorthFifoExactly(1);
1962     }
1963
1964     private void testSetOlcFollowedByDPredicated(Marina marina) {
1965         for(boolean d_set : new boolean[] { false, true }) {
1966             prln("");
1967             marina.fillSouthProperStopper(new Instruction[] {
1968                     setOlc(0),
1969                     marina.kesselsCounter ? null : FLAG_NOP,
1970                     d_set ? SEND_DATA_IF_D_SET : SEND_DATA_IF_D_NOT_SET,
1971                 });
1972             expectNorthFifoExactly(d_set ? 1 : 0);
1973
1974             prln("");
1975             marina.fillSouthProperStopper(new Instruction[] {
1976                     setOlc(32),
1977                     marina.kesselsCounter ? null : FLAG_NOP,
1978                     d_set ? SEND_DATA_IF_D_SET : SEND_DATA_IF_D_NOT_SET,
1979                 });
1980             expectNorthFifoExactly(d_set ? 0 : 1);
1981
1982             if (marina.kesselsCounter) {
1983                 marina.masterClear();
1984                 marina.enableInstructionSend(true);
1985             }
1986         }
1987     }
1988
1989     private void testOlcDecrementAtHighSpeed(Marina marina) {
1990         prln("Begin testOlcDecrementAtHighSpeed");
1991         adjustIndent(2);
1992
1993         List<BitVector> dataItems;
1994         
1995         // Each element of the following pair of arrays is one "test".
1996         // The OLC will be loaded with olcs[i] and then decremented
1997         // decr_amounts[i] times; after that has happened the zeroness
1998         // of the OLC will be checked by executing a MOVE with
1999         // [olc!=0] as the predicate.
2000
2001         int[] olcs         = new int[] { 3, 3, 3, 10, 41 };
2002         int[] decr_amounts = new int[] { 2, 3, 4, 9,  9  };
2003
2004         for(int which=0; which<olcs.length; which++) {
2005             int olc = olcs[which];
2006             int decr_amount = decr_amounts[which];
2007
2008             prln("inserting set olc="+olc);
2009             prln("inserting set ilc=1");
2010             marina.fillSouthProperStopper(new Instruction[] {
2011                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
2012                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc),
2013                 });
2014
2015             // commenting the following four lines causes this test to pass
2016
2017             prln("inserting: "+decr_amount+" olc-- instructions");
2018             prln("inserting: [!d] send data");
2019             Instruction[] instructions = new Instruction[decr_amount+1];
2020             for(int i=0; i<decr_amount; i++)
2021                 instructions[i] =
2022                     new Instruction.Set(dock,
2023                                         Predicate.Default,
2024                                         SetDest.OuterLoopCounter,
2025                                         SetSource.Decrement);
2026             instructions[instructions.length-1] =
2027                 new Instruction.Move(dock,
2028                                      Predicate.Default,     // predicate   
2029                                      false,                 // torpedoable 
2030                                      null,                  // path        
2031                                      false,                 // tokenIn     
2032                                      false,                 // dataIn      
2033                                      false,                 // latchData   
2034                                      false,                 // latchPath   
2035                                      true,                  // dataOut     
2036                                      false                  // tokenOut    
2037                                      );
2038
2039             marina.fillSouthProperStopper(instructions);
2040             model.waitNS(64 * CYCLE_TIME_NS);
2041
2042             int expected = decr_amount>=olc ? 0 : 1;
2043             dataItems = marina.data.drainMany(2);
2044             fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
2045
2046             if (marina.kesselsCounter) {
2047                 // master clear on each iteration; otherwise we'd need to "run down" the olc
2048                 marina.masterClear();
2049                 marina.enableInstructionSend(true);
2050             }
2051         }
2052
2053         adjustIndent(-2);
2054         prln("End testOlcDecrementAtHighSpeed");
2055     }
2056
2057     private void flipIlcBit(Marina marina) {
2058         prln("Begin flipIlcBit");
2059         adjustIndent(2);
2060         prln("Using the set ILC instruction, toggle a single bit between zero and one. \n" +
2061              "Check correct setting of the ILC zero bit");
2062
2063         for (int i=0; i<6; i++) {
2064             int notZero = 1<<i;
2065
2066             prln("Then immediately set ILC="+notZero);
2067             marina.fillSouthProperStopper(new Instruction[] {
2068                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
2069                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
2070                 });
2071                 
2072             model.waitNS(64 * CYCLE_TIME_NS);
2073
2074             prln("Verify ILC using scan chain");
2075             Ilc ilc = marina.getILC();
2076             int ilcCount = ilc.getCount();
2077             fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
2078             fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
2079                    
2080             marina.fillSouthProperStopper(new Instruction[] {     
2081                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
2082                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
2083                 });
2084
2085             model.waitNS(64 * CYCLE_TIME_NS);
2086                         
2087             prln("Verify ILC using scan chain");
2088             ilc = marina.getILC();
2089             ilcCount = ilc.getCount();
2090             fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
2091             fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
2092         }
2093
2094         adjustIndent(-2);
2095         prln("End flipIlcBit");
2096     }
2097     private void flipOlcBit(Marina marina) {
2098         prln("Begin flipOlcBit");
2099         adjustIndent(2);
2100         prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
2101              "Check correct setting of the OLC zero bit");
2102
2103         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
2104
2105         for (int i=0; i<6; i++) {
2106             int notZero = 32 >> i;
2107
2108             if (marina.kesselsCounter) {
2109                 // master clear on each iteration; otherwise we'd need to "run down" the olc
2110                 marina.masterClear();
2111                 marina.enableInstructionSend(true);
2112             }
2113
2114             int outOlc;
2115             prln("Set OLC=0");
2116             prln("Then immediately set OLC="+notZero);
2117             marina.fillSouthProperStopper(new Instruction[] {
2118                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
2119                     new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
2120                 });
2121
2122             model.waitNS(64 * CYCLE_TIME_NS);
2123             prln("Verify OLC count using scan chain");
2124             expectOlc(notZero);
2125
2126             if (!marina.kesselsCounter) {
2127                 prln("Set OLC="+notZero);
2128                 prln("Then immediately set OLC=0");
2129                 marina.fillSouthProperStopper(new Instruction[] {
2130                         new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
2131                         new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
2132                     });
2133                 
2134                 model.waitNS(64 * CYCLE_TIME_NS);
2135                 prln("Verify OLC count using scan chain");
2136                 expectOlc(0);
2137             }
2138         }
2139         
2140         adjustIndent(-2);
2141         prln("End flipOlcBit");
2142     }
2143     private void testSouthRecirculate(Marina marina, int AMOUNT) {
2144         prln("Begin testSouthRecirculate("+AMOUNT+")");
2145         adjustIndent(2);
2146
2147         marina.enableInstructionSend(false);
2148         marina.enableInstructionRecirculate(true);
2149         
2150         prln("Completely fill south ring");
2151         adjustIndent(2);
2152         for (int i=0; i<AMOUNT; i++) {
2153             prln("inserting item " + (i+1) + " / " + AMOUNT);
2154             BitVector path = new BitVector(MarinaPacket.PATH_WIDTH, "path");
2155             BitVector data = new BitVector(MarinaPacket.WORD_WIDTH, "path");
2156             path.set(0, MarinaPacket.PATH_WIDTH, false);
2157             data.setFromLong(i+9);
2158             marina.instrIn.fill(new MarinaPacket(data, false, path));
2159         }
2160         adjustIndent(-2);
2161
2162         prln("Drain south ring and check contents");
2163         adjustIndent(2);
2164         List<BitVector> out = marina.instrIn.drainMany();
2165         boolean bad = false;
2166         for (int i=0; i<AMOUNT; i++) {
2167             prln("extracting item " + (i+1) + " / " + AMOUNT);
2168             //int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
2169             int expect = i+9;
2170             long got = new MarinaPacket(out.get(i)).data.toLong();
2171             if (got!=expect) {
2172                 bad = true;
2173                 prln("  bad instruction: "+got+" expected: "+expect);
2174             } else {
2175                 prln("  good instruction.");
2176             }
2177         }
2178         fatal(bad, "data inserted does not match data retrieved");
2179         adjustIndent(-2);
2180         
2181         for (int i=0; i<5; i++) {}
2182         
2183         adjustIndent(-2);
2184         prln("End testSouthRecirculate("+AMOUNT+")");
2185     }
2186
2187
2188     private void testOverfillTokens(Marina marina) {
2189         prln("Begin testOverfillTokens");
2190         adjustIndent(2);
2191
2192         for(int i=0; i<marina.TOKEN_FIFO_CAPACITY + 3; i++)
2193             marina.instrIn.fill(SEND_TOKEN);
2194         marina.instrIn.fill(SEND_DATA);
2195         expectNorthFifoExactly(0);
2196         
2197         adjustIndent(-2);
2198         prln("End testSouthRecirculate");
2199     }
2200
2201
2202
2203     private void doOneTest(int testNum) {
2204         prln("");
2205         prln("============================================================");
2206         prln("MarinaTest: performing test: "+testNum);
2207
2208         if (testNum!=0) {
2209             marina.masterClear();
2210             marina.enableInstructionSend(true);
2211         }
2212         
2213         try {
2214             switch (testNum) {
2215                 case 0: {
2216
2217                     doOneTest(1);       // passes extracted parasitics
2218                     doOneTest(2);       // passes extracted parasitics
2219                     doOneTest(3);       // passes extracted parasitics
2220                     doOneTest(4);       // passes extracted parasitics
2221                     doOneTest(5);       // passes extracted parasitics
2222                     doOneTest(6);
2223
2224                     doOneTest(1000);    // passes extracted parasitics
2225                     doOneTest(1001);    // passes extracted parasitics
2226                     doOneTest(1003);    // passes extracted parasitics
2227                     doOneTest(1005);
2228                     doOneTest(3000);    // passes extracted parasitics
2229                     doOneTest(3001);    // passes extracted parasitics
2230                     doOneTest(3003);    // passes extracted parasitics
2231                     doOneTest(3004);    // passes extracted parasitics
2232                     doOneTest(3005);    // passes extracted parasitics
2233                     doOneTest(3006);    // passes extracted parasitics
2234                     doOneTest(3007);    // passes extracted parasitics
2235                     doOneTest(3008);    // passes extracted parasitics
2236                     doOneTest(3009);    // passes extracted parasitics
2237                     doOneTest(3010);    // passes extracted parasitics
2238                     doOneTest(3011);    // passes extracted parasitics
2239                     doOneTest(3012);    // passes extracted parasitics
2240                     doOneTest(3013);    // passes extracted parasitics
2241                     doOneTest(3014);    // passes extracted parasitics
2242                     doOneTest(3015);    // passes extracted parasitics
2243                     doOneTest(3019);    // passes extracted parasitics
2244                     doOneTest(3020);    // passes extracted parasitics
2245                     doOneTest(3022);    // passes extracted parasitics
2246                     doOneTest(3023);    // passes extracted parasitics
2247                     doOneTest(3025);    // passes extracted parasitics
2248                     doOneTest(3026);    // passes extracted parasitics
2249                     doOneTest(3027);    // passes extracted parasitics
2250                     doOneTest(3028);    // passes extracted parasitics
2251                     doOneTest(3029);    // passes extracted parasitics
2252                     doOneTest(3030);    // passes extracted parasitics
2253                     doOneTest(3031);    // passes extracted parasitics
2254                     
2255                     // these tests take a while and usually pass
2256                     doOneTest(1002);
2257                     doOneTest(1004);
2258                     doOneTest(1005);
2259                     doOneTest(1006);
2260                     doOneTest(3002);
2261                     doOneTest(3016);
2262                     doOneTest(3021);
2263                     doOneTest(3024);
2264                     doOneTest(3025);
2265                     doOneTest(3040);
2266                     
2267                     // this takes an insanely long time
2268                     doOneTest(3017);
2269                     break;
2270                 }
2271                 case 1:    testChains(marina);                     break; // passes, 24-Mar (+verilog)
2272                 case 2:    testProperStoppers(marina);             break; // passes, 24-Mar (+verilog)
2273                 case 3:    testSouthRecirculate(marina, 1);        break; // passes, 24-Mar (+verilog)
2274                 case 4:    getCtrsFlags(marina);                   break; //         20-Apr (+verilog)
2275                 case 5:    sendInstructions(marina);               break; // passes, 24-Mar (+verilog)
2276                 case 6:    walkOneOLC(marina);                     break; //         21-Apr (+verilog)
2277                 
2278                     // Russell's tests begin with 1000
2279                 case 1000: walkOneILC(marina);                     break; //         20-Apr (+verilog)
2280                 case 1001: countIlc(marina);                       break; //         20-Apr (+verilog)
2281                 case 1002: countOlc(marina);                       break; //         23-Apr (+verilog)
2282
2283                 case 1003: sendTorpedo(marina);                    break; //         23-Apr (+verilog)  [with wor-hack]
2284
2285                 case 1004: flipIlcBit(marina);                     break; //         20-Apr (+verilog)
2286                 case 1005: flipOlcBit(marina);                     break; //         21-Apr (+verilog)
2287
2288                 case 1006: testSouthRecirculate(marina, Marina.SOUTH_RING_CAPACITY-1);        break; // passes, 24-Mar (+verilog)
2289
2290                     // Adam's tests begin with 3000
2291                 case 3000: sendToken(marina);                      break; // passes, 24-Mar (+verilog)
2292                 case 3001: testFlagAB(marina);                     break; // passes, 08-Apr (+verilog)
2293                 case 3002: testPredicationOnAB(marina);            break; //         22-Apr (+verilog)
2294                 case 3003: testFlagC(marina);                      break; //         23-Apr (+verilog)
2295                 case 3004: testFlagD(marina);                      break; //         23-Apr (+verilog)
2296                 case 3005: testFlagDRecomputationTime(marina);     break;
2297
2298                 case 3006: testTailWaitsForHead(marina);           break;
2299                 case 3007: testTailWithoutHead(marina);            break;
2300                 case 3008: testHeadWaitsForTail(marina);           break; //         22-Apr (+verilog)
2301                 case 3009: testAbort(marina);                      break; //         22-Apr (+verilog)
2302
2303                 case 3010: sendData(marina);                       break; // passes, 24-Mar (+verilog)
2304                 case 3011: recvData(marina);                       break; //         21-Apr (+verilog)
2305                 case 3012: sendDataWithPath(marina);               break; // passes, 13-Apr (+verilog)
2306
2307                 case 3013: testSignExtendedLiteral(marina);        break; //         20-Apr (+verilog)
2308                 case 3014: testShiftedLiteral(marina);             break; //         20-Apr (+verilog)
2309                 case 3015: testSendAndRecvToken(marina);           break; //         21-Apr (+verilog)
2310
2311                 case 3016: sendDataIlcInfinite(marina);            break; //         22-Apr (+verilog)
2312                 case 3017: testFlagTruthTable(marina);             break; //         23-Apr (+verilog)
2313
2314                 case 3019: setOlcFromDataLatch(marina);            break; //         23-Apr (+verilog)
2315                 case 3020: setIlcFromDataLatch(marina);            break; //         23-Apr (+verilog)
2316                 case 3021: recvPath(marina);                       break; //         22-Apr (+verilog)
2317                 case 3022: testILC(marina);                        break; //         23-Apr (+verilog)
2318                 case 3023: testTorpedoOnAnInfinite(marina);        break; //         23-Apr (+verilog)
2319                 case 3024: testRecvAndSendWalkingOne(marina);      break; //         21-Apr (+verilog)
2320                 case 3025: testOlcDecrementAtHighSpeed(marina);    break; //         23-Apr (+verilog)
2321
2322                 case 3026: testNonTorpedoableMoveDoesNotResetDFlag(marina);        break; //         23-Apr (+verilog)
2323                 case 3027: testILCZero(marina);                    break;
2324                 case 3028: testAbortOutsideOfLoop(marina); break;
2325                 case 3029: testDFlagWhenTorpedoLyingInWait(marina); break;
2326                 case 3030: testSetOlcFollowedByDPredicated(marina); break;
2327                 case 3031: testOverfillTokens(marina); break;
2328
2329                 case 3040: loadEveryValueOLC(marina); break;
2330
2331                 default:
2332                     fatal(true, "Test number: "+testNum+" doesn't exist.");
2333                     break;
2334             }
2335             // If we get here then test passed
2336             prln("Test Result: Passed");
2337             printTestTime();
2338             //Infrastructure.exit(0);
2339         } catch (MarinaUtils.FailureException fe) {
2340             System.out.println("******************************************************************************");
2341             System.out.println("******************************************************************************");
2342             System.out.println("******************************************************************************");
2343             System.out.println("******************************************************************************");
2344             fe.printStackTrace();
2345         }
2346     }
2347
2348
2349     //============================ for public use =============================
2350
2351     /** Exit codes:
2352      * 0: test detected success
2353      * 2: test detected failure
2354      * 1: test crashed
2355      */ 
2356     public static void main(String[] args) {
2357         startTime = System.currentTimeMillis();
2358         new MarinaTest(args);
2359     }
2360
2361 }