1 package com.sun.vlsi.chips.marina.test;
2 /* -*- tab-width: 4 -*- */
3 import java.util.ArrayList;
6 import com.sun.async.test.BitVector;
7 import com.sun.async.test.ChainControl;
8 import com.sun.async.test.ChainG;
9 import com.sun.async.test.ChainTest;
10 import com.sun.async.test.ChipModel;
11 import com.sun.async.test.HP34401A;
12 import com.sun.async.test.Infrastructure;
13 import com.sun.async.test.JtagSubchainTesterModel;
14 import com.sun.async.test.JtagTester;
15 import com.sun.async.test.ManualPowerChannel;
16 import com.sun.async.test.NanosimModel;
17 import com.sun.async.test.Netscan4;
18 import com.sun.async.test.PowerChannel;
19 import com.sun.async.test.Pst3202Channel;
20 import com.sun.async.test.SiliconChip;
21 import com.sun.async.test.SimulationModel;
22 import com.sun.async.test.VoltageReadable;
23 import com.sun.vlsi.chips.marina.test.Marina.Ilc;
24 import com.sun.vlsi.chips.marina.test.MarinaUtils.CmdArgs;
25 import com.sun.vlsi.chips.marina.test.MarinaUtils.Station;
26 import com.sun.vlsi.chips.marina.test.MarinaUtils.CmdArgs.Mode;
28 import edu.berkeley.fleet.api.Dock;
29 import edu.berkeley.fleet.api.Instruction;
30 import edu.berkeley.fleet.api.Predicate;
31 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
32 import edu.berkeley.fleet.api.Instruction.Set.SetSource;
33 import edu.berkeley.fleet.marina.MarinaFleet;
34 import edu.berkeley.fleet.marina.MarinaPath;
39 public class MarinaTest {
40 //-------------------------- constants -----------------------------------
41 private static final String SCAN_CHAIN_XML = "marina.xml";
42 private static final String NET_LIST = "marina.spi";
44 public static final int INSTR_SZ = 36;
46 public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE = 13;
47 public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = 0;
49 public static final Dock DOCK = InstructionStopper.DOCK;
50 public static final Instruction.Set.FlagFunction CLEAR_FLAG
51 = Instruction.Set.FlagFunction.ZERO;
52 public static final Instruction.Set.FlagFunction SET_FLAG
53 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA)
54 .add(Predicate.NotFlagA);
55 public static final Instruction.Set.FlagFunction A_FLAG
56 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA);
58 public static final Instruction.Set.FlagFunction B_FLAG
59 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB);
61 // COLUMN_LATENCY is a delay that is larger than the latency through an Infinity column
62 private static final int COLUMN_LATENCY = 10; // nanoseconds
65 // Officially, this should be the number of requeueing no-ops that
66 // can be inserted into an idle dock whose OLC is nonzero.
68 // Less formally, this is roughly the number of stages of
69 // buffering between the instruction insertion point and the
70 // instruction ring, plus the capacity of the instruction ring.
71 private static final int INSTRUCTION_IN_SATURATION_AMOUNT = 19;
73 // This is some number which is significantly greater than
74 // INSTRUCTION_IN_SATURATION_AMOUNT. Increasing it may slow the tests down, but
75 // will never cause them to operate incorrectly.
76 private static final int MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT = 25;
78 // This is the number of items which can be in the instruction
79 // fifo ring WITHOUT causing it to stop circulating.
80 private static final int INSTRUCTION_RING_CAPACITY = 13;
82 // Officially, this should be the number of data items which can
83 // be sent from the dock while the "data" proper stopper is in
84 // the "stopped" state
86 // Less formally, this is roughly the number of stages of
87 // buffering between the dock's data successor and the "data"
90 FIXME: what is the correct value here?
91 private static final int DATA_OUT_SATURATION_AMOUNT = XXX;
94 // This is some number which is greater than
95 // DATA_OUT_SATURATION_AMOUNT, but less than the capacity of the
97 private static final int MORE_THAN_DATA_OUT_SATURATION_AMOUNT = 10;
99 // Nominal cycle time assuming 4 GHz throughput
100 private static final double CYCLE_TIME_NS = 0.250;
102 //-------------------------------- types ---------------------------------
104 //-------------------------- private data --------------------------------
105 private static long startTime;
107 private Indenter indenter = new Indenter();
108 private Marina marina;
109 private ChipModel model;
110 //private ChainControl cc;
111 //private JtagTester tester;
112 private CmdArgs cmdArgs;
113 private PowerChannel corePowerSupply, padsPowerSupply;
114 private VoltageReadable coreVoltmeter, voltmeterForCurrent;
116 //-------------------------- private methods -----------------------------
117 /** @return true if simulation. Return false if we're testing silicon. */
118 private boolean sim() {return model instanceof SimulationModel;}
120 private void prln(String msg) {indenter.prln(msg);}
121 private void pr(String msg) {indenter.pr(msg);}
122 private void adjustIndent(int n) {indenter.adjustIndent(n);}
124 public static void fatal(boolean pred, String msg) {
126 Exception err = new Exception(msg);
127 err.printStackTrace();
128 System.out.println("Test Result: Test Failed");
131 Infrastructure.exit(2);
134 public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
135 // FIXME: better error reporting needed here
137 fatal(bv1.getNumBits()!=bv2.getNumBits(), "lengths do not match");
139 boolean mismatch = false;
141 for(int i=0; i<bv1.getNumBits(); i++) {
142 if (bv1.get(i) != bv2.get(i)) {
147 fatal(mismatch, "bit vectors do not match on bits " + err + "\n "+bv1+"\n "+bv2);
150 private static void printTestTime() {
151 long endTime = System.currentTimeMillis();
152 System.out.println("Test took: "+(endTime-startTime)/1000.0+" sec");
155 // Tell user what we're about to do
156 private static void reportTask(CmdArgs args) {
157 System.out.println("Begin testing Marina");
159 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
160 System.out.println(" Simulate whole chip, schematic parasitics");
162 case WHOLE_CHIP_LAYOUT_PARASITICS:
163 System.out.println(" Simulate whole chip, layout parasitics");
166 System.out.println(" Test silicon");
169 fatal(true, "unrecognized CmdArgs.Mode");
173 private void setUpSuppliesAndMeters(Station station) {
174 // set up power supplies and meters
176 prln("Testing station: "+station);
177 Infrastructure.gpibControllers = new int[] {0};
178 switch (cmdArgs.station) {
180 corePowerSupply = new Pst3202Channel("ch1", "HPST3202", 1);
181 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202", 2);
184 corePowerSupply = new Pst3202Channel("ch1", "HPST3202B", 1);
185 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202B", 2);
188 fatal(true, "Unrecognized station: "+cmdArgs.station);
190 corePowerSupply.setCurrent((float)1.7);
191 corePowerSupply.setVoltageWait((float)1.0);
193 padsPowerSupply.setCurrent((float)0.100);
194 padsPowerSupply.setVoltageWait((float)1.8);
196 coreVoltmeter = new HP34401A(station.coreVoltmeter);
197 voltmeterForCurrent = new HP34401A(station.currentVoltmenter);
201 private MarinaTest(String[] args) {
202 cmdArgs = new MarinaUtils.CmdArgs(args);
204 if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim();
207 private void doSim() {
209 switch (cmdArgs.mode) {
210 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
211 netListName = NET_LIST;
213 case WHOLE_CHIP_LAYOUT_PARASITICS:
214 netListName = "marina_pads_guts.spi";
217 fatal(true, "unrecognized CmdArgs.Mode");
220 model = new NanosimModel();
222 //tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
223 ChainControls ccs = new ChainControls();
224 JtagTester testerD, testerR, testerC;
225 testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null);
226 testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null);
227 testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null);
228 testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
232 ChainControl ccD, ccR, ccC;
233 ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
234 ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
235 ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
236 ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
238 PowerChannel pc = new ManualPowerChannel("pc", false);
240 ChainTest ctD, ctR, ctC;
241 ctD = new ChainTest(ccD, pc);
242 ctR = new ChainTest(ccR, pc);
243 ctC = new ChainTest(ccC, pc);
245 ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
248 ctD.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
249 ctR.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
250 ctC.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
253 ccs.addChain(Marina.DATA_CHAIN, ccD);
254 ccs.addChain(Marina.REPORT_CHAIN, ccR);
255 ccs.addChain(Marina.CONTROL_CHAIN, ccC);
257 marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter);
259 //System.out.println("launching");
260 //ChainG.createAndShowGUI(marina.cc.getChainControlFromPath(Marina.REPORT_CHAIN));
261 //System.out.println(" launched.");
263 doOneTest(cmdArgs.testNum);
265 ((SimulationModel)model).finish();
267 private void doSilicon() {
268 model = new SiliconChip();
269 String ip = cmdArgs.station.ipAddr;
270 JtagTester tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
271 tester.printInfo = false;
273 ChainControl cc = new ChainControl("???", tester, 1.8f, khz);
274 cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
275 ChainControls ccs = new ChainControls();
276 ccs.addChain(Marina.DATA_CHAIN, cc);
277 ccs.addChain(Marina.REPORT_CHAIN, cc);
278 ccs.addChain(Marina.CONTROL_CHAIN, cc);
279 marina = new Marina(ccs, model, false, indenter);
280 PowerChannel pc = new ManualPowerChannel("pc", false);
281 ChainTest ct = new ChainTest(cc, pc);
282 ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
284 doOneTest(cmdArgs.testNum);
286 setUpSuppliesAndMeters(cmdArgs.station);
290 /** In the absence of looping, the longest path through Infinity is 4 column delays */
291 private void waitUntilQuiescent() {
292 model.waitNS(4*COLUMN_LATENCY);
295 private double readCurrent() {
296 return voltmeterForCurrent.readVoltage() / cmdArgs.station.ammeterShuntResistance;
299 /** Generate List of BitVectors where Token=true, high 25 data bits
300 * are alternating ones and zeros, low 12 data bits increment from
301 * zero, and address is given by addr. */
302 private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
303 List<BitVector> ans = new ArrayList<BitVector>();
304 BitVector dHi = new BitVector(25, "dataHi");
305 BitVector dLo = new BitVector(12, "dataLo");
306 BitVector t = new BitVector("1", "token");
307 BitVector a = new BitVector(14, "addr");
308 dHi.setFromLong(0x00aaaaa);
310 for (int i=0; i<num; i++) {
312 ans.add(dHi.cat(dLo).cat(t).cat(a));
317 private void stopToStop(ProperStopper s1, ProperStopper s2,
319 List<BitVector> din) {
320 prln("Begin stopToStop");
325 long ctrStart = ctr==null ? 0 : ctr.getCount();
328 waitUntilQuiescent();
330 List<BitVector> dout = s2.drainMany();
332 MarinaUtils.compareItemsOrdered(din, dout);
335 long ctrEnd = ctr.getCount();
336 long delta = ctrEnd - ctrStart;
337 long expect = din.size();
339 "counter delta wrong: expected delta: "+expect+
340 " counter before:"+ctrStart+" counter after:"+ctrEnd);
344 prln("End stopToStop");
346 /** Burst data from src to dst. gate is stopped while loading src. gate
347 * is then run to allow the burst to flow. */
348 private void stopToStopBurst(ProperStopper src, ProperStopper gate,
351 List<BitVector> din) {
352 prln("Begin stopToStopBurst test");
358 long ctrStart = ctr==null ? 0 : ctr.getCount();
361 waitUntilQuiescent();
363 // open the gate to start the burst
365 waitUntilQuiescent();
367 List<BitVector> dout = dst.drainMany();
369 MarinaUtils.compareItemsOrdered(din, dout);
372 long ctrEnd = ctr.getCount();
373 long delta = ctrEnd - ctrStart;
375 long expectA = din.size();
376 fatal(delta!=expectA,
377 "counter delta wrong: expected delta: "+expectA+
378 " counter before:"+ctrStart+" counter after:"+ctrEnd);
382 prln("End stopToStopBurst test");
385 private void stopToStopOne(ProperStopper s1, ProperStopper s2,
386 Counter ctr, int adr) {
387 prln("Begin stopToStopOne");
390 List<BitVector> din = makeIncrDataConstAdr(1, adr);
391 stopToStop(s1, s2, ctr, din);
394 prln("End stopToStopOne");
397 private void stopToStopThree(ProperStopper s1, ProperStopper s2,
398 Counter ctr, int adr) {
399 prln("Begin stopToStopOne");
402 List<BitVector> din = makeIncrDataConstAdr(3, adr);
403 stopToStop(s1, s2, ctr, din);
406 prln("End stopToStopOne");
409 private int indexOf(BitVector o, List<BitVector> dIn) {
410 for (int i=0; i<dIn.size(); i++) {
411 if (o.equals(dIn.get(i))) return i;
415 private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
416 StringBuffer sb = new StringBuffer();
417 sb.append(" ring dump: ");
418 for (BitVector o : dOut) {
419 sb.append(indexOf(o, dIn)+" ");
421 return sb.toString();
424 private int[][] makeIntArray2D(int a, int b) {
425 int[][] ans = new int[a][];
426 for (int i=0; i<a; i++) ans[i] = new int[b];
430 //=========================================================================
431 // Put top level tests here
433 private void testProperStoppers(Marina marina) {
434 prln("Begin testProperStoppers");
437 for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) {
438 prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper");
441 prln("un-stopping stopper");
443 fatal( ps.getStopped(), "stopper should not have been stopped, but was");
445 prln("stopping stopper");
447 fatal( !ps.getStopped(), "stopper should have been stopped, but was not");
455 private void sendInstructions(Marina marina) {
456 prln("Begin sendInstructions");
459 List<BitVector> din = new ArrayList<BitVector>();
461 BitVector count = new BitVector(36,"count");
462 BitVector one = new BitVector(36, "one");
463 count.setFromLong(0);
465 for (int i=0; i<3; i++) {
467 count = count.add(one);
470 marina.instrIn.fillMany(din);
473 prln("End sendInstructions");
476 private void sendToken(Marina marina) {
477 prln("Begin sendToken");
480 //getCtrsFlags(marina);
484 new Instruction.Move(DOCK,
485 false, /* requeueing */
486 Predicate.IgnoreFlagD, /* predicate */
487 false, /* torpedoable */
491 false, /* latchData */
492 false, /* latchPath */
497 //getCtrsFlags(marina);
499 int nbToks = marina.getNumTokens();
500 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
503 prln("End sendToken");
506 private void sendData(Marina marina) {
507 prln("Begin sendData");
512 new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
514 getCtrsFlags(marina);
518 new Instruction.Move(DOCK,
519 false, /* requeueing */
520 Predicate.IgnoreFlagD, /* predicate */
521 false, /* torpedoable */
525 false, /* latchData */
526 false, /* latchPath */
531 getCtrsFlags(marina);
533 List<BitVector> dataItems = marina.data.drainMany();
534 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
536 prln("Datum="+MarinaUtils.formatDataTokAddr(dataItems.get(0)));
539 prln("End sendData");
542 private void sendDataIlcInfinite(Marina marina) {
543 prln("Begin sendDataIlcInfinite");
548 new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity));
550 getCtrsFlags(marina);
553 marina.instrIn.fill(SEND_DATA);
555 getCtrsFlags(marina);
559 List<BitVector> dataItems = marina.data.drainMany(howmany);
560 fatal(dataItems.size()!=howmany,
561 "Expected an unending supply of data items to emerge but only got got: "+dataItems.size());
564 prln("End sendDataIlcInfinite");
567 private void setOLC(Marina marina, int olc) {
568 // ugly hack, to be removed when we fix the zero-detect circuit
569 for(int i=0; i<2; i++) {
570 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc));
574 private void testFlagZ(Marina marina) {
575 prln("Begin testFlagZ");
578 List<BitVector> toks;
580 Predicate only_if_olc_zero = Predicate.FlagD;
581 Predicate only_if_olc_nonzero = Predicate.Default;
583 for(int olc : new int[] { 1, 0 }) {
584 for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
585 prln("Attempting send token with "+
587 "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
590 prln("Inserting Set OLC="+olc);
593 prln("Inserting ["+(predicate_olc_nonzero?"olc!=0":"olc==0")+"] send data");
594 marina.instrIn.fill(new Instruction.Move(DOCK,
595 false, /* requeueing */
596 predicate_olc_nonzero /* predicate */
597 ? only_if_olc_nonzero
600 false, /* torpedoable */
604 false, /* latchData */
605 false, /* latchPath */
609 toks = marina.data.drainMany();
610 int expected = (predicate_olc_nonzero == (olc!=0)) ? 1 : 0;
611 fatal(toks.size()!=expected, "Expected "+expected+" token to emerge but got: "+toks.size()+" token(s)");
616 prln("End testFlagZ");
619 private void testPredicationOnAB(Marina marina) {
620 prln("Begin testPredicationOnAB");
623 List<BitVector> dItems;
625 prln("Setting OLC=63");
628 for(boolean flag_a : new boolean[] { false, true }) {
629 for(boolean flag_b : new boolean[] { false, true }) {
630 prln("Setting flags, a="+flag_a+" b="+flag_b);
631 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
633 ? Instruction.Set.FlagFunction.ONE
634 : Instruction.Set.FlagFunction.ZERO,
636 ? Instruction.Set.FlagFunction.ONE
637 : Instruction.Set.FlagFunction.ZERO
639 getCtrsFlags(marina);
642 for(Predicate predicate : new Predicate[] {
650 prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate.getClass().getName());
652 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
653 marina.instrIn.fill(new Instruction.Move(DOCK,
654 false, /* requeueing */
655 predicate, /* predicate */
656 false, /* torpedoable */
660 false, /* latchData */
661 false, /* latchPath */
666 dItems = marina.data.drainMany();
667 int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
668 fatal(dItems.size()!=expected, "Expected "+expected+" data items to emerge but got: "+
669 dItems.size()+" items(s)");
675 prln("End testPredicationOnAB");
680 private void getCtrsFlags(Marina marina) {
681 prln("begin getCtrsFlags");
684 int olc = marina.getOLC();
687 Ilc ilc = marina.getILC();
688 prln("ILC.done=="+ilc.getDone()+
689 " ILC.infinity=="+ilc.getInfinity()+
690 " ILC.zero=="+ilc.getZero()+
691 " ILC.count=="+ilc.getCount());
693 boolean a = marina.getFlagA();
696 boolean b = marina.getFlagB();
700 prln("end getCtrsFlags");
702 private void walkOneOLC(Marina marina) {
703 prln("Begin walkOneOLC");
705 for (int i=0; i<7; i++) {
706 int inOlc = 0x20 >> i;
707 prln("Set inOlc="+inOlc);
708 marina.instrIn.fill(new
709 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
710 int outOlc = marina.getOLC();
711 fatal(outOlc!=inOlc, "walkOneOLC: got="+outOlc+" expected="+inOlc);
714 prln("End walkOneOLC");
716 private void walkOneILC(Marina marina) {
717 prln("Begin walkOneILC");
719 for (int i=0; i<7; i++) {
720 // Mask off the "zero" bit position
721 int inIlc = 0x20 >> i;
722 prln("inIlc="+inIlc);
724 marina.instrIn.fill(new
725 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
727 Ilc ilc = marina.getILC();
728 int outIlc = ilc.getCount();
729 fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+outIlc);
731 boolean inZero = inIlc==0;
732 boolean outZero = ilc.getZero();
733 fatal(outZero!=inZero, "bad ILC zero: "+outZero);
734 fatal(ilc.getInfinity(), "bad Infinity bit: true");
736 prln("Now test the infinity bit");
737 marina.instrIn.fill(new
738 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
739 Ilc ilc = marina.getILC();
740 fatal(!ilc.getInfinity(), "bad Infinity bit: false");
742 prln("End walkOneILC");
744 private void countIlc(Marina marina) {
745 final int maxIlc = 63;
746 prln("Begin countIlc");
750 marina.instrIn.fill(new
751 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
753 int ilc = marina.getILC().getCount();
754 fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
756 prln("execute a move instruction that does nothing except decrement the ILC to zero");
758 new Instruction.Move(DOCK,
759 false, /* requeueing */
760 Predicate.IgnoreFlagD, /* predicate */
761 false, /* torpedoable */
765 false, /* latchData */
766 false, /* latchPath */
771 // wait for ILC to count from 63 to 0
772 model.waitNS(64 * CYCLE_TIME_NS);
774 prln("Check that ILC==0");
775 ilc = marina.getILC().getCount();
776 fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
779 prln("End countIlc");
781 // Note: countOlc takes 44 minutes to run on nanosim
782 private void countOlc(Marina marina) {
783 final int maxOlc = 63;
784 prln("Begin countOlc");
787 marina.instrIn.fill(new
788 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, maxOlc));
789 for (int i=maxOlc; i>=0; i--) {
790 prln("OLC should be: "+i);
791 int olc = marina.getOLC();
792 fatal(olc!=i, "bad OLC: "+olc+" expected: "+i);
793 marina.instrIn.fill(new
794 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
798 prln("End countOlc");
801 private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
802 prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
805 for(i=0; i<quantity; i++) {
806 prln("Inserting instruction " + (i+1) +"/"+ quantity);
807 marina.instrIn.fill(instruction);
808 boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
809 if (jammed && expect_it_to_jam_up) {
810 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
814 fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
816 fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
818 prln("Successfully inserted " + i + " instructions");
821 private static final Instruction NOP =
822 new Instruction.Move(DOCK,
823 false, /* requeueing */
824 Predicate.IgnoreFlagD, /* predicate */
825 false, /* torpedoable */
829 false, /* latchData */
830 false, /* latchPath */
835 private static final Instruction REQUEUEING_NOP =
836 new Instruction.Move(DOCK,
837 true, /* requeueing */
838 Predicate.IgnoreFlagD, /* predicate */
839 false, /* torpedoable */
843 false, /* latchData */
844 false, /* latchPath */
849 private static final Instruction SEND_DATA =
850 new Instruction.Move(DOCK,
851 false, /* requeueing */
852 Predicate.IgnoreFlagD, /* predicate */
853 false, /* torpedoable */
857 false, /* latchData */
858 false, /* latchPath */
863 private static final Instruction RECV_DATA =
864 new Instruction.Move(DOCK,
865 false, /* requeueing */
866 Predicate.IgnoreFlagD, /* predicate */
867 false, /* torpedoable */
871 true, /* latchData */
872 false, /* latchPath */
877 private static final Instruction SEND_TOKEN =
878 new Instruction.Move(DOCK,
879 false, /* requeueing */
880 Predicate.IgnoreFlagD, /* predicate */
881 false, /* torpedoable */
885 false, /* latchData */
886 false, /* latchPath */
891 private static final Instruction RECV_TOKEN =
892 new Instruction.Move(DOCK,
893 false, /* requeueing */
894 Predicate.IgnoreFlagD, /* predicate */
895 false, /* torpedoable */
899 false, /* latchData */
900 false, /* latchPath */
905 private static final Instruction REQUEUEING_SEND_DATA =
906 new Instruction.Move(DOCK,
907 true, /* requeueing */
908 Predicate.IgnoreFlagD, /* predicate */
909 false, /* torpedoable */
913 false, /* latchData */
914 false, /* latchPath */
919 private void testRequeueStage0(Marina marina) {
920 prln("Begin testRequeueStage0");
923 prln("Executing Set OLC=0");
925 saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false);
927 prln("End testRequeueStage0");
930 private void testRequeueStage0to1(Marina marina) {
931 prln("Begin testRequeueStage0to1");
934 prln("Executing Set OLC=63");
936 saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true);
938 prln("End testRequeueStage0to1");
942 * This test brings the requeue stage through the 0->1->3->0 state
943 * transition sequence.
946 * According to the diagram in IES50, there are three transitions
947 * (0->1, 1->3, 3->0) to perform, and in each state there are two
948 * behaviors to verify (the two notations in each oval of the
949 * state diagram). The "OD->drain" behavior of state 0 is
950 * verified by testRequeueStage0().
952 private void testRequeueStage0to1to3to0(Marina marina) {
953 List<BitVector> dataItems;
956 int olc_value = MORE_THAN_DATA_OUT_SATURATION_AMOUNT + extras;
958 prln("Begin testRequeueStage0to1to3to0");
961 // State 0 //////////////////////////////////////////////////////////////////////////////
963 prln("Executing Set OLC="+olc_value);
964 setOLC(marina, olc_value);
965 prln("Executing Set ILC=1");
966 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
968 // verify state0 "EPI->ring" and 0->1 transition
969 prln("Executing Send Data (requeueable); this will cause 0->1 transition and be discarded");
970 marina.instrIn.fill(REQUEUEING_SEND_DATA);
972 // State 1 //////////////////////////////////////////////////////////////////////////////
974 // verify state1 "EPI->ring"
975 prln("Executing Set ILC=1; this will be recirculated");
976 marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
978 prln("Executing Send Data; this will be recirculated");
979 marina.instrIn.fill(REQUEUEING_SEND_DATA);
981 prln("Executing Set OLC--; this will be recirculated");
982 marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement));
984 // verify state1 "OD waits"
985 dataItems = marina.data.drainMany(2);
986 fatal(dataItems.size()!=1, "Expected exactly one data item to emerge but got: "+dataItems.size()+" data items");
988 // verify 1->3 transition
989 prln("Executing Tail; this will cause the 2->3 transition and be discarded");
990 marina.instrIn.fill(new Instruction.Tail(DOCK));
992 // State 3 //////////////////////////////////////////////////////////////////////////////
994 // verify state3 "OD->ring"
995 dataItems = marina.data.drainMany(MORE_THAN_DATA_OUT_SATURATION_AMOUNT);
996 fatal(dataItems.size()<MORE_THAN_DATA_OUT_SATURATION_AMOUNT,
997 "Expected more than " + MORE_THAN_DATA_OUT_SATURATION_AMOUNT +
998 " data items, but only got: "+dataItems.size()+" of them");
1000 // verify state3 "OD->ring"
1001 saturateInstructionFifo(marina, NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true);
1003 // verify state3->state0
1004 dataItems = marina.data.drainMany(extras + 4);
1005 fatal(dataItems.size()!=(extras+1),
1006 "Expected exactly " + (extras+1) + " items to emerge, but got at least : "+dataItems.size()+" of them");
1008 // State 0 //////////////////////////////////////////////////////////////////////////////
1010 // verify that we are back in state0
1011 saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false);
1014 prln("End testRequeueStage0to1to3to0");
1018 * This test brings the requeue stage through the 0->2->3->0 state
1019 * transition sequence.
1021 * According to the diagram in IES50, there are two transitions
1022 * (0->2, 2->3, 3->0) to perform, and in each state there are two
1023 * behaviors to verify (the two notations in each oval of the
1024 * state diagram). The "OD->drain" behavior of state 0 is
1025 * verified by testRequeueStage0().
1027 private void testRequeueStage0to2to3to0(Marina marina) {
1028 List<BitVector> dataItems;
1031 int number_of_non_requeueable_send_datas = INSTRUCTION_RING_CAPACITY;
1033 prln("Begin testRequeueStage0to2to3to0");
1036 // State 0 //////////////////////////////////////////////////////////////////////////////
1038 prln("Executing Set OLC="+olc_value);
1039 setOLC(marina, olc_value);
1041 prln("Executing Set ILC=1");
1042 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
1044 // insert many non-requeueing "send data item" instructions;
1045 // this will let us single-step the execution point by
1046 // extracting data items.
1047 for(int i=0; i<number_of_non_requeueable_send_datas; i++) {
1048 prln("Inserting Send Data");
1049 marina.instrIn.fill(SEND_DATA);
1052 // this will send us a token later
1053 prln("Inserting [Rq] Nop; this will be discarded");
1054 marina.instrIn.fill(REQUEUEING_NOP);
1056 // this will send us a token later
1057 prln("Inserting [Rq] Send Data; this will be recirculated");
1058 marina.instrIn.fill(REQUEUEING_SEND_DATA);
1060 prln("Inserting [Rq] Set OLC--; this will be recirculated");
1061 marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement));
1063 // insert the tail, which will cause the 0->2 transition
1064 prln("Inserting Tail");
1065 marina.instrIn.fill(new Instruction.Tail(DOCK));
1067 // State 2 //////////////////////////////////////////////////////////////////////////////
1069 // confirm state 2 "EPI waits"
1070 prln("Saturating the instruction input to confirm that EPI waits");
1071 saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true);
1073 // confirm state 2 "OD->drain"
1074 prln("Draining data output to cause the 2->3 transition");
1075 dataItems = marina.data.drainMany(number_of_non_requeueable_send_datas);
1076 fatal(dataItems.size()!=number_of_non_requeueable_send_datas,
1077 "Expected at least " + number_of_non_requeueable_send_datas +
1078 " items to emerge, but got only : "+dataItems.size()+" of them");
1080 // State 3 //////////////////////////////////////////////////////////////////////////////
1082 // verify state3 "EPI waits"
1083 prln("Verifying that EPI still waits in state3");
1084 fatal(marina.instrIn.getFillStateWire()!=MarinaUtils.StateWireState.FULL,
1085 "state3 EPI waits not verified");
1089 // verify state3 "OD->ring" and state3->state0
1090 prln("Removing data items to run down the OLC to zero and cause 3->0 transition");
1091 dataItems = marina.data.drainMany(olc_value+10);
1092 fatal(dataItems.size()!=(olc_value+1),
1093 "Expected exactly " + (olc_value+1) + " items to emerge, but got: "+dataItems.size()+" of them");
1095 // State 0 //////////////////////////////////////////////////////////////////////////////
1097 // verify that we are back in state0
1098 prln("Confirming that we are back in state0");
1099 saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false);
1102 prln("End testRequeueStage0to2to3to0");
1105 private void testWaitForTail(Marina marina) {
1106 List<BitVector> dataItems;
1108 prln("Begin testWaitForTail");
1111 prln("inserting instruction: Set OLC=63");
1114 prln("inserting instruction: [Rq] Nop; this will cause 0->1 transition and possibly be discarded");
1115 marina.instrIn.fill(REQUEUEING_NOP);
1117 // just in case there is some capacity between the execution
1118 // stage and the requeue stage, we stick in a whole bunch of
1120 for(int i=0; i<4; i++) {
1121 prln("inserting instruction: [Rq] Nop; this (and subsequent instructions) should not execute until Tail is inserted");
1122 marina.instrIn.fill(REQUEUEING_NOP);
1125 prln("inserting instruction: [Rq] Set ILC=1");
1126 marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1128 prln("inserting instruction: [Rq] Send Data");
1129 marina.instrIn.fill(REQUEUEING_SEND_DATA);
1131 dataItems = marina.data.drainMany(1);
1132 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
1135 prln("End testWaitForTail");
1138 // This test case will FAIL if the requeue stage behaves as
1139 // described in IES50. If we determine that the behavior
1140 // described there is actually desirable, then this test should be
1142 private void testRequeueStageDrop(Marina marina) {
1143 List<BitVector> dataItems;
1145 prln("Begin testRequeueStageDrop");
1148 // We have decided that this issue will not be fixed in
1149 // Marina. Therefore, the test is commented out.
1152 prln("inserting instruction: Set OLC=63");
1155 prln("inserting instruction: Set ILC=1");
1156 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1158 // if you uncomment this, then the NOP will be dropped and the test will pass
1159 //prln("inserting instruction: [Rq] Nop; this will cause 0->1 transition and possibly be discarded");
1160 //marina.instrIn.fill(REQUEUEING_NOP);
1162 prln("inserting instruction: [Rq] Send Data; this will cause 0->1 transition and be discarded");
1163 marina.instrIn.fill(REQUEUEING_SEND_DATA);
1165 prln("inserting instruction: [Rq] Set ILC=1");
1166 marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1168 prln("inserting instruction: Tail");
1169 marina.instrIn.fill(new Instruction.Tail(DOCK));
1171 dataItems = marina.data.drainMany(3);
1172 fatal(dataItems.size()<3, "Expected exactly unlimited data items to emerge but got only: "+dataItems.size());
1176 prln("End testRequeueStageDrop");
1180 private void testFlagAB(Marina marina) {
1181 prln("Begin testFlagAB");
1184 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1185 Instruction.Set.FlagFunction one = zero;
1188 // we should be able to use any pair of FlagX+NotFlagX,
1189 // but we toss them all in to maximize the chances of the
1190 // test passing (later we will try the individual
1191 // combinations to maximize the chances of failure).
1192 one = one.add(Predicate.FlagA);
1193 one = one.add(Predicate.NotFlagA);
1194 one = one.add(Predicate.FlagB);
1195 one = one.add(Predicate.NotFlagB);
1196 one = one.add(Predicate.FlagC);
1197 one = one.add(Predicate.NotFlagC);
1199 // clear the flags to a known state, then check both 0->1 and 1->0 transitions
1200 for(boolean b : new boolean[] { false, true, false }) {
1201 prln((b?"Setting":"Clearing")+" flags");
1203 marina.instrIn.fill(new
1204 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1208 fatal(marina.getFlagA()!=b, "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
1209 fatal(marina.getFlagB()!=b, "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
1213 prln("End testFlagAB");
1217 * WARNING: this is a very, very, very long test case -- it goes
1218 * through 216 iterations.
1220 private void testFlagTruthTable(Marina marina) {
1221 prln("Begin testFlagTruthTable");
1224 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1225 Instruction.Set.FlagFunction one = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
1227 for(Predicate a_input : new Predicate[] { null, Predicate.FlagA, Predicate.NotFlagA })
1228 for(Predicate b_input : new Predicate[] { null, Predicate.FlagB, Predicate.NotFlagB })
1229 for(Predicate c_input : new Predicate[] { null, Predicate.FlagC, Predicate.NotFlagC })
1230 for(boolean a_state : new boolean[] { false, true })
1231 for(boolean b_state : new boolean[] { false, true })
1232 for(boolean c_state : new boolean[] { false, true }) {
1233 for(boolean which : new boolean[] { false, true }) {
1235 prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
1237 // set A,B flags to a_state and b_state
1238 marina.instrIn.fill(new
1239 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1240 a_state ? one : zero,
1241 b_state ? one : zero
1244 // set C flag to c_state
1245 BitVector data = new BitVector(37, "empty");
1246 BitVector addr = new BitVector(14, "empty");
1247 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1248 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1249 addr.set(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
1250 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1251 marina.instrIn.fill(RECV_DATA);
1253 Instruction.Set.FlagFunction func = zero;
1254 if (a_input!=null) func = func.add(a_input);
1255 if (b_input!=null) func = func.add(b_input);
1256 if (c_input!=null) func = func.add(c_input);
1258 Instruction inst = new
1259 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1260 !which ? func : zero.add(Predicate.FlagA),
1261 which ? func : zero.add(Predicate.FlagB)
1264 prln("executing instruction: " + inst);
1265 marina.instrIn.fill(inst);
1267 boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
1268 boolean expected_b = which ? func.evaluate(a_state, b_state, c_state, false) : b_state;
1269 fatal(expected_a != marina.getFlagA(),
1270 "expected A="+expected_a+", but got "+marina.getFlagA());
1271 fatal(expected_b != marina.getFlagB(),
1272 "expected B="+expected_b+", but got "+marina.getFlagB());
1276 prln("End testFlagTruthTable");
1279 private void recvData(Marina marina) {
1280 prln("Begin recvData");
1283 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1284 marina.instrIn.fill(new Instruction.Move(DOCK,
1285 false, /* requeueing */
1286 Predicate.IgnoreFlagD, /* predicate */
1287 true, /* torpedoable */
1289 false, /* tokenIn */
1291 false, /* latchData */
1292 false, /* latchPath */
1293 false, /* dataOut */
1294 false /* tokenOut */
1296 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG));
1298 prln("checking to confirm that A flag is cleared");
1299 fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1301 prln("inserting data item in north fifo ring");
1302 BitVector data = new BitVector(37, "empty");
1303 BitVector addr = new BitVector(14, "empty");
1304 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1305 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1306 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1308 prln("checking to see if A flag got set");
1309 fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1312 prln("End recvData");
1316 private void testRecvAndSendWalkingOne(Marina marina) {
1317 prln("Begin testRecvAndSendWalkingOne");
1320 List<BitVector> dataItems;
1321 for(int bit=0; bit<37; bit++) {
1323 BitVector data = new BitVector(37, "empty");
1324 BitVector addr = new BitVector(14, "empty");
1325 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1326 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1327 data.set(bit, true);
1328 prln("testing with bit pattern " + data);
1330 prln("inserting data item into north fifo ring");
1331 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1333 prln("stopping the north proper stopper");
1336 dataItems = marina.data.drainMany(1);
1337 fatal(dataItems.size()!=0,
1338 "found a data item waiting in the north proper stopper, but should not have");
1340 marina.instrIn.fill(new Instruction.Move(DOCK,
1341 false, // requeueing
1342 Predicate.IgnoreFlagD, // predicate
1343 true, // torpedoable
1353 dataItems = marina.data.drainMany(2);
1354 fatal(dataItems.size()!=1,
1355 "found "+dataItems.size()+" data items in north fifo; expected one");
1356 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1357 fatalIfBitVectorsDoNotMatch(mp.data, data);
1361 prln("End testRecvAndSendWalkingOne");
1366 private void setOlcFromDataLatch(Marina marina) {
1367 prln("Begin setOlcFromDataLatch");
1370 // walk a bit from 0 to 5
1371 for(int bit=0; bit<6; bit++) {
1372 prln("inserting data item in north fifo ring");
1373 BitVector data = new BitVector(37, "empty");
1374 BitVector addr = new BitVector(14, "empty");
1375 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1376 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1377 data.set(bit, true);
1378 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1380 marina.instrIn.fill(RECV_DATA);
1381 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch));
1383 int olc = marina.getOLC();
1384 fatal(olc != (1<<bit), "expected olc to be " + (1<<bit) + ", but got " + olc);
1388 prln("End setOlcFromDataLatch");
1391 private void setIlcFromDataLatch(Marina marina) {
1392 prln("Begin setIlcFromDataLatch");
1395 // walk a bit from 0 to 5
1396 for(int bit=0; bit<6; bit++) {
1397 prln("inserting data item in north fifo ring");
1398 BitVector data = new BitVector(37, "empty");
1399 BitVector addr = new BitVector(14, "empty");
1400 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1401 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1402 data.set(bit, true);
1403 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1405 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1406 marina.instrIn.fill(RECV_DATA);
1407 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch));
1409 int ilc = marina.getILC().getCount();
1410 fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc);
1414 prln("End setIlcFromDataLatch");
1417 private void testSendAndRecvToken(Marina marina) {
1418 prln("Begin testSendAndRecvToken");
1421 prln("sending token");
1422 marina.instrIn.fill(SEND_TOKEN);
1424 prln("receiving token");
1425 marina.instrIn.fill(RECV_TOKEN);
1427 prln("sending data item");
1428 marina.instrIn.fill(SEND_DATA);
1430 prln("checking to confirm that data item arrived");
1431 List<BitVector> dataItems = marina.data.drainMany(3);
1432 fatal(dataItems.size()!=1,
1433 "expected exactly one data item, got " + dataItems.size());
1436 prln("End testSendAndRecvToken");
1439 private void testSignExtendedLiteral(Marina marina) {
1440 prln("Begin testSignExtendedLiteral");
1443 for(long val : new long[] { -1, 0, 1, (-1L << 14) }) {
1444 prln("inserting Set Data Latch (sign-extended) 37'b" + Long.toString(val, 1));
1445 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1446 Instruction.Set.SetDest.DataLatch,
1449 prln("sending data item");
1450 marina.instrIn.fill(SEND_DATA);
1452 List<BitVector> dataItems = marina.data.drainMany(3);
1453 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1455 BitVector bv = dataItems.get(0);
1456 prln("got back " + MarinaUtils.extractData(bv).getState());
1458 boolean mismatch = false;
1460 for(int i=0; i<37; i++) {
1461 if (bv.get(i) != ( (val & (1L << i)) != 0 )) {
1466 fatal(mismatch, "data read back did not match inserted literal; mismatch on bits " + err);
1470 prln("End testSignExtendedLiteral");
1473 private void testShiftedLiteral(Marina marina) {
1474 prln("Begin testShiftedLiteral");
1477 prln("clearing the D register");
1478 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1479 Instruction.Set.SetDest.DataLatch,
1482 BitVector dreg = new BitVector(37, "what we think is in the d-register");
1483 for(int i=0; i<37; i++) dreg.set(i, false);
1485 for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
1487 prln("inserting Shift 19'b" + Long.toString(val, 1));
1488 edu.berkeley.fleet.api.BitVector immediate =
1489 new edu.berkeley.fleet.api.BitVector(19);
1490 for(int i=0; i<immediate.length(); i++)
1491 immediate.set(i, (val & (1L << i)) != 0);
1492 marina.instrIn.fill(new Instruction.Shift(DOCK,false,Predicate.IgnoreFlagD,immediate));
1494 // shift over 19 LSB's towards MSB
1495 for(int i=0; i<19; i++)
1496 if (i+19 <= 36) dreg.set(i+19, dreg.get(i));
1497 for(int i=0; i<19; i++)
1498 dreg.set(i, immediate.get(i));
1500 prln("sending data item");
1501 marina.instrIn.fill(SEND_DATA);
1503 List<BitVector> dataItems = marina.data.drainMany(3);
1504 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1506 BitVector bv = MarinaUtils.extractData(dataItems.get(0));
1507 fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" +
1508 "got: "+bv.bitReverse().getState()+"\n"+
1509 "expected:"+dreg.bitReverse().getState());
1513 prln("End testShiftedLiteral");
1516 private void testFlagC(Marina marina) {
1517 prln("Begin testFlagC");
1525 // Dc=1 => sigS is copied into C-flag
1526 // Dc=0 => sigA is copied into C-flag
1528 for(boolean dc : new boolean[] { false, true }) {
1529 for(boolean c_flag : new boolean[] { true, false, true }) {
1532 prln("****** checking case where dc="+dc+", cflag="+c_flag);
1533 BitVector data = new BitVector(37, "empty");
1534 BitVector addr = new BitVector(14, "empty");
1535 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1536 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1539 ? INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
1540 : INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
1541 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
1542 addr.set(whichbit, c_flag);
1544 prln("... and filling north fifo proper stopper");
1545 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1547 prln("clearing flags");
1548 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1550 prln("executing recv data with Dc="+dc);
1551 marina.instrIn.fill(new Instruction.Move(DOCK,
1552 false, /* requeueing */
1553 Predicate.IgnoreFlagD, /* predicate */
1554 true, /* torpedoable */
1556 false, /* tokenIn */
1559 false, /* latchPath */
1560 false, /* dataOut */
1561 false /* tokenOut */
1564 prln("copying c-flag to a-flag");
1565 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1566 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
1570 prln("checking to confirm that A flag is " + c_flag);
1571 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
1575 prln("End testFlagC");
1578 private void sendDataWithPath(Marina marina) {
1579 prln("Begin sendDataWithPath");
1582 getCtrsFlags(marina);
1584 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
1586 // alternating ones and zeroes
1587 for(int i=0; i<bv.length(); i+=2)
1589 // and then ones in the lower four bits so it's not symmetric
1590 for(int i=0; i<4; i++)
1593 MarinaPath path = new MarinaPath((MarinaFleet)DOCK.getShip().getFleet(), bv);
1595 prln("send data with path="+bv);
1596 marina.instrIn.fill(new Instruction.Move(DOCK,
1597 false, /* requeueing */
1598 Predicate.IgnoreFlagD, /* predicate */
1599 false, /* torpedoable */
1601 false, /* tokenIn */
1603 false, /* latchData */
1604 false, /* latchPath */
1606 false /* tokenOut */
1608 List<BitVector> dataItems;
1611 dataItems = marina.data.drainMany();
1612 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1613 mp = new MarinaPacket(dataItems.get(0));
1615 // the 14th bit of the outbound address cannot be set by the
1616 // ship, so we don't care about it
1617 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1619 prln("send data with no change to path");
1620 marina.instrIn.fill(new Instruction.Move(DOCK,
1621 false, /* requeueing */
1622 Predicate.IgnoreFlagD, /* predicate */
1623 false, /* torpedoable */
1625 false, /* tokenIn */
1627 false, /* latchData */
1628 false, /* latchPath */
1630 false /* tokenOut */
1633 dataItems = marina.data.drainMany();
1634 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1635 mp = new MarinaPacket(dataItems.get(0));
1637 // the 14th bit of the outbound address cannot be set by the
1638 // ship, so we don't care about it
1639 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1642 prln("End sendDataWithPath");
1645 private void recvPath(Marina marina) {
1646 prln("Begin recvPath");
1649 for(int bit=0; bit<11; bit++) {
1650 BitVector packet_data = new BitVector(37, "inbound data item");
1651 for(int i=0; i<37; i++) packet_data.set(i, false);
1652 packet_data.set(27+bit, true);
1653 BitVector packet_path = new BitVector(14, "inbound data item");
1654 for(int i=0; i<14; i++) packet_path.set(i, false);
1656 marina.fillNorthProperStopper(new MarinaPacket(packet_data, false, packet_path));
1658 prln("recv path, send data (using recv'd path)");
1659 marina.instrIn.fill(new Instruction.Move(DOCK,
1660 false, /* requeueing */
1661 Predicate.IgnoreFlagD, /* predicate */
1662 false, /* torpedoable */
1664 false, /* tokenIn */
1666 false, /* latchData */
1667 true, /* latchPath */
1669 false /* tokenOut */
1672 List<BitVector> dataItems = marina.data.drainMany();
1673 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1674 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1676 fatalIfBitVectorsDoNotMatch(packet_data.get(26,11), mp.path.get(0,11));
1680 prln("End recvPath");
1683 private void testILC(Marina marina) {
1684 prln("Begin testILC");
1687 for(int bit=0; bit<6; bit++) {
1688 int ilc = bit<0 ? 0 : (1<<bit);
1690 prln("set ilc="+ilc);
1691 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc));
1694 marina.instrIn.fill(SEND_DATA);
1696 List<BitVector> dataItems = marina.data.drainMany();
1697 fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
1701 prln("End testILC");
1704 private void sendTorpedo(Marina marina) {
1705 prln("Begin sendTorpedo");
1708 prln("Set OLC = 1");
1709 marina.instrIn.fill(new
1710 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
1712 int olc = marina.getOLC();
1713 fatal(olc!=1, "bad OLC: "+olc+" expected: 1");
1715 prln("Set A=0, B=0");
1716 marina.instrIn.fill(new
1717 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1719 fatal(marina.getFlagA(), "bad A flag: true");
1720 fatal(marina.getFlagB(), "bad B flag: true");
1722 prln("Set ILC = Infinity");
1723 marina.instrIn.fill(new
1724 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
1726 prln("execute a move instruction that does nothing but loops until torpedo arrives");
1727 marina.instrIn.fill(
1728 new Instruction.Move(DOCK,
1729 false, /* requeueing */
1730 Predicate.IgnoreFlagD, /* predicate */
1731 true, /* torpedoable */
1733 false, /* tokenIn */
1735 false, /* latchData */
1736 false, /* latchPath */
1737 false, /* dataOut */
1738 false /* tokenOut */
1741 prln("A=1, B=1 This instruction should get torpedoed along with the Move");
1742 marina.instrIn.fill(new
1743 Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG));
1745 prln("send torpedo. This should clear the OLC");
1746 marina.instrIn.fill(InstructionStopper.TORPEDO);
1748 getCtrsFlags(marina);
1750 // Note: It's tempting to test that OLC==0 here. However, hardware doesn't
1751 // actually set counter bits to zero; it just sets the OLCZERO bit
1753 prln("A and B should remain false");
1754 fatal(marina.getFlagA(), "bad A flag: true");
1755 fatal(marina.getFlagB(), "bad B flag: true");
1757 prln("OLC = 63. Reload OLC after torpedo");
1758 marina.instrIn.fill(new
1759 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1761 olc = marina.getOLC();
1762 fatal(olc!=63, "bad OLC: "+olc+" expected: 63");
1764 prln("Set A=1, B=1 This instruction should execute because OLC!=0");
1765 marina.instrIn.fill(new
1766 Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG));
1768 prln("A and B should be true");
1769 fatal(!marina.getFlagA(), "bad A flag: false");
1770 fatal(!marina.getFlagB(), "bad B flag: false");
1773 prln("End sendTorpedo");
1776 private void testTorpedoOnAnInfiniteNop(Marina marina) {
1777 prln("Begin testTorpedoOnAnInfiniteNop");
1780 List<BitVector> dataItems;
1782 for(boolean torpedoable : new boolean[] { true, false }) {
1783 prln("set ilc=\\infty");
1784 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity));
1787 marina.instrIn.fill(new Instruction.Move(DOCK,
1788 false, /* requeueing */
1789 Predicate.IgnoreFlagD, /* predicate */
1790 torpedoable, /* torpedoable */
1792 false, /* tokenIn */
1794 false, /* latchData */
1795 false, /* latchPath */
1796 false, /* dataOut */
1797 false /* tokenOut */
1800 marina.instrIn.fill(SEND_DATA);
1802 // expect nothing to come out, because the NOP is executing
1803 dataItems = marina.data.drainMany(10);
1804 fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
1806 prln("send torpedo");
1807 marina.instrIn.fill(InstructionStopper.TORPEDO);
1809 int expected = torpedoable?1:0;
1810 dataItems = marina.data.drainMany(2);
1811 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1815 prln("End testTorpedoOnAnInfiniteNop");
1818 private void testOlcDecrementAtHighSpeed(Marina marina) {
1819 prln("Begin testOlcDecrementAtHighSpeed");
1822 List<BitVector> dataItems;
1824 // Each element of the following pair of arrays is one "test".
1825 // The OLC will be loaded with olcs[i] and then decremented
1826 // decr_amounts[i] times; after that has happened the zeroness
1827 // of the OLC will be checked by executing a MOVE with
1828 // [olc!=0] as the predicate.
1830 int[] olcs = new int[] { 3 /*, 3, 3, 10, 41*/ };
1831 int[] decr_amounts = new int[] { 2 /*, 3, 4, 9, 10*/ };
1833 for(int which=0; which<olcs.length; which++) {
1834 int olc = olcs[which];
1835 int decr_amount = decr_amounts[which];
1837 prln("inserting set olc="+olc);
1838 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc));
1839 prln("inserting set ilc=1");
1840 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1842 // commenting the following four lines causes this test to pass
1843 prln("disabling instruction send");
1844 marina.enableInstructionSend(false);
1845 prln("enabling instruction recirculate");
1846 marina.enableInstructionRecirculate(true);
1848 prln("inserting "+decr_amount+" olc-- instructions");
1849 for(int i=0; i<decr_amount; i++)
1850 marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,
1851 SetDest.OuterLoopCounter,SetSource.Decrement));
1853 prln("inserting [olc!=0] send data");
1854 marina.instrIn.fill(new Instruction.Move(DOCK,
1855 false, /* requeueing */
1856 Predicate.Default, /* predicate */
1857 false, /* torpedoable */
1859 false, /* tokenIn */
1861 false, /* latchData */
1862 false, /* latchPath */
1864 false /* tokenOut */
1867 prln("disabling instruction recirculate");
1868 marina.enableInstructionRecirculate(false);
1869 prln("enabling instruction send");
1870 marina.enableInstructionSend(true);
1872 prln("calling marina.instrIn.run()");
1873 marina.instrIn.run();
1877 int expected = decr_amount>=olc ? 0 : 1;
1878 dataItems = marina.data.drainMany(2);
1879 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1883 prln("End testOlcDecrementAtHighSpeed");
1886 private void flipIlcBit(Marina marina) {
1887 prln("Begin flipIlcBit");
1889 prln("Using the set ILC instruction, toggle a single bit between zero and one. \n" +
1890 "Check correct setting of the ILC zero bit");
1892 for (int i=0; i<6; i++) {
1893 int notZero = 32 >> i;
1895 marina.instrIn.fill(new
1896 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0));
1898 prln("Then immediately set ILC="+notZero);
1899 marina.instrIn.fill(new
1900 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero));
1902 prln("Verify ILC using scan chain");
1903 Ilc ilc = marina.getILC();
1904 int ilcCount = ilc.getCount();
1905 fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
1907 fatal(ilc.getZero(), "bad ILC zero bit: true");
1908 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
1910 prln("Set ILC="+notZero);
1911 marina.instrIn.fill(new
1912 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero));
1914 prln("Then immediately set ILC=0");
1915 marina.instrIn.fill(new
1916 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0));
1918 prln("Verify ILC using scan chain");
1919 ilc = marina.getILC();
1920 ilcCount = ilc.getCount();
1921 fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
1923 fatal(!ilc.getZero(), "bad ILC zero bit: false");
1924 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
1928 prln("End flipIlcBit");
1930 private void flipOlcBit(Marina marina) {
1931 prln("Begin flipOlcBit");
1933 prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
1934 "Check correct setting of the OLC zero bit");
1936 prln("Set A=0, B=0");
1937 marina.instrIn.fill(new
1938 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1940 for (int i=0; i<6; i++) {
1941 int notZero = 32 >> i;
1943 marina.instrIn.fill(new
1944 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0));
1946 prln("Then immediately set OLC="+notZero);
1947 marina.instrIn.fill(new
1948 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero));
1950 prln("Verify OLC count using scan chain");
1951 int outOlc = marina.getOLC();
1952 fatal(outOlc!=notZero, "bad OLC count: "+outOlc+" expected: "+notZero);
1954 prln("Verify OLC zero bit using predication");
1955 prln("if (OLC==0) {A=1; B=1;} // should not get executed");
1956 marina.instrIn.fill(new
1957 Instruction.Set(DOCK,false,Predicate.FlagD, SET_FLAG, SET_FLAG));
1958 fatal(marina.getFlagA(), "bad A flag. expected: false");
1960 prln("Set OLC="+notZero);
1961 marina.instrIn.fill(new
1962 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero));
1964 prln("Then immediately set OLC=0");
1965 marina.instrIn.fill(new
1966 Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0));
1968 prln("Verify OLC count using scan chain");
1969 outOlc = marina.getOLC();
1970 fatal(outOlc!=0, "bad OLC count: "+outOlc+" expected: 0");
1972 prln("Verify OLC zero bit using predication");
1973 prln("if (OLC!=0) {A=1; B=1;} // should not get executed");
1974 marina.instrIn.fill(new
1975 Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG));
1976 fatal(marina.getFlagA(), "bad A flag. expected: false");
1980 prln("End flipOlcBit");
1982 private void testSouthRecirculate (Marina marina) {
1983 prln("Begin testSouthRecirculate");
1986 marina.enableInstructionSend(false);
1987 marina.enableInstructionRecirculate(true);
1989 prln("Completely fill south ring");
1990 for (int i=0; i<Marina.SOUTH_RING_CAPACITY; i++) {
1991 BitVector instr = new BitVector(36, "Instr"+i);
1992 instr.setFromLong(i);
1993 marina.instrIn.fill(instr);
1995 prln("Drain south ring and check contents");
1996 List<BitVector> out = marina.instrIn.drainMany();
1997 for (int i=0; i<Marina.SOUTH_RING_CAPACITY; i++) {
1998 int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
1999 long got = out.get(i).toLong();
2000 fatal(got!=expect, "bad instruction: "+got+" expected: "+expect);
2003 for (int i=0; i<5; i++) {}
2006 prln("End testSouthRecirculate");
2008 private void doOneTest(int testNum) {
2009 prln("MarinaTest: performing test: "+testNum);
2010 marina.masterClear();
2012 marina.enableInstructionSend(true);
2015 case 1: testProperStoppers(marina); break;
2016 case 2: sendInstructions(marina); break;
2017 case 3: sendToken(marina); break;
2018 case 4: getCtrsFlags(marina); break;
2019 case 5: walkOneOLC(marina); break;
2021 // Russell's tests begin with 1000
2022 case 1000: walkOneILC(marina); break;
2023 case 1001: countIlc(marina); break;
2024 case 1002: countOlc(marina); break;
2025 case 1003: sendTorpedo(marina); break;
2026 case 1004: flipIlcBit(marina); break;
2027 case 1005: flipOlcBit(marina); break;
2028 case 1006: testSouthRecirculate(marina); break;
2030 // Bill's tests begin with 2000
2033 // Adam's tests begin with 3000
2034 case 3000: sendToken(marina); break;
2035 case 3001: testFlagAB(marina); break;
2036 case 3002: testRequeueStage0(marina); break;
2037 case 3003: testRequeueStage0to1(marina); break;
2038 case 3004: testFlagZ(marina); break;
2039 case 3005: testPredicationOnAB(marina); break;
2040 case 3006: sendData(marina); break;
2041 case 3007: testRequeueStage0to1to3to0(marina); break;
2042 case 3008: testWaitForTail(marina); break;
2043 case 3009: testRequeueStageDrop(marina); break;
2044 case 3010: testRequeueStage0to2to3to0(marina); break;
2045 case 3011: recvData(marina); break;
2046 case 3012: testFlagC(marina); break;
2047 case 3013: testSignExtendedLiteral(marina); break;
2048 case 3014: testShiftedLiteral(marina); break;
2049 case 3015: testSendAndRecvToken(marina); break;
2050 case 3016: sendDataIlcInfinite(marina); break;
2051 case 3017: testFlagTruthTable(marina); break;
2052 case 3018: sendDataWithPath(marina); break;
2053 case 3019: setOlcFromDataLatch(marina); break;
2054 case 3020: setIlcFromDataLatch(marina); break;
2055 case 3021: recvPath(marina); break;
2056 case 3022: testILC(marina); break;
2057 case 3023: testTorpedoOnAnInfiniteNop(marina); break;
2058 case 3024: testRecvAndSendWalkingOne(marina); break;
2059 case 3025: testOlcDecrementAtHighSpeed(marina); break;
2062 fatal(true, "Test number: "+testNum+" doesn't exist.");
2065 // If we get here then test passed
2066 prln("Test Result: Passed");
2068 Infrastructure.exit(0);
2072 //============================ for public use =============================
2075 * 0: test detected success
2076 * 2: test detected failure
2079 public static void main(String[] args) {
2080 startTime = System.currentTimeMillis();
2081 new MarinaTest(args);