test script updates
[fleet.git] / testCode / com / sun / vlsi / chips / marina / test / MarinaTest.java
index cc2d2b9..9a5df19 100644 (file)
@@ -14,6 +14,7 @@ import com.sun.async.test.JtagSubchainTesterModel;
 import com.sun.async.test.JtagTester;
 import com.sun.async.test.ManualPowerChannel;
 import com.sun.async.test.NanosimModel;
+import com.sun.async.test.HsimModel;
 import com.sun.async.test.VerilogModel;
 import com.sun.async.test.Netscan4;
 import com.sun.async.test.PowerChannel;
@@ -46,9 +47,7 @@ public class MarinaTest {
 
     public static final int INSTR_SZ = 36;
 
-    public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE  = 13;
-    public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = 0;
-        
+       
     public static final Instruction.Set.FlagFunction CLEAR_FLAG 
         = Instruction.Set.FlagFunction.ZERO;
     public static final Instruction.Set.FlagFunction SET_FLAG 
@@ -99,14 +98,14 @@ public class MarinaTest {
     private static final int MORE_THAN_DATA_OUT_SATURATION_AMOUNT = 10;
         
     // Nominal cycle time assuming 4 GHz throughput
-    private static final double CYCLE_TIME_NS = 0.250;
+    public static double CYCLE_TIME_NS;
 
     //--------------------------------  types ---------------------------------
 
     //--------------------------  private data --------------------------------
     private static long startTime;
 
-    private Indenter indenter = new Indenter();
+    public static Indenter indenter = new Indenter();
     private Marina marina;
     private ChipModel model;
     //private ChainControl cc;
@@ -114,6 +113,9 @@ public class MarinaTest {
     private CmdArgs cmdArgs;
     private PowerChannel corePowerSupply, padsPowerSupply;
     private VoltageReadable coreVoltmeter, voltmeterForCurrent;
+
+    private ChainTest ctD, ctR, ctC, ct;
+    private ChainControl ccD, ccR, ccC, cc;
         
     //--------------------------  private methods -----------------------------
     /** @return true if simulation. Return false if we're testing silicon. */
@@ -123,16 +125,8 @@ public class MarinaTest {
     private void pr(String msg) {indenter.pr(msg);}
     private void adjustIndent(int n) {indenter.adjustIndent(n);}
         
-    public static void fatal(boolean pred, String msg) {
-        if (pred) {
-            Exception err = new Exception(msg);
-            err.printStackTrace();
-            System.out.println("Test Result: Test Failed");
+    public static void fatal(boolean pred, String msg) { MarinaUtils.fatal(pred, msg); }
 
-            printTestTime();
-            Infrastructure.exit(2);
-        }
-    }
     public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
         // FIXME: better error reporting needed here
 
@@ -219,72 +213,67 @@ public class MarinaTest {
                 fatal(true, "unrecognized CmdArgs.Mode");
                 return;
         }
-        model = cmdArgs.useVerilog ? new VerilogModel() : new NanosimModel();
-        
-        //tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
+        model = cmdArgs.useVerilog
+            ? new VerilogModel()
+            : cmdArgs.useHsim
+            ? new HsimModel()
+            : new NanosimModel();
+            
+        ((SimulationModel)model).setOptimizedDirectReadsWrites(true);
+
+        CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250;
+        int khz   = model instanceof VerilogModel ?  100000 : 1000000;
+
+        JtagTester tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
+        tester.printInfo = false;
         ChainControls ccs = new ChainControls();
+        PowerChannel pc = new ManualPowerChannel("pc", false);
+        /*
         JtagTester testerD, testerR, testerC;
         testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null); 
         testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null); 
         testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null); 
         testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
 
-        int khz   = model instanceof VerilogModel ?  100000 : 1000000;
-        
-        ChainControl ccD, ccR, ccC;
         ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
         ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
         ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
         ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
+
         
-        PowerChannel pc = new ManualPowerChannel("pc", false);
-        
-        ChainTest ctD, ctR, ctC;
         ctD = new ChainTest(ccD, pc);
         ctR = new ChainTest(ccR, pc);
         ctC = new ChainTest(ccC, pc);
-        
-        if (model instanceof VerilogModel) {
-            VerilogModel vm = (VerilogModel)model;
-            vm.start("verilog", "marina.v", VerilogModel.DUMPVARS);
-            vm.setNodeState("sid[9]", 1);
-            vm.setNodeState("sic[9]", 1);
-            vm.setNodeState("sir[9]", 1);
-            model.waitNS(1000);
-            vm.setNodeState("sid[9]", 0);
-            vm.setNodeState("sic[9]", 0);
-            vm.setNodeState("sir[9]", 0);
-            model.waitNS(1000);
-        } else {
-            ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
-            System.out.println("**** vdd="+((NanosimModel)model).getVdd());
-        }
-
-        if (cmdArgs.testChains) {
-            ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
-        }
-        ccC.resetInBits();
-        ccC.shift(Marina.CONTROL_CHAIN, false, true);
-        if (cmdArgs.testChains) {            
-            ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
-            //ccD.resetInBits();
-            //ccD.shift(Marina.DATA_CHAIN, false, true);
-            
-            ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
-            //ccR.resetInBits();
-            //ccR.shift(Marina.REPORT_CHAIN, false, true);
-        }
-
+        */        
+        /*
         ccs.addChain(Marina.DATA_CHAIN, ccD);
         ccs.addChain(Marina.REPORT_CHAIN, ccR);
         ccs.addChain(Marina.CONTROL_CHAIN, ccC);
+        */
+
+        cc = new ChainControl(SCAN_CHAIN_XML, tester, 1.8f, khz);
+        ct = new ChainTest(cc, pc);
+        ccs.addChain(Marina.DATA_CHAIN, cc);
+        ccs.addChain(Marina.REPORT_CHAIN, cc);
+        ccs.addChain(Marina.CONTROL_CHAIN, cc);
 
         marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter);
 
-        //System.out.println("launching");
-        //ChainG.createAndShowGUI(marina.cc.getChainControlFromPath(Marina.REPORT_CHAIN));
-        //System.out.println("  launched.");
+        if (model instanceof VerilogModel)
+            ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift);
+        else if (model instanceof HsimModel)
+            ((SimulationModel)model).start("hsim64", netListName, 0, !cmdArgs.jtagShift);
+        else
+            ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
 
+        /*
+        ccC.resetInBits();
+        ccC.shift(Marina.CONTROL_CHAIN, false, true);
+        */
+
+        cc.resetInBits();
+        cc.shift(Marina.CONTROL_CHAIN, false, true);
+        
         doOneTest(cmdArgs.testNum);
         
         ((SimulationModel)model).finish();
@@ -305,11 +294,8 @@ public class MarinaTest {
         PowerChannel pc = new ManualPowerChannel("pc", false);
         ChainTest ct = new ChainTest(cc, pc);
         ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
-
         doOneTest(cmdArgs.testNum);
-        
         setUpSuppliesAndMeters(cmdArgs.station);
-                
     }
 
     /** In the absence of looping, the longest path through Infinity is 4 column delays */
@@ -455,6 +441,40 @@ public class MarinaTest {
     //=========================================================================
     // Put top level tests here
 
+    private void testChains(Marina marina) {
+        if (ctC!=null) {
+            prln("Testing control chain...");
+            ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
+            ccC.resetInBits();
+            ccC.shift(Marina.CONTROL_CHAIN, false, true);
+        }
+        
+        if (ctD!=null) {
+            prln("Testing data chain...");
+            ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
+            //ccD.resetInBits();
+            //ccD.shift(Marina.DATA_CHAIN, false, true);
+        }
+        
+        if (ctR!=null) {
+            prln("Testing report chain...");            
+            ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
+            //ccR.resetInBits();
+            //ccR.shift(Marina.REPORT_CHAIN, false, true);
+        }
+
+        if (ct!=null) {
+            prln("Testing control chain...");
+            ct.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
+            cc.resetInBits();
+            cc.shift(Marina.CONTROL_CHAIN, false, true);
+            prln("Testing data chain...");
+            ct.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
+            prln("Testing report chain...");            
+            ct.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
+        }
+    }
+
     private void testProperStoppers(Marina marina) {
         prln("Begin testProperStoppers");
         adjustIndent(2);
@@ -509,22 +529,8 @@ public class MarinaTest {
         int nbToks = marina.getNumTokens();
         fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens");
 
-        prln("send token");
-        marina.instrIn.fill(
-                            new Instruction.Move(dock,
-                                                 Predicate.IgnoreFlagD, /* predicate   */
-                                                 false,                 /* torpedoable */
-                                                 null,                  /* path        */
-                                                 false,                 /* tokenIn     */
-                                                 false,                 /* dataIn      */
-                                                 false,                 /* latchData   */
-                                                 false,                 /* latchPath   */
-                                                 false,                 /* dataOut     */
-                                                 true                   /* tokenOut    */
-                                                 ));
-        
-        //getCtrsFlags(marina);
-        
+        marina.instrIn.fill(setIlc(1));
+        marina.instrIn.fill(SEND_TOKEN);
         nbToks = marina.getNumTokens();
         fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
         
@@ -536,33 +542,17 @@ public class MarinaTest {
         prln("Begin sendData");
         adjustIndent(2);
         
-        //getCtrsFlags(marina);
-
         edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
         for(int i=0; i<bv.length(); i+=2) bv.set(i, false);
         MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
 
-        prln("send data");
-        marina.instrIn.fill(
-                            new Instruction.Move(dock,
-                                                 Predicate.IgnoreFlagD, /* predicate   */
-                                                 false,                 /* torpedoable */
-                                                 path,                  /* path        */
-                                                 false,                 /* tokenIn     */
-                                                 false,                 /* dataIn      */
-                                                 false,                 /* latchData   */
-                                                 false,                 /* latchPath   */
-                                                 true,                  /* dataOut     */
-                                                 false                  /* tokenOut    */
-                                                 ));
-        
-        //getCtrsFlags(marina);
+        marina.instrIn.fill(setIlc(1));
+        marina.instrIn.fill(SEND_DATA);
         
         List<BitVector> dataItems = marina.data.drainMany();
         fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
 
         MarinaPacket mp = new MarinaPacket(dataItems.get(0));
-        prln("packet: "+mp);
         fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token");
 
         adjustIndent(-2);
@@ -573,16 +563,10 @@ public class MarinaTest {
         prln("Begin sendDataIlcInfinite");
         adjustIndent(2);
         
-        prln("ILC=\\infty");
-        marina.instrIn.fill(
-                            new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity));
-
-        getCtrsFlags(marina);
-        
-        prln("send data");
-        marina.instrIn.fill(SEND_DATA);
-        
-        getCtrsFlags(marina);
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
+                SEND_DATA,
+            });
         
         // more than MAX_ILC
         int howmany = 70;
@@ -594,15 +578,18 @@ public class MarinaTest {
         prln("End sendDataIlcInfinite");
     }
 
-    private void setOLC(Marina marina, int olc) {
-        // ugly hack, to be removed when we fix the zero-detect circuit
-        for(int i=0; i<2; i++) {
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc));
-        }
+    private Instruction setOlc(int olc) {
+        return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc);
+    }
+    private Instruction setOlcIfZero(int olc) {
+        return new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, olc);
+    }
+    private Instruction setIlc(int ilc) {
+        return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, ilc);
     }
 
-    private void testFlagZ(Marina marina) {
-        prln("Begin testFlagZ");
+    private void testFlagD(Marina marina) {
+        prln("Begin testFlagD");
         adjustIndent(2);
         
         List<BitVector> toks;
@@ -610,39 +597,42 @@ public class MarinaTest {
         Predicate only_if_olc_zero    = Predicate.FlagD;
         Predicate only_if_olc_nonzero = Predicate.Default;
 
+        marina.instrIn.fill(setIlc(1));
+
         for(int olc : new int[] { 1, 0 }) {
             for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
-                prln("Attempting send token with "+
+                prln("Attempting send data item with "+
                      "olc=="+olc+" and "+
                      "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
                 adjustIndent(2);
 
-                prln("Inserting Set OLC="+olc);
-                setOLC(marina, olc);
-
-                prln("Inserting ["+(predicate_olc_nonzero?"olc!=0":"olc==0")+"] send data");
-                marina.instrIn.fill(new Instruction.Move(dock,
-                                                         predicate_olc_nonzero  /* predicate   */
-                                                         ? only_if_olc_nonzero
-                                                         : only_if_olc_zero
-                                                         ,
-                                                         false,                 /* torpedoable */
-                                                         null,                  /* path        */
-                                                         false,                 /* tokenIn     */
-                                                         false,                 /* dataIn      */
-                                                         false,                 /* latchData   */
-                                                         false,                 /* latchPath   */
-                                                         true,                  /* dataOut     */
-                                                         false                  /* tokenOut    */
-                                                         ));
-                toks = marina.data.drainMany();
-                int expected = (predicate_olc_nonzero == (olc!=0)) ? 1 : 0;
-                fatal(toks.size()!=expected, "Expected "+expected+" token to emerge but got: "+toks.size()+" token(s)");
+                marina.fillSouthProperStopper(new Instruction[] {
+                        setOlc(olc),
+                        new Instruction.Move(dock,
+                                             predicate_olc_nonzero  // predicate   
+                                             ? only_if_olc_nonzero
+                                             : only_if_olc_zero
+                                             ,
+                                             false,                 // torpedoable 
+                                             null,                  // path        
+                                             false,                 // tokenIn     
+                                             false,                 // dataIn      
+                                             false,                 // latchData   
+                                             false,                 // latchPath   
+                                             true,                  // dataOut     
+                                             false                  // tokenOut    
+                                             ),
+                    });
+                expectNorthFifoExactly((predicate_olc_nonzero == (olc!=0)) ? 1 : 0);
+
+                for(int i=0; i<olc; i++)
+                    marina.instrIn.fill(DEC);
+
                 adjustIndent(-2);
             }
         }
         adjustIndent(-2);
-        prln("End testFlagZ");
+        prln("End testFlagD");
     }
 
     private void testPredicationOnAB(Marina marina) {
@@ -651,8 +641,8 @@ public class MarinaTest {
         
         List<BitVector> dItems;
 
-        prln("Setting OLC=63");
-        setOLC(marina, 63);
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
 
         for(boolean flag_a : new boolean[] { false, true }) {
             for(boolean flag_b : new boolean[] { false, true }) {
@@ -676,19 +666,18 @@ public class MarinaTest {
                         Predicate.NotFlagB,
                     }) {
 
-                    prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate.getClass().getName());
+                    prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate);
                     adjustIndent(2);
-                    marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
                     marina.instrIn.fill(new Instruction.Move(dock,
-                                                             predicate,             /* predicate   */
-                                                             false,                 /* torpedoable */
-                                                             null,                  /* path        */
-                                                             false,                 /* tokenIn     */
-                                                             false,                 /* dataIn      */
-                                                             false,                 /* latchData   */
-                                                             false,                 /* latchPath   */
-                                                             true,                 /* dataOut     */
-                                                             false                  /* tokenOut    */
+                                                             predicate,  // predicate   
+                                                             false,      // torpedoable 
+                                                             null,       // path        
+                                                             false,      // tokenIn     
+                                                             false,      // dataIn      
+                                                             false,      // latchData   
+                                                             false,      // latchPath   
+                                                             true,       // dataOut     
+                                                             false       // tokenOut    
                                                              ));
                     adjustIndent(-2);
                     dItems = marina.data.drainMany();
@@ -704,38 +693,47 @@ public class MarinaTest {
     }
 
 
+    private void showOlc() {
+        prln("OLC=="+marina.getOLC());
+    }
+    private void expectOlc(int x) {
+        int olc = marina.getOLC();
+        fatal(x!=olc, "expected OLC=="+x+", but scanned out OLC=="+olc);
+    }
 
     private void getCtrsFlags(Marina marina) {
         prln("begin getCtrsFlags");
         adjustIndent(2);
         
-        int olc = marina.getOLC();
-        prln("OLC=="+olc);
-        
+        showOlc();
         Ilc ilc = marina.getILC();
         prln("ILC.done=="+ilc.getDone()+
              " ILC.infinity=="+ilc.getInfinity()+
              " ILC.count=="+ilc.getCount());
-        
-        boolean a = marina.getFlagA();
-        prln("flagA=="+a);
-        
-        boolean b = marina.getFlagB();
-        prln("flagB=="+b);
-        
+        prln("flagA=="+marina.getFlagA());
+        prln("flagB=="+marina.getFlagB());
         adjustIndent(-2);
         prln("end getCtrsFlags");
     }
+
     private void walkOneOLC(Marina marina) {
         prln("Begin walkOneOLC");
         adjustIndent(2);
-        for (int i=6; i>=0; i--) {
-            int inOlc = 0x20 >> i;
-            prln("Set inOlc="+inOlc);
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
-            int outOlc = marina.getOLC();
-            fatal(outOlc!=inOlc, "walkOneOLC: got="+outOlc+" expected="+inOlc);
+        for (int i=0; i<6; i++) {
+
+            if (marina.kesselsCounter) {
+                System.out.println("master-clearing...");
+                // master clear on each iteration; otherwise we'd need to "run down" the olc
+                marina.masterClear();
+                marina.enableInstructionSend(true);
+            }
+
+            int inOlc = i==-1 ? 0 : (1<<i);
+            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
+
+            model.waitNS(128 * CYCLE_TIME_NS);
+
+            expectOlc(inOlc);
             prln("walkOneOLC: "+inOlc+" checks out");
         }
         adjustIndent(-2);
@@ -748,19 +746,14 @@ public class MarinaTest {
             // Mask off the "zero" bit position
             int inIlc = 1 << i;
             prln("inIlc="+inIlc);
-
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
-
+            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
             Ilc ilc = marina.getILC();
             int outIlc = ilc.getCount();
-            fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+outIlc);
-
+            fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc);
             fatal(ilc.getInfinity(), "bad Infinity bit: true");
         }
         prln("Now test the infinity bit");
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
         Ilc ilc = marina.getILC();
         fatal(!ilc.getInfinity(), "bad Infinity bit: false");
         adjustIndent(-2);
@@ -771,7 +764,6 @@ public class MarinaTest {
         prln("Begin countIlc");
         adjustIndent(2);
         
-        prln("Set ILC=63");
         marina.instrIn.fill(new 
                             Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
 
@@ -781,19 +773,20 @@ public class MarinaTest {
         prln("execute a move instruction that does nothing except decrement the ILC to zero");
         marina.instrIn.fill(
                             new Instruction.Move(dock,
-                                                 Predicate.IgnoreFlagD, /* predicate   */
-                                                 false,                 /* torpedoable */
-                                                 null,                  /* path        */
-                                                 false,                 /* tokenIn     */
-                                                 false,                 /* dataIn      */
-                                                 false,                 /* latchData   */
-                                                 false,                 /* latchPath   */
-                                                 false,                 /* dataOut     */
-                                                 false                  /* tokenOut    */
+                                                 Predicate.IgnoreFlagD, // predicate   
+                                                 false,                 // torpedoable 
+                                                 null,                  // path        
+                                                 false,                 // tokenIn     
+                                                 false,                 // dataIn      
+                                                 false,                 // latchData   
+                                                 false,                 // latchPath   
+                                                 false,                 // dataOut     
+                                                 false                  // tokenOut    
                                                  ));
         
         // wait for ILC to count from 63 to 0
-        model.waitNS(64 * CYCLE_TIME_NS);
+        model.waitNS(128 * CYCLE_TIME_NS);
+        //model.waitNS(10000);
 
         prln("Check that ILC==0");
         ilc = marina.getILC().getCount();
@@ -804,16 +797,16 @@ public class MarinaTest {
     }
     // Note: countOlc takes 44 minutes to run on nanosim
     private void countOlc(Marina marina) {
-        final int maxOlc = 63;
+        int maxOlc = 63;
         prln("Begin countOlc");
         adjustIndent(2);
-        
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, maxOlc));
+
+        marina.instrIn.fill(setOlc(maxOlc));
+
         for (int i=maxOlc; i>=0; i--) {
+            model.waitNS(128 * CYCLE_TIME_NS);
             prln("OLC should be: "+i);
-            int olc = marina.getOLC();
-            fatal(olc!=i, "bad OLC: "+olc+" expected: "+i);
+            expectOlc(i);
             marina.instrIn.fill(new 
                                 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
         }
@@ -842,6 +835,17 @@ public class MarinaTest {
         prln("Successfully inserted " + i + " instructions");
     }
 
+    private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(),
+                                                         MarinaUtils.sunToBerk(MarinaPacket.null_path));
+
+    private static final Instruction DEC = 
+        new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, SetSource.Decrement);
+
+    private static final Instruction FLAG_NOP =
+        new Instruction.Set(dock, Predicate.IgnoreFlagD,
+                            CLEAR_FLAG.add(Predicate.FlagA),
+                            CLEAR_FLAG.add(Predicate.FlagB));
+
     private static final Instruction NOP =
         new Instruction.Move(dock,
                              Predicate.IgnoreFlagD,   /* predicate   */
@@ -855,24 +859,24 @@ public class MarinaTest {
                              false                  /* tokenOut    */
                              );
 
-    private static final Instruction REQUEUEING_NOP =
+    private static final Instruction SEND_DATA =
         new Instruction.Move(dock,
                              Predicate.IgnoreFlagD,   /* predicate   */
                              false,                 /* torpedoable */
-                             null,                  /* path        */
+                             null_path,                  /* path        */
                              false,                 /* tokenIn     */
                              false,                 /* dataIn      */
                              false,                 /* latchData   */
                              false,                 /* latchPath   */
-                             false,                 /* dataOut     */
+                             true,                  /* dataOut     */
                              false                  /* tokenOut    */
                              );
 
-    private static final Instruction SEND_DATA =
+    private static final Instruction SEND_DATA_IF_D_NOT_SET =
         new Instruction.Move(dock,
-                             Predicate.IgnoreFlagD,   /* predicate   */
+                             Predicate.Default,     /* predicate   */
                              false,                 /* torpedoable */
-                             null,                  /* path        */
+                             null_path,             /* path        */
                              false,                 /* tokenIn     */
                              false,                 /* dataIn      */
                              false,                 /* latchData   */
@@ -881,10 +885,10 @@ public class MarinaTest {
                              false                  /* tokenOut    */
                              );
 
-    private static final Instruction RECV_DATA =
+    private static final Instruction TORPEDOABLE_RECV_DATA =
         new Instruction.Move(dock,
-                             Predicate.IgnoreFlagD,   /* predicate   */
-                             false,                 /* torpedoable */
+                             Predicate.IgnoreFlagD, /* predicate   */
+                             true,                  /* torpedoable */
                              null,                  /* path        */
                              false,                 /* tokenIn     */
                              true,                  /* dataIn      */
@@ -894,306 +898,292 @@ public class MarinaTest {
                              false                  /* tokenOut    */
                              );
 
-    private static final Instruction SEND_TOKEN =
+    private static final Instruction RECV_DATA =
         new Instruction.Move(dock,
                              Predicate.IgnoreFlagD,   /* predicate   */
                              false,                 /* torpedoable */
                              null,                  /* path        */
                              false,                 /* tokenIn     */
-                             false,                 /* dataIn      */
-                             false,                 /* latchData   */
+                             true,                  /* dataIn      */
+                             true,                  /* latchData   */
                              false,                 /* latchPath   */
                              false,                 /* dataOut     */
-                             true                   /* tokenOut    */
+                             false                  /* tokenOut    */
                              );
 
-    private static final Instruction RECV_TOKEN =
+    private static final Instruction SEND_TOKEN =
         new Instruction.Move(dock,
                              Predicate.IgnoreFlagD,   /* predicate   */
                              false,                 /* torpedoable */
-                             null,                  /* path        */
-                             true,                  /* tokenIn     */
+                             null_path,                  /* path        */
+                             false,                 /* tokenIn     */
                              false,                 /* dataIn      */
                              false,                 /* latchData   */
                              false,                 /* latchPath   */
                              false,                 /* dataOut     */
-                             false                  /* tokenOut    */
+                             true                   /* tokenOut    */
                              );
 
-    private static final Instruction REQUEUEING_SEND_DATA =
+    private static final Instruction RECV_TOKEN =
         new Instruction.Move(dock,
                              Predicate.IgnoreFlagD,   /* predicate   */
                              false,                 /* torpedoable */
                              null,                  /* path        */
-                             false,                 /* tokenIn     */
+                             true,                  /* tokenIn     */
                              false,                 /* dataIn      */
                              false,                 /* latchData   */
                              false,                 /* latchPath   */
-                             true,                  /* dataOut     */
+                             false,                 /* dataOut     */
                              false                  /* tokenOut    */
                              );
 
-    private void testRequeueStage0(Marina marina) {
-        prln("Begin testRequeueStage0");
-        adjustIndent(2);
 
-        prln("Executing Set OLC=0");
-        setOLC(marina, 0);
-        saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false);
-        adjustIndent(-2);
-        prln("End testRequeueStage0");
+    private void expectNorthFifoNoMoreThan(int num) {
+        model.waitNS(128 * CYCLE_TIME_NS);
+        List<BitVector> dataItems = marina.data.drainMany(num+1);
+        fatal(dataItems.size()>num,
+              "Expected no more than "+num+
+              " data items to emerge but got at least: "+dataItems.size());
     }
-
-    private void testRequeueStage0to1(Marina marina) {
-        prln("Begin testRequeueStage0to1");
-        adjustIndent(2);
-
-        prln("Executing Set OLC=63");
-        setOLC(marina, 63);
-        saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true);
-        adjustIndent(-2);
-        prln("End testRequeueStage0to1");
+    private void expectNorthFifoExactly(int num) {
+        model.waitNS(128 * CYCLE_TIME_NS);
+        List<BitVector> dataItems = marina.data.drainMany(num+1);
+        fatal(dataItems.size()!=num,
+              "Expected exactly "+num+
+              " data items to emerge but got at least: "+dataItems.size());
+    }
+    private void expectTokensNoMoreThan(int num) {
+        int x = marina.getNumTokens();
+        List<BitVector> dataItems = marina.data.drainMany(num+1);
+        fatal(x>num,
+              "Expected no more than "+num+
+              " data items to emerge but got at least: "+x);
+    }
+    private void expectTokensExactly(int num) {
+        int x = marina.getNumTokens();
+        fatal(x!=num,
+              "Expected exactly "+num+
+              " data items to emerge but got at least: "+x);
     }
 
-    /**
-     *  This test brings the requeue stage through the 0->1->3->0 state
-     *  transition sequence.
-     *
-
-     *  According to the diagram in IES50, there are three transitions
-     *  (0->1, 1->3, 3->0) to perform, and in each state there are two
-     *  behaviors to verify (the two notations in each oval of the
-     *  state diagram).  The "OD->drain" behavior of state 0 is
-     *  verified by testRequeueStage0().
-     */
-    private void testRequeueStage0to1to3to0(Marina marina) {
-        List<BitVector> dataItems;
-
-        int extras = 5;
-        int olc_value = MORE_THAN_DATA_OUT_SATURATION_AMOUNT + extras;
-
-        prln("Begin testRequeueStage0to1to3to0");
-        adjustIndent(2);
-
-        // State 0 //////////////////////////////////////////////////////////////////////////////
-
-        prln("Executing Set OLC="+olc_value);
-        setOLC(marina, olc_value);
-        prln("Executing Set ILC=1");
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
-
-        // verify state0 "EPI->ring" and 0->1 transition
-        prln("Executing Send Data (requeueable); this will cause 0->1 transition and be discarded");
-        marina.instrIn.fill(REQUEUEING_SEND_DATA);
-
-        // State 1 //////////////////////////////////////////////////////////////////////////////
-
-        // verify state1 "EPI->ring"
-        prln("Executing Set ILC=1; this will be recirculated");
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
-
-        prln("Executing Send Data; this will be recirculated");
-        marina.instrIn.fill(REQUEUEING_SEND_DATA);
-
-        prln("Executing Set OLC--; this will be recirculated");
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement));
-
-        // verify state1 "OD waits"
-        dataItems = marina.data.drainMany(2);
-        fatal(dataItems.size()!=1, "Expected exactly one data item to emerge but got: "+dataItems.size()+" data items");
+    private void testFlagDRecomputationTime(Marina marina) {
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                RECV_DATA,
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
+                SEND_DATA_IF_D_NOT_SET
+            });
+        marina.fillNorthProperStopper();
+        expectNorthFifoNoMoreThan(0);
+
+        marina.fillSouthProperStopper(new Instruction[] {
+                RECV_DATA,
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
+                SEND_DATA_IF_D_NOT_SET
+            });
+        marina.fillNorthProperStopper();
+        expectNorthFifoNoMoreThan(0);
+
+        marina.fillSouthProperStopper(new Instruction[] {
+                RECV_DATA,
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
+                SEND_DATA_IF_D_NOT_SET
+            });
+        marina.fillNorthProperStopper();
+        expectNorthFifoExactly(1);
+        marina.instrIn.fill(DEC);
+
+        marina.fillSouthProperStopper(new Instruction[] {
+                RECV_DATA,
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
+                SEND_DATA_IF_D_NOT_SET
+            });
+        marina.fillNorthProperStopper();
+        expectNorthFifoExactly(1);
+    }
 
-        // verify 1->3 transition
-        prln("Executing Tail; this will cause the 2->3 transition and be discarded");
+    private void testTailWaitsForHead(Marina marina) {
+        marina.instrIn.fill(setIlc(1));
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
+        
+        marina.enableInstructionSend(false);
+        marina.enableInstructionRecirculate(true);
+        
+        marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
+        marina.instrIn.fill(new Instruction.Head(dock));
+        marina.instrIn.fill(SEND_DATA);
+        marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
+        marina.instrIn.fill(SEND_TOKEN);
+        marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
         marina.instrIn.fill(new Instruction.Tail(dock));
+        marina.instrIn.fillTorpedo();
+        
+        marina.enableInstructionRecirculate(false);
+        marina.enableInstructionSend(true);
+        marina.instrIn.run();
+        
+        expectNorthFifoNoMoreThan(0);
+        prln("inserting into north proper stopper");
+        marina.fillNorthProperStopper();
+        expectNorthFifoExactly(1);
+        int nbToks = marina.getNumTokens();
+        fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
+    }
 
-        // State 3 //////////////////////////////////////////////////////////////////////////////
+        /*
+        marina.instrIn.fill(setIlc(1));
+        marina.instrIn.fill(setOlc(1));
 
-        // verify state3 "OD->ring"
-        dataItems = marina.data.drainMany(MORE_THAN_DATA_OUT_SATURATION_AMOUNT);
-        fatal(dataItems.size()<MORE_THAN_DATA_OUT_SATURATION_AMOUNT,
-              "Expected more than " + MORE_THAN_DATA_OUT_SATURATION_AMOUNT +
-              " data items, but only got: "+dataItems.size()+" of them");
+        // this makes the head wait for the torpedo
+        marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
 
-        // verify state3 "OD->ring"
-        saturateInstructionFifo(marina, NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true);
+        // the head should wait for the tail
+        marina.instrIn.fill(new Instruction.Head(dock));
+        marina.instrIn.fill(NOP);
+        marina.instrIn.fill(SEND_DATA);
+        marina.instrIn.fill(RECV_DATA);
 
-        // verify state3->state0
-        dataItems = marina.data.drainMany(extras + 4);
-        fatal(dataItems.size()!=(extras+1),
-              "Expected exactly " + (extras+1) + " items to emerge, but got at least : "+dataItems.size()+" of them");
+        expectNorthFifoNoMoreThan(0);
 
-        // State 0 //////////////////////////////////////////////////////////////////////////////
+        marina.instrIn.fillTorpedo();
+        expectNorthFifoNoMoreThan(0);
 
-        // verify that we are back in state0
-        saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false);
+        marina.instrIn.fill(new Instruction.Tail(dock));
+        expectNorthFifoExactly(1);
+        */
 
-        adjustIndent(-2);
-        prln("End testRequeueStage0to1to3to0");
+    private void testTailWithoutHead(Marina marina) {
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
+                new Instruction.Tail(dock),
+                SEND_DATA,
+            });
+        List<BitVector> dataItems = marina.data.drainMany(1);
+        fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
     }
 
-    /**
-     *  This test brings the requeue stage through the 0->2->3->0 state
-     *  transition sequence.
-     *
-     *  According to the diagram in IES50, there are two transitions
-     *  (0->2, 2->3, 3->0) to perform, and in each state there are two
-     *  behaviors to verify (the two notations in each oval of the
-     *  state diagram).  The "OD->drain" behavior of state 0 is
-     *  verified by testRequeueStage0().
-     */
-    private void testRequeueStage0to2to3to0(Marina marina) {
+    private void testHeadWaitsForTail(Marina marina) {
         List<BitVector> dataItems;
 
-        int olc_value = 10;
-        int number_of_non_requeueable_send_datas = INSTRUCTION_RING_CAPACITY;
-
-        prln("Begin testRequeueStage0to2to3to0");
+        prln("Begin testHeadWaitsForTail");
         adjustIndent(2);
 
-        // State 0 //////////////////////////////////////////////////////////////////////////////
-
-        prln("Executing Set OLC="+olc_value);
-        setOLC(marina, olc_value);
-
-        prln("Executing Set ILC=1");
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
-
-        // insert many non-requeueing "send data item" instructions;
-        // this will let us single-step the execution point by
-        // extracting data items.
-        for(int i=0; i<number_of_non_requeueable_send_datas; i++) {
-            prln("Inserting Send Data");
-            marina.instrIn.fill(SEND_DATA);
-        }
-
-        // this will send us a token later
-        prln("Inserting [Rq] Nop; this will be discarded");
-        marina.instrIn.fill(REQUEUEING_NOP);
-
-        // this will send us a token later
-        prln("Inserting [Rq] Send Data; this will be recirculated");
-        marina.instrIn.fill(REQUEUEING_SEND_DATA);
-
-        prln("Inserting [Rq] Set OLC--; this will be recirculated");
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement));
-
-        // insert the tail, which will cause the 0->2 transition
-        prln("Inserting Tail");
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
+                new Instruction.Head(dock),
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
+                SEND_DATA,
+            });
+        dataItems = marina.data.drainMany(1);
+        fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
         marina.instrIn.fill(new Instruction.Tail(dock));
 
-        // State 2 //////////////////////////////////////////////////////////////////////////////
-
-        // confirm state 2 "EPI waits"
-        prln("Saturating the instruction input to confirm that EPI waits");
-        saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true);
-
-        // confirm state 2 "OD->drain"
-        prln("Draining data output to cause the 2->3 transition");
-        dataItems = marina.data.drainMany(number_of_non_requeueable_send_datas);
-        fatal(dataItems.size()!=number_of_non_requeueable_send_datas,
-              "Expected at least " + number_of_non_requeueable_send_datas +
-              " items to emerge, but got only : "+dataItems.size()+" of them");
-
-        // State 3 //////////////////////////////////////////////////////////////////////////////
-
-        // verify state3 "EPI waits"
-        prln("Verifying that EPI still waits in state3");
-        fatal(marina.instrIn.getFillStateWire()!=MarinaUtils.StateWireState.FULL,
-              "state3 EPI waits not verified");
-        prln("  ok");
-        prln("");
-
-        // verify state3 "OD->ring" and state3->state0
-        prln("Removing data items to run down the OLC to zero and cause 3->0 transition");
-        dataItems = marina.data.drainMany(olc_value+10);
-        fatal(dataItems.size()!=(olc_value+1),
-              "Expected exactly " + (olc_value+1) + " items to emerge, but got: "+dataItems.size()+" of them");
-
-        // State 0 //////////////////////////////////////////////////////////////////////////////
-
-        // verify that we are back in state0
-        prln("Confirming that we are back in state0");
-        saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false);
+        BitVector bv = marina.data.drain();
+        fatal(bv==null, "Expected at least one data item to emerge but got none");
 
         adjustIndent(-2);
-        prln("End testRequeueStage0to2to3to0");
+        prln("End testHeadWaitsForTail");
     }
 
-    private void testWaitForTail(Marina marina) {
-        List<BitVector> dataItems;
-
-        prln("Begin testWaitForTail");
-        adjustIndent(2);
-
-        prln("inserting instruction: Set OLC=63");
-        setOLC(marina, 63);
-
-        prln("inserting instruction: [Rq] Nop; this will cause 0->1 transition and possibly be discarded");
-        marina.instrIn.fill(REQUEUEING_NOP);
+    private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) {
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,63),
+                new Instruction.Move(dock,
+                                     Predicate.IgnoreFlagD, // predicate   
+                                     true,                  // torpedoable 
+                                     null,                  // path        
+                                     true,                  // tokenIn     
+                                     false,                 // dataIn      
+                                     false,                 // latchData   
+                                     false,                 // latchPath   
+                                     false,                 // dataOut     
+                                     false                  // tokenOut    
+                                     ),
+                new Instruction.Move(dock,
+                                     Predicate.FlagD,       // predicate   
+                                     false,                 // torpedoable 
+                                     null,                  // path        
+                                     false,                 // tokenIn     
+                                     false,                 // dataIn      
+                                     false,                 // latchData   
+                                     false,                 // latchPath   
+                                     true,                  // dataOut     
+                                     false                  // tokenOut    
+                                     ),
+            });
+        marina.instrIn.fillTorpedo();
+        expectNorthFifoExactly(1);
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Move(dock,
+                                     Predicate.Default,     // predicate   
+                                     false,                 // torpedoable 
+                                     null,                  // path        
+                                     false,                 // tokenIn     
+                                     false,                 // dataIn      
+                                     false,                 // latchData   
+                                     false,                 // latchPath   
+                                     true,                  // dataOut     
+                                     false                  // tokenOut    
+                                     ),
+            });
+        expectNorthFifoNoMoreThan(0);
+    }
 
-        // just in case there is some capacity between the execution
-        // stage and the requeue stage, we stick in a whole bunch of
-        // NOPs.
+    private void testAbort(Marina marina) {
+        
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1),
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
+                SEND_DATA_IF_D_NOT_SET,
+                new Instruction.Head(dock),
+                SEND_DATA_IF_D_NOT_SET,
+                new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2),
+                new Instruction.Abort(dock, Predicate.FlagD),
+                new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement),
+                new Instruction.Tail(dock),
+            }, true);
+        
         for(int i=0; i<4; i++) {
-            prln("inserting instruction: [Rq] Nop; this (and subsequent instructions) should not execute until Tail is inserted");
-            marina.instrIn.fill(REQUEUEING_NOP);
+            BitVector bv;
+            
+            model.waitNS(128 * CYCLE_TIME_NS);
+            bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
+            fatal(bv==null, "no data item found");
+            prln("got " + bv.toLong());
+            fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
+            
+            model.waitNS(128 * CYCLE_TIME_NS);
+            bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
+            fatal(bv==null, "no data item found");
+            prln("got " + bv.toLong());
+            fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
+            
+            model.waitNS(128 * CYCLE_TIME_NS);
+            bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
+            fatal(bv==null, "no data item found");
+            prln("got " + bv.toLong());
+            fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong());
+            
         }
-
-        prln("inserting instruction: [Rq] Set ILC=1");
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
-
-        prln("inserting instruction: [Rq] Send Data");
-        marina.instrIn.fill(REQUEUEING_SEND_DATA);
-
-        dataItems = marina.data.drainMany(1);
-        fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
-
-        adjustIndent(-2);
-        prln("End testWaitForTail");
     }
 
-    // This test case will FAIL if the requeue stage behaves as
-    // described in IES50.  If we determine that the behavior
-    // described there is actually desirable, then this test should be
-    // modified.
-    private void testRequeueStageDrop(Marina marina) {
-        List<BitVector> dataItems;
-
-        prln("Begin testRequeueStageDrop");
-        adjustIndent(2);
-
-        // We have decided that this issue will not be fixed in
-        // Marina.  Therefore, the test is commented out.
-
-        /*
-          prln("inserting instruction: Set OLC=63");
-          setOLC(marina, 63);
-
-          prln("inserting instruction: Set ILC=1");
-          marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
-
-          // if you uncomment this, then the NOP will be dropped and the test will pass
-          //prln("inserting instruction: [Rq] Nop; this will cause 0->1 transition and possibly be discarded");
-          //marina.instrIn.fill(REQUEUEING_NOP);
-
-          prln("inserting instruction: [Rq] Send Data; this will cause 0->1 transition and be discarded");
-          marina.instrIn.fill(REQUEUEING_SEND_DATA);
-
-          prln("inserting instruction: [Rq] Set ILC=1");
-          marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
-
-          prln("inserting instruction: Tail");
-          marina.instrIn.fill(new Instruction.Tail(dock));
-
-          dataItems = marina.data.drainMany(3);
-          fatal(dataItems.size()<3, "Expected exactly unlimited data items to emerge but got only: "+dataItems.size());
-        */
-
-        adjustIndent(-2);
-        prln("End testRequeueStageDrop");
+    private void testAbortOutsideOfLoop(Marina marina) {
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                // ensure that an abort doesn't cause problems if no loop is in progress
+                new Instruction.Abort(dock, Predicate.IgnoreFlagD),
+                SEND_DATA,
+            });
+        expectNorthFifoExactly(1);
     }
 
-
     private void testFlagAB(Marina marina) {
         prln("Begin testFlagAB");
         adjustIndent(2);
@@ -1213,18 +1203,34 @@ public class MarinaTest {
         one = one.add(Predicate.FlagC);
         one = one.add(Predicate.NotFlagC);
 
-        // clear the flags to a known state, then check both 0->1 and 1->0 transitions
-        for(boolean b : new boolean[] { false, true, false }) {
-            prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
-            prln((b?"Setting":"Clearing")+" flags");
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
+        for(boolean fast : new boolean[] { true, false }) {
+            // clear the flags to a known state, then check both 0->1 and 1->0 transitions
+            for(boolean b : new boolean[] { false, true, false }) {
+                prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
+                prln((b?"Setting":"Clearing")+" flags");
+                
+                Instruction inst = new Instruction.Set(dock,Predicate.IgnoreFlagD,
+                                                       b ? one : zero,
+                                                       b ? one : zero
+                                                       );
+                if (fast) {
+                    marina.fillSouthProperStopper(new Instruction[] {
+                            RECV_DATA,
+                            inst,
+                            NOP,
+                        });
+                    model.waitNS(64 * CYCLE_TIME_NS);
+                    marina.fillNorthProperStopper();
+                } else {
+                    marina.instrIn.fill(inst);
+                }
 
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,
-                                                b ? one : zero,
-                                                b ? one : zero
-                                                ));
-            fatal(marina.getFlagA()!=b, "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
-            fatal(marina.getFlagB()!=b, "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
+                fatal(marina.getFlagA()!=b,
+                      "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
+                fatal(marina.getFlagB()!=b,
+                      "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
+            }
         }
 
         adjustIndent(-2);
@@ -1239,6 +1245,7 @@ public class MarinaTest {
         prln("Begin testFlagTruthTable");
         adjustIndent(2);
 
+        marina.instrIn.fill(setIlc(1));
         Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
         Instruction.Set.FlagFunction one  = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
 
@@ -1251,7 +1258,6 @@ public class MarinaTest {
                                 for(boolean which : new boolean[] { false, true }) {
 
                                     prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
-
                                     // set A,B flags to a_state and b_state
                                     marina.instrIn.fill(new 
                                                         Instruction.Set(dock,Predicate.IgnoreFlagD,
@@ -1264,7 +1270,7 @@ public class MarinaTest {
                                     BitVector addr = new BitVector(14, "empty");
                                     for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
                                     for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
-                                    addr.set(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
+                                    addr.set(Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
                                     marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
                                     marina.instrIn.fill(RECV_DATA);
                                     
@@ -1279,7 +1285,6 @@ public class MarinaTest {
                                                         which  ? func : zero.add(Predicate.FlagB)
                                                         );
 
-                                    prln("executing instruction: " + inst);
                                     marina.instrIn.fill(inst);
 
                                     boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
@@ -1298,19 +1303,23 @@ public class MarinaTest {
         prln("Begin recvData");
         adjustIndent(2);
 
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
-        marina.instrIn.fill(new Instruction.Move(dock,
-                                                 Predicate.IgnoreFlagD, /* predicate   */
-                                                 true,                  /* torpedoable */
-                                                 null,                  /* path        */
-                                                 false,                 /* tokenIn     */
-                                                 true,                  /* dataIn      */
-                                                 false,                 /* latchData   */
-                                                 false,                 /* latchPath   */
-                                                 false,                 /* dataOut     */
-                                                 false                  /* tokenOut    */
-                                                 ));
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG));
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
+                new Instruction.Move(dock,
+                                     Predicate.IgnoreFlagD, // predicate   
+                                     false,                 // torpedoable 
+                                     null,                  // path        
+                                     false,                 // tokenIn     
+                                     true,                  // dataIn      
+                                     false,                 // latchData   
+                                     false,                 // latchPath   
+                                     false,                 // dataOut     
+                                     false                  // tokenOut    
+                                     ),
+                new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG),
+            });
+        model.waitNS(64 * CYCLE_TIME_NS);
 
         prln("checking to confirm that A flag is cleared");
         fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
@@ -1321,6 +1330,7 @@ public class MarinaTest {
         for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
         for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
         marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
+        model.waitNS(64 * CYCLE_TIME_NS);
 
         prln("checking to see if A flag got set");
         fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
@@ -1334,6 +1344,8 @@ public class MarinaTest {
         prln("Begin testRecvAndSendWalkingOne");
         adjustIndent(2);
 
+        marina.instrIn.fill(setIlc(1));
+
         List<BitVector> dataItems;
         for(int bit=0; bit<37; bit++) {
 
@@ -1355,15 +1367,15 @@ public class MarinaTest {
                   "found a data item waiting in the north proper stopper, but should not have");
 
             marina.instrIn.fill(new Instruction.Move(dock,
-                                                     Predicate.IgnoreFlagD,   // predicate   
-                                                     true,                  // torpedoable 
-                                                     null,                  // path        
-                                                     false,                 // tokenIn     
-                                                     true,                  // dataIn      
-                                                     true,                  // latchData   
-                                                     false,                 // latchPath   
-                                                     true,                  // dataOut     
-                                                     false                  // tokenOut    
+                                                     Predicate.IgnoreFlagD,  // predicate   
+                                                     false,                  // torpedoable 
+                                                     null_path,              // path        
+                                                     false,                  // tokenIn     
+                                                     true,                   // dataIn      
+                                                     true,                   // latchData   
+                                                     false,                  // latchPath   
+                                                     true,                   // dataOut     
+                                                     false                   // tokenOut    
                                                      ));
 
             dataItems = marina.data.drainMany(2);
@@ -1383,6 +1395,8 @@ public class MarinaTest {
         prln("Begin setOlcFromDataLatch");
         adjustIndent(2);
 
+        marina.instrIn.fill(setIlc(1));
+
         // walk a bit from 0 to 5
         for(int bit=0; bit<6; bit++) {
             prln("inserting data item in north fifo ring");
@@ -1393,11 +1407,21 @@ public class MarinaTest {
             data.set(bit, true);
             marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
 
-            marina.instrIn.fill(RECV_DATA);
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch));
+            marina.fillSouthProperStopper(new Instruction[] {
+                    RECV_DATA,
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch),
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,-1),
+                });
+
+            model.waitNS(CYCLE_TIME_NS * 64);
 
-            int olc = marina.getOLC();
-            fatal(olc != (1<<bit), "expected olc to be " + (1<<bit) + ", but got " + olc); 
+            expectOlc(1<<bit);
+
+            if (marina.kesselsCounter) {
+                // master clear on each iteration; otherwise we'd need to "run down" the olc
+                marina.masterClear();
+                marina.enableInstructionSend(true);
+            }
         }
 
         adjustIndent(-2);
@@ -1408,8 +1432,10 @@ public class MarinaTest {
         prln("Begin setIlcFromDataLatch");
         adjustIndent(2);
 
+        marina.instrIn.fill(setIlc(1));
+
         // walk a bit from 0 to 5
-        for(int bit=0; bit<6; bit++) {
+        for(int bit=5; bit>=0; bit--) {
             prln("inserting data item in north fifo ring");
             BitVector data = new BitVector(37, "empty");
             BitVector addr = new BitVector(14, "empty");
@@ -1418,9 +1444,12 @@ public class MarinaTest {
             data.set(bit, true);
             marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
 
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
-            marina.instrIn.fill(RECV_DATA);
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch));
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
+                    RECV_DATA,
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch),
+                });
+            model.waitNS(CYCLE_TIME_NS * 64);
 
             int ilc = marina.getILC().getCount();
             fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc); 
@@ -1434,19 +1463,13 @@ public class MarinaTest {
         prln("Begin testSendAndRecvToken");
         adjustIndent(2);
 
-        prln("sending token");
-        marina.instrIn.fill(SEND_TOKEN);
-
-        prln("receiving token");
-        marina.instrIn.fill(RECV_TOKEN);
-
-        prln("sending data item");
-        marina.instrIn.fill(SEND_DATA);
-
-        prln("checking to confirm that data item arrived");
-        List<BitVector> dataItems = marina.data.drainMany(3);
-        fatal(dataItems.size()!=1,
-              "expected exactly one data item, got " + dataItems.size());
+        marina.instrIn.fill(setIlc(1));
+        marina.fillSouthProperStopper(new Instruction[] {
+                SEND_TOKEN,
+                RECV_TOKEN,
+                SEND_DATA,
+            });
+        expectNorthFifoExactly(1);
 
         adjustIndent(-2);
         prln("End testSendAndRecvToken");       
@@ -1456,14 +1479,16 @@ public class MarinaTest {
         prln("Begin testSignExtendedLiteral");
         adjustIndent(2);
 
-        for(long val : new long[] { -1, 0, 1, (-1L << 14) }) {
-            prln("inserting Set Data Latch (sign-extended) 37'b" + Long.toString(val, 1));
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
-                                                    Instruction.Set.SetDest.DataLatch,
-                                                    val));
+        marina.instrIn.fill(setIlc(1));
+        for(long val : new long[] { (-1L << 14), -1, 0, 1 }) {
 
-            prln("sending data item");
-            marina.instrIn.fill(SEND_DATA);
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,
+                                        Instruction.Set.SetDest.DataLatch,
+                                        val),
+                    SEND_DATA,
+                });
+            model.waitNS(CYCLE_TIME_NS * 64);
 
             List<BitVector> dataItems = marina.data.drainMany(3);
             fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
@@ -1491,7 +1516,7 @@ public class MarinaTest {
         prln("Begin testShiftedLiteral");
         adjustIndent(2);
 
-        prln("clearing the D register");
+        marina.instrIn.fill(setIlc(1));
         marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
                                                 Instruction.Set.SetDest.DataLatch,
                                                 0));
@@ -1501,12 +1526,10 @@ public class MarinaTest {
 
         for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
 
-            prln("inserting Shift 19'b" + Long.toString(val, 1));
             edu.berkeley.fleet.api.BitVector immediate =
                 new edu.berkeley.fleet.api.BitVector(19);
             for(int i=0; i<immediate.length(); i++)
                 immediate.set(i, (val & (1L << i)) != 0);
-            marina.instrIn.fill(new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate));
 
             // shift over 19 LSB's towards MSB
             for(int i=0; i<19; i++)
@@ -1514,9 +1537,12 @@ public class MarinaTest {
             for(int i=0; i<19; i++)
                 dreg.set(i, immediate.get(i));
 
-            prln("sending data item");
-            marina.instrIn.fill(SEND_DATA);
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate),
+                    SEND_DATA,
+                });
 
+            model.waitNS(CYCLE_TIME_NS * 64);
             List<BitVector> dataItems = marina.data.drainMany(3);
             fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
 
@@ -1542,6 +1568,7 @@ public class MarinaTest {
         // Dc=1 => sigS is copied into C-flag
         // Dc=0 => sigA is copied into C-flag
        
+        marina.instrIn.fill(setIlc(1));
         for(boolean dc : new boolean[] { false, true }) {
             for(boolean c_flag : new boolean[] { true, false, true }) {
 
@@ -1553,8 +1580,8 @@ public class MarinaTest {
                 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
 
                 int whichbit = dc
-                    ? INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
-                    : INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
+                    ? Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
+                    : Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
                 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
                 addr.set(whichbit, c_flag);
 
@@ -1562,26 +1589,29 @@ public class MarinaTest {
                 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
                 
                 prln("clearing flags");
-                marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
-                
                 prln("executing recv data with Dc="+dc);
-                marina.instrIn.fill(new Instruction.Move(dock,
-                                                         Predicate.IgnoreFlagD,   /* predicate   */
-                                                         true,                  /* torpedoable */
-                                                         null,                  /* path        */
-                                                         false,                 /* tokenIn     */
-                                                         true,                  /* dataIn      */
-                                                         dc,                    /* latchData   */
-                                                         false,                 /* latchPath   */
-                                                         false,                 /* dataOut     */
-                                                         false                  /* tokenOut    */
-                                                         ));
-                
                 prln("copying c-flag to a-flag");
-                marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
-                                                        Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
-                                                        CLEAR_FLAG
-                                                        ));
+                marina.fillSouthProperStopper(new Instruction[] {
+                        new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
+                        new Instruction.Move(dock,
+                                             Predicate.IgnoreFlagD,   /* predicate   */
+                                             true,                  /* torpedoable */
+                                             null,                  /* path        */
+                                             false,                 /* tokenIn     */
+                                             true,                  /* dataIn      */
+                                             dc,                    /* latchData   */
+                                             false,                 /* latchPath   */
+                                             false,                 /* dataOut     */
+                                             false                  /* tokenOut    */
+                                             ),
+                        FLAG_NOP,
+                        new Instruction.Set(dock,Predicate.IgnoreFlagD,
+                                            Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
+                                            CLEAR_FLAG
+                                            ),
+                    });
+
+                model.waitNS(CYCLE_TIME_NS * 64);
                 
                 prln("checking to confirm that A flag is " + c_flag);
                 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
@@ -1595,9 +1625,8 @@ public class MarinaTest {
         prln("Begin sendDataWithPath");
         adjustIndent(2);
 
-        //getCtrsFlags(marina);
-
         edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
+        marina.instrIn.fill(setIlc(1));
 
         // alternating ones and zeroes
         for(int i=0; i<bv.length(); i+=2)
@@ -1608,19 +1637,21 @@ public class MarinaTest {
 
         MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
 
-        prln("send data with path="+bv);
-        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
-        marina.instrIn.fill(new Instruction.Move(dock,
-                                                 Predicate.IgnoreFlagD, /* predicate   */
-                                                 false,                 /* torpedoable */
-                                                 path,                  /* path        */
-                                                 false,                 /* tokenIn     */
-                                                 false,                 /* dataIn      */
-                                                 false,                 /* latchData   */
-                                                 false,                 /* latchPath   */
-                                                 true,                  /* dataOut     */
-                                                 false                  /* tokenOut    */
-                                                 ));
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
+                new Instruction.Move(dock,
+                                     Predicate.IgnoreFlagD, /* predicate   */
+                                     false,                 /* torpedoable */
+                                     path,                  /* path        */
+                                     false,                 /* tokenIn     */
+                                     false,                 /* dataIn      */
+                                     false,                 /* latchData   */
+                                     false,                 /* latchPath   */
+                                     true,                  /* dataOut     */
+                                     false                  /* tokenOut    */
+                                     ),
+            });
+
         List<BitVector> dataItems;
         MarinaPacket mp;
 
@@ -1661,6 +1692,7 @@ public class MarinaTest {
         prln("Begin recvPath");
         adjustIndent(2);
 
+        marina.instrIn.fill(setIlc(1));
         for(int bit=0; bit<11; bit++) {
             BitVector packet_data = new BitVector(37, "inbound data item");
             for(int i=0; i<37; i++) packet_data.set(i, false);
@@ -1677,7 +1709,7 @@ public class MarinaTest {
                                                      null,                  /* path        */
                                                      false,                 /* tokenIn     */
                                                      true,                  /* dataIn      */
-                                                     false,                 /* latchData   */
+                                                     true,                  /* latchData   */
                                                      true,                  /* latchPath   */
                                                      true,                  /* dataOut     */
                                                      false                  /* tokenOut    */
@@ -1687,7 +1719,8 @@ public class MarinaTest {
             fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
             MarinaPacket mp = new MarinaPacket(dataItems.get(0));
             
-            fatalIfBitVectorsDoNotMatch(packet_data.get(26,11), mp.path.get(0,11));
+            fatalIfBitVectorsDoNotMatch(packet_data.get(25,11), mp.path.get(0,11));
+            fatalIfBitVectorsDoNotMatch(packet_data, mp.data);
         }
 
         adjustIndent(-2);
@@ -1700,13 +1733,10 @@ public class MarinaTest {
 
         for(int bit=0; bit<6; bit++) {
             int ilc = bit<0 ? 0 : (1<<bit);
-
-            prln("set ilc="+ilc);
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc));
-
-            prln("send data");
-            marina.instrIn.fill(SEND_DATA);
-
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc),
+                    SEND_DATA,
+                });
             List<BitVector> dataItems = marina.data.drainMany();
             fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
         }
@@ -1715,64 +1745,81 @@ public class MarinaTest {
         prln("End testILC");
     }
 
+    private void testILCZero(Marina marina) {
+        adjustIndent(2);
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0),
+                SEND_DATA,
+                SEND_TOKEN,
+            });
+        expectNorthFifoNoMoreThan(0);
+        expectTokensExactly(1);
+        adjustIndent(-2);
+    }
+
     private void sendTorpedo(Marina marina) {
         prln("Begin sendTorpedo");
         adjustIndent(2);
-        
-        prln("Set OLC = 1");
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
+        marina.instrIn.fill(setIlc(1));
+        marina.instrIn.fill(setOlc(63));
 
-        int olc = marina.getOLC();
-        fatal(olc!=1, "bad OLC: "+olc+" expected: 1");
+        model.waitNS(128 * CYCLE_TIME_NS);
+        expectOlc(63);
 
-        prln("Set A=0, B=0");
         marina.instrIn.fill(new 
                             Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
-
         fatal(marina.getFlagA(), "bad A flag: true");
         fatal(marina.getFlagB(), "bad B flag: true");
-                
-        prln("Set ILC = Infinity");
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
-                
+
         prln("execute a move instruction that does nothing but loops until torpedo arrives"); 
-        marina.instrIn.fill(
-                            new Instruction.Move(dock,
-                                                 Predicate.IgnoreFlagD,   /* predicate   */
-                                                 true,                 /* torpedoable */
-                                                 null,                  /* path        */
-                                                 false,                 /* tokenIn     */
-                                                 false,                 /* dataIn      */
-                                                 false,                 /* latchData   */
-                                                 false,                 /* latchPath   */
-                                                 false,                 /* dataOut     */
-                                                 false                  /* tokenOut    */
-                                                 ));
-        
-        prln("A=1, B=1 This instruction should get torpedoed along with the Move");
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
+        prln("A=1, B=B This instruction should not execute because D-flag is set");
+        prln("Set A=A, B=1 This instruction should execute because D-flag is set");
+
+        model.waitNS(128 * CYCLE_TIME_NS);
+
+        marina.fillSouthProperStopper(new Instruction[] {
+                new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity),
+                new Instruction.Move(dock,
+                                     Predicate.IgnoreFlagD, // predicate   
+                                     true,                  // torpedoable 
+                                     null,                  // path        
+                                     false,                 // tokenIn     
+                                     true,                  // dataIn      
+                                     false,                 // latchData   
+                                     false,                 // latchPath   
+                                     false,                 // dataOut     
+                                     false                  // tokenOut    
+                                     ),
+                new Instruction.Set(dock,Predicate.Default,
+                                    SET_FLAG,
+                                    Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB)
+                                    ),
+                new Instruction.Set(dock, Predicate.FlagD,
+                                    Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA),
+                                    SET_FLAG
+                                    ),
+            });
+
+        model.waitNS(128 * CYCLE_TIME_NS);
 
         prln("send torpedo. This should clear the OLC");
         marina.instrIn.fillTorpedo();
+        model.waitNS(128 * CYCLE_TIME_NS);
+
+        model.waitNS(128 * CYCLE_TIME_NS);
                 
-        getCtrsFlags(marina);
-                
-        // Note: It's tempting to test that OLC==0 here. However, hardware doesn't
-        // actually set counter bits to zero; it just sets the OLCZERO bit
-                
-        prln("A and B should remain false");
+        prln("A should remain false, B should be true");
         fatal(marina.getFlagA(), "bad A flag: true");
-        fatal(marina.getFlagB(), "bad B flag: true");
+        fatal(!marina.getFlagB(), "bad B flag: false");
         
-        prln("OLC = 63. Reload OLC after torpedo");
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
+        model.waitNS(128 * CYCLE_TIME_NS);
 
-        olc = marina.getOLC();
-        fatal(olc!=63, "bad OLC: "+olc+" expected: 63");
+        prln("Reload OLC after torpedo, clears D-flag");
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
+
+        // FIXME: find another way to test this
+        model.waitNS(128 * CYCLE_TIME_NS);
+        expectOlc(63);
                 
         prln("Set A=1, B=1 This instruction should execute because OLC!=0");
         marina.instrIn.fill(new 
@@ -1786,45 +1833,60 @@ public class MarinaTest {
         prln("End sendTorpedo");        
     }    
 
-    private void testTorpedoOnAnInfiniteNop(Marina marina) {
-        prln("Begin testTorpedoOnAnInfiniteNop");
+    private void testTorpedoOnAnInfinite(Marina marina) {
+        prln("Begin testTorpedoOnAnInfinite");
         adjustIndent(2);
 
         List<BitVector> dataItems;
 
+        marina.instrIn.fill(setIlc(1));
         for(boolean torpedoable : new boolean[] { true, false }) {
-            prln("set ilc=\\infty");
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity));
             
-            prln("nop");
-            marina.instrIn.fill(new Instruction.Move(dock,
-                                                     Predicate.IgnoreFlagD,   /* predicate   */
-                                                     torpedoable,           /* torpedoable */
-                                                     null,                  /* path        */
-                                                     false,                 /* tokenIn     */
-                                                     false,                 /* dataIn      */
-                                                     false,                 /* latchData   */
-                                                     false,                 /* latchPath   */
-                                                     false,                 /* dataOut     */
-                                                     false                  /* tokenOut    */
-                                                     ));
-            prln("send data");
-            marina.instrIn.fill(SEND_DATA);
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Move(dock,
+                                         Predicate.IgnoreFlagD, // predicate   
+                                         false,                 // torpedoable 
+                                         null,                  // path        
+                                         false,                 // tokenIn     
+                                         false,                 // dataIn      
+                                         false,                 // latchData   
+                                         false,                 // latchPath   
+                                         false,                 // dataOut     
+                                         true                   // tokenOut    
+                                         ),
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
+                    new Instruction.Move(dock,
+                                         Predicate.IgnoreFlagD, // predicate   
+                                         torpedoable,           // torpedoable 
+                                         null,                  // path        
+                                         true,                  // tokenIn     
+                                         false,                 // dataIn      
+                                         false,                 // latchData   
+                                         false,                 // latchPath   
+                                         false,                 // dataOut     
+                                         true                   // tokenOut    
+                                         ),
+                    // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
+
+                    SEND_DATA,
+                });
             
             // expect nothing to come out, because the NOP is executing
-            dataItems = marina.data.drainMany(10);
+            dataItems = marina.data.drainMany(2);
             fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
             
-            prln("send torpedo");
             marina.instrIn.fillTorpedo();
             
             int expected = torpedoable?1:0;
             dataItems = marina.data.drainMany(2);
             fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
+
+            fatal(!marina.getILC().getDone(), "Expected ilc=done, but got "+marina.getILC());
         }
 
         adjustIndent(-2);
-        prln("End testTorpedoOnAnInfiniteNop");
+        prln("End testTorpedoOnAnInfinite");
     }
 
     private void testOlcDecrementAtHighSpeed(Marina marina) {
@@ -1839,55 +1901,56 @@ public class MarinaTest {
         // of the OLC will be checked by executing a MOVE with
         // [olc!=0] as the predicate.
 
-        int[] olcs         = new int[] { 3 /*, 3, 3, 10, 41*/ };
-        int[] decr_amounts = new int[] { 2 /*, 3, 4, 9,  10*/ };
+        int[] olcs         = new int[] { 3, 3, 3, 10, 41 };
+        int[] decr_amounts = new int[] { 2, 3, 4, 9,  9  };
 
         for(int which=0; which<olcs.length; which++) {
             int olc = olcs[which];
             int decr_amount = decr_amounts[which];
 
             prln("inserting set olc="+olc);
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc));
             prln("inserting set ilc=1");
-            marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc),
+                });
 
             // commenting the following four lines causes this test to pass
-            prln("disabling instruction send");
-            marina.enableInstructionSend(false);
-            prln("enabling instruction recirculate");
-            marina.enableInstructionRecirculate(true);
 
-            prln("inserting "+decr_amount+" olc-- instructions");
+            prln("inserting: "+decr_amount+" olc-- instructions");
+            prln("inserting: [!d] send data");
+            Instruction[] instructions = new Instruction[decr_amount+1];
             for(int i=0; i<decr_amount; i++)
-                marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
-                                                        SetDest.OuterLoopCounter,SetSource.Decrement));
-
-            prln("inserting [olc!=0] send data");
-            marina.instrIn.fill(new Instruction.Move(dock,
-                                                     Predicate.Default,     /* predicate   */
-                                                     false,                 /* torpedoable */
-                                                     null,                  /* path        */
-                                                     false,                 /* tokenIn     */
-                                                     false,                 /* dataIn      */
-                                                     false,                 /* latchData   */
-                                                     false,                 /* latchPath   */
-                                                     true,                  /* dataOut     */
-                                                     false                  /* tokenOut    */
-                                                     ));
-
-            prln("disabling instruction recirculate");
-            marina.enableInstructionRecirculate(false);
-            prln("enabling instruction send");
-            marina.enableInstructionSend(true);
-
-            prln("calling marina.instrIn.run()");
-            marina.instrIn.run();
-            
-            model.waitNS(5);
+                instructions[i] =
+                    new Instruction.Set(dock,
+                                        Predicate.Default,
+                                        SetDest.OuterLoopCounter,
+                                        SetSource.Decrement);
+            instructions[instructions.length-1] =
+                new Instruction.Move(dock,
+                                     Predicate.Default,     // predicate   
+                                     false,                 // torpedoable 
+                                     null,                  // path        
+                                     false,                 // tokenIn     
+                                     false,                 // dataIn      
+                                     false,                 // latchData   
+                                     false,                 // latchPath   
+                                     true,                  // dataOut     
+                                     false                  // tokenOut    
+                                     );
+
+            marina.fillSouthProperStopper(instructions);
+            model.waitNS(64 * CYCLE_TIME_NS);
 
             int expected = decr_amount>=olc ? 0 : 1;
             dataItems = marina.data.drainMany(2);
             fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
+
+            if (marina.kesselsCounter) {
+                // master clear on each iteration; otherwise we'd need to "run down" the olc
+                marina.masterClear();
+                marina.enableInstructionSend(true);
+            }
         }
 
         adjustIndent(-2);
@@ -1901,35 +1964,33 @@ public class MarinaTest {
              "Check correct setting of the ILC zero bit");
 
         for (int i=0; i<6; i++) {
-            int notZero = 32 >> i;
-            prln("Set ILC=0");
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0));
-                
+            int notZero = 1<<i;
+
             prln("Then immediately set ILC="+notZero);
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero));
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
+                });
                 
+            model.waitNS(64 * CYCLE_TIME_NS);
+
             prln("Verify ILC using scan chain");
             Ilc ilc = marina.getILC();
             int ilcCount = ilc.getCount();
             fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
-        
             fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
-                        
-            prln("Set ILC="+notZero);
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero));
-                
-            prln("Then immediately set ILC=0");
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0));
+                   
+            marina.fillSouthProperStopper(new Instruction[] {     
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
+                });
+
+            model.waitNS(64 * CYCLE_TIME_NS);
                         
             prln("Verify ILC using scan chain");
             ilc = marina.getILC();
             ilcCount = ilc.getCount();
             fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
-        
             fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
         }
 
@@ -1942,58 +2003,50 @@ public class MarinaTest {
         prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
              "Check correct setting of the OLC zero bit");
 
-        prln("Set A=0, B=0");
-        marina.instrIn.fill(new 
-                            Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
+        marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
 
         for (int i=0; i<6; i++) {
             int notZero = 32 >> i;
+
+            if (marina.kesselsCounter) {
+                // master clear on each iteration; otherwise we'd need to "run down" the olc
+                marina.masterClear();
+                marina.enableInstructionSend(true);
+            }
+
+            int outOlc;
             prln("Set OLC=0");
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0));
-        
             prln("Then immediately set OLC="+notZero);
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero));
-        
-            prln("Verify OLC count using scan chain");
-            int outOlc = marina.getOLC();
-            fatal(outOlc!=notZero, "bad OLC count: "+outOlc+" expected: "+notZero);
-                        
-            prln("Verify OLC zero bit using predication");
-            prln("if (OLC==0) {A=1; B=1;} // should not get executed");
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.FlagD, SET_FLAG, SET_FLAG));
-            fatal(marina.getFlagA(), "bad A flag. expected: false");
-        
-            prln("Set OLC="+notZero);
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero));
-        
-            prln("Then immediately set OLC=0");
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0));
-                        
+            marina.fillSouthProperStopper(new Instruction[] {
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
+                    new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
+                });
+
+            model.waitNS(64 * CYCLE_TIME_NS);
             prln("Verify OLC count using scan chain");
-            outOlc = marina.getOLC();
-            fatal(outOlc!=0, "bad OLC count: "+outOlc+" expected: 0");
-                        
-            prln("Verify OLC zero bit using predication");
-            prln("if (OLC!=0) {A=1; B=1;} // should not get executed");
-            marina.instrIn.fill(new 
-                                Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
-            fatal(marina.getFlagA(), "bad A flag. expected: false");
+            expectOlc(notZero);
+
+            if (!marina.kesselsCounter) {
+                prln("Set OLC="+notZero);
+                prln("Then immediately set OLC=0");
+                marina.fillSouthProperStopper(new Instruction[] {
+                        new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
+                        new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
+                    });
+                
+                model.waitNS(64 * CYCLE_TIME_NS);
+                prln("Verify OLC count using scan chain");
+                expectOlc(0);
+            }
         }
         
         adjustIndent(-2);
         prln("End flipOlcBit");
     }
-    private void testSouthRecirculate(Marina marina) {
-        prln("Begin testSouthRecirculate");
+    private void testSouthRecirculate(Marina marina, int AMOUNT) {
+        prln("Begin testSouthRecirculate("+AMOUNT+")");
         adjustIndent(2);
 
-        int AMOUNT = Marina.SOUTH_RING_CAPACITY-1;
-
         marina.enableInstructionSend(false);
         marina.enableInstructionRecirculate(true);
         
@@ -2004,7 +2057,7 @@ public class MarinaTest {
             BitVector path = new BitVector(MarinaPacket.PATH_WIDTH, "path");
             BitVector data = new BitVector(MarinaPacket.WORD_WIDTH, "path");
             path.set(0, MarinaPacket.PATH_WIDTH, false);
-            data.setFromLong(i+1);
+            data.setFromLong(i+9);
             marina.instrIn.fill(new MarinaPacket(data, false, path));
         }
         adjustIndent(-2);
@@ -2016,7 +2069,7 @@ public class MarinaTest {
         for (int i=0; i<AMOUNT; i++) {
             prln("extracting item " + (i+1) + " / " + AMOUNT);
             //int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
-            int expect = i+1;
+            int expect = i+9;
             long got = new MarinaPacket(out.get(i)).data.toLong();
             if (got!=expect) {
                 bad = true;
@@ -2031,87 +2084,147 @@ public class MarinaTest {
         for (int i=0; i<5; i++) {}
         
         adjustIndent(-2);
-        prln("End testSouthRecirculate");
+        prln("End testSouthRecirculate("+AMOUNT+")");
     }
     private void doOneTest(int testNum) {
         prln("");
         prln("============================================================");
         prln("MarinaTest: performing test: "+testNum);
 
-        marina.masterClear();
-        marina.enableInstructionSend(true);
+        if (testNum!=0) {
+            marina.masterClear();
+            marina.enableInstructionSend(true);
+        }
         
-        switch (testNum) {
-            case 0: {
-
-                // these tests run fairly quickly
-                doOneTest(1);
-                doOneTest(2);
-                doOneTest(3000);
-                doOneTest(3001);
-                doOneTest(3006);
-                doOneTest(3018);
-                //doOneTest(1000);
-
-                // these tests take a while and usually pass
-                doOneTest(1006);
-
-                break;
-            }
-            case 1:    testProperStoppers(marina);             break; // passes, 24-Mar (+verilog)
-            case 2:    sendInstructions(marina);               break; // passes, 24-Mar (+verilog)
-
-            case 4:    getCtrsFlags(marina);                   break;
-            case 5:    walkOneOLC(marina);                     break;
-                
-                // Russell's tests begin with 1000
-            case 1000: walkOneILC(marina);                     break; //         20-Apr (+verilog)
-            case 1001: countIlc(marina);                       break;
-            case 1002: countOlc(marina);                       break;
-
-            case 1003: sendTorpedo(marina);                    break;
-
-            case 1004: flipIlcBit(marina);                     break;
-            case 1005: flipOlcBit(marina);                     break;
-
-            case 1006: testSouthRecirculate(marina);           break; // passes, 24-Mar (+verilog)
+        try {
+            switch (testNum) {
+                case 0: {
+
+                    // these tests run fairly quickly
+
+
+                    doOneTest(1);       // passes extracted parasitics
+                    doOneTest(2);       // passes extracted parasitics
+                    doOneTest(3);       // passes extracted parasitics
+                    doOneTest(4);       // passes extracted parasitics
+                    doOneTest(5);       // passes extracted parasitics
+                    doOneTest(6);
+                    doOneTest(1002);
+                    doOneTest(1005);
+                    doOneTest(3019);
+                    doOneTest(3025);
+
+                    doOneTest(1000);    // passes extracted parasitics
+                    doOneTest(1001);    // passes extracted parasitics
+                    doOneTest(1003);    // passes extracted parasitics
+                    doOneTest(3000);    // passes extracted parasitics
+                    doOneTest(3001);    // passes extracted parasitics
+                    doOneTest(3003);    // passes extracted parasitics
+                    doOneTest(3004);    // passes extracted parasitics
+                    doOneTest(3005);    // passes extracted parasitics
+                    doOneTest(3006);    // passes extracted parasitics
+                    doOneTest(3007);    // passes extracted parasitics
+                    doOneTest(3008);    // passes extracted parasitics
+                    doOneTest(3009);    // passes extracted parasitics
+                    doOneTest(3010);    // passes extracted parasitics
+                    doOneTest(3011);    // passes extracted parasitics
+                    doOneTest(3012);    // passes extracted parasitics
+                    doOneTest(3013);    // passes extracted parasitics
+                    doOneTest(3014);    // passes extracted parasitics
+                    doOneTest(3015);    // passes extracted parasitics
+                    doOneTest(3019);    // passes extracted parasitics
+                    doOneTest(3020);    // passes extracted parasitics
+                    doOneTest(3022);    // passes extracted parasitics
+                    doOneTest(3023);    // passes extracted parasitics
+                    doOneTest(3026);    // passes extracted parasitics
+                    doOneTest(3027);    // passes extracted parasitics
+                    doOneTest(3028);    // passes extracted parasitics
+                    
+                    // these tests take a while and usually pass
+                    doOneTest(1002);
+                    doOneTest(1004);
+                    doOneTest(1005);
+                    doOneTest(1006);
+                    doOneTest(3002);
+                    doOneTest(3016);
+                    doOneTest(3021);
+                    doOneTest(3024);
+                    doOneTest(3025);
+                    
+                    // this takes an insanely long time
+                    doOneTest(3017);
+                    break;
+                }
+                case 1:    testChains(marina);                     break; // passes, 24-Mar (+verilog)
+                case 2:    testProperStoppers(marina);             break; // passes, 24-Mar (+verilog)
+                case 3:    testSouthRecirculate(marina, 1);        break; // passes, 24-Mar (+verilog)
+                case 4:    getCtrsFlags(marina);                   break; //         20-Apr (+verilog)
+                case 5:    sendInstructions(marina);               break; // passes, 24-Mar (+verilog)
+                case 6:    walkOneOLC(marina);                     break; //         21-Apr (+verilog)
                 
-                // Adam's tests begin with 3000
-            case 3000: sendToken(marina);                      break; // passes, 24-Mar (+verilog)
-            case 3001: testFlagAB(marina);                     break; // passes, 08-Apr (+verilog)
-            case 3002: testRequeueStage0(marina);              break;
-            case 3003: testRequeueStage0to1(marina);           break;
-            case 3004: testFlagZ(marina);                      break;
-            case 3005: testPredicationOnAB(marina);            break;
-            case 3006: sendData(marina);                       break; // passes, 24-Mar (+verilog)
-            case 3007: testRequeueStage0to1to3to0(marina);     break;
-            case 3008: testWaitForTail(marina);                break;
-            case 3009: testRequeueStageDrop(marina);           break;         
-            case 3010: testRequeueStage0to2to3to0(marina);     break;
-            case 3011: recvData(marina);                       break;
-            case 3012: testFlagC(marina);                      break;
-            case 3013: testSignExtendedLiteral(marina);        break;
-            case 3014: testShiftedLiteral(marina);             break; // fails, 09-Apr
-            case 3015: testSendAndRecvToken(marina);           break;
-            case 3016: sendDataIlcInfinite(marina);            break;
-            case 3017: testFlagTruthTable(marina);             break;
-            case 3018: sendDataWithPath(marina);               break; // passes, 13-Apr (+verilog)
-            case 3019: setOlcFromDataLatch(marina);            break;
-            case 3020: setIlcFromDataLatch(marina);            break;
-            case 3021: recvPath(marina);                       break;
-            case 3022: testILC(marina);                        break;
-            case 3023: testTorpedoOnAnInfiniteNop(marina);     break;
-            case 3024: testRecvAndSendWalkingOne(marina);      break;
-            case 3025: testOlcDecrementAtHighSpeed(marina);    break;
+                    // Russell's tests begin with 1000
+                case 1000: walkOneILC(marina);                     break; //         20-Apr (+verilog)
+                case 1001: countIlc(marina);                       break; //         20-Apr (+verilog)
+                case 1002: countOlc(marina);                       break; //         23-Apr (+verilog)
+
+                case 1003: sendTorpedo(marina);                    break; //         23-Apr (+verilog)  [with wor-hack]
+
+                case 1004: flipIlcBit(marina);                     break; //         20-Apr (+verilog)
+                case 1005: flipOlcBit(marina);                     break; //         21-Apr (+verilog)
+
+                case 1006: testSouthRecirculate(marina, Marina.SOUTH_RING_CAPACITY-1);        break; // passes, 24-Mar (+verilog)
+
+                    // Adam's tests begin with 3000
+                case 3000: sendToken(marina);                      break; // passes, 24-Mar (+verilog)
+                case 3001: testFlagAB(marina);                     break; // passes, 08-Apr (+verilog)
+                case 3002: testPredicationOnAB(marina);            break; //         22-Apr (+verilog)
+                case 3003: testFlagC(marina);                      break; //         23-Apr (+verilog)
+                case 3004: testFlagD(marina);                      break; //         23-Apr (+verilog)
+                case 3005: testFlagDRecomputationTime(marina);     break;
+
+                case 3006: testTailWaitsForHead(marina);           break;
+                case 3007: testTailWithoutHead(marina);            break;
+                case 3008: testHeadWaitsForTail(marina);           break; //         22-Apr (+verilog)
+                case 3009: testAbort(marina);                      break; //         22-Apr (+verilog)
+
+                case 3010: sendData(marina);                       break; // passes, 24-Mar (+verilog)
+                case 3011: recvData(marina);                       break; //         21-Apr (+verilog)
+                case 3012: sendDataWithPath(marina);               break; // passes, 13-Apr (+verilog)
+
+                case 3013: testSignExtendedLiteral(marina);        break; //         20-Apr (+verilog)
+                case 3014: testShiftedLiteral(marina);             break; //         20-Apr (+verilog)
+                case 3015: testSendAndRecvToken(marina);           break; //         21-Apr (+verilog)
+
+                case 3016: sendDataIlcInfinite(marina);            break; //         22-Apr (+verilog)
+                case 3017: testFlagTruthTable(marina);             break; //         23-Apr (+verilog)
+
+                case 3019: setOlcFromDataLatch(marina);            break; //         23-Apr (+verilog)
+                case 3020: setIlcFromDataLatch(marina);            break; //         23-Apr (+verilog)
+                case 3021: recvPath(marina);                       break; //         22-Apr (+verilog)
+                case 3022: testILC(marina);                        break; //         23-Apr (+verilog)
+                case 3023: testTorpedoOnAnInfinite(marina);        break; //         23-Apr (+verilog)
+                case 3024: testRecvAndSendWalkingOne(marina);      break; //         21-Apr (+verilog)
+                case 3025: testOlcDecrementAtHighSpeed(marina);    break; //         23-Apr (+verilog)
+
+                case 3026: testNonTorpedoableMoveDoesNotResetDFlag(marina);        break; //         23-Apr (+verilog)
+                case 3027: testILCZero(marina);                    break;
+                case 3028: testAbortOutsideOfLoop(marina); break;
 
-            default:
-                fatal(true, "Test number: "+testNum+" doesn't exist.");
-                break;
+                default:
+                    fatal(true, "Test number: "+testNum+" doesn't exist.");
+                    break;
+            }
+            // If we get here then test passed
+            prln("Test Result: Passed");
+            printTestTime();
+            //Infrastructure.exit(0);
+        } catch (MarinaUtils.FailureException fe) {
+            System.out.println("******************************************************************************");
+            System.out.println("******************************************************************************");
+            System.out.println("******************************************************************************");
+            System.out.println("******************************************************************************");
+            fe.printStackTrace();
         }
-        // If we get here then test passed
-        prln("Test Result: Passed");
-        printTestTime();
-        //Infrastructure.exit(0);
     }