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