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 import com.sun.async.test.*;
11 import edu.berkeley.fleet.api.Instruction;
12 import edu.berkeley.fleet.marina.MarinaPath;
14 /** The Marina object will eventually represent the Marina test chip.
15 * Right now, it doesn't do much of anything. It just helps me exercise
16 * my test infrastructure. */
19 public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE = 5;
20 public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = MarinaPath.SIGNAL_BIT_INDEX;
23 public static int TOKEN_FIFO_CAPACITY = 3;
25 //public static boolean kesselsCounter = true;
26 public static boolean kesselsCounter = false;
27 public static boolean omegaCounter = false;
29 public static final String DATA_CHAIN = kesselsCounter ? "marina.marina_data" : "marina.ivan_data";
30 public static final String CONTROL_CHAIN = kesselsCounter ? "marina.marina_control" : "marina.ivan_control";
31 public static final String REPORT_CHAIN = kesselsCounter ? "marina.marina_report" : "marina.ivan_report";
33 public static String prefix = "marinaGu@0.outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@"+(kesselsCounter?"1":"0")+".";
34 public static String MASTER_CLEAR = "mc";
38 private static String prefix = "outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@1.";
39 private static String MASTER_CLEAR = "EXTmasterClear";
42 private static final String OLC_PATH_EVEN =
43 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@1"; // bits 2,4,6
44 private static final String OLC_PATH_ODD =
45 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@2"; // bits 1,3,5
46 public static final String OLC_PATH_KESSEL =
47 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.counte@0.adamScan@1.scanEx6h@";
48 private static final String ILC_PATH_ODD =
49 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@0"; // bits 1,3,5,7
50 private static final String ILC_PATH_EVEN =
51 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@1"; // bits 2,4,6,8
52 private static final String FLAGS_PATH =
53 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.scanEx3h@0";
55 private static final String INSTR_RING_CONTROL_PATH =
56 prefix+"southFif@1.tapPropS@1.tapStage@2";
57 private static final String TOK_FIFO_PATH =
59 private static final String INSTRUCTION_COUNTER_PATH =
60 prefix+"southFif@1.tapPropS@1.instruct@0";
61 private static final String DATA_COUNTER_PATH =
62 prefix+"northFif@1.fillDrai@1.instruct@0";
63 private static final String TOK_PRED_PATH =
64 prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx2h@0.scanCell@10";
66 private static final int COUNTER_LENGTH = 34;
67 private static final int INSTRUCTION_SEND_NDX = 1;
68 private static final int INSTRUCTION_RECIRCULATE_NDX = 0;
70 public static final int INSTRUCTION_LENGTH = 36;
72 private static final int A_FLAG_NDX = 0;
73 private static final int B_FLAG_NDX = 1;
75 public static final int SOUTH_RING_CAPACITY = 11;
77 // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
79 // value is bit reversed and complemented
82 shiftReport(true, false);
83 BitVector odd = cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH_ODD).bitReverse().not();
84 BitVector even = cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH_EVEN).bitReverse().not();
85 BitVector ret = new BitVector(8, "olc");
86 for(int i=0; i<4; i++) {
87 ret.set(i*2+1, odd.get(i));
88 ret.set(i*2, even.get(i));
90 value = (int)ret.toLong();
92 /** Get the inner loop counter done bit. */
93 public boolean getDone() {
94 return (value & 0x40) != 0;
96 /** Get the inner loop counter infinity bit */
97 public boolean getInfinity() {
98 return (value & 0x80) != 0;
100 /** Get the 6 bits of count of the inner loop counter */
101 public int getCount() {
104 public String toString() {
105 return "[ilc, count="+getCount()+", infinity="+getInfinity()+", done="+getDone()+"]";
109 private final Indenter indenter;
111 // The name of the scan chain
112 // The instance path, from the top cell of the netlist, of the instance of infinityWithCover
113 public final ChainControls cc; // specifies the scan chain
114 private final ChipModel model;
115 public final ProperStopper data;
116 public final InstructionStopper instrIn;
118 private void prln(String msg) {indenter.prln(msg);}
119 private void pr(String msg) {indenter.pr(msg);}
121 /** Shift the report scan chain */
122 public void shiftReport(boolean readEnable, boolean writeEnable) {
123 cc.shift(REPORT_CHAIN, readEnable, writeEnable);
126 /** Shift the report scan chain */
127 private void shiftControl(boolean readEnable, boolean writeEnable) {
128 cc.shift(CONTROL_CHAIN, readEnable, writeEnable);
131 /** Shift the data scan chain */
132 private void shiftData(boolean readEnable, boolean writeEnable) {
133 cc.shift(DATA_CHAIN, readEnable, writeEnable);
136 public Marina(ChainControls cc, ChipModel model, boolean clockHack, Indenter indenter) {
139 this.indenter = indenter;
140 data = new ProperStopper("north fifo",
141 prefix+"northFif@1.fillDrai@1.properSt@1",
145 cc, model, clockHack, indenter,
146 prefix+"northFif@1.fillDrai@1.instruct@0.cntScnTh@1.cntScnOn@1");
147 instrIn = new InstructionStopper("south fifo",
148 prefix+"southFif@1.tapPropS@1.properSt@1",
152 cc, model, clockHack, indenter,
153 prefix+"southFif@1.tapPropS@1.instruct@0.cntScnTh@1.cntScnOn@1");
159 public void stopAndResetCounters() {
160 instrIn.setCounterEnable(false);
161 data.setCounterEnable(false);
162 cc.shift(DATA_CHAIN, true, false);
163 northCount = data.getCounterValue();
164 southCount = instrIn.getCounterValue();
165 data.setCounterValue(0);
166 instrIn.setCounterValue(0);
168 public void startCounters() {
169 instrIn.setCounterEnable(true);
170 data.setCounterEnable(true);
172 public int getNorthCount() { return northCount; }
173 public int getSouthCount() { return southCount; }
176 public void masterClear() {
177 final double WIDTH = 10; // ns
178 // Put a high going pulse on the internal chip master clear signal
179 if (model instanceof VerilogModel) {
184 VerilogModel vm = (VerilogModel)model;
186 // In real life the flags come up with some undefined
187 // value. In verilog we need to prevent the X'es from
188 // propagating, so we force the flags to a known value
190 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__set_", 0);
191 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__clr_", 1);
192 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__set_", 0);
193 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__clr_", 1);
195 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__set_", 1);
196 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__clr_", 0);
198 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@0.net_50", 0); // A
199 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@1.net_50", 0); // B
200 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_", 0); // C
202 // possible C-flag inputs
203 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]", 0);
204 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]", 0);
206 // force the OLC to zero
208 for(int i=1; i<=6; i++)
209 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
211 // set the ILC input to 1
212 for(int i=1; i<=8; i++) {
214 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
217 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 1);
219 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 0);
222 vm.setNodeState(MASTER_CLEAR, 1);
224 vm.setNodeState(MASTER_CLEAR, 0);
227 // pulse ilc[load] and olc[load]
228 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_", 1);
229 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_decLO_", 1);
230 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_torpLO_", 1);
232 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_", 1);
235 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_");
236 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_decLO_");
237 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_torpLO_");
239 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_");
241 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__set_");
242 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__clr_");
243 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__set_");
244 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__clr_");
246 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__set_");
247 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__clr_");
249 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@0.net_50");
250 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@1.net_50");
252 // Every move instruction, even those with Ti=0,Di=0,
253 // loads the C-flag. It will get loaded with an "X",
254 // which will then leak into the flags and from there the
256 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_");
257 vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]");
258 vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]");
259 vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire");
261 for(int i=1; i<=8; i++) {
263 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
268 for(int i=1; i<=6; i++)
269 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.inLO["+i+"]");
271 // the proper stopper states come up in an undefined ("X")
272 // state, so under Verilog we need to force them to a
278 } else if (model instanceof NanosimModel) {
279 NanosimModel nModel = (NanosimModel) model;
281 nModel.setNodeVoltage(prefix+"sid[9]",1.0);
282 nModel.setNodeVoltage(prefix+"sic[9]",1.0);
283 nModel.setNodeVoltage(prefix+"sir[9]",1.0);
284 nModel.waitNS(WIDTH);
285 nModel.setNodeVoltage(prefix+"sid[9]",0.0);
286 nModel.setNodeVoltage(prefix+"sic[9]",0.0);
287 nModel.setNodeVoltage(prefix+"sir[9]",0.0);
290 nModel.setNodeVoltage(MASTER_CLEAR,1.0);
291 nModel.waitNS(WIDTH);
292 nModel.setNodeVoltage(MASTER_CLEAR,0.0);
296 mc0.setLogicState(true);
297 mc1.setLogicState(true);
299 mc0.setLogicState(false);
300 mc1.setLogicState(false);
304 resetAfterMasterClear();
310 private void resetAfterMasterClear() {
311 // The following call to ChainControl.resetInBits() is vital!
312 // If you forget, then the inBits member initializes
313 // with random data. Then when you do your first write,
314 // some bits are written randomly.
317 // For reset, I want to clear all the stoppers simultaneously
326 data.resetAfterMasterClear();
327 //tokOut.resetAfterMasterClear();
328 instrIn.resetAfterMasterClear();
332 /** Get the 6 bit outer loop counter. */
333 public int getOLC() {
334 shiftReport(true, false);
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);
342 System.out.print(" kesselsCounter = ");
346 for(int bit=5; bit>=0; bit--) {
347 boolean zeroOrTwo = bits.get(4+bit*3);
348 boolean zeroOrDone = bits.get(4+bit*3+1);
349 if ( zeroOrTwo && !zeroOrDone) {
351 System.out.print("2");
353 } else if (!zeroOrTwo && !zeroOrDone) {
355 System.out.print("1");
357 } else if ( zeroOrTwo && zeroOrDone) {
358 System.out.print("0");
361 } else if (!zeroOrTwo && zeroOrDone) {
362 System.out.print("_");
363 if (!done) bad = true;
365 // FIXME: check for unreduced counter and warn about it
367 if (bad) System.out.print(" WARNING: UNREDUCED COUNTER VALUE!!!!!!");
368 System.out.println();
370 } else if (kesselsCounter) {
371 BitVector bits = null;
372 for(int i=0; i<4; i++) {
373 BitVector x = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
374 //System.out.println("bits are: " + x);
375 bits = bits==null ? x : bits.cat(x);
377 //System.out.println("kesselsCounter = " + bits);
384 for(int i=0; i<6; i++) {
385 first |= bits.get(4+i*3) ? (1<<i) : 0;
386 second |= bits.get(4+i*3+2) ? (1<<i) : 0;
387 hi = (bits.get(4+i*3) ? "1" : "0") + hi;
388 lo = (bits.get(4+i*3+2) ? "1" : "0") + lo;
390 ( bits.get(4+i*3) && !bits.get(4+i*3+2) ? "X"
391 : !bits.get(4+i*3) && !bits.get(4+i*3+2) ? "0"
392 : !bits.get(4+i*3) && bits.get(4+i*3+2) ? "1"
395 latched = (bits.get(4+i*3+1) ? "0" : "1") + latched;
397 System.out.println("kesselsCounter: "+
400 " latched="+latched +
402 " do[ins]="+(bits.get(0) ? "1" : "0")+
403 " dec="+(bits.get(1) ? "1" : "0")+
404 " flag[D][set]="+(bits.get(2) ? "1" : "0")+
405 " resetting="+(bits.get(3) ? "1" : "0")+
408 return (first+second);
410 BitVector odd = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse();
411 BitVector even = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_EVEN).bitReverse();
414 BitVector bv = new BitVector(6, "olc");
415 for(int i=0; i<3; i++) {
416 bv.set(i*2, odd.get(i));
417 bv.set(i*2+1, even.get(i));
419 return (int)bv.toLong();
422 /** Get the 7 bit inner loop counter. The MSB is the zero bit.
423 * The low order 6 bits are the count */
424 public Ilc getILC() {
427 /** Get the A flag */
428 public boolean getFlagA() {
429 shiftReport(true, false);
430 return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(A_FLAG_NDX);
432 /** Get the B flag */
433 public boolean getFlagB() {
434 shiftReport(true, false);
435 return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(B_FLAG_NDX);
437 /** return value of instruction counter. Instruction counter counts
438 * the instructions flowing through 1/2 of alternating FIFO.
439 * Caution: instruction counter is written by all scans,
440 * regardless of readEnable or writeEnable! */
441 public long getInstructionCounter() {
442 shiftData(true, false);
443 BitVector count = cc.getOutBits(DATA_CHAIN+"."+INSTRUCTION_COUNTER_PATH);
444 int sz = count.getNumBits();
445 MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
446 " expected: "+COUNTER_LENGTH);
447 return count.bitReverse().toLong();
449 /** return value of data counter. Data counter counts items flowing
450 * through drain stage of data proper stopper.
451 * Caution: data counter is written by all scans,
452 * regardless of readEnable or writeEnable! */
453 public long getDataCounter() {
454 shiftData(true, false);
455 BitVector count = cc.getOutBits(DATA_CHAIN+"."+DATA_COUNTER_PATH);
456 int sz = count.getNumBits();
457 MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
458 " expected: "+COUNTER_LENGTH);
459 return count.bitReverse().toLong();
461 /** Fill the "North" Fifo ring */
462 public void fillNorthProperStopper() {
463 BitVector data = new BitVector(37, "empty");
464 BitVector addr = new BitVector(14, "empty");
465 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
466 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
467 fillNorthProperStopper(new MarinaPacket(data, false, addr));
469 /** Fill the "North" Fifo ring */
470 public void fillNorthProperStopper(MarinaPacket mp) {
471 prln("inserting into north: " + mp);
472 this.data.fill(mp.toSingleBitVector());
474 /** Enable the transmission of instructions from the instruction
475 * ring test structure to the EPI FIFO. */
476 public void enableInstructionSend(boolean b) {
477 BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
478 bv.set(INSTRUCTION_SEND_NDX, b);
479 cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv);
480 shiftControl(false, true);
482 /** Enable the recirculation of instructions within the South FIFO */
483 public void enableInstructionRecirculate(boolean b) {
484 BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
485 bv.set(INSTRUCTION_RECIRCULATE_NDX, b);
486 cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv);
487 shiftControl(false, true);
489 /** get the number of tokens in the token FIFO.
490 * This includes the Token successor wire, the token FIFO wires,
491 * and Token predecessor wire.
492 * Master clear clears the token FIFO. */
493 public int getNumTokens() {
494 shiftReport(true, false);
495 // get the token successor and token FIFO wires
496 BitVector bv = cc.getOutBits(REPORT_CHAIN+"."+TOK_FIFO_PATH);
497 int sz = bv.getNumBits();
498 MarinaTest.fatal(sz!=3, "wrong token FIFO size: "+sz+" expected: 3");
500 // get the token predecessor wire
501 BitVector pred = cc.getOutBits(REPORT_CHAIN+"."+TOK_PRED_PATH);
502 sz = pred.getNumBits();
503 MarinaTest.fatal(sz!=1, "wrong token predecessor size: "+sz+" expected: 1");
507 sz = bv.getNumBits();
508 prln("Token state wires: "+bv.getState());
511 for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
514 /** Configure the test probe so it measures the throughput of
515 * the north data FIFO. The test probe frequency is 8192
516 * times slower than the FIFO throughput. This control has
517 * highest priority. */
518 public void probeDataCounter(Boolean b) {
519 data.setGeneralPurposeOutput(b);
521 /** Configure the test probe so it measures the throughput of
522 * the alternating instruction FIFO. The test probe frequency is
523 * 1/16384 of the FIFO throughput. This control has second
524 * highest priority. Thus the following two calls probe the
525 * instruction counter:
526 * probeDataCounter(false);
527 * probeInstructionCounter(true)
529 public void enableInstructionCounter(Boolean b) {
530 instrIn.setGeneralPurposeOutput(b);
533 public void fillSouthProperStopper(Instruction i) {
536 public void fillSouthProperStopper(Instruction[] instructions) { fillSouthProperStopper(instructions, false); }
537 public void fillSouthProperStopper(Instruction[] instructions, boolean repeat) { fillSouthProperStopper(instructions, repeat, false); }
538 public void fillSouthProperStopper(Instruction[] instructions, boolean repeat, boolean leaveStopped) {
539 enableInstructionSend(false);
540 enableInstructionRecirculate(true);
541 for(Instruction i : instructions)
545 instrIn.fillTorpedo();
547 enableInstructionRecirculate(repeat);
548 enableInstructionSend(true);
549 if (!leaveStopped) instrIn.run();