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.VerilogModel;
18 import com.sun.async.test.Netscan4;
19 import com.sun.async.test.PowerChannel;
20 import com.sun.async.test.Pst3202Channel;
21 import com.sun.async.test.SiliconChip;
22 import com.sun.async.test.SimulationModel;
23 import com.sun.async.test.VoltageReadable;
24 import com.sun.vlsi.chips.marina.test.Marina.Ilc;
25 import com.sun.vlsi.chips.marina.test.CmdArgs;
26 import com.sun.vlsi.chips.marina.test.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 public static final MarinaFleet marinaFleet = new MarinaFleet();
41 public static final Dock dock = marinaFleet.getOnlyInputDock();
43 //-------------------------- constants -----------------------------------
44 private static final String SCAN_CHAIN_XML = "marina.xml";
45 private static final String NET_LIST = "marina.spi";
47 public static final int INSTR_SZ = 36;
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 double CYCLE_TIME_NS;
102 //-------------------------------- types ---------------------------------
104 //-------------------------- private data --------------------------------
105 private static long startTime;
107 public static 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 ChainTest ctD, ctR, ctC;
117 private ChainControl ccD, ccR, ccC;
119 //-------------------------- private methods -----------------------------
120 /** @return true if simulation. Return false if we're testing silicon. */
121 private boolean sim() {return model instanceof SimulationModel;}
123 private void prln(String msg) {indenter.prln(msg);}
124 private void pr(String msg) {indenter.pr(msg);}
125 private void adjustIndent(int n) {indenter.adjustIndent(n);}
127 public static void fatal(boolean pred, String msg) {
129 Exception err = new Exception(msg);
130 err.printStackTrace();
131 System.out.println("Test Result: Test Failed");
134 Infrastructure.exit(2);
137 public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
138 // FIXME: better error reporting needed here
140 fatal(bv1.getNumBits()!=bv2.getNumBits(), "lengths do not match");
142 boolean mismatch = false;
144 for(int i=0; i<bv1.getNumBits(); i++) {
145 if (bv1.get(i) != bv2.get(i)) {
150 fatal(mismatch, "bit vectors do not match on bits " + err + "\n "+bv1+"\n "+bv2);
153 private static void printTestTime() {
154 long endTime = System.currentTimeMillis();
155 System.out.println("Test took: "+(endTime-startTime)/1000.0+" sec");
158 // Tell user what we're about to do
159 private static void reportTask(CmdArgs args) {
160 System.out.println("Begin testing Marina");
162 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
163 System.out.println(" Simulate whole chip, schematic parasitics");
165 case WHOLE_CHIP_LAYOUT_PARASITICS:
166 System.out.println(" Simulate whole chip, layout parasitics");
169 System.out.println(" Test silicon");
172 fatal(true, "unrecognized CmdArgs.Mode");
176 private void setUpSuppliesAndMeters(Station station) {
177 // set up power supplies and meters
179 prln("Testing station: "+station);
180 Infrastructure.gpibControllers = new int[] {0};
181 switch (cmdArgs.station) {
183 corePowerSupply = new Pst3202Channel("ch1", "HPST3202", 1);
184 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202", 2);
187 corePowerSupply = new Pst3202Channel("ch1", "HPST3202B", 1);
188 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202B", 2);
191 fatal(true, "Unrecognized station: "+cmdArgs.station);
193 corePowerSupply.setCurrent((float)1.7);
194 corePowerSupply.setVoltageWait((float)1.0);
196 padsPowerSupply.setCurrent((float)0.100);
197 padsPowerSupply.setVoltageWait((float)1.8);
199 coreVoltmeter = new HP34401A(station.coreVoltmeter);
200 voltmeterForCurrent = new HP34401A(station.currentVoltmenter);
204 private MarinaTest(String[] args) {
205 cmdArgs = new CmdArgs(args);
207 if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim();
210 private void doSim() {
212 switch (cmdArgs.mode) {
213 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
214 netListName = NET_LIST;
216 case WHOLE_CHIP_LAYOUT_PARASITICS:
217 netListName = "marina_pads_guts.spi";
220 fatal(true, "unrecognized CmdArgs.Mode");
223 model = cmdArgs.useVerilog ? new VerilogModel() : new NanosimModel();
225 ((SimulationModel)model).setOptimizedDirectReadsWrites(true);
227 CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250;
229 //tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
230 ChainControls ccs = new ChainControls();
231 JtagTester testerD, testerR, testerC;
232 testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null);
233 testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null);
234 testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null);
235 testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
237 int khz = model instanceof VerilogModel ? 100000 : 1000000;
239 ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
240 ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
241 ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
242 ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
244 PowerChannel pc = new ManualPowerChannel("pc", false);
246 ctD = new ChainTest(ccD, pc);
247 ctR = new ChainTest(ccR, pc);
248 ctC = new ChainTest(ccC, pc);
250 ccs.addChain(Marina.DATA_CHAIN, ccD);
251 ccs.addChain(Marina.REPORT_CHAIN, ccR);
252 ccs.addChain(Marina.CONTROL_CHAIN, ccC);
254 marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter);
256 if (model instanceof VerilogModel)
257 ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift);
259 ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
262 ccC.shift(Marina.CONTROL_CHAIN, false, true);
264 doOneTest(cmdArgs.testNum);
266 ((SimulationModel)model).finish();
268 private void doSilicon() {
269 model = new SiliconChip();
270 String ip = cmdArgs.station.ipAddr;
271 JtagTester tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
272 tester.printInfo = false;
274 ChainControl cc = new ChainControl("???", tester, 1.8f, khz);
275 cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
276 ChainControls ccs = new ChainControls();
277 ccs.addChain(Marina.DATA_CHAIN, cc);
278 ccs.addChain(Marina.REPORT_CHAIN, cc);
279 ccs.addChain(Marina.CONTROL_CHAIN, cc);
280 marina = new Marina(ccs, model, false, indenter);
281 PowerChannel pc = new ManualPowerChannel("pc", false);
282 ChainTest ct = new ChainTest(cc, pc);
283 ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
284 doOneTest(cmdArgs.testNum);
285 setUpSuppliesAndMeters(cmdArgs.station);
288 /** In the absence of looping, the longest path through Infinity is 4 column delays */
289 private void waitUntilQuiescent() {
290 model.waitNS(4*COLUMN_LATENCY);
293 private double readCurrent() {
294 return voltmeterForCurrent.readVoltage() / cmdArgs.station.ammeterShuntResistance;
297 /** Generate List of BitVectors where Token=true, high 25 data bits
298 * are alternating ones and zeros, low 12 data bits increment from
299 * zero, and address is given by addr. */
300 private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
301 List<BitVector> ans = new ArrayList<BitVector>();
302 BitVector dHi = new BitVector(25, "dataHi");
303 BitVector dLo = new BitVector(12, "dataLo");
304 BitVector t = new BitVector("1", "token");
305 BitVector a = new BitVector(14, "addr");
306 dHi.setFromLong(0x00aaaaa);
308 for (int i=0; i<num; i++) {
310 ans.add(dHi.cat(dLo).cat(t).cat(a));
315 private void stopToStop(ProperStopper s1, ProperStopper s2,
317 List<BitVector> din) {
318 prln("Begin stopToStop");
323 long ctrStart = ctr==null ? 0 : ctr.getCount();
326 waitUntilQuiescent();
328 List<BitVector> dout = s2.drainMany();
330 MarinaUtils.compareItemsOrdered(din, dout);
333 long ctrEnd = ctr.getCount();
334 long delta = ctrEnd - ctrStart;
335 long expect = din.size();
337 "counter delta wrong: expected delta: "+expect+
338 " counter before:"+ctrStart+" counter after:"+ctrEnd);
342 prln("End stopToStop");
344 /** Burst data from src to dst. gate is stopped while loading src. gate
345 * is then run to allow the burst to flow. */
346 private void stopToStopBurst(ProperStopper src, ProperStopper gate,
349 List<BitVector> din) {
350 prln("Begin stopToStopBurst test");
356 long ctrStart = ctr==null ? 0 : ctr.getCount();
359 waitUntilQuiescent();
361 // open the gate to start the burst
363 waitUntilQuiescent();
365 List<BitVector> dout = dst.drainMany();
367 MarinaUtils.compareItemsOrdered(din, dout);
370 long ctrEnd = ctr.getCount();
371 long delta = ctrEnd - ctrStart;
373 long expectA = din.size();
374 fatal(delta!=expectA,
375 "counter delta wrong: expected delta: "+expectA+
376 " counter before:"+ctrStart+" counter after:"+ctrEnd);
380 prln("End stopToStopBurst test");
383 private void stopToStopOne(ProperStopper s1, ProperStopper s2,
384 Counter ctr, int adr) {
385 prln("Begin stopToStopOne");
388 List<BitVector> din = makeIncrDataConstAdr(1, adr);
389 stopToStop(s1, s2, ctr, din);
392 prln("End stopToStopOne");
395 private void stopToStopThree(ProperStopper s1, ProperStopper s2,
396 Counter ctr, int adr) {
397 prln("Begin stopToStopOne");
400 List<BitVector> din = makeIncrDataConstAdr(3, adr);
401 stopToStop(s1, s2, ctr, din);
404 prln("End stopToStopOne");
407 private int indexOf(BitVector o, List<BitVector> dIn) {
408 for (int i=0; i<dIn.size(); i++) {
409 if (o.equals(dIn.get(i))) return i;
413 private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
414 StringBuffer sb = new StringBuffer();
415 sb.append(" ring dump: ");
416 for (BitVector o : dOut) {
417 sb.append(indexOf(o, dIn)+" ");
419 return sb.toString();
422 private int[][] makeIntArray2D(int a, int b) {
423 int[][] ans = new int[a][];
424 for (int i=0; i<a; i++) ans[i] = new int[b];
428 //=========================================================================
429 // Put top level tests here
431 private void testChains(Marina marina) {
432 prln("Testing control chain...");
433 ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
435 ccC.shift(Marina.CONTROL_CHAIN, false, true);
437 prln("Testing data chain...");
438 ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
440 //ccD.shift(Marina.DATA_CHAIN, false, true);
442 prln("Testing report chain...");
443 ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
445 //ccR.shift(Marina.REPORT_CHAIN, false, true);
448 private void testProperStoppers(Marina marina) {
449 prln("Begin testProperStoppers");
452 for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) {
454 prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper");
457 prln("un-stopping stopper");
459 fatal( ps.getStopped(), "stopper should not have been stopped, but was");
461 prln("stopping stopper");
463 fatal( !ps.getStopped(), "stopper should have been stopped, but was not");
471 private void sendInstructions(Marina marina) {
472 prln("Begin sendInstructions");
475 List<BitVector> din = new ArrayList<BitVector>();
477 BitVector count = new BitVector(MarinaPacket.WORD_WIDTH,"count");
478 BitVector one = new BitVector(MarinaPacket.WORD_WIDTH, "one");
479 count.setFromLong(0);
481 for (int i=0; i<3; i++) {
483 count = count.add(one);
486 for(BitVector d : din)
487 marina.instrIn.fill(new MarinaPacket(d, false, MarinaPacket.null_path));
490 prln("End sendInstructions");
493 private void sendToken(Marina marina) {
494 prln("Begin sendToken");
497 //getCtrsFlags(marina);
499 int nbToks = marina.getNumTokens();
500 fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens");
502 marina.instrIn.fill(SEND_TOKEN);
503 nbToks = marina.getNumTokens();
504 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
507 prln("End sendToken");
510 private void sendData(Marina marina) {
511 prln("Begin sendData");
514 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
515 for(int i=0; i<bv.length(); i+=2) bv.set(i, false);
516 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
518 marina.instrIn.fill(SEND_DATA);
520 List<BitVector> dataItems = marina.data.drainMany();
521 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
523 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
524 fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token");
527 prln("End sendData");
530 private void sendDataIlcInfinite(Marina marina) {
531 prln("Begin sendDataIlcInfinite");
534 marina.fillSouthProperStopper(new Instruction[] {
535 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
541 List<BitVector> dataItems = marina.data.drainMany(howmany);
542 fatal(dataItems.size()!=howmany,
543 "Expected an unending supply of data items to emerge but only got got: "+dataItems.size());
546 prln("End sendDataIlcInfinite");
549 private Instruction setOlc(int olc) {
550 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc);
553 private void testFlagD(Marina marina) {
554 prln("Begin testFlagD");
557 List<BitVector> toks;
559 Predicate only_if_olc_zero = Predicate.FlagD;
560 Predicate only_if_olc_nonzero = Predicate.Default;
562 for(int olc : new int[] { 1, 0 }) {
563 for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
564 prln("Attempting send token with "+
566 "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
569 marina.fillSouthProperStopper(new Instruction[] {
571 new Instruction.Move(dock,
572 predicate_olc_nonzero // predicate
573 ? only_if_olc_nonzero
576 false, // torpedoable
586 toks = marina.data.drainMany();
587 int expected = (predicate_olc_nonzero == (olc!=0)) ? 1 : 0;
588 fatal(toks.size()!=expected, "Expected "+expected+" token to emerge but got: "+toks.size()+" token(s)");
593 prln("End testFlagD");
596 private void testPredicationOnAB(Marina marina) {
597 prln("Begin testPredicationOnAB");
600 List<BitVector> dItems;
602 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
603 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
605 for(boolean flag_a : new boolean[] { false, true }) {
606 for(boolean flag_b : new boolean[] { false, true }) {
607 prln("Setting flags, a="+flag_a+" b="+flag_b);
608 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
610 ? Instruction.Set.FlagFunction.ONE
611 : Instruction.Set.FlagFunction.ZERO,
613 ? Instruction.Set.FlagFunction.ONE
614 : Instruction.Set.FlagFunction.ZERO
616 getCtrsFlags(marina);
619 for(Predicate predicate : new Predicate[] {
627 prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate);
629 marina.instrIn.fill(new Instruction.Move(dock,
630 predicate, // predicate
631 false, // torpedoable
641 dItems = marina.data.drainMany();
642 int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
643 fatal(dItems.size()!=expected, "Expected "+expected+" data items to emerge but got: "+
644 dItems.size()+" items(s)");
650 prln("End testPredicationOnAB");
655 private void getCtrsFlags(Marina marina) {
656 prln("begin getCtrsFlags");
659 int olc = marina.getOLC();
662 Ilc ilc = marina.getILC();
663 prln("ILC.done=="+ilc.getDone()+
664 " ILC.infinity=="+ilc.getInfinity()+
665 " ILC.count=="+ilc.getCount());
666 prln("flagA=="+marina.getFlagA());
667 prln("flagB=="+marina.getFlagB());
669 prln("end getCtrsFlags");
671 private void walkOneOLC(Marina marina) {
672 prln("Begin walkOneOLC");
674 for (int i=5; i>=0; i--) {
676 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
677 int outOlc = marina.getOLC();
678 fatal(outOlc!=inOlc, "walkOneOLC: got="+outOlc+" expected="+inOlc);
679 prln("walkOneOLC: "+inOlc+" checks out");
682 prln("End walkOneOLC");
684 private void walkOneILC(Marina marina) {
685 prln("Begin walkOneILC");
687 for (int i=0; i<6; i++) {
688 // Mask off the "zero" bit position
690 prln("inIlc="+inIlc);
691 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
692 Ilc ilc = marina.getILC();
693 int outIlc = ilc.getCount();
694 fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc);
695 fatal(ilc.getInfinity(), "bad Infinity bit: true");
697 prln("Now test the infinity bit");
698 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
699 Ilc ilc = marina.getILC();
700 fatal(!ilc.getInfinity(), "bad Infinity bit: false");
702 prln("End walkOneILC");
704 private void countIlc(Marina marina) {
705 final int maxIlc = 63;
706 prln("Begin countIlc");
709 marina.instrIn.fill(new
710 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
712 int ilc = marina.getILC().getCount();
713 fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
715 prln("execute a move instruction that does nothing except decrement the ILC to zero");
717 new Instruction.Move(dock,
718 Predicate.IgnoreFlagD, // predicate
719 false, // torpedoable
729 // wait for ILC to count from 63 to 0
730 //model.waitNS(64 * CYCLE_TIME_NS);
733 prln("Check that ILC==0");
734 ilc = marina.getILC().getCount();
735 fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
738 prln("End countIlc");
740 // Note: countOlc takes 44 minutes to run on nanosim
741 private void countOlc(Marina marina) {
742 final int maxOlc = 63;
743 prln("Begin countOlc");
746 marina.instrIn.fill(new
747 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, maxOlc));
748 for (int i=maxOlc; i>=0; i--) {
749 prln("OLC should be: "+i);
750 int olc = marina.getOLC();
751 fatal(olc!=i, "bad OLC: "+olc+" expected: "+i);
752 marina.instrIn.fill(new
753 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
757 prln("End countOlc");
760 private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
761 prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
764 for(i=0; i<quantity; i++) {
765 prln("Inserting instruction " + (i+1) +"/"+ quantity);
766 marina.instrIn.fill(instruction);
767 boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
768 if (jammed && expect_it_to_jam_up) {
769 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
773 fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
775 fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
777 prln("Successfully inserted " + i + " instructions");
780 private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(),
781 MarinaUtils.sunToBerk(MarinaPacket.null_path));
783 private static final Instruction NOP =
784 new Instruction.Move(dock,
785 Predicate.IgnoreFlagD, /* predicate */
786 false, /* torpedoable */
790 false, /* latchData */
791 false, /* latchPath */
796 private static final Instruction SEND_DATA =
797 new Instruction.Move(dock,
798 Predicate.IgnoreFlagD, /* predicate */
799 false, /* torpedoable */
800 null_path, /* path */
803 false, /* latchData */
804 false, /* latchPath */
809 private static final Instruction SEND_DATA_IF_D_NOT_SET =
810 new Instruction.Move(dock,
811 Predicate.Default, /* predicate */
812 false, /* torpedoable */
813 null_path, /* path */
816 false, /* latchData */
817 false, /* latchPath */
822 private static final Instruction TORPEDOABLE_RECV_DATA =
823 new Instruction.Move(dock,
824 Predicate.IgnoreFlagD, /* predicate */
825 true, /* torpedoable */
829 true, /* latchData */
830 false, /* latchPath */
835 private static final Instruction RECV_DATA =
836 new Instruction.Move(dock,
837 Predicate.IgnoreFlagD, /* predicate */
838 false, /* torpedoable */
842 true, /* latchData */
843 false, /* latchPath */
848 private static final Instruction SEND_TOKEN =
849 new Instruction.Move(dock,
850 Predicate.IgnoreFlagD, /* predicate */
851 false, /* torpedoable */
852 null_path, /* path */
855 false, /* latchData */
856 false, /* latchPath */
861 private static final Instruction RECV_TOKEN =
862 new Instruction.Move(dock,
863 Predicate.IgnoreFlagD, /* predicate */
864 false, /* torpedoable */
868 false, /* latchData */
869 false, /* latchPath */
875 private void expectNorthFifoNoMoreThan(int num) {
876 List<BitVector> dataItems = marina.data.drainMany(num+1);
877 fatal(dataItems.size()>num,
878 "Expected no more than "+num+
879 " data items to emerge but got at least: "+dataItems.size());
881 private void expectNorthFifoExactly(int num) {
882 List<BitVector> dataItems = marina.data.drainMany(num+1);
883 fatal(dataItems.size()!=num,
884 "Expected exactly "+num+
885 " data items to emerge but got at least: "+dataItems.size());
887 private void expectTokensNoMoreThan(int num) {
888 int x = marina.getNumTokens();
889 List<BitVector> dataItems = marina.data.drainMany(num+1);
891 "Expected no more than "+num+
892 " data items to emerge but got at least: "+x);
894 private void expectTokensExactly(int num) {
895 int x = marina.getNumTokens();
897 "Expected exactly "+num+
898 " data items to emerge but got at least: "+x);
901 private void testFlagDRecomputationTime(Marina marina) {
902 marina.fillSouthProperStopper(new Instruction[] {
904 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
905 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
906 SEND_DATA_IF_D_NOT_SET
908 marina.fillNorthProperStopper();
909 expectNorthFifoNoMoreThan(0);
911 marina.fillSouthProperStopper(new Instruction[] {
913 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
914 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
915 SEND_DATA_IF_D_NOT_SET
917 marina.fillNorthProperStopper();
918 expectNorthFifoNoMoreThan(0);
920 marina.fillSouthProperStopper(new Instruction[] {
922 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
923 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
924 SEND_DATA_IF_D_NOT_SET
926 marina.fillNorthProperStopper();
927 expectNorthFifoExactly(1);
929 marina.fillSouthProperStopper(new Instruction[] {
931 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
932 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
933 SEND_DATA_IF_D_NOT_SET
935 marina.fillNorthProperStopper();
936 expectNorthFifoExactly(1);
939 private void testTailWaitsForHead(Marina marina) {
940 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
942 marina.enableInstructionSend(false);
943 marina.enableInstructionRecirculate(true);
945 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
946 marina.instrIn.fill(new Instruction.Head(dock));
947 marina.instrIn.fill(SEND_DATA);
948 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
949 marina.instrIn.fill(SEND_TOKEN);
950 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
951 marina.instrIn.fill(new Instruction.Tail(dock));
952 marina.instrIn.fillTorpedo();
954 marina.enableInstructionRecirculate(false);
955 marina.enableInstructionSend(true);
956 marina.instrIn.run();
958 expectNorthFifoNoMoreThan(0);
959 prln("inserting into north proper stopper");
960 marina.fillNorthProperStopper();
961 expectNorthFifoExactly(1);
962 int nbToks = marina.getNumTokens();
963 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
966 private void testTailWithoutHead(Marina marina) {
967 marina.fillSouthProperStopper(new Instruction[] {
968 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
969 new Instruction.Tail(dock),
972 List<BitVector> dataItems = marina.data.drainMany(1);
973 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
976 private void testHeadWaitsForTail(Marina marina) {
977 List<BitVector> dataItems;
979 prln("Begin testHeadWaitsForTail");
982 marina.fillSouthProperStopper(new Instruction[] {
983 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
984 new Instruction.Head(dock),
985 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
988 dataItems = marina.data.drainMany(1);
989 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
990 marina.instrIn.fill(new Instruction.Tail(dock));
992 BitVector bv = marina.data.drain();
993 fatal(bv==null, "Expected at least one data item to emerge but got none");
996 prln("End testHeadWaitsForTail");
999 private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) {
1000 marina.fillSouthProperStopper(new Instruction[] {
1001 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,3),
1002 new Instruction.Move(dock,
1003 Predicate.IgnoreFlagD, // predicate
1004 true, // torpedoable
1013 new Instruction.Move(dock,
1014 Predicate.FlagD, // predicate
1015 false, // torpedoable
1025 marina.instrIn.fillTorpedo();
1026 expectNorthFifoExactly(1);
1027 marina.fillSouthProperStopper(new Instruction[] {
1028 new Instruction.Move(dock,
1029 Predicate.Default, // predicate
1030 false, // torpedoable
1040 expectNorthFifoNoMoreThan(0);
1043 private void testAbort(Marina marina) {
1045 marina.fillSouthProperStopper(new Instruction[] {
1046 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1),
1047 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1048 SEND_DATA_IF_D_NOT_SET,
1049 new Instruction.Head(dock),
1050 SEND_DATA_IF_D_NOT_SET,
1051 new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2),
1052 new Instruction.Abort(dock, Predicate.FlagD),
1053 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement),
1054 new Instruction.Tail(dock),
1057 for(int i=0; i<4; i++) {
1060 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1061 fatal(bv==null, "no data item found");
1062 prln("got " + bv.toLong());
1063 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1065 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1066 fatal(bv==null, "no data item found");
1067 prln("got " + bv.toLong());
1068 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1070 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1071 fatal(bv==null, "no data item found");
1072 prln("got " + bv.toLong());
1073 fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong());
1078 private void testAbortOutsideOfLoop(Marina marina) {
1079 marina.fillSouthProperStopper(new Instruction[] {
1080 // ensure that an abort doesn't cause problems if no loop is in progress
1081 new Instruction.Abort(dock, Predicate.IgnoreFlagD),
1084 expectNorthFifoExactly(1);
1087 private void testFlagAB(Marina marina) {
1088 prln("Begin testFlagAB");
1091 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1092 Instruction.Set.FlagFunction one = zero;
1095 // we should be able to use any pair of FlagX+NotFlagX,
1096 // but we toss them all in to maximize the chances of the
1097 // test passing (later we will try the individual
1098 // combinations to maximize the chances of failure).
1099 one = one.add(Predicate.FlagA);
1100 one = one.add(Predicate.NotFlagA);
1101 one = one.add(Predicate.FlagB);
1102 one = one.add(Predicate.NotFlagB);
1103 one = one.add(Predicate.FlagC);
1104 one = one.add(Predicate.NotFlagC);
1106 // clear the flags to a known state, then check both 0->1 and 1->0 transitions
1107 for(boolean b : new boolean[] { false, true, false }) {
1108 prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
1109 prln((b?"Setting":"Clearing")+" flags");
1111 marina.instrIn.fill(new
1112 Instruction.Set(dock,Predicate.IgnoreFlagD,
1116 fatal(marina.getFlagA()!=b, "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
1117 fatal(marina.getFlagB()!=b, "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
1121 prln("End testFlagAB");
1125 * WARNING: this is a very, very, very long test case -- it goes
1126 * through 216 iterations.
1128 private void testFlagTruthTable(Marina marina) {
1129 prln("Begin testFlagTruthTable");
1132 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1133 Instruction.Set.FlagFunction one = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
1135 for(Predicate a_input : new Predicate[] { null, Predicate.FlagA, Predicate.NotFlagA })
1136 for(Predicate b_input : new Predicate[] { null, Predicate.FlagB, Predicate.NotFlagB })
1137 for(Predicate c_input : new Predicate[] { null, Predicate.FlagC, Predicate.NotFlagC })
1138 for(boolean a_state : new boolean[] { false, true })
1139 for(boolean b_state : new boolean[] { false, true })
1140 for(boolean c_state : new boolean[] { false, true }) {
1141 for(boolean which : new boolean[] { false, true }) {
1143 prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
1144 // set A,B flags to a_state and b_state
1145 marina.instrIn.fill(new
1146 Instruction.Set(dock,Predicate.IgnoreFlagD,
1147 a_state ? one : zero,
1148 b_state ? one : zero
1151 // set C flag to c_state
1152 BitVector data = new BitVector(37, "empty");
1153 BitVector addr = new BitVector(14, "empty");
1154 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1155 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1156 addr.set(Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
1157 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1158 marina.instrIn.fill(RECV_DATA);
1160 Instruction.Set.FlagFunction func = zero;
1161 if (a_input!=null) func = func.add(a_input);
1162 if (b_input!=null) func = func.add(b_input);
1163 if (c_input!=null) func = func.add(c_input);
1165 Instruction inst = new
1166 Instruction.Set(dock,Predicate.IgnoreFlagD,
1167 !which ? func : zero.add(Predicate.FlagA),
1168 which ? func : zero.add(Predicate.FlagB)
1171 marina.instrIn.fill(inst);
1173 boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
1174 boolean expected_b = which ? func.evaluate(a_state, b_state, c_state, false) : b_state;
1175 fatal(expected_a != marina.getFlagA(),
1176 "expected A="+expected_a+", but got "+marina.getFlagA());
1177 fatal(expected_b != marina.getFlagB(),
1178 "expected B="+expected_b+", but got "+marina.getFlagB());
1182 prln("End testFlagTruthTable");
1185 private void recvData(Marina marina) {
1186 prln("Begin recvData");
1189 marina.fillSouthProperStopper(new Instruction[] {
1190 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1191 new Instruction.Move(dock,
1192 Predicate.IgnoreFlagD, // predicate
1193 false, // torpedoable
1202 new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG),
1204 model.waitNS(64 * CYCLE_TIME_NS);
1206 prln("checking to confirm that A flag is cleared");
1207 fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1209 prln("inserting data item in north fifo ring");
1210 BitVector data = new BitVector(37, "empty");
1211 BitVector addr = new BitVector(14, "empty");
1212 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1213 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1214 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1215 model.waitNS(64 * CYCLE_TIME_NS);
1217 prln("checking to see if A flag got set");
1218 fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1221 prln("End recvData");
1225 private void testRecvAndSendWalkingOne(Marina marina) {
1226 prln("Begin testRecvAndSendWalkingOne");
1229 List<BitVector> dataItems;
1230 for(int bit=0; bit<37; bit++) {
1232 BitVector data = new BitVector(37, "empty");
1233 BitVector addr = new BitVector(14, "empty");
1234 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1235 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1236 data.set(bit, true);
1237 prln("testing with bit pattern " + data);
1239 prln("inserting data item into north fifo ring");
1240 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1242 prln("stopping the north proper stopper");
1245 dataItems = marina.data.drainMany(1);
1246 fatal(dataItems.size()!=0,
1247 "found a data item waiting in the north proper stopper, but should not have");
1249 marina.instrIn.fill(new Instruction.Move(dock,
1250 Predicate.IgnoreFlagD, // predicate
1251 false, // torpedoable
1261 dataItems = marina.data.drainMany(2);
1262 fatal(dataItems.size()!=1,
1263 "found "+dataItems.size()+" data items in north fifo; expected one");
1264 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1265 fatalIfBitVectorsDoNotMatch(mp.data, data);
1269 prln("End testRecvAndSendWalkingOne");
1274 private void setOlcFromDataLatch(Marina marina) {
1275 prln("Begin setOlcFromDataLatch");
1278 // walk a bit from 0 to 5
1279 for(int bit=0; bit<6; bit++) {
1280 prln("inserting data item in north fifo ring");
1281 BitVector data = new BitVector(37, "empty");
1282 BitVector addr = new BitVector(14, "empty");
1283 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1284 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1285 data.set(bit, true);
1286 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1288 marina.fillSouthProperStopper(new Instruction[] {
1290 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch)
1293 int olc = marina.getOLC();
1294 fatal(olc != (1<<bit), "expected olc to be " + (1<<bit) + ", but got " + olc);
1298 prln("End setOlcFromDataLatch");
1301 private void setIlcFromDataLatch(Marina marina) {
1302 prln("Begin setIlcFromDataLatch");
1305 // walk a bit from 0 to 5
1306 for(int bit=5; bit>=0; bit--) {
1307 prln("inserting data item in north fifo ring");
1308 BitVector data = new BitVector(37, "empty");
1309 BitVector addr = new BitVector(14, "empty");
1310 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1311 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1312 data.set(bit, true);
1313 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1315 marina.fillSouthProperStopper(new Instruction[] {
1316 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1318 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch),
1320 model.waitNS(CYCLE_TIME_NS * 64);
1322 int ilc = marina.getILC().getCount();
1323 fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc);
1327 prln("End setIlcFromDataLatch");
1330 private void testSendAndRecvToken(Marina marina) {
1331 prln("Begin testSendAndRecvToken");
1334 marina.fillSouthProperStopper(new Instruction[] {
1339 List<BitVector> dataItems = marina.data.drainMany(3);
1340 fatal(dataItems.size()!=1,
1341 "expected exactly one data item, got " + dataItems.size());
1344 prln("End testSendAndRecvToken");
1347 private void testSignExtendedLiteral(Marina marina) {
1348 prln("Begin testSignExtendedLiteral");
1351 for(long val : new long[] { (-1L << 14), -1, 0, 1 }) {
1353 marina.fillSouthProperStopper(new Instruction[] {
1354 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1355 Instruction.Set.SetDest.DataLatch,
1360 List<BitVector> dataItems = marina.data.drainMany(3);
1361 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1363 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1364 BitVector bv = mp.data;
1365 prln("got back " + mp);
1367 boolean mismatch = false;
1369 for(int i=0; i<37; i++) {
1370 if (bv.get(i) != ( (val & (1L << i)) != 0 )) {
1375 fatal(mismatch, "data read back did not match inserted literal; mismatch on bits " + err);
1379 prln("End testSignExtendedLiteral");
1382 private void testShiftedLiteral(Marina marina) {
1383 prln("Begin testShiftedLiteral");
1386 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
1387 Instruction.Set.SetDest.DataLatch,
1390 BitVector dreg = new BitVector(37, "what we think is in the d-register");
1391 for(int i=0; i<37; i++) dreg.set(i, false);
1393 for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
1395 edu.berkeley.fleet.api.BitVector immediate =
1396 new edu.berkeley.fleet.api.BitVector(19);
1397 for(int i=0; i<immediate.length(); i++)
1398 immediate.set(i, (val & (1L << i)) != 0);
1400 // shift over 19 LSB's towards MSB
1401 for(int i=0; i<19; i++)
1402 if (i+19 <= 36) dreg.set(i+19, dreg.get(i));
1403 for(int i=0; i<19; i++)
1404 dreg.set(i, immediate.get(i));
1406 marina.fillSouthProperStopper(new Instruction[] {
1407 new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate),
1411 List<BitVector> dataItems = marina.data.drainMany(3);
1412 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1414 BitVector bv = new MarinaPacket(dataItems.get(0)).data;
1415 fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" +
1416 "got: "+bv.bitReverse().getState()+"\n"+
1417 "expected:"+dreg.bitReverse().getState());
1421 prln("End testShiftedLiteral");
1424 private void testFlagC(Marina marina) {
1425 prln("Begin testFlagC");
1433 // Dc=1 => sigS is copied into C-flag
1434 // Dc=0 => sigA is copied into C-flag
1436 for(boolean dc : new boolean[] { false, true }) {
1437 for(boolean c_flag : new boolean[] { true, false, true }) {
1440 prln("****** checking case where dc="+dc+", cflag="+c_flag);
1441 BitVector data = new BitVector(37, "empty");
1442 BitVector addr = new BitVector(14, "empty");
1443 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1444 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1447 ? Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
1448 : Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
1449 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
1450 addr.set(whichbit, c_flag);
1452 prln("... and filling north fifo proper stopper");
1453 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1455 prln("clearing flags");
1456 prln("executing recv data with Dc="+dc);
1457 prln("copying c-flag to a-flag");
1458 marina.fillSouthProperStopper(new Instruction[] {
1459 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1460 new Instruction.Move(dock,
1461 Predicate.IgnoreFlagD, /* predicate */
1462 true, /* torpedoable */
1464 false, /* tokenIn */
1467 false, /* latchPath */
1468 false, /* dataOut */
1469 false /* tokenOut */
1471 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1472 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
1477 model.waitNS(CYCLE_TIME_NS * 64);
1479 prln("checking to confirm that A flag is " + c_flag);
1480 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
1484 prln("End testFlagC");
1487 private void sendDataWithPath(Marina marina) {
1488 prln("Begin sendDataWithPath");
1491 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
1493 // alternating ones and zeroes
1494 for(int i=0; i<bv.length(); i+=2)
1496 // and then ones in the lower four bits so it's not symmetric
1497 for(int i=0; i<4; i++)
1500 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
1502 marina.fillSouthProperStopper(new Instruction[] {
1503 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1504 new Instruction.Move(dock,
1505 Predicate.IgnoreFlagD, /* predicate */
1506 false, /* torpedoable */
1508 false, /* tokenIn */
1510 false, /* latchData */
1511 false, /* latchPath */
1513 false /* tokenOut */
1517 List<BitVector> dataItems;
1520 dataItems = marina.data.drainMany();
1521 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1522 mp = new MarinaPacket(dataItems.get(0));
1524 // the 14th bit of the outbound address cannot be set by the
1525 // ship, so we don't care about it
1526 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1528 prln("send data with no change to path");
1529 marina.instrIn.fill(new Instruction.Move(dock,
1530 Predicate.IgnoreFlagD, /* predicate */
1531 false, /* torpedoable */
1533 false, /* tokenIn */
1535 false, /* latchData */
1536 false, /* latchPath */
1538 false /* tokenOut */
1541 dataItems = marina.data.drainMany();
1542 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1543 mp = new MarinaPacket(dataItems.get(0));
1545 // the 14th bit of the outbound address cannot be set by the
1546 // ship, so we don't care about it
1547 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1550 prln("End sendDataWithPath");
1553 private void recvPath(Marina marina) {
1554 prln("Begin recvPath");
1557 for(int bit=0; bit<11; bit++) {
1558 BitVector packet_data = new BitVector(37, "inbound data item");
1559 for(int i=0; i<37; i++) packet_data.set(i, false);
1560 packet_data.set(27+bit, true);
1561 BitVector packet_path = new BitVector(14, "inbound data item");
1562 for(int i=0; i<14; i++) packet_path.set(i, false);
1564 marina.fillNorthProperStopper(new MarinaPacket(packet_data, false, packet_path));
1566 prln("recv path, send data (using recv'd path)");
1567 marina.instrIn.fill(new Instruction.Move(dock,
1568 Predicate.IgnoreFlagD, /* predicate */
1569 false, /* torpedoable */
1571 false, /* tokenIn */
1573 true, /* latchData */
1574 true, /* latchPath */
1576 false /* tokenOut */
1579 List<BitVector> dataItems = marina.data.drainMany();
1580 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1581 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1583 fatalIfBitVectorsDoNotMatch(packet_data.get(25,11), mp.path.get(0,11));
1584 fatalIfBitVectorsDoNotMatch(packet_data, mp.data);
1588 prln("End recvPath");
1591 private void testILC(Marina marina) {
1592 prln("Begin testILC");
1595 for(int bit=0; bit<6; bit++) {
1596 int ilc = bit<0 ? 0 : (1<<bit);
1597 marina.fillSouthProperStopper(new Instruction[] {
1598 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc),
1601 List<BitVector> dataItems = marina.data.drainMany();
1602 fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
1606 prln("End testILC");
1609 private void testILCZero(Marina marina) {
1611 marina.fillSouthProperStopper(new Instruction[] {
1612 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0),
1616 expectNorthFifoNoMoreThan(0);
1617 expectTokensExactly(1);
1621 private void sendTorpedo(Marina marina) {
1622 prln("Begin sendTorpedo");
1624 marina.instrIn.fill(new
1625 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
1626 int olc = marina.getOLC();
1627 fatal(olc!=1, "bad OLC: "+olc+" expected: 1");
1628 marina.instrIn.fill(new
1629 Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1630 fatal(marina.getFlagA(), "bad A flag: true");
1631 fatal(marina.getFlagB(), "bad B flag: true");
1633 prln("execute a move instruction that does nothing but loops until torpedo arrives");
1634 prln("A=1, B=B This instruction should not execute because D-flag is set");
1635 prln("Set A=A, B=1 This instruction should execute because D-flag is set");
1636 marina.fillSouthProperStopper(new Instruction[] {
1637 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity),
1638 new Instruction.Move(dock,
1639 Predicate.IgnoreFlagD, // predicate
1640 true, // torpedoable
1649 new Instruction.Set(dock,Predicate.Default,
1651 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB)
1653 new Instruction.Set(dock, Predicate.FlagD,
1654 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA),
1659 prln("send torpedo. This should clear the OLC");
1660 marina.instrIn.fillTorpedo();
1661 model.waitNS(64 * CYCLE_TIME_NS);
1663 prln("A should remain false, B should be true");
1664 fatal(marina.getFlagA(), "bad A flag: true");
1665 fatal(!marina.getFlagB(), "bad B flag: false");
1667 prln("OLC = 63. Reload OLC after torpedo, clears D-flag");
1668 marina.instrIn.fill(new
1669 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1671 olc = marina.getOLC();
1672 fatal(olc!=63, "bad OLC: "+olc+" expected: 63");
1674 prln("Set A=1, B=1 This instruction should execute because OLC!=0");
1675 marina.instrIn.fill(new
1676 Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
1678 prln("A and B should be true");
1679 fatal(!marina.getFlagA(), "bad A flag: false");
1680 fatal(!marina.getFlagB(), "bad B flag: false");
1683 prln("End sendTorpedo");
1686 private void testTorpedoOnAnInfinite(Marina marina) {
1687 prln("Begin testTorpedoOnAnInfinite");
1690 List<BitVector> dataItems;
1692 for(boolean torpedoable : new boolean[] { true, false }) {
1694 marina.fillSouthProperStopper(new Instruction[] {
1695 new Instruction.Move(dock,
1696 Predicate.IgnoreFlagD, // predicate
1697 false, // torpedoable
1706 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
1707 new Instruction.Move(dock,
1708 Predicate.IgnoreFlagD, // predicate
1709 torpedoable, // torpedoable
1718 // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior
1719 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1724 // expect nothing to come out, because the NOP is executing
1725 dataItems = marina.data.drainMany(2);
1726 fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
1728 marina.instrIn.fillTorpedo();
1730 int expected = torpedoable?1:0;
1731 dataItems = marina.data.drainMany(2);
1732 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1734 fatal(!marina.getILC().getDone(), "Expected ilc=done, but got "+marina.getILC());
1738 prln("End testTorpedoOnAnInfinite");
1741 private void testOlcDecrementAtHighSpeed(Marina marina) {
1742 prln("Begin testOlcDecrementAtHighSpeed");
1745 List<BitVector> dataItems;
1747 // Each element of the following pair of arrays is one "test".
1748 // The OLC will be loaded with olcs[i] and then decremented
1749 // decr_amounts[i] times; after that has happened the zeroness
1750 // of the OLC will be checked by executing a MOVE with
1751 // [olc!=0] as the predicate.
1753 int[] olcs = new int[] { 3, 3, 3, 10, 41 };
1754 int[] decr_amounts = new int[] { 2, 3, 4, 9, 9 };
1756 for(int which=0; which<olcs.length; which++) {
1757 int olc = olcs[which];
1758 int decr_amount = decr_amounts[which];
1760 prln("inserting set olc="+olc);
1761 prln("inserting set ilc=1");
1762 marina.fillSouthProperStopper(new Instruction[] {
1763 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1764 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc),
1767 // commenting the following four lines causes this test to pass
1769 prln("inserting: "+decr_amount+" olc-- instructions");
1770 prln("inserting: [!d] send data");
1771 Instruction[] instructions = new Instruction[decr_amount+1];
1772 for(int i=0; i<decr_amount; i++)
1774 new Instruction.Set(dock,
1775 Predicate.IgnoreFlagD,
1776 SetDest.OuterLoopCounter,
1777 SetSource.Decrement);
1778 instructions[instructions.length-1] =
1779 new Instruction.Move(dock,
1780 Predicate.Default, // predicate
1781 false, // torpedoable
1790 marina.fillSouthProperStopper(instructions);
1791 model.waitNS(64 * CYCLE_TIME_NS);
1793 int expected = decr_amount>=olc ? 0 : 1;
1794 dataItems = marina.data.drainMany(2);
1795 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1799 prln("End testOlcDecrementAtHighSpeed");
1802 private void flipIlcBit(Marina marina) {
1803 prln("Begin flipIlcBit");
1805 prln("Using the set ILC instruction, toggle a single bit between zero and one. \n" +
1806 "Check correct setting of the ILC zero bit");
1808 for (int i=0; i<6; i++) {
1811 prln("Then immediately set ILC="+notZero);
1812 marina.fillSouthProperStopper(new Instruction[] {
1813 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
1814 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
1817 prln("Verify ILC using scan chain");
1818 Ilc ilc = marina.getILC();
1819 int ilcCount = ilc.getCount();
1820 fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
1821 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
1823 marina.fillSouthProperStopper(new Instruction[] {
1824 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
1825 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
1828 prln("Verify ILC using scan chain");
1829 ilc = marina.getILC();
1830 ilcCount = ilc.getCount();
1831 fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
1832 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
1836 prln("End flipIlcBit");
1838 private void flipOlcBit(Marina marina) {
1839 prln("Begin flipOlcBit");
1841 prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
1842 "Check correct setting of the OLC zero bit");
1844 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1846 for (int i=0; i<6; i++) {
1847 int notZero = 32 >> i;
1849 prln("Then immediately set OLC="+notZero);
1850 marina.fillSouthProperStopper(new Instruction[] {
1851 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
1852 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
1855 prln("Verify OLC count using scan chain");
1856 int outOlc = marina.getOLC();
1857 fatal(outOlc!=notZero, "bad OLC count: "+outOlc+" expected: "+notZero);
1859 prln("Set OLC="+notZero);
1860 prln("Then immediately set OLC=0");
1861 marina.fillSouthProperStopper(new Instruction[] {
1862 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
1863 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
1866 prln("Verify OLC count using scan chain");
1867 outOlc = marina.getOLC();
1868 fatal(outOlc!=0, "bad OLC count: "+outOlc+" expected: 0");
1872 prln("End flipOlcBit");
1874 private void testSouthRecirculate(Marina marina, int AMOUNT) {
1875 prln("Begin testSouthRecirculate("+AMOUNT+")");
1878 marina.enableInstructionSend(false);
1879 marina.enableInstructionRecirculate(true);
1881 prln("Completely fill south ring");
1883 for (int i=0; i<AMOUNT; i++) {
1884 prln("inserting item " + (i+1) + " / " + AMOUNT);
1885 BitVector path = new BitVector(MarinaPacket.PATH_WIDTH, "path");
1886 BitVector data = new BitVector(MarinaPacket.WORD_WIDTH, "path");
1887 path.set(0, MarinaPacket.PATH_WIDTH, false);
1888 data.setFromLong(i+1);
1889 marina.instrIn.fill(new MarinaPacket(data, false, path));
1893 prln("Drain south ring and check contents");
1895 List<BitVector> out = marina.instrIn.drainMany();
1896 boolean bad = false;
1897 for (int i=0; i<AMOUNT; i++) {
1898 prln("extracting item " + (i+1) + " / " + AMOUNT);
1899 //int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
1901 long got = new MarinaPacket(out.get(i)).data.toLong();
1904 prln(" bad instruction: "+got+" expected: "+expect);
1906 prln(" good instruction.");
1909 fatal(bad, "data inserted does not match data retrieved");
1912 for (int i=0; i<5; i++) {}
1915 prln("End testSouthRecirculate("+AMOUNT+")");
1917 private void doOneTest(int testNum) {
1919 prln("============================================================");
1920 prln("MarinaTest: performing test: "+testNum);
1922 marina.masterClear();
1923 marina.enableInstructionSend(true);
1928 // these tests run fairly quickly
1962 // these tests take a while and usually pass
1973 // this takes an insanely long time
1978 case 1: testChains(marina); break; // passes, 24-Mar (+verilog)
1979 case 2: testProperStoppers(marina); break; // passes, 24-Mar (+verilog)
1980 case 3: testSouthRecirculate(marina, 1); break; // passes, 24-Mar (+verilog)
1981 case 4: getCtrsFlags(marina); break; // 20-Apr (+verilog)
1982 case 5: sendInstructions(marina); break; // passes, 24-Mar (+verilog)
1983 case 6: walkOneOLC(marina); break; // 21-Apr (+verilog)
1985 // Russell's tests begin with 1000
1986 case 1000: walkOneILC(marina); break; // 20-Apr (+verilog)
1987 case 1001: countIlc(marina); break; // 20-Apr (+verilog)
1988 case 1002: countOlc(marina); break; // 23-Apr (+verilog)
1990 case 1003: sendTorpedo(marina); break; // 23-Apr (+verilog) [with wor-hack]
1992 case 1004: flipIlcBit(marina); break; // 20-Apr (+verilog)
1993 case 1005: flipOlcBit(marina); break; // 21-Apr (+verilog)
1995 case 1006: testSouthRecirculate(marina, Marina.SOUTH_RING_CAPACITY-1); break; // passes, 24-Mar (+verilog)
1997 // Adam's tests begin with 3000
1998 case 3000: sendToken(marina); break; // passes, 24-Mar (+verilog)
1999 case 3001: testFlagAB(marina); break; // passes, 08-Apr (+verilog)
2000 case 3002: testPredicationOnAB(marina); break; // 22-Apr (+verilog)
2001 case 3003: testFlagC(marina); break; // 23-Apr (+verilog)
2002 case 3004: testFlagD(marina); break; // 23-Apr (+verilog)
2003 case 3005: testFlagDRecomputationTime(marina); break;
2005 case 3006: testTailWaitsForHead(marina); break;
2006 case 3007: testTailWithoutHead(marina); break;
2007 case 3008: testHeadWaitsForTail(marina); break; // 22-Apr (+verilog)
2008 case 3009: testAbort(marina); break; // 22-Apr (+verilog)
2010 case 3010: sendData(marina); break; // passes, 24-Mar (+verilog)
2011 case 3011: recvData(marina); break; // 21-Apr (+verilog)
2012 case 3012: sendDataWithPath(marina); break; // passes, 13-Apr (+verilog)
2014 case 3013: testSignExtendedLiteral(marina); break; // 20-Apr (+verilog)
2015 case 3014: testShiftedLiteral(marina); break; // 20-Apr (+verilog)
2016 case 3015: testSendAndRecvToken(marina); break; // 21-Apr (+verilog)
2018 case 3016: sendDataIlcInfinite(marina); break; // 22-Apr (+verilog)
2019 case 3017: testFlagTruthTable(marina); break; // 23-Apr (+verilog)
2021 case 3019: setOlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2022 case 3020: setIlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2023 case 3021: recvPath(marina); break; // 22-Apr (+verilog)
2024 case 3022: testILC(marina); break; // 23-Apr (+verilog)
2025 case 3023: testTorpedoOnAnInfinite(marina); break; // 23-Apr (+verilog)
2026 case 3024: testRecvAndSendWalkingOne(marina); break; // 21-Apr (+verilog)
2027 case 3025: testOlcDecrementAtHighSpeed(marina); break; // 23-Apr (+verilog)
2029 case 3026: testNonTorpedoableMoveDoesNotResetDFlag(marina); break; // 23-Apr (+verilog)
2030 case 3027: testILCZero(marina); break;
2031 case 3028: testAbortOutsideOfLoop(marina); break;
2034 fatal(true, "Test number: "+testNum+" doesn't exist.");
2037 // If we get here then test passed
2038 prln("Test Result: Passed");
2040 //Infrastructure.exit(0);
2044 //============================ for public use =============================
2047 * 0: test detected success
2048 * 2: test detected failure
2051 public static void main(String[] args) {
2052 startTime = System.currentTimeMillis();
2053 new MarinaTest(args);