merge omegaCounter 40nm/90nm branches into chips/omegaCounter/
[fleet.git] / src / com / sun / vlsi / chips / marina / test / Marina.java
1 package com.sun.vlsi.chips.marina.test;
2 /* -*- tab-width: 4 -*- */
3 import com.sun.async.test.BitVector;
4 import com.sun.async.test.ChainControl;
5 import com.sun.async.test.ChipModel;
6 import com.sun.async.test.JtagTester;
7 import com.sun.async.test.NanosimModel;
8 import com.sun.async.test.VerilogModel;
9
10 import edu.berkeley.fleet.api.Instruction;
11 import edu.berkeley.fleet.marina.MarinaPath;
12
13 /** The Marina object will eventually represent the Marina test chip.  
14  * Right now, it doesn't do much of anything. It just helps me exercise
15  * my test infrastructure. */
16 public class Marina {
17
18     public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE  = 5;
19     public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = MarinaPath.SIGNAL_BIT_INDEX;
20
21        
22     public static int TOKEN_FIFO_CAPACITY = 3;
23     
24     //public static boolean kesselsCounter = true;
25     public static boolean kesselsCounter = false;
26     public static boolean omegaCounter = false;
27
28     public static final String DATA_CHAIN =    kesselsCounter ? "marina.marina_data" : "marina.ivan_data";      
29     public static final String CONTROL_CHAIN = kesselsCounter ? "marina.marina_control" : "marina.ivan_control";
30     public static final String REPORT_CHAIN =  kesselsCounter ? "marina.marina_report" : "marina.ivan_report";
31
32     public static String prefix = "marinaGu@0.outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@"+(kesselsCounter?"1":"0")+".";
33     public static String MASTER_CLEAR = "mc";
34
35
36     /*
37     private static String prefix = "outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@1.";
38     private static String MASTER_CLEAR = "EXTmasterClear";
39     */
40
41     private static final String OLC_PATH_EVEN = 
42         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@1"; // bits 2,4,6
43     private static final String OLC_PATH_ODD = 
44         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@2"; // bits 1,3,5
45     private static final String OLC_PATH_KESSEL = 
46         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.counte@0.adamScan@1.scanEx6h@";
47     private static final String ILC_PATH_ODD = 
48         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@0"; // bits 1,3,5,7
49     private static final String ILC_PATH_EVEN = 
50         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@1"; // bits 2,4,6,8
51     private static final String FLAGS_PATH = 
52         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.scanEx3h@0";
53
54     private static final String INSTR_RING_CONTROL_PATH = 
55         prefix+"southFif@1.tapPropS@1.tapStage@2";
56     private static final String TOK_FIFO_PATH =
57         prefix+"tokenFIF@1";
58     private static final String INSTRUCTION_COUNTER_PATH =
59         prefix+"southFif@1.tapPropS@1.instruct@0";
60     private static final String DATA_COUNTER_PATH =
61         prefix+"northFif@1.fillDrai@1.instruct@0";
62     private static final String TOK_PRED_PATH =
63         prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx2h@0.scanCell@10";
64
65     private static final int COUNTER_LENGTH = 34;
66     private static final int INSTRUCTION_SEND_NDX = 1;
67     private static final int INSTRUCTION_RECIRCULATE_NDX = 0;
68
69     public static final int INSTRUCTION_LENGTH = 36;
70         
71     private static final int A_FLAG_NDX = 0;
72     private static final int B_FLAG_NDX = 1;
73         
74     public static final int SOUTH_RING_CAPACITY = 11;
75         
76     // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
77     public class Ilc {
78         // value is bit reversed and complemented
79         private int value;
80         private Ilc() {
81             shiftReport(true, false);
82             BitVector odd  = cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH_ODD).bitReverse().not();
83             BitVector even = cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH_EVEN).bitReverse().not();
84             BitVector ret  = new BitVector(8, "olc");
85             for(int i=0; i<4; i++) {
86                 ret.set(i*2+1, odd.get(i));
87                 ret.set(i*2,   even.get(i));
88             }
89             value = (int)ret.toLong();
90         }
91         /** Get the inner loop counter done bit. */
92         public boolean getDone() {
93             return (value & 0x40) != 0;
94         }
95         /** Get the inner loop counter infinity bit */
96         public boolean getInfinity() {
97             return (value & 0x80) != 0;
98         }
99         /** Get the 6 bits of count of the inner loop counter */
100         public int getCount() {
101             return value & 0x3f;
102         }
103         public String toString() {
104             return "[ilc, count="+getCount()+", infinity="+getInfinity()+", done="+getDone()+"]";
105         }
106     }
107         
108     private final Indenter indenter;
109
110     // The name of the scan chain
111     // The instance path, from the top cell of the netlist, of the instance of infinityWithCover 
112     private final ChainControls cc;           // specifies the scan chain
113     private final ChipModel model;
114     public final ProperStopper data;
115     public final InstructionStopper instrIn;
116     
117     private void prln(String msg) {indenter.prln(msg);}
118     private void pr(String msg) {indenter.pr(msg);}
119     
120     /** Shift the report scan chain */
121     private void shiftReport(boolean readEnable, boolean writeEnable) {
122         cc.shift(REPORT_CHAIN, readEnable, writeEnable);
123     }
124     
125     /** Shift the report scan chain */
126     private void shiftControl(boolean readEnable, boolean writeEnable) {
127         cc.shift(CONTROL_CHAIN, readEnable, writeEnable);
128     }
129         
130     /** Shift the data scan chain */
131     private void shiftData(boolean readEnable, boolean writeEnable) {
132         cc.shift(DATA_CHAIN, readEnable, writeEnable);
133     }
134
135     public Marina(ChainControls cc, ChipModel model, boolean clockHack, Indenter indenter) {
136         this.cc = cc;
137         this.model = model;
138         this.indenter = indenter;
139         data = new ProperStopper("north fifo",
140                                  prefix+"northFif@1.fillDrai@1.properSt@1",
141                                  CONTROL_CHAIN, 
142                                  DATA_CHAIN,  
143                                  REPORT_CHAIN,
144                                  cc, model, clockHack, indenter);
145         instrIn = new InstructionStopper("south fifo",
146                                          prefix+"southFif@1.tapPropS@1.properSt@1", 
147                                          CONTROL_CHAIN,
148                                          DATA_CHAIN,
149                                          REPORT_CHAIN,
150                                          cc, model, clockHack, indenter);
151     }
152     public void masterClear() {
153         final double WIDTH = 10; // ns
154         // Put a high going pulse on the internal chip master clear signal
155         if (model instanceof VerilogModel) {
156
157             data.clear();
158             instrIn.clear();
159
160             VerilogModel vm = (VerilogModel)model;
161             //
162             // In real life the flags come up with some undefined
163             // value.  In verilog we need to prevent the X'es from
164             // propagating, so we force the flags to a known value
165             //
166             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__set_", 0);
167             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__clr_", 1);
168             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__set_", 0);
169             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__clr_", 1);
170
171             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__set_", 1);
172             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__clr_", 0);
173
174             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@0.net_50", 0);       // A
175             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@1.net_50", 0);       // B
176             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_", 0); // C
177
178             // possible C-flag inputs
179             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]", 0);
180             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]", 0);
181
182             // force the OLC to zero
183             if (!kesselsCounter)
184                 for(int i=1; i<=6; i++)
185                     vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
186
187             // set the ILC input to 1
188             for(int i=1; i<=8; i++) {
189                 if (i!=7)
190                     vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
191             }
192
193             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 1);
194             model.waitNS(1000);
195             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 0);
196             model.waitNS(1000);
197
198             vm.setNodeState(MASTER_CLEAR, 1);
199             model.waitNS(1000);
200             vm.setNodeState(MASTER_CLEAR, 0);
201             model.waitNS(1000);
202
203             // pulse ilc[load] and olc[load]
204             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_", 1);
205             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_decLO_", 1);
206             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_torpLO_", 1);
207             if (!kesselsCounter)
208                 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_", 1);
209             model.waitNS(100);
210             model.waitNS(1);
211             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_");
212             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_decLO_");
213             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_torpLO_");
214             if (!kesselsCounter)
215                 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_");
216
217             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__set_");
218             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__clr_");
219             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__set_");
220             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__clr_");
221
222             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__set_");
223             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__clr_");
224
225             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@0.net_50");
226             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@1.net_50");
227
228             // Every move instruction, even those with Ti=0,Di=0,
229             // loads the C-flag.  It will get loaded with an "X",
230             // which will then leak into the flags and from there the
231             // predicate.
232             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_");
233             vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]");
234             vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]");
235             vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire");
236
237             for(int i=1; i<=8; i++) {
238                 if (i!=7)
239                     vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
240             }
241             model.waitNS(1000);
242
243             if (!kesselsCounter)
244                 for(int i=1; i<=6; i++)
245                     vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.inLO["+i+"]");
246
247             // the proper stopper states come up in an undefined ("X")
248             // state, so under Verilog we need to force them to a
249             // known state
250
251             data.idle();
252             instrIn.idle();
253
254         } else if (model instanceof NanosimModel) {
255             NanosimModel nModel = (NanosimModel) model;
256             /*
257             nModel.setNodeVoltage(prefix+"sid[9]",1.0);
258             nModel.setNodeVoltage(prefix+"sic[9]",1.0);
259             nModel.setNodeVoltage(prefix+"sir[9]",1.0);
260             nModel.waitNS(WIDTH);
261             nModel.setNodeVoltage(prefix+"sid[9]",0.0);
262             nModel.setNodeVoltage(prefix+"sic[9]",0.0);
263             nModel.setNodeVoltage(prefix+"sir[9]",0.0);
264             nModel.waitNS(1);
265             */
266             nModel.setNodeVoltage(MASTER_CLEAR,1.0);
267             nModel.waitNS(WIDTH);
268             nModel.setNodeVoltage(MASTER_CLEAR,0.0);
269             nModel.waitNS(1);
270         } else {
271             prln("FIXME!");
272         }
273         resetAfterMasterClear();
274     }
275     private void resetAfterMasterClear() {
276         // The following call to ChainControl.resetInBits() is vital!
277         // If you forget, then the inBits member initializes 
278         // with random data. Then when you do your first write,
279         // some bits are written randomly.
280         cc.resetInBits();
281
282         // For reset, I want to clear all the stoppers simultaneously
283         data.clear();
284         //tokOut.clear();
285         instrIn.clear();
286         
287         data.stop();
288         //tokOut.stop();
289         instrIn.stop();
290         
291         data.resetAfterMasterClear();
292         //tokOut.resetAfterMasterClear();
293         instrIn.resetAfterMasterClear();
294     }
295
296
297     /** Get the 6 bit outer loop counter. */
298     public int getOLC() {
299         shiftReport(true, false);
300         if (omegaCounter) {
301             BitVector bits = null;
302             for(int i=0; i<4; i++) {
303                 BitVector x = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
304                 //System.out.println("bits are: " + x);
305                 bits = bits==null ? x : bits.cat(x);
306             }
307             System.out.print("  kesselsCounter = ");
308             int ret = 0;
309             boolean done = true;
310             boolean bad = false;
311             for(int bit=5; bit>=0; bit--) {
312                 boolean zeroOrTwo  = bits.get(4+bit*3);
313                 boolean zeroOrDone = bits.get(4+bit*3+1);
314                 if      ( zeroOrTwo && !zeroOrDone) {
315                     ret += (2<<bit);
316                     System.out.print("2");
317                     done = false;
318                 } else if (!zeroOrTwo && !zeroOrDone) {
319                     ret += (1<<bit);
320                     System.out.print("1");
321                     done = false;
322                 } else if ( zeroOrTwo &&  zeroOrDone) {
323                     System.out.print("0");
324                     bad = true;
325                     done = false;
326                 } else if (!zeroOrTwo &&  zeroOrDone) {
327                     System.out.print("_");
328                     if (!done) bad = true;
329                 }
330                 // FIXME: check for unreduced counter and warn about it
331             }
332             if (bad) System.out.print("  WARNING: UNREDUCED COUNTER VALUE!!!!!!");
333             System.out.println();
334             return ret;
335         } else if (kesselsCounter) {
336             BitVector bits = null;
337             for(int i=0; i<4; i++) {
338                 BitVector x = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
339                 //System.out.println("bits are: " + x);
340                 bits = bits==null ? x : bits.cat(x);
341             }
342             //System.out.println("kesselsCounter = " + bits);
343             int first = 0;
344             int second = 0;
345             for(int i=0; i<6; i++) first  |= bits.get(4+i*3)   ? (1<<i) : 0;
346             for(int i=0; i<6; i++) second |= bits.get(4+i*3+2) ? (1<<i) : 0;
347             return (first+second);
348         } else {
349             BitVector odd = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse();
350             BitVector even = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_EVEN).bitReverse();
351             odd = odd.not();
352             even = even.not();
353             BitVector bv = new BitVector(6, "olc");
354             for(int i=0; i<3; i++) {
355                 bv.set(i*2,   odd.get(i));
356                 bv.set(i*2+1, even.get(i));
357             }
358             return (int)bv.toLong();
359         }
360     }
361     /** Get the 7 bit inner loop counter. The MSB is the zero bit.
362      * The low order 6 bits are the count */
363     public Ilc getILC() {
364         return new Ilc();
365     }
366     /** Get the A flag */
367     public boolean getFlagA() {
368         shiftReport(true, false);
369         return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(A_FLAG_NDX);
370     }
371     /** Get the B flag */
372     public boolean getFlagB() {
373         shiftReport(true, false);
374         return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(B_FLAG_NDX);
375     }
376     /** return value of instruction counter. Instruction counter counts 
377      * the instructions flowing through 1/2 of alternating FIFO.
378      * Caution: instruction counter is written by all scans, 
379      * regardless of readEnable or writeEnable! */
380     public long getInstructionCounter() {
381         shiftData(true, false);
382         BitVector count = cc.getOutBits(DATA_CHAIN+"."+INSTRUCTION_COUNTER_PATH);
383         int sz = count.getNumBits(); 
384         MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
385                          " expected: "+COUNTER_LENGTH);
386         return count.bitReverse().toLong();
387     }
388     /** return value of data counter. Data counter counts items flowing
389      * through drain stage of data proper stopper. 
390      * Caution: data counter is written by all scans, 
391      * regardless of readEnable or writeEnable! */
392     public long getDataCounter() {
393         shiftData(true, false);
394         BitVector count = cc.getOutBits(DATA_CHAIN+"."+DATA_COUNTER_PATH);
395         int sz = count.getNumBits(); 
396         MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
397                          " expected: "+COUNTER_LENGTH);
398         return count.bitReverse().toLong();
399     }
400     /** Fill the "North" Fifo ring */
401     public void fillNorthProperStopper() {
402         BitVector data = new BitVector(37, "empty");
403         BitVector addr = new BitVector(14, "empty");
404         for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
405         for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
406         fillNorthProperStopper(new MarinaPacket(data, false, addr));
407     }
408     /** Fill the "North" Fifo ring */
409     public void fillNorthProperStopper(MarinaPacket mp) {
410         prln("inserting into north: " + mp);
411         this.data.fill(mp.toSingleBitVector());
412     }
413     /** Enable the transmission of instructions from the instruction
414      * ring test structure to the EPI FIFO. */
415     public void enableInstructionSend(boolean b) {
416         BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
417         bv.set(INSTRUCTION_SEND_NDX, b);
418         cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv); 
419         shiftControl(false, true);
420     } 
421     /** Enable the recirculation of instructions within the South FIFO */
422     public void enableInstructionRecirculate(boolean b) {
423         BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
424         bv.set(INSTRUCTION_RECIRCULATE_NDX, b);
425         cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv); 
426         shiftControl(false, true);
427     }
428     /** get the number of tokens in the token FIFO.
429      * This includes the Token successor wire, the token FIFO wires,
430      * and Token predecessor wire.
431      * Master clear clears the token FIFO. */
432     public int getNumTokens() {
433         shiftReport(true, false);
434         // get the token successor and token FIFO wires
435         BitVector bv = cc.getOutBits(REPORT_CHAIN+"."+TOK_FIFO_PATH);
436         int sz = bv.getNumBits();
437         MarinaTest.fatal(sz!=3, "wrong token FIFO size: "+sz+" expected: 3");
438         
439         // get the token predecessor wire
440         BitVector pred = cc.getOutBits(REPORT_CHAIN+"."+TOK_PRED_PATH);
441         sz = pred.getNumBits();
442         MarinaTest.fatal(sz!=1, "wrong token predecessor size: "+sz+" expected: 1");
443
444         // concatenate them
445         bv = bv.cat(pred);
446         sz = bv.getNumBits();
447         prln("Token state wires: "+bv.getState());
448         
449         int nbTok = 0;
450         for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
451         return nbTok;
452     }
453     /** Configure the test probe so it measures the throughput of
454      * the north data FIFO. The test probe frequency is 8192 
455      * times slower than the FIFO throughput. This control has
456      * highest priority. */
457     public void probeDataCounter(Boolean b) {
458         data.setGeneralPurposeOutput(b);
459     }
460     /** Configure the test probe so it measures the throughput of
461      * the alternating instruction FIFO. The test probe frequency is
462      * 1/16384 of the FIFO throughput. This control has second
463      * highest priority. Thus the following two calls probe the
464      * instruction counter: 
465      *      probeDataCounter(false);
466      *      probeInstructionCounter(true)
467      */
468     public void enableInstructionCounter(Boolean b) {
469         instrIn.setGeneralPurposeOutput(b);
470     }
471
472     public void fillSouthProperStopper(Instruction[] instructions) { fillSouthProperStopper(instructions, false); }
473     public void fillSouthProperStopper(Instruction[] instructions, boolean repeat) {
474         enableInstructionSend(false);
475         enableInstructionRecirculate(true);
476         for(Instruction i : instructions)
477             if (i!=null)
478                 instrIn.fill(i);
479         enableInstructionRecirculate(repeat);
480         enableInstructionSend(true);
481         instrIn.run();
482     }
483
484     
485 }