lots of changes to Marina test code, mostly for scan chain counters
authorAdam Megacz <adam@megacz.com>
Sun, 20 Sep 2009 19:38:38 +0000 (12:38 -0700)
committerAdam Megacz <adam@megacz.com>
Sun, 20 Sep 2009 19:38:38 +0000 (12:38 -0700)
src/com/sun/vlsi/chips/marina/test/InstructionStopper.java
src/com/sun/vlsi/chips/marina/test/Marina.java
src/com/sun/vlsi/chips/marina/test/MarinaTest.java
src/com/sun/vlsi/chips/marina/test/MarinaUtils.java
src/com/sun/vlsi/chips/marina/test/ProperStopper.java

index 5c18ef7..d8192f9 100644 (file)
@@ -25,8 +25,8 @@ public class InstructionStopper extends ProperStopper {
                               String reportChain,
                               ChainControls cc, ChipModel model,
                               boolean clockHack,
-                              Indenter indenter) {
-        super(name, propInst, controlChain, dataChain, reportChain, cc, model, clockHack, indenter);
+                              Indenter indenter, String counterPath) {
+        super(name, propInst, controlChain, dataChain, reportChain, cc, model, clockHack, indenter, counterPath);
     }
 
     /** put one Instruction into InstructionStopper */
index 759662d..5aa6dae 100644 (file)
@@ -43,7 +43,7 @@ public class Marina {
         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@1"; // bits 2,4,6
     private static final String OLC_PATH_ODD = 
         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@2"; // bits 1,3,5
-    private static final String OLC_PATH_KESSEL = 
+    public static final String OLC_PATH_KESSEL = 
         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.counte@0.adamScan@1.scanEx6h@";
     private static final String ILC_PATH_ODD = 
         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@0"; // bits 1,3,5,7
@@ -110,7 +110,7 @@ public class Marina {
 
     // The name of the scan chain
     // The instance path, from the top cell of the netlist, of the instance of infinityWithCover 
-    private final ChainControls cc;           // specifies the scan chain
+    public final ChainControls cc;           // specifies the scan chain
     private final ChipModel model;
     public final ProperStopper data;
     public final InstructionStopper instrIn;
@@ -119,7 +119,7 @@ public class Marina {
     private void pr(String msg) {indenter.pr(msg);}
     
     /** Shift the report scan chain */
-    private void shiftReport(boolean readEnable, boolean writeEnable) {
+    public void shiftReport(boolean readEnable, boolean writeEnable) {
         cc.shift(REPORT_CHAIN, readEnable, writeEnable);
     }
     
@@ -142,14 +142,37 @@ public class Marina {
                                  CONTROL_CHAIN, 
                                  DATA_CHAIN,  
                                  REPORT_CHAIN,
-                                 cc, model, clockHack, indenter);
+                                 cc, model, clockHack, indenter,
+                                 prefix+"northFif@1.fillDrai@1.instruct@0.cntScnTh@1.cntScnOn@1");
         instrIn = new InstructionStopper("south fifo",
                                          prefix+"southFif@1.tapPropS@1.properSt@1", 
                                          CONTROL_CHAIN,
                                          DATA_CHAIN,
                                          REPORT_CHAIN,
-                                         cc, model, clockHack, indenter);
+                                         cc, model, clockHack, indenter,
+                                         prefix+"southFif@1.tapPropS@1.instruct@0.cntScnTh@1.cntScnOn@1");
     }
+
+    int northCount = 0;
+    int southCount = 0;
+
+    public void stopAndResetCounters() {
+        instrIn.setCounterEnable(false);
+        data.setCounterEnable(false);
+        cc.shift(DATA_CHAIN, true, false);        
+        northCount = data.getCounterValue();
+        southCount = instrIn.getCounterValue();
+        data.setCounterValue(0);
+        instrIn.setCounterValue(0);
+    }
+    public void startCounters() {
+        instrIn.setCounterEnable(true);
+        data.setCounterEnable(true);
+    }
+    public int getNorthCount() { return northCount; }
+    public int getSouthCount() { return southCount; }
+
+
     public void masterClear() {
         final double WIDTH = 10; // ns
         // Put a high going pulse on the internal chip master clear signal
@@ -269,12 +292,14 @@ public class Marina {
             nModel.setNodeVoltage(MASTER_CLEAR,0.0);
             nModel.waitNS(1);
         } else {
+
             mc0.setLogicState(true);
             mc1.setLogicState(true);
             model.waitNS(1000);
             mc0.setLogicState(false);
             mc1.setLogicState(false);
             model.waitNS(1000);
+
         }
         resetAfterMasterClear();
     }
@@ -352,8 +377,34 @@ public class Marina {
             //System.out.println("kesselsCounter = " + bits);
             int first = 0;
             int second = 0;
-            for(int i=0; i<6; i++) first  |= bits.get(4+i*3)   ? (1<<i) : 0;
-            for(int i=0; i<6; i++) second |= bits.get(4+i*3+2) ? (1<<i) : 0;
+            String hi="";
+            String lo="";
+            String latched="";
+            String res="";
+            for(int i=0; i<6; i++) {
+                first  |= bits.get(4+i*3)   ? (1<<i) : 0;
+                second |= bits.get(4+i*3+2) ? (1<<i) : 0;
+                hi = (bits.get(4+i*3)   ? "1" : "0") + hi;
+                lo = (bits.get(4+i*3+2)   ? "1" : "0") + lo;
+                res =
+                    (   bits.get(4+i*3) && !bits.get(4+i*3+2) ? "X"
+                     : !bits.get(4+i*3) && !bits.get(4+i*3+2) ? "0"
+                     : !bits.get(4+i*3) &&  bits.get(4+i*3+2) ? "1"
+                     : "2")
+                    +res;
+                latched = (bits.get(4+i*3+1)   ? "0" : "1") + latched;
+            }
+            System.out.println("kesselsCounter: "+
+                               "s[1]="+hi+
+                               " s[3]="+lo+
+                               " latched="+latched +
+                               " res="+res+
+                               " do[ins]="+(bits.get(0) ? "1" : "0")+
+                               " dec="+(bits.get(1) ? "1" : "0")+
+                               " flag[D][set]="+(bits.get(2) ? "1" : "0")+
+                               " resetting="+(bits.get(3) ? "1" : "0")+
+                               ""
+                               );
             return (first+second);
         } else {
             BitVector odd = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse();
@@ -479,16 +530,23 @@ public class Marina {
         instrIn.setGeneralPurposeOutput(b);
     }
 
+    public void fillSouthProperStopper(Instruction i) {
+        instrIn.fill(i);
+    }
     public void fillSouthProperStopper(Instruction[] instructions) { fillSouthProperStopper(instructions, false); }
-    public void fillSouthProperStopper(Instruction[] instructions, boolean repeat) {
+    public void fillSouthProperStopper(Instruction[] instructions, boolean repeat) { fillSouthProperStopper(instructions, repeat, false); }
+    public void fillSouthProperStopper(Instruction[] instructions, boolean repeat, boolean leaveStopped) {
         enableInstructionSend(false);
         enableInstructionRecirculate(true);
         for(Instruction i : instructions)
-            if (i!=null)
+            if (i!=null) {
                 instrIn.fill(i);
+            } else {
+                instrIn.fillTorpedo();
+            }
         enableInstructionRecirculate(repeat);
         enableInstructionSend(true);
-        instrIn.run();
+        if (!leaveStopped) instrIn.run();
     }
 
     
index 1094c97..b712057 100644 (file)
@@ -36,6 +36,8 @@ import edu.berkeley.fleet.marina.MarinaFleet;
 import edu.berkeley.fleet.marina.MarinaPath;
 import com.sun.async.test.*;
 
+import java.io.*;
+
 /**
  * Tests for Marina
  */
@@ -43,6 +45,8 @@ public class MarinaTest {
     public static final MarinaFleet marinaFleet = new MarinaFleet();
     public static final Dock dock = marinaFleet.getOnlyInputDock();
 
+    public static float vdd = 1.0f;
+
     //--------------------------  constants -----------------------------------
     private static final String SCAN_CHAIN_XML = "marina.xml";
     private static final String NET_LIST = "marina.spi";
@@ -196,13 +200,16 @@ public class MarinaTest {
         }
     }
         
-    private MarinaTest(String[] args) {
+    private MarinaTest(String[] args) throws Exception {
         cmdArgs = new CmdArgs(args);
         reportTask(cmdArgs);
         if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim();
     }
         
-    private void doSim() {
+    static PowerChannel vdd18;
+    static PowerChannel vdd10;
+
+    private void doSim() throws Exception {
         String netListName;
         switch (cmdArgs.mode) {
             case WHOLE_CHIP_SCHEMATIC_PARASITICS:
@@ -216,6 +223,12 @@ public class MarinaTest {
                 return;
         }
 
+        Infrastructure.gpibControllers = new int[]{1};
+        vdd18 = new Pst3202Channel("ch2", "tiPST3202", 2);
+        vdd10 = new Pst3202Channel("ch3", "tiPST3202", 3);
+        vdd10.setVoltageNoWait(vdd);
+        vdd18.setVoltageNoWait(1.8f);
+
         model = cmdArgs.useVerilog
             ? new VerilogModel()
             : cmdArgs.useHsim
@@ -241,11 +254,12 @@ public class MarinaTest {
         JtagTester tester =
             model instanceof SimulationModel
             ? ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO")
-            : new Netscan4("jtag3", 2);
+            : new Netscan("jtag2"); // bad kessels counter
+            //: new Netscan4("jtag3", 4);    // good kessels counter
         JtagLogicLevel mc0=null;
         JtagLogicLevel mc1=null;
-        if (tester instanceof Netscan4) {
-            ((Netscan4)tester).reset();
+        if (tester instanceof Netscan) {
+            ((Netscan)tester).reset();
             // master clear
             // not sure if "GPIO1" means "index 0" or not
             mc0 = new JtagLogicLevel(tester, 0);
@@ -286,6 +300,14 @@ public class MarinaTest {
         ccs.addChain(Marina.REPORT_CHAIN, ccR);
         ccs.addChain(Marina.CONTROL_CHAIN, ccC);
         */
+        /*
+        PowerChannel ch2 = new Pst3202Channel("ch2", "tiPST3202", 2);
+        PowerChannel ch3 = new Pst3202Channel("ch3", "tiPST3202", 3);
+        Infrastructure.gpibControllers = new int[]{1};
+        ch2.setVoltageNoWait(1f);
+        ch3.setVoltageNoWait(1.8f);
+        */
+
 
         cc = new ChainControl(SCAN_CHAIN_XML, tester, 1.8f, khz);
         cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
@@ -333,7 +355,7 @@ public class MarinaTest {
         if (model instanceof SimulationModel)
             ((SimulationModel)model).finish();
     }
-    private void doSilicon() {
+    private void doSilicon() throws Exception {
         model = new SiliconChip();
         String ip = cmdArgs.station.ipAddr;
         JtagTester tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
@@ -774,7 +796,43 @@ public class MarinaTest {
     private void walkOneOLC(Marina marina) {
         prln("Begin walkOneOLC");
         adjustIndent(2);
-        for (int i=0; i<6; i++) {
+        /*
+        //for (int i=-1; i<6; i++) {
+        marina.fillSouthProperStopper(new Instruction[] {
+
+                new Instruction.Head(dock),
+
+                //                new Instruction.Set(dock,Predicate.IgnoreFlagD, SetDest.OuterLoopCounter, 1),
+                FLAG_NOP,
+                FLAG_NOP,
+                FLAG_NOP,
+                TORPEDOABLE_RECV_DATA,
+                FLAG_NOP,
+                FLAG_NOP,
+                FLAG_NOP,
+
+
+                //new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement),
+                
+                new Instruction.Tail(dock),
+            });
+        marina.fillSouthProperStopper(new Instruction[] {
+                null,
+            },
+            true);
+        while(true) {
+            BitVector bits = null;
+            marina.shiftReport(true, false);
+            for(int i=0; i<4; i++) {
+                BitVector x = marina.cc.getOutBits(marina.REPORT_CHAIN+"."+marina.OLC_PATH_KESSEL+i);
+                //System.out.println("bits are: " + x);
+                bits = bits==null ? x : bits.cat(x);
+            }
+            System.out.println("dec="+bits.get(0));
+            if (bits.get(1)) throw new RuntimeException();
+        }
+        */
+        /*        for (int i=0; i<64; i++) {
 
             if (marina.kesselsCounter) {
                 System.out.println("master-clearing...");
@@ -783,16 +841,25 @@ public class MarinaTest {
                 marina.enableInstructionSend(true);
             }
 
+            expectTokensExactly(0);
+            marina.getOLC();
+
             int inOlc = i==-1 ? 0 : (1<<i);
+            inOlc = i;
             marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
+            marina.instrIn.fill(SEND_DATA_IF_D_SET);
+            marina.instrIn.fill(SEND_DATA_IF_D_NOT_SET);
+            marina.instrIn.fill(SEND_DATA);
 
             model.waitNS(128 * CYCLE_TIME_NS);
 
             expectOlc(inOlc);
             prln("walkOneOLC: "+inOlc+" checks out");
+            expectNorthFifoExactly(0);
         }
         adjustIndent(-2);
         prln("End walkOneOLC");
+        */
     }
     private void walkOneILC(Marina marina) {
         prln("Begin walkOneILC");
@@ -871,6 +938,7 @@ public class MarinaTest {
     }
     private void loadEveryValueOLC(Marina marina) {
         adjustIndent(2);
+        //while(true)
         for (int i=0; i<(1<<6); i++) {
 
             if (marina.kesselsCounter) {
@@ -1003,6 +1071,19 @@ public class MarinaTest {
                              true                   /* tokenOut    */
                              );
 
+    private static final Instruction SEND_TOKEN_IF_D_NOT_SET =
+        new Instruction.Move(dock,
+                             Predicate.Default,     /* predicate   */
+                             false,                 /* torpedoable */
+                             null_path,             /* path        */
+                             false,                 /* tokenIn     */
+                             false,                 /* dataIn      */
+                             false,                 /* latchData   */
+                             false,                 /* latchPath   */
+                             false,                 /* dataOut     */
+                             true                   /* tokenOut    */
+                             );
+
     private static final Instruction TORPEDOABLE_RECV_DATA =
         new Instruction.Move(dock,
                              Predicate.IgnoreFlagD, /* predicate   */
@@ -2113,6 +2194,7 @@ public class MarinaTest {
             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");
+            expectOlc(Math.max(0,olc-decr_amount));
 
             if (marina.kesselsCounter) {
                 // master clear on each iteration; otherwise we'd need to "run down" the olc
@@ -2271,17 +2353,54 @@ public class MarinaTest {
 
 
 
-    private void doOneTest(int testNum) {
+    private void doOneTest(int testNum) throws Exception {
+        try {
+            doOneTest_(testNum);
+        } catch (MarinaUtils.FailureException fe) {
+            System.out.println("******************************************************************************");
+            System.out.println("******************************************************************************");
+            System.out.println("******************************************************************************");
+            System.out.println("******************************************************************************");
+            fe.printStackTrace();
+        }
+    }
+
+    private void doOneTest_(int testNum) throws Exception {
         prln("");
         prln("============================================================");
         prln("MarinaTest: performing test: "+testNum);
 
+        if (testNum==999) {
+            //vdd = 0.5f;
+            vdd = 1.0f;
+            int[] tests = new int[] { 1002, 1003, 1005, 3002, 3004, 3005, 3006, 3008, 3009, 3025, 3026, 3029 };
+            try {
+                PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("test.out")));
+                while(vdd <= 1.3f) {
+                    vdd10.setVoltageWait(vdd);
+                    System.out.println("vdd10 = " + vdd10.readVoltage());
+                    Thread.sleep(1000);
+                    for(int i=0; i<tests.length; i++) {
+                        try {
+                            doOneTest_(tests[i]);
+                            pw.println(vdd + " " + i + " " + "1");
+                        } catch (MarinaUtils.FailureException fe) {
+                            pw.println(vdd + " " + i + " " + "0");
+                        }
+                        pw.flush();
+                    }
+                    vdd -= 0.01f;
+                }
+            } catch (Exception e) { throw new RuntimeException(e); }
+        }
+
         if (testNum!=0) {
             marina.masterClear();
             marina.enableInstructionSend(true);
         }
-        
-        try {
+
+        MarinaUtils.testnum = testNum;
+
             switch (testNum) {
                 case 0: {
 
@@ -2320,8 +2439,8 @@ public class MarinaTest {
                     doOneTest(3027);    // passes extracted parasitics
                     doOneTest(3028);    // passes extracted parasitics
                     doOneTest(3029);    // passes extracted parasitics
-                    doOneTest(3030);    // passes extracted parasitics
-                    doOneTest(3031);    // passes extracted parasitics
+                    //doOneTest(3030);    // passes extracted parasitics (questionable)
+                    //doOneTest(3031);    // passes extracted parasitics should not pass!
                     
                     // these tests take a while and usually pass
                     doOneTest(1002);
@@ -2398,6 +2517,68 @@ public class MarinaTest {
                 case 3031: testOverfillTokens(marina); break;
 
                 case 3040: loadEveryValueOLC(marina); break;
+                case 8888: {
+
+                    //int wait = 1000;
+                    int wait = 200;
+                    //int toks = 1;
+
+                    PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("out.dat")));
+                    for(double myvdd = 1.0; myvdd<2.0; myvdd += 0.05) {
+                        vdd = (float)myvdd;
+                        vdd18.setVoltageWait((float)Math.max(1.8,vdd));
+                        vdd10.setVoltageWait(vdd);
+                        Thread.sleep(1000);
+
+                    for(int toks = 0; toks < 13; toks++) {
+                            int MAX_ITER = 10;
+                            double total = 0;
+                            for(int iter = 0; iter < MAX_ITER; iter++) {
+
+                                marina.masterClear();
+                                marina.data.sink();
+                                marina.stopAndResetCounters();
+                                
+                                marina.enableInstructionSend(true);
+                                marina.fillSouthProperStopper(setOlc(1));
+                                marina.fillSouthProperStopper(new Instruction.Head(dock));
+                                for(int i=0; i<toks; i++)
+                                    marina.fillSouthProperStopper(/*SEND_DATA*/NOP);
+                                marina.fillSouthProperStopper(new Instruction[] {
+                                        new Instruction.Tail(dock),
+                                    }, false, true);
+                                marina.startCounters();
+                                
+                                marina.instrIn.run();
+                                try { Thread.sleep(wait); } catch (Exception e) { }
+                                //marina.instrIn.stop();
+                                
+                                marina.stopAndResetCounters();
+                                int countNorth = marina.getNorthCount();
+                                int count      = marina.getSouthCount();
+                                System.out.println();
+                                System.out.println();
+                                if (count > (2<<29))
+                                    System.out.println("warning: count was greater than 2^29...");
+                                double gst = ((((double)count*2)) / (1000000. * wait /* * toks*/));
+                                System.out.println("south counter is: " + count + ", which is " + gst + "Ginst/sec with toks="+toks + " @vdd="+vdd);
+                                total += gst;
+
+                                System.out.println();
+                                System.out.println();
+                                /*
+                                  System.out.println("counters are " + count + " and " + countNorth + "; ratio is "+
+                                  (((double)countNorth)/((double)(count*2))) + " " +
+                                  (((double)countNorth)/((double)(count*2+1))) + " " +
+                                  "");
+                                */
+                            }
+                            pw.println(vdd + " " + toks + " " + (((double)total) / MAX_ITER));
+                            pw.flush();
+                        }
+                    }
+                    break;
+                }
                 case 9999:
                     loadEveryValueOLC(marina);
                     countOlc(marina);
@@ -2411,13 +2592,6 @@ public class MarinaTest {
             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();
-        }
     }
 
 
@@ -2428,7 +2602,7 @@ public class MarinaTest {
      * 2: test detected failure
      * 1: test crashed
      */ 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         startTime = System.currentTimeMillis();
         new MarinaTest(args);
     }
index 2ccc8c8..02b7fcc 100644 (file)
@@ -15,13 +15,15 @@ public class MarinaUtils {
     public static enum StateWireState {
         FULL, EMPTY
             };
+
+    public static int testnum;
     
     public static void fatal(boolean pred, String msg) {
         if (pred) throw new FailureException(msg);
     }
 
     public static class FailureException extends RuntimeException {
-        public FailureException(String s) { super(s); }
+        public FailureException(String s) { super("test " + testnum + ": " + s); }
     }
 
     /**
index 484ac8e..46151fa 100644 (file)
@@ -2,12 +2,7 @@ package com.sun.vlsi.chips.marina.test;
 import java.util.ArrayList;
 import java.util.List;
 
-import com.sun.async.test.BitVector;
-import com.sun.async.test.ChainControl;
-import com.sun.async.test.ChipModel;
-import com.sun.async.test.Infrastructure;
-import com.sun.async.test.NanosimModel;
-import com.sun.async.test.VerilogModel;
+import com.sun.async.test.*;
 import com.sun.vlsi.chips.marina.test.MarinaUtils.StateWireState;
 
 public class ProperStopper {
@@ -48,6 +43,8 @@ public class ProperStopper {
     private final ChipModel model;
     private final Indenter indenter;
 
+    private final String pathToCounter;
+
     protected static void fatal(boolean pred, String msg) { MarinaUtils.fatal(pred, msg); }
     private void prln(String msg) { indenter.prln(msg); }
     private void adjustIndent(int n) { indenter.adjustIndent(n); }
@@ -100,8 +97,35 @@ public class ProperStopper {
     private StateWireState boolToState(boolean b) {
         return b ? StateWireState.FULL : StateWireState.EMPTY;
     }
+
+    private CommandCodes fdcstate = null;
+
+    public void setCounterEnable(boolean enable) {
+        this.extra = enable;
+        setFillDrainControl(fdcstate);
+    }
+
+    public void setCounterValue(int val) {
+        SubchainNode chainNode = (SubchainNode) cc.getChainControlFromPath(dataChain).findNode(pathToCounter);
+        int bitIndex = chainNode.getBitIndex();
+        ChainNode root = chainNode.getParentChain();
+        for(int i=0; i<31; i++)
+            root.getInBits().set(bitIndex+i, ((1<<i) & val)!=0);
+        shiftData(false, true);
+    }
+
+    // DOES NOT SHIFT THE CHAIN!!!!
+    public int getCounterValue() {
+        SubchainNode chainNode = (SubchainNode) cc.getChainControlFromPath(dataChain).findNode(pathToCounter);
+        int bitIndex = chainNode.getBitIndex();
+        ChainNode root = chainNode.getParentChain();
+        return (int)root.getOutBits().get(bitIndex, 30).bitReverse().toLong();
+    }
+
     // The first 5 bits of the control chain control the fill and drain stages
-    private void setFillDrainControl(BitVector fdCtl) {
+    private void setFillDrainControl(CommandCodes ccc) {
+        BitVector fdCtl = ccc.bits(extra);
+        fdcstate = ccc;
         fatal(fdCtl.getNumBits()!=6, "expect 6 proper stopper control bits");
         BitVector val = cc.getInBits(controlPath);
         for (int i=0; i<fdCtl.getNumBits(); i++) {
@@ -122,45 +146,47 @@ public class ProperStopper {
 
     /** Put stopper in RUN state */
     public void run() {
-        setFillDrainControl(CommandCodes.RUN.bits());
+        setFillDrainControl(CommandCodes.RUN);
     }
     /** Put stopper in IDLE state */
     public void idle() {
-        setFillDrainControl(CommandCodes.IDLE.bits());
+        setFillDrainControl(CommandCodes.IDLE);
     }
     /** Put stopper in FILL state */
     public void fill() {
-        setFillDrainControl(CommandCodes.FILL.bits());
+        setFillDrainControl(CommandCodes.FILL);
     }
     /** Put stopper in BLOCK state */
     public void block() {
-        setFillDrainControl(CommandCodes.BLOCK.bits());
+        setFillDrainControl(CommandCodes.BLOCK);
     }
     /** Put stopper in STOP state */
     public void stop() {
-        setFillDrainControl(CommandCodes.STOP.bits());
+        setFillDrainControl(CommandCodes.STOP);
     }
     /** Put stopper in CLEAR state */
     public void clear() {
-        setFillDrainControl(CommandCodes.CLEAR.bits());
+        setFillDrainControl(CommandCodes.CLEAR);
     }
     /** Put stopper in SOURCE state */
     public void source() {
-        setFillDrainControl(CommandCodes.SOURCE.bits());
+        setFillDrainControl(CommandCodes.SOURCE);
     }
     /** Put stopper in STOPSOURCE state */
     public void stopSource() {
-        setFillDrainControl(CommandCodes.STOPSOURCE.bits());
+        setFillDrainControl(CommandCodes.STOPSOURCE);
     }
     /** Put stopper in SINK state */
     public void sink() {
-        setFillDrainControl(CommandCodes.SINK.bits());
+        setFillDrainControl(CommandCodes.SINK);
     }
     /** Put stopper in STOPSINK state */
     public void stopSink() {
-        setFillDrainControl(CommandCodes.STOPSINK.bits());
+        setFillDrainControl(CommandCodes.STOPSINK);
     }
 
+    public boolean extra = false;
+
     /** Stop a running stopper in order to add items.  Ensure that we don't
      * lose the item in the fill stage.  
      * Exit state: block */
@@ -218,7 +244,8 @@ public class ProperStopper {
                          String reportChain,
                          ChainControls cc, ChipModel model,
                          boolean clockHack,
-                         Indenter indenter) {
+                         Indenter indenter,
+                         String pathToCounter) {
         this.name = name;
         this.controlChain = controlChain;
         this.controlPath = controlChain+'.'+propInst;
@@ -233,6 +260,7 @@ public class ProperStopper {
         this.cc = cc;
         this.clockHack = clockHack;
         this.indenter = indenter;
+        this.pathToCounter = dataChain+'.'+pathToCounter;
     }
 
     /** Reset ProperStopper after the JTAG TRST has been pulsed */
@@ -389,6 +417,12 @@ public class ProperStopper {
         return ans;
     }
 
+    // proper stopper ring occupancy bits
+    //southFif@1.upDown8w@1.weakStag@18.scanEx1@0 REPORT chain
+    //18, 22, 19, 23, 20, 24, 21, 25
+    //northFif@1.upDown8w@2...
+    // south fifo tap stage:
+    //   southFif@1.tapPropS@1.tapStage@2.scanEx1@0 (also REPORT chain)
 
     /**
      * (Note by Bill and Adam: Ivan has struck again!)
@@ -405,21 +439,25 @@ public class ProperStopper {
      *  The old bit order for Infinity was: Fill, Block, Clear, Silent, Go
      */
     private static enum CommandCodes {
-        RUN        ("000100"),
-            IDLE       ("100000"),
-            FILL       ("101000"),
-            BLOCK      ("100100"),
-            STOP       ("000000"),
-            CLEAR      ("100010"),
-            SOURCE     ("001100"),
-            STOPSOURCE ("001000"),
-            SINK       ("000101"),
-            STOPSINK   ("000001");
-        private BitVector scanBits;
-        CommandCodes(String bits) {
-            scanBits = new BitVector(bits,"CommandCodes");
+        RUN        ("000100","010100"),
+            IDLE       ("100000","110000"),
+            FILL       ("101000","111000"),
+            BLOCK      ("100100","110100"),
+            STOP       ("000000","010000"),
+            CLEAR      ("100010","110010"),
+            SOURCE     ("001100","011100"),
+            STOPSOURCE ("001000","011000"),
+            SINK       ("000101","010101"),
+            STOPSINK   ("000001","010001");
+        private BitVector scanBits0;
+        private BitVector scanBits1;
+        CommandCodes(String bits0,String bits1) {
+            scanBits0 = new BitVector(bits0,"CommandCodes");
+            scanBits1 = new BitVector(bits1,"CommandCodes");
+        }
+        public BitVector bits(boolean extra) {
+            return extra ? scanBits1 : scanBits0;
         }
-        public BitVector bits() {return scanBits;}
     }
 
 }