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