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