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) { MarinaUtils.fatal(pred, msg); }
129 public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
130 // FIXME: better error reporting needed here
132 fatal(bv1.getNumBits()!=bv2.getNumBits(), "lengths do not match");
134 boolean mismatch = false;
136 for(int i=0; i<bv1.getNumBits(); i++) {
137 if (bv1.get(i) != bv2.get(i)) {
142 fatal(mismatch, "bit vectors do not match on bits " + err + "\n "+bv1+"\n "+bv2);
145 private static void printTestTime() {
146 long endTime = System.currentTimeMillis();
147 System.out.println("Test took: "+(endTime-startTime)/1000.0+" sec");
150 // Tell user what we're about to do
151 private static void reportTask(CmdArgs args) {
152 System.out.println("Begin testing Marina");
154 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
155 System.out.println(" Simulate whole chip, schematic parasitics");
157 case WHOLE_CHIP_LAYOUT_PARASITICS:
158 System.out.println(" Simulate whole chip, layout parasitics");
161 System.out.println(" Test silicon");
164 fatal(true, "unrecognized CmdArgs.Mode");
168 private void setUpSuppliesAndMeters(Station station) {
169 // set up power supplies and meters
171 prln("Testing station: "+station);
172 Infrastructure.gpibControllers = new int[] {0};
173 switch (cmdArgs.station) {
175 corePowerSupply = new Pst3202Channel("ch1", "HPST3202", 1);
176 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202", 2);
179 corePowerSupply = new Pst3202Channel("ch1", "HPST3202B", 1);
180 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202B", 2);
183 fatal(true, "Unrecognized station: "+cmdArgs.station);
185 corePowerSupply.setCurrent((float)1.7);
186 corePowerSupply.setVoltageWait((float)1.0);
188 padsPowerSupply.setCurrent((float)0.100);
189 padsPowerSupply.setVoltageWait((float)1.8);
191 coreVoltmeter = new HP34401A(station.coreVoltmeter);
192 voltmeterForCurrent = new HP34401A(station.currentVoltmenter);
196 private MarinaTest(String[] args) {
197 cmdArgs = new CmdArgs(args);
199 if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim();
202 private void doSim() {
204 switch (cmdArgs.mode) {
205 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
206 netListName = NET_LIST;
208 case WHOLE_CHIP_LAYOUT_PARASITICS:
209 netListName = "marina_pads_guts.spi";
212 fatal(true, "unrecognized CmdArgs.Mode");
215 model = cmdArgs.useVerilog ? new VerilogModel() : new NanosimModel();
217 ((SimulationModel)model).setOptimizedDirectReadsWrites(true);
219 CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250;
221 //tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO");
222 ChainControls ccs = new ChainControls();
223 JtagTester testerD, testerR, testerC;
224 testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null);
225 testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null);
226 testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null);
227 testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
229 int khz = model instanceof VerilogModel ? 100000 : 1000000;
231 ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
232 ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
233 ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
234 ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
236 PowerChannel pc = new ManualPowerChannel("pc", false);
238 ctD = new ChainTest(ccD, pc);
239 ctR = new ChainTest(ccR, pc);
240 ctC = new ChainTest(ccC, pc);
242 ccs.addChain(Marina.DATA_CHAIN, ccD);
243 ccs.addChain(Marina.REPORT_CHAIN, ccR);
244 ccs.addChain(Marina.CONTROL_CHAIN, ccC);
246 marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter);
248 if (model instanceof VerilogModel)
249 ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift);
251 ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
254 ccC.shift(Marina.CONTROL_CHAIN, false, true);
256 doOneTest(cmdArgs.testNum);
258 ((SimulationModel)model).finish();
260 private void doSilicon() {
261 model = new SiliconChip();
262 String ip = cmdArgs.station.ipAddr;
263 JtagTester tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
264 tester.printInfo = false;
266 ChainControl cc = new ChainControl("???", tester, 1.8f, khz);
267 cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
268 ChainControls ccs = new ChainControls();
269 ccs.addChain(Marina.DATA_CHAIN, cc);
270 ccs.addChain(Marina.REPORT_CHAIN, cc);
271 ccs.addChain(Marina.CONTROL_CHAIN, cc);
272 marina = new Marina(ccs, model, false, indenter);
273 PowerChannel pc = new ManualPowerChannel("pc", false);
274 ChainTest ct = new ChainTest(cc, pc);
275 ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
276 doOneTest(cmdArgs.testNum);
277 setUpSuppliesAndMeters(cmdArgs.station);
280 /** In the absence of looping, the longest path through Infinity is 4 column delays */
281 private void waitUntilQuiescent() {
282 model.waitNS(4*COLUMN_LATENCY);
285 private double readCurrent() {
286 return voltmeterForCurrent.readVoltage() / cmdArgs.station.ammeterShuntResistance;
289 /** Generate List of BitVectors where Token=true, high 25 data bits
290 * are alternating ones and zeros, low 12 data bits increment from
291 * zero, and address is given by addr. */
292 private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
293 List<BitVector> ans = new ArrayList<BitVector>();
294 BitVector dHi = new BitVector(25, "dataHi");
295 BitVector dLo = new BitVector(12, "dataLo");
296 BitVector t = new BitVector("1", "token");
297 BitVector a = new BitVector(14, "addr");
298 dHi.setFromLong(0x00aaaaa);
300 for (int i=0; i<num; i++) {
302 ans.add(dHi.cat(dLo).cat(t).cat(a));
307 private void stopToStop(ProperStopper s1, ProperStopper s2,
309 List<BitVector> din) {
310 prln("Begin stopToStop");
315 long ctrStart = ctr==null ? 0 : ctr.getCount();
318 waitUntilQuiescent();
320 List<BitVector> dout = s2.drainMany();
322 MarinaUtils.compareItemsOrdered(din, dout);
325 long ctrEnd = ctr.getCount();
326 long delta = ctrEnd - ctrStart;
327 long expect = din.size();
329 "counter delta wrong: expected delta: "+expect+
330 " counter before:"+ctrStart+" counter after:"+ctrEnd);
334 prln("End stopToStop");
336 /** Burst data from src to dst. gate is stopped while loading src. gate
337 * is then run to allow the burst to flow. */
338 private void stopToStopBurst(ProperStopper src, ProperStopper gate,
341 List<BitVector> din) {
342 prln("Begin stopToStopBurst test");
348 long ctrStart = ctr==null ? 0 : ctr.getCount();
351 waitUntilQuiescent();
353 // open the gate to start the burst
355 waitUntilQuiescent();
357 List<BitVector> dout = dst.drainMany();
359 MarinaUtils.compareItemsOrdered(din, dout);
362 long ctrEnd = ctr.getCount();
363 long delta = ctrEnd - ctrStart;
365 long expectA = din.size();
366 fatal(delta!=expectA,
367 "counter delta wrong: expected delta: "+expectA+
368 " counter before:"+ctrStart+" counter after:"+ctrEnd);
372 prln("End stopToStopBurst test");
375 private void stopToStopOne(ProperStopper s1, ProperStopper s2,
376 Counter ctr, int adr) {
377 prln("Begin stopToStopOne");
380 List<BitVector> din = makeIncrDataConstAdr(1, adr);
381 stopToStop(s1, s2, ctr, din);
384 prln("End stopToStopOne");
387 private void stopToStopThree(ProperStopper s1, ProperStopper s2,
388 Counter ctr, int adr) {
389 prln("Begin stopToStopOne");
392 List<BitVector> din = makeIncrDataConstAdr(3, adr);
393 stopToStop(s1, s2, ctr, din);
396 prln("End stopToStopOne");
399 private int indexOf(BitVector o, List<BitVector> dIn) {
400 for (int i=0; i<dIn.size(); i++) {
401 if (o.equals(dIn.get(i))) return i;
405 private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
406 StringBuffer sb = new StringBuffer();
407 sb.append(" ring dump: ");
408 for (BitVector o : dOut) {
409 sb.append(indexOf(o, dIn)+" ");
411 return sb.toString();
414 private int[][] makeIntArray2D(int a, int b) {
415 int[][] ans = new int[a][];
416 for (int i=0; i<a; i++) ans[i] = new int[b];
420 //=========================================================================
421 // Put top level tests here
423 private void testChains(Marina marina) {
424 prln("Testing control chain...");
425 ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
427 ccC.shift(Marina.CONTROL_CHAIN, false, true);
429 prln("Testing data chain...");
430 ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
432 //ccD.shift(Marina.DATA_CHAIN, false, true);
434 prln("Testing report chain...");
435 ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
437 //ccR.shift(Marina.REPORT_CHAIN, false, true);
440 private void testProperStoppers(Marina marina) {
441 prln("Begin testProperStoppers");
444 for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) {
446 prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper");
449 prln("un-stopping stopper");
451 fatal( ps.getStopped(), "stopper should not have been stopped, but was");
453 prln("stopping stopper");
455 fatal( !ps.getStopped(), "stopper should have been stopped, but was not");
463 private void sendInstructions(Marina marina) {
464 prln("Begin sendInstructions");
467 List<BitVector> din = new ArrayList<BitVector>();
469 BitVector count = new BitVector(MarinaPacket.WORD_WIDTH,"count");
470 BitVector one = new BitVector(MarinaPacket.WORD_WIDTH, "one");
471 count.setFromLong(0);
473 for (int i=0; i<3; i++) {
475 count = count.add(one);
478 for(BitVector d : din)
479 marina.instrIn.fill(new MarinaPacket(d, false, MarinaPacket.null_path));
482 prln("End sendInstructions");
485 private void sendToken(Marina marina) {
486 prln("Begin sendToken");
489 //getCtrsFlags(marina);
491 int nbToks = marina.getNumTokens();
492 fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens");
494 marina.instrIn.fill(setIlc(1));
495 marina.instrIn.fill(SEND_TOKEN);
496 nbToks = marina.getNumTokens();
497 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
500 prln("End sendToken");
503 private void sendData(Marina marina) {
504 prln("Begin sendData");
507 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
508 for(int i=0; i<bv.length(); i+=2) bv.set(i, false);
509 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
511 marina.instrIn.fill(setIlc(1));
512 marina.instrIn.fill(SEND_DATA);
514 List<BitVector> dataItems = marina.data.drainMany();
515 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
517 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
518 fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token");
521 prln("End sendData");
524 private void sendDataIlcInfinite(Marina marina) {
525 prln("Begin sendDataIlcInfinite");
528 marina.fillSouthProperStopper(new Instruction[] {
529 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
535 List<BitVector> dataItems = marina.data.drainMany(howmany);
536 fatal(dataItems.size()!=howmany,
537 "Expected an unending supply of data items to emerge but only got got: "+dataItems.size());
540 prln("End sendDataIlcInfinite");
543 private Instruction setOlc(int olc) {
544 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc);
546 private Instruction setIlc(int ilc) {
547 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, ilc);
550 private void testFlagD(Marina marina) {
551 prln("Begin testFlagD");
554 List<BitVector> toks;
556 Predicate only_if_olc_zero = Predicate.FlagD;
557 Predicate only_if_olc_nonzero = Predicate.Default;
559 marina.instrIn.fill(setIlc(1));
561 for(int olc : new int[] { 1, 0 }) {
562 for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
563 prln("Attempting send data item with "+
565 "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
568 marina.fillSouthProperStopper(new Instruction[] {
570 new Instruction.Move(dock,
571 predicate_olc_nonzero // predicate
572 ? only_if_olc_nonzero
575 false, // torpedoable
585 expectNorthFifoExactly((predicate_olc_nonzero == (olc!=0)) ? 1 : 0);
590 prln("End testFlagD");
593 private void testPredicationOnAB(Marina marina) {
594 prln("Begin testPredicationOnAB");
597 List<BitVector> dItems;
599 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
600 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
602 for(boolean flag_a : new boolean[] { false, true }) {
603 for(boolean flag_b : new boolean[] { false, true }) {
604 prln("Setting flags, a="+flag_a+" b="+flag_b);
605 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
607 ? Instruction.Set.FlagFunction.ONE
608 : Instruction.Set.FlagFunction.ZERO,
610 ? Instruction.Set.FlagFunction.ONE
611 : Instruction.Set.FlagFunction.ZERO
613 getCtrsFlags(marina);
616 for(Predicate predicate : new Predicate[] {
624 prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate);
626 marina.instrIn.fill(new Instruction.Move(dock,
627 predicate, // predicate
628 false, // torpedoable
638 dItems = marina.data.drainMany();
639 int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
640 fatal(dItems.size()!=expected, "Expected "+expected+" data items to emerge but got: "+
641 dItems.size()+" items(s)");
647 prln("End testPredicationOnAB");
652 private void getCtrsFlags(Marina marina) {
653 prln("begin getCtrsFlags");
656 int olc = marina.getOLC();
659 Ilc ilc = marina.getILC();
660 prln("ILC.done=="+ilc.getDone()+
661 " ILC.infinity=="+ilc.getInfinity()+
662 " ILC.count=="+ilc.getCount());
663 prln("flagA=="+marina.getFlagA());
664 prln("flagB=="+marina.getFlagB());
666 prln("end getCtrsFlags");
668 private void walkOneOLC(Marina marina) {
669 prln("Begin walkOneOLC");
671 for (int i=5; i>=0; i--) {
673 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
674 int outOlc = marina.getOLC();
675 fatal(outOlc!=inOlc, "walkOneOLC: got="+outOlc+" expected="+inOlc);
676 prln("walkOneOLC: "+inOlc+" checks out");
679 prln("End walkOneOLC");
681 private void walkOneILC(Marina marina) {
682 prln("Begin walkOneILC");
684 for (int i=0; i<6; i++) {
685 // Mask off the "zero" bit position
687 prln("inIlc="+inIlc);
688 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
689 Ilc ilc = marina.getILC();
690 int outIlc = ilc.getCount();
691 fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc);
692 fatal(ilc.getInfinity(), "bad Infinity bit: true");
694 prln("Now test the infinity bit");
695 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
696 Ilc ilc = marina.getILC();
697 fatal(!ilc.getInfinity(), "bad Infinity bit: false");
699 prln("End walkOneILC");
701 private void countIlc(Marina marina) {
702 final int maxIlc = 63;
703 prln("Begin countIlc");
706 marina.instrIn.fill(new
707 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
709 int ilc = marina.getILC().getCount();
710 fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
712 prln("execute a move instruction that does nothing except decrement the ILC to zero");
714 new Instruction.Move(dock,
715 Predicate.IgnoreFlagD, // predicate
716 false, // torpedoable
726 // wait for ILC to count from 63 to 0
727 model.waitNS(128 * CYCLE_TIME_NS);
728 //model.waitNS(10000);
730 prln("Check that ILC==0");
731 ilc = marina.getILC().getCount();
732 fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
735 prln("End countIlc");
737 // Note: countOlc takes 44 minutes to run on nanosim
738 private void countOlc(Marina marina) {
739 final int maxOlc = 63;
740 prln("Begin countOlc");
743 marina.instrIn.fill(new
744 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, maxOlc));
745 for (int i=maxOlc; i>=0; i--) {
746 prln("OLC should be: "+i);
747 int olc = marina.getOLC();
748 fatal(olc!=i, "bad OLC: "+olc+" expected: "+i);
749 marina.instrIn.fill(new
750 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
754 prln("End countOlc");
757 private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
758 prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
761 for(i=0; i<quantity; i++) {
762 prln("Inserting instruction " + (i+1) +"/"+ quantity);
763 marina.instrIn.fill(instruction);
764 boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
765 if (jammed && expect_it_to_jam_up) {
766 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
770 fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
772 fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
774 prln("Successfully inserted " + i + " instructions");
777 private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(),
778 MarinaUtils.sunToBerk(MarinaPacket.null_path));
780 private static final Instruction NOP =
781 new Instruction.Move(dock,
782 Predicate.IgnoreFlagD, /* predicate */
783 false, /* torpedoable */
787 false, /* latchData */
788 false, /* latchPath */
793 private static final Instruction SEND_DATA =
794 new Instruction.Move(dock,
795 Predicate.IgnoreFlagD, /* predicate */
796 false, /* torpedoable */
797 null_path, /* path */
800 false, /* latchData */
801 false, /* latchPath */
806 private static final Instruction SEND_DATA_IF_D_NOT_SET =
807 new Instruction.Move(dock,
808 Predicate.Default, /* predicate */
809 false, /* torpedoable */
810 null_path, /* path */
813 false, /* latchData */
814 false, /* latchPath */
819 private static final Instruction TORPEDOABLE_RECV_DATA =
820 new Instruction.Move(dock,
821 Predicate.IgnoreFlagD, /* predicate */
822 true, /* torpedoable */
826 true, /* latchData */
827 false, /* latchPath */
832 private static final Instruction RECV_DATA =
833 new Instruction.Move(dock,
834 Predicate.IgnoreFlagD, /* predicate */
835 false, /* torpedoable */
839 true, /* latchData */
840 false, /* latchPath */
845 private static final Instruction SEND_TOKEN =
846 new Instruction.Move(dock,
847 Predicate.IgnoreFlagD, /* predicate */
848 false, /* torpedoable */
849 null_path, /* path */
852 false, /* latchData */
853 false, /* latchPath */
858 private static final Instruction RECV_TOKEN =
859 new Instruction.Move(dock,
860 Predicate.IgnoreFlagD, /* predicate */
861 false, /* torpedoable */
865 false, /* latchData */
866 false, /* latchPath */
872 private void expectNorthFifoNoMoreThan(int num) {
873 model.waitNS(128 * CYCLE_TIME_NS);
874 List<BitVector> dataItems = marina.data.drainMany(num+1);
875 fatal(dataItems.size()>num,
876 "Expected no more than "+num+
877 " data items to emerge but got at least: "+dataItems.size());
879 private void expectNorthFifoExactly(int num) {
880 model.waitNS(128 * CYCLE_TIME_NS);
881 List<BitVector> dataItems = marina.data.drainMany(num+1);
882 fatal(dataItems.size()!=num,
883 "Expected exactly "+num+
884 " data items to emerge but got at least: "+dataItems.size());
886 private void expectTokensNoMoreThan(int num) {
887 int x = marina.getNumTokens();
888 List<BitVector> dataItems = marina.data.drainMany(num+1);
890 "Expected no more than "+num+
891 " data items to emerge but got at least: "+x);
893 private void expectTokensExactly(int num) {
894 int x = marina.getNumTokens();
896 "Expected exactly "+num+
897 " data items to emerge but got at least: "+x);
900 private void testFlagDRecomputationTime(Marina marina) {
901 marina.instrIn.fill(setIlc(1));
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(setIlc(1));
941 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
943 marina.enableInstructionSend(false);
944 marina.enableInstructionRecirculate(true);
946 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
947 marina.instrIn.fill(new Instruction.Head(dock));
948 marina.instrIn.fill(SEND_DATA);
949 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
950 marina.instrIn.fill(SEND_TOKEN);
951 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
952 marina.instrIn.fill(new Instruction.Tail(dock));
953 marina.instrIn.fillTorpedo();
955 marina.enableInstructionRecirculate(false);
956 marina.enableInstructionSend(true);
957 marina.instrIn.run();
959 expectNorthFifoNoMoreThan(0);
960 prln("inserting into north proper stopper");
961 marina.fillNorthProperStopper();
962 expectNorthFifoExactly(1);
963 int nbToks = marina.getNumTokens();
964 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
967 private void testTailWithoutHead(Marina marina) {
968 marina.instrIn.fill(setIlc(1));
969 marina.fillSouthProperStopper(new Instruction[] {
970 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
971 new Instruction.Tail(dock),
974 List<BitVector> dataItems = marina.data.drainMany(1);
975 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
978 private void testHeadWaitsForTail(Marina marina) {
979 List<BitVector> dataItems;
981 prln("Begin testHeadWaitsForTail");
984 marina.instrIn.fill(setIlc(1));
985 marina.fillSouthProperStopper(new Instruction[] {
986 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
987 new Instruction.Head(dock),
988 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
991 dataItems = marina.data.drainMany(1);
992 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
993 marina.instrIn.fill(new Instruction.Tail(dock));
995 BitVector bv = marina.data.drain();
996 fatal(bv==null, "Expected at least one data item to emerge but got none");
999 prln("End testHeadWaitsForTail");
1002 private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) {
1003 marina.instrIn.fill(setIlc(1));
1004 marina.fillSouthProperStopper(new Instruction[] {
1005 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,3),
1006 new Instruction.Move(dock,
1007 Predicate.IgnoreFlagD, // predicate
1008 true, // torpedoable
1017 new Instruction.Move(dock,
1018 Predicate.FlagD, // predicate
1019 false, // torpedoable
1029 marina.instrIn.fillTorpedo();
1030 expectNorthFifoExactly(1);
1031 marina.fillSouthProperStopper(new Instruction[] {
1032 new Instruction.Move(dock,
1033 Predicate.Default, // predicate
1034 false, // torpedoable
1044 expectNorthFifoNoMoreThan(0);
1047 private void testAbort(Marina marina) {
1049 marina.instrIn.fill(setIlc(1));
1050 marina.fillSouthProperStopper(new Instruction[] {
1051 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1),
1052 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1053 SEND_DATA_IF_D_NOT_SET,
1054 new Instruction.Head(dock),
1055 SEND_DATA_IF_D_NOT_SET,
1056 new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2),
1057 new Instruction.Abort(dock, Predicate.FlagD),
1058 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement),
1059 new Instruction.Tail(dock),
1062 for(int i=0; i<4; i++) {
1065 model.waitNS(128 * CYCLE_TIME_NS);
1066 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1067 fatal(bv==null, "no data item found");
1068 prln("got " + bv.toLong());
1069 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1071 model.waitNS(128 * CYCLE_TIME_NS);
1072 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1073 fatal(bv==null, "no data item found");
1074 prln("got " + bv.toLong());
1075 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1077 model.waitNS(128 * CYCLE_TIME_NS);
1078 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1079 fatal(bv==null, "no data item found");
1080 prln("got " + bv.toLong());
1081 fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong());
1086 private void testAbortOutsideOfLoop(Marina marina) {
1087 marina.instrIn.fill(setIlc(1));
1088 marina.fillSouthProperStopper(new Instruction[] {
1089 // ensure that an abort doesn't cause problems if no loop is in progress
1090 new Instruction.Abort(dock, Predicate.IgnoreFlagD),
1093 expectNorthFifoExactly(1);
1096 private void testFlagAB(Marina marina) {
1097 prln("Begin testFlagAB");
1100 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1101 Instruction.Set.FlagFunction one = zero;
1104 // we should be able to use any pair of FlagX+NotFlagX,
1105 // but we toss them all in to maximize the chances of the
1106 // test passing (later we will try the individual
1107 // combinations to maximize the chances of failure).
1108 one = one.add(Predicate.FlagA);
1109 one = one.add(Predicate.NotFlagA);
1110 one = one.add(Predicate.FlagB);
1111 one = one.add(Predicate.NotFlagB);
1112 one = one.add(Predicate.FlagC);
1113 one = one.add(Predicate.NotFlagC);
1115 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1116 for(boolean fast : new boolean[] { true, false }) {
1117 // clear the flags to a known state, then check both 0->1 and 1->0 transitions
1118 for(boolean b : new boolean[] { false, true, false }) {
1119 prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
1120 prln((b?"Setting":"Clearing")+" flags");
1122 Instruction inst = new Instruction.Set(dock,Predicate.IgnoreFlagD,
1127 marina.fillSouthProperStopper(new Instruction[] {
1132 model.waitNS(64 * CYCLE_TIME_NS);
1133 marina.fillNorthProperStopper();
1135 marina.instrIn.fill(inst);
1138 fatal(marina.getFlagA()!=b,
1139 "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
1140 fatal(marina.getFlagB()!=b,
1141 "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
1146 prln("End testFlagAB");
1150 * WARNING: this is a very, very, very long test case -- it goes
1151 * through 216 iterations.
1153 private void testFlagTruthTable(Marina marina) {
1154 prln("Begin testFlagTruthTable");
1157 marina.instrIn.fill(setIlc(1));
1158 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1159 Instruction.Set.FlagFunction one = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
1161 for(Predicate a_input : new Predicate[] { null, Predicate.FlagA, Predicate.NotFlagA })
1162 for(Predicate b_input : new Predicate[] { null, Predicate.FlagB, Predicate.NotFlagB })
1163 for(Predicate c_input : new Predicate[] { null, Predicate.FlagC, Predicate.NotFlagC })
1164 for(boolean a_state : new boolean[] { false, true })
1165 for(boolean b_state : new boolean[] { false, true })
1166 for(boolean c_state : new boolean[] { false, true }) {
1167 for(boolean which : new boolean[] { false, true }) {
1169 prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
1170 // set A,B flags to a_state and b_state
1171 marina.instrIn.fill(new
1172 Instruction.Set(dock,Predicate.IgnoreFlagD,
1173 a_state ? one : zero,
1174 b_state ? one : zero
1177 // set C flag to c_state
1178 BitVector data = new BitVector(37, "empty");
1179 BitVector addr = new BitVector(14, "empty");
1180 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1181 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1182 addr.set(Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
1183 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1184 marina.instrIn.fill(RECV_DATA);
1186 Instruction.Set.FlagFunction func = zero;
1187 if (a_input!=null) func = func.add(a_input);
1188 if (b_input!=null) func = func.add(b_input);
1189 if (c_input!=null) func = func.add(c_input);
1191 Instruction inst = new
1192 Instruction.Set(dock,Predicate.IgnoreFlagD,
1193 !which ? func : zero.add(Predicate.FlagA),
1194 which ? func : zero.add(Predicate.FlagB)
1197 marina.instrIn.fill(inst);
1199 boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
1200 boolean expected_b = which ? func.evaluate(a_state, b_state, c_state, false) : b_state;
1201 fatal(expected_a != marina.getFlagA(),
1202 "expected A="+expected_a+", but got "+marina.getFlagA());
1203 fatal(expected_b != marina.getFlagB(),
1204 "expected B="+expected_b+", but got "+marina.getFlagB());
1208 prln("End testFlagTruthTable");
1211 private void recvData(Marina marina) {
1212 prln("Begin recvData");
1215 marina.instrIn.fill(setIlc(1));
1216 marina.fillSouthProperStopper(new Instruction[] {
1217 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1218 new Instruction.Move(dock,
1219 Predicate.IgnoreFlagD, // predicate
1220 false, // torpedoable
1229 new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG),
1231 model.waitNS(64 * CYCLE_TIME_NS);
1233 prln("checking to confirm that A flag is cleared");
1234 fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1236 prln("inserting data item in north fifo ring");
1237 BitVector data = new BitVector(37, "empty");
1238 BitVector addr = new BitVector(14, "empty");
1239 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1240 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1241 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1242 model.waitNS(64 * CYCLE_TIME_NS);
1244 prln("checking to see if A flag got set");
1245 fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1248 prln("End recvData");
1252 private void testRecvAndSendWalkingOne(Marina marina) {
1253 prln("Begin testRecvAndSendWalkingOne");
1256 marina.instrIn.fill(setIlc(1));
1258 List<BitVector> dataItems;
1259 for(int bit=0; bit<37; bit++) {
1261 BitVector data = new BitVector(37, "empty");
1262 BitVector addr = new BitVector(14, "empty");
1263 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1264 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1265 data.set(bit, true);
1266 prln("testing with bit pattern " + data);
1268 prln("inserting data item into north fifo ring");
1269 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1271 prln("stopping the north proper stopper");
1274 dataItems = marina.data.drainMany(1);
1275 fatal(dataItems.size()!=0,
1276 "found a data item waiting in the north proper stopper, but should not have");
1278 marina.instrIn.fill(new Instruction.Move(dock,
1279 Predicate.IgnoreFlagD, // predicate
1280 false, // torpedoable
1290 dataItems = marina.data.drainMany(2);
1291 fatal(dataItems.size()!=1,
1292 "found "+dataItems.size()+" data items in north fifo; expected one");
1293 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1294 fatalIfBitVectorsDoNotMatch(mp.data, data);
1298 prln("End testRecvAndSendWalkingOne");
1303 private void setOlcFromDataLatch(Marina marina) {
1304 prln("Begin setOlcFromDataLatch");
1307 marina.instrIn.fill(setIlc(1));
1309 // walk a bit from 0 to 5
1310 for(int bit=0; bit<6; bit++) {
1311 prln("inserting data item in north fifo ring");
1312 BitVector data = new BitVector(37, "empty");
1313 BitVector addr = new BitVector(14, "empty");
1314 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1315 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1316 data.set(bit, true);
1317 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1319 marina.fillSouthProperStopper(new Instruction[] {
1321 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch)
1324 int olc = marina.getOLC();
1325 fatal(olc != (1<<bit), "expected olc to be " + (1<<bit) + ", but got " + olc);
1329 prln("End setOlcFromDataLatch");
1332 private void setIlcFromDataLatch(Marina marina) {
1333 prln("Begin setIlcFromDataLatch");
1336 marina.instrIn.fill(setIlc(1));
1338 // walk a bit from 0 to 5
1339 for(int bit=5; bit>=0; bit--) {
1340 prln("inserting data item in north fifo ring");
1341 BitVector data = new BitVector(37, "empty");
1342 BitVector addr = new BitVector(14, "empty");
1343 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1344 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1345 data.set(bit, true);
1346 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1348 marina.fillSouthProperStopper(new Instruction[] {
1349 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1351 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch),
1353 model.waitNS(CYCLE_TIME_NS * 64);
1355 int ilc = marina.getILC().getCount();
1356 fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc);
1360 prln("End setIlcFromDataLatch");
1363 private void testSendAndRecvToken(Marina marina) {
1364 prln("Begin testSendAndRecvToken");
1367 marina.instrIn.fill(setIlc(1));
1368 marina.fillSouthProperStopper(new Instruction[] {
1373 List<BitVector> dataItems = marina.data.drainMany(3);
1374 fatal(dataItems.size()!=1,
1375 "expected exactly one data item, got " + dataItems.size());
1378 prln("End testSendAndRecvToken");
1381 private void testSignExtendedLiteral(Marina marina) {
1382 prln("Begin testSignExtendedLiteral");
1385 marina.instrIn.fill(setIlc(1));
1386 for(long val : new long[] { (-1L << 14), -1, 0, 1 }) {
1388 marina.fillSouthProperStopper(new Instruction[] {
1389 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1390 Instruction.Set.SetDest.DataLatch,
1395 List<BitVector> dataItems = marina.data.drainMany(3);
1396 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1398 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1399 BitVector bv = mp.data;
1400 prln("got back " + mp);
1402 boolean mismatch = false;
1404 for(int i=0; i<37; i++) {
1405 if (bv.get(i) != ( (val & (1L << i)) != 0 )) {
1410 fatal(mismatch, "data read back did not match inserted literal; mismatch on bits " + err);
1414 prln("End testSignExtendedLiteral");
1417 private void testShiftedLiteral(Marina marina) {
1418 prln("Begin testShiftedLiteral");
1421 marina.instrIn.fill(setIlc(1));
1422 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
1423 Instruction.Set.SetDest.DataLatch,
1426 BitVector dreg = new BitVector(37, "what we think is in the d-register");
1427 for(int i=0; i<37; i++) dreg.set(i, false);
1429 for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
1431 edu.berkeley.fleet.api.BitVector immediate =
1432 new edu.berkeley.fleet.api.BitVector(19);
1433 for(int i=0; i<immediate.length(); i++)
1434 immediate.set(i, (val & (1L << i)) != 0);
1436 // shift over 19 LSB's towards MSB
1437 for(int i=0; i<19; i++)
1438 if (i+19 <= 36) dreg.set(i+19, dreg.get(i));
1439 for(int i=0; i<19; i++)
1440 dreg.set(i, immediate.get(i));
1442 marina.fillSouthProperStopper(new Instruction[] {
1443 new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate),
1447 List<BitVector> dataItems = marina.data.drainMany(3);
1448 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1450 BitVector bv = new MarinaPacket(dataItems.get(0)).data;
1451 fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" +
1452 "got: "+bv.bitReverse().getState()+"\n"+
1453 "expected:"+dreg.bitReverse().getState());
1457 prln("End testShiftedLiteral");
1460 private void testFlagC(Marina marina) {
1461 prln("Begin testFlagC");
1469 // Dc=1 => sigS is copied into C-flag
1470 // Dc=0 => sigA is copied into C-flag
1472 marina.instrIn.fill(setIlc(1));
1473 for(boolean dc : new boolean[] { false, true }) {
1474 for(boolean c_flag : new boolean[] { true, false, true }) {
1477 prln("****** checking case where dc="+dc+", cflag="+c_flag);
1478 BitVector data = new BitVector(37, "empty");
1479 BitVector addr = new BitVector(14, "empty");
1480 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1481 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1484 ? Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
1485 : Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
1486 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
1487 addr.set(whichbit, c_flag);
1489 prln("... and filling north fifo proper stopper");
1490 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1492 prln("clearing flags");
1493 prln("executing recv data with Dc="+dc);
1494 prln("copying c-flag to a-flag");
1495 marina.fillSouthProperStopper(new Instruction[] {
1496 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1497 new Instruction.Move(dock,
1498 Predicate.IgnoreFlagD, /* predicate */
1499 true, /* torpedoable */
1501 false, /* tokenIn */
1504 false, /* latchPath */
1505 false, /* dataOut */
1506 false /* tokenOut */
1508 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1509 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
1514 model.waitNS(CYCLE_TIME_NS * 64);
1516 prln("checking to confirm that A flag is " + c_flag);
1517 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
1521 prln("End testFlagC");
1524 private void sendDataWithPath(Marina marina) {
1525 prln("Begin sendDataWithPath");
1528 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
1529 marina.instrIn.fill(setIlc(1));
1531 // alternating ones and zeroes
1532 for(int i=0; i<bv.length(); i+=2)
1534 // and then ones in the lower four bits so it's not symmetric
1535 for(int i=0; i<4; i++)
1538 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
1540 marina.fillSouthProperStopper(new Instruction[] {
1541 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1542 new Instruction.Move(dock,
1543 Predicate.IgnoreFlagD, /* predicate */
1544 false, /* torpedoable */
1546 false, /* tokenIn */
1548 false, /* latchData */
1549 false, /* latchPath */
1551 false /* tokenOut */
1555 List<BitVector> dataItems;
1558 dataItems = marina.data.drainMany();
1559 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1560 mp = new MarinaPacket(dataItems.get(0));
1562 // the 14th bit of the outbound address cannot be set by the
1563 // ship, so we don't care about it
1564 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1566 prln("send data with no change to path");
1567 marina.instrIn.fill(new Instruction.Move(dock,
1568 Predicate.IgnoreFlagD, /* predicate */
1569 false, /* torpedoable */
1571 false, /* tokenIn */
1573 false, /* latchData */
1574 false, /* latchPath */
1576 false /* tokenOut */
1579 dataItems = marina.data.drainMany();
1580 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1581 mp = new MarinaPacket(dataItems.get(0));
1583 // the 14th bit of the outbound address cannot be set by the
1584 // ship, so we don't care about it
1585 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1588 prln("End sendDataWithPath");
1591 private void recvPath(Marina marina) {
1592 prln("Begin recvPath");
1595 marina.instrIn.fill(setIlc(1));
1596 for(int bit=0; bit<11; bit++) {
1597 BitVector packet_data = new BitVector(37, "inbound data item");
1598 for(int i=0; i<37; i++) packet_data.set(i, false);
1599 packet_data.set(27+bit, true);
1600 BitVector packet_path = new BitVector(14, "inbound data item");
1601 for(int i=0; i<14; i++) packet_path.set(i, false);
1603 marina.fillNorthProperStopper(new MarinaPacket(packet_data, false, packet_path));
1605 prln("recv path, send data (using recv'd path)");
1606 marina.instrIn.fill(new Instruction.Move(dock,
1607 Predicate.IgnoreFlagD, /* predicate */
1608 false, /* torpedoable */
1610 false, /* tokenIn */
1612 true, /* latchData */
1613 true, /* latchPath */
1615 false /* tokenOut */
1618 List<BitVector> dataItems = marina.data.drainMany();
1619 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1620 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1622 fatalIfBitVectorsDoNotMatch(packet_data.get(25,11), mp.path.get(0,11));
1623 fatalIfBitVectorsDoNotMatch(packet_data, mp.data);
1627 prln("End recvPath");
1630 private void testILC(Marina marina) {
1631 prln("Begin testILC");
1634 for(int bit=0; bit<6; bit++) {
1635 int ilc = bit<0 ? 0 : (1<<bit);
1636 marina.fillSouthProperStopper(new Instruction[] {
1637 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc),
1640 List<BitVector> dataItems = marina.data.drainMany();
1641 fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
1645 prln("End testILC");
1648 private void testILCZero(Marina marina) {
1650 marina.fillSouthProperStopper(new Instruction[] {
1651 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0),
1655 expectNorthFifoNoMoreThan(0);
1656 expectTokensExactly(1);
1660 private void sendTorpedo(Marina marina) {
1661 prln("Begin sendTorpedo");
1663 marina.instrIn.fill(setIlc(1));
1664 marina.instrIn.fill(new
1665 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
1666 int olc = marina.getOLC();
1667 fatal(olc!=1, "bad OLC: "+olc+" expected: 1");
1668 marina.instrIn.fill(new
1669 Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1670 fatal(marina.getFlagA(), "bad A flag: true");
1671 fatal(marina.getFlagB(), "bad B flag: true");
1673 prln("execute a move instruction that does nothing but loops until torpedo arrives");
1674 prln("A=1, B=B This instruction should not execute because D-flag is set");
1675 prln("Set A=A, B=1 This instruction should execute because D-flag is set");
1676 marina.fillSouthProperStopper(new Instruction[] {
1677 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity),
1678 new Instruction.Move(dock,
1679 Predicate.IgnoreFlagD, // predicate
1680 true, // torpedoable
1689 new Instruction.Set(dock,Predicate.Default,
1691 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB)
1693 new Instruction.Set(dock, Predicate.FlagD,
1694 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA),
1699 prln("send torpedo. This should clear the OLC");
1700 marina.instrIn.fillTorpedo();
1701 model.waitNS(64 * CYCLE_TIME_NS);
1703 prln("A should remain false, B should be true");
1704 fatal(marina.getFlagA(), "bad A flag: true");
1705 fatal(!marina.getFlagB(), "bad B flag: false");
1707 prln("OLC = 63. Reload OLC after torpedo, clears D-flag");
1708 marina.instrIn.fill(new
1709 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1711 olc = marina.getOLC();
1712 fatal(olc!=63, "bad OLC: "+olc+" expected: 63");
1714 prln("Set A=1, B=1 This instruction should execute because OLC!=0");
1715 marina.instrIn.fill(new
1716 Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
1718 prln("A and B should be true");
1719 fatal(!marina.getFlagA(), "bad A flag: false");
1720 fatal(!marina.getFlagB(), "bad B flag: false");
1723 prln("End sendTorpedo");
1726 private void testTorpedoOnAnInfinite(Marina marina) {
1727 prln("Begin testTorpedoOnAnInfinite");
1730 List<BitVector> dataItems;
1732 marina.instrIn.fill(setIlc(1));
1733 for(boolean torpedoable : new boolean[] { true, false }) {
1735 marina.fillSouthProperStopper(new Instruction[] {
1736 new Instruction.Move(dock,
1737 Predicate.IgnoreFlagD, // predicate
1738 false, // torpedoable
1747 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
1748 new Instruction.Move(dock,
1749 Predicate.IgnoreFlagD, // predicate
1750 torpedoable, // torpedoable
1759 // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior
1760 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1765 // expect nothing to come out, because the NOP is executing
1766 dataItems = marina.data.drainMany(2);
1767 fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
1769 marina.instrIn.fillTorpedo();
1771 int expected = torpedoable?1:0;
1772 dataItems = marina.data.drainMany(2);
1773 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1775 fatal(!marina.getILC().getDone(), "Expected ilc=done, but got "+marina.getILC());
1779 prln("End testTorpedoOnAnInfinite");
1782 private void testOlcDecrementAtHighSpeed(Marina marina) {
1783 prln("Begin testOlcDecrementAtHighSpeed");
1786 List<BitVector> dataItems;
1788 // Each element of the following pair of arrays is one "test".
1789 // The OLC will be loaded with olcs[i] and then decremented
1790 // decr_amounts[i] times; after that has happened the zeroness
1791 // of the OLC will be checked by executing a MOVE with
1792 // [olc!=0] as the predicate.
1794 int[] olcs = new int[] { 3, 3, 3, 10, 41 };
1795 int[] decr_amounts = new int[] { 2, 3, 4, 9, 9 };
1797 for(int which=0; which<olcs.length; which++) {
1798 int olc = olcs[which];
1799 int decr_amount = decr_amounts[which];
1801 prln("inserting set olc="+olc);
1802 prln("inserting set ilc=1");
1803 marina.fillSouthProperStopper(new Instruction[] {
1804 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1805 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc),
1808 // commenting the following four lines causes this test to pass
1810 prln("inserting: "+decr_amount+" olc-- instructions");
1811 prln("inserting: [!d] send data");
1812 Instruction[] instructions = new Instruction[decr_amount+1];
1813 for(int i=0; i<decr_amount; i++)
1815 new Instruction.Set(dock,
1816 Predicate.IgnoreFlagD,
1817 SetDest.OuterLoopCounter,
1818 SetSource.Decrement);
1819 instructions[instructions.length-1] =
1820 new Instruction.Move(dock,
1821 Predicate.Default, // predicate
1822 false, // torpedoable
1831 marina.fillSouthProperStopper(instructions);
1832 model.waitNS(64 * CYCLE_TIME_NS);
1834 int expected = decr_amount>=olc ? 0 : 1;
1835 dataItems = marina.data.drainMany(2);
1836 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
1840 prln("End testOlcDecrementAtHighSpeed");
1843 private void flipIlcBit(Marina marina) {
1844 prln("Begin flipIlcBit");
1846 prln("Using the set ILC instruction, toggle a single bit between zero and one. \n" +
1847 "Check correct setting of the ILC zero bit");
1849 for (int i=0; i<6; i++) {
1852 prln("Then immediately set ILC="+notZero);
1853 marina.fillSouthProperStopper(new Instruction[] {
1854 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
1855 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
1858 prln("Verify ILC using scan chain");
1859 Ilc ilc = marina.getILC();
1860 int ilcCount = ilc.getCount();
1861 fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
1862 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
1864 marina.fillSouthProperStopper(new Instruction[] {
1865 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
1866 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
1869 prln("Verify ILC using scan chain");
1870 ilc = marina.getILC();
1871 ilcCount = ilc.getCount();
1872 fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
1873 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
1877 prln("End flipIlcBit");
1879 private void flipOlcBit(Marina marina) {
1880 prln("Begin flipOlcBit");
1882 prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
1883 "Check correct setting of the OLC zero bit");
1885 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1887 for (int i=0; i<6; i++) {
1888 int notZero = 32 >> i;
1890 prln("Then immediately set OLC="+notZero);
1891 marina.fillSouthProperStopper(new Instruction[] {
1892 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
1893 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
1896 prln("Verify OLC count using scan chain");
1897 int outOlc = marina.getOLC();
1898 fatal(outOlc!=notZero, "bad OLC count: "+outOlc+" expected: "+notZero);
1900 prln("Set OLC="+notZero);
1901 prln("Then immediately set OLC=0");
1902 marina.fillSouthProperStopper(new Instruction[] {
1903 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
1904 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
1907 prln("Verify OLC count using scan chain");
1908 outOlc = marina.getOLC();
1909 fatal(outOlc!=0, "bad OLC count: "+outOlc+" expected: 0");
1913 prln("End flipOlcBit");
1915 private void testSouthRecirculate(Marina marina, int AMOUNT) {
1916 prln("Begin testSouthRecirculate("+AMOUNT+")");
1919 marina.enableInstructionSend(false);
1920 marina.enableInstructionRecirculate(true);
1922 prln("Completely fill south ring");
1924 for (int i=0; i<AMOUNT; i++) {
1925 prln("inserting item " + (i+1) + " / " + AMOUNT);
1926 BitVector path = new BitVector(MarinaPacket.PATH_WIDTH, "path");
1927 BitVector data = new BitVector(MarinaPacket.WORD_WIDTH, "path");
1928 path.set(0, MarinaPacket.PATH_WIDTH, false);
1929 data.setFromLong(i+9);
1930 marina.instrIn.fill(new MarinaPacket(data, false, path));
1934 prln("Drain south ring and check contents");
1936 List<BitVector> out = marina.instrIn.drainMany();
1937 boolean bad = false;
1938 for (int i=0; i<AMOUNT; i++) {
1939 prln("extracting item " + (i+1) + " / " + AMOUNT);
1940 //int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
1942 long got = new MarinaPacket(out.get(i)).data.toLong();
1945 prln(" bad instruction: "+got+" expected: "+expect);
1947 prln(" good instruction.");
1950 fatal(bad, "data inserted does not match data retrieved");
1953 for (int i=0; i<5; i++) {}
1956 prln("End testSouthRecirculate("+AMOUNT+")");
1958 private void doOneTest(int testNum) {
1960 prln("============================================================");
1961 prln("MarinaTest: performing test: "+testNum);
1963 marina.masterClear();
1964 marina.enableInstructionSend(true);
1971 // these tests run fairly quickly
1972 doOneTest(1); // passes extracted parasitics
1973 doOneTest(2); // passes extracted parasitics
1974 doOneTest(3); // passes extracted parasitics
1975 doOneTest(4); // passes extracted parasitics
1976 doOneTest(5); // passes extracted parasitics
1977 doOneTest(6); // passes extracted parasitics
1978 doOneTest(1000); // passes extracted parasitics
1979 doOneTest(1001); // passes extracted parasitics
1980 doOneTest(1003); // passes extracted parasitics
1981 doOneTest(3000); // passes extracted parasitics
1982 doOneTest(3001); // passes extracted parasitics
1983 doOneTest(3003); // passes extracted parasitics
1984 doOneTest(3004); // passes extracted parasitics
1985 doOneTest(3005); // passes extracted parasitics
1986 doOneTest(3006); // passes extracted parasitics
1987 doOneTest(3007); // passes extracted parasitics
1988 doOneTest(3008); // passes extracted parasitics
1989 doOneTest(3009); // fails extracted parasitics
1990 doOneTest(3010); // passes extracted parasitics
1991 doOneTest(3011); // passes extracted parasitics
1992 doOneTest(3012); // passes extracted parasitics
1993 doOneTest(3013); // passes extracted parasitics
1994 doOneTest(3014); // passes extracted parasitics
1995 doOneTest(3015); // fails extracted parasitics
1996 doOneTest(3019); // fails extracted parasitics
1997 doOneTest(3020); // passes extracted parasitics
1998 doOneTest(3022); // passes extracted parasitics
1999 doOneTest(3023); // passes extracted parasitics
2000 doOneTest(3026); // passes extracted parasitics
2001 doOneTest(3027); // passes extracted parasitics
2002 doOneTest(3028); // passes extracted parasitics
2004 // these tests take a while and usually pass
2015 // this takes an insanely long time
2020 case 1: testChains(marina); break; // passes, 24-Mar (+verilog)
2021 case 2: testProperStoppers(marina); break; // passes, 24-Mar (+verilog)
2022 case 3: testSouthRecirculate(marina, 1); break; // passes, 24-Mar (+verilog)
2023 case 4: getCtrsFlags(marina); break; // 20-Apr (+verilog)
2024 case 5: sendInstructions(marina); break; // passes, 24-Mar (+verilog)
2025 case 6: walkOneOLC(marina); break; // 21-Apr (+verilog)
2027 // Russell's tests begin with 1000
2028 case 1000: walkOneILC(marina); break; // 20-Apr (+verilog)
2029 case 1001: countIlc(marina); break; // 20-Apr (+verilog)
2030 case 1002: countOlc(marina); break; // 23-Apr (+verilog)
2032 case 1003: sendTorpedo(marina); break; // 23-Apr (+verilog) [with wor-hack]
2034 case 1004: flipIlcBit(marina); break; // 20-Apr (+verilog)
2035 case 1005: flipOlcBit(marina); break; // 21-Apr (+verilog)
2037 case 1006: testSouthRecirculate(marina, Marina.SOUTH_RING_CAPACITY-1); break; // passes, 24-Mar (+verilog)
2039 // Adam's tests begin with 3000
2040 case 3000: sendToken(marina); break; // passes, 24-Mar (+verilog)
2041 case 3001: testFlagAB(marina); break; // passes, 08-Apr (+verilog)
2042 case 3002: testPredicationOnAB(marina); break; // 22-Apr (+verilog)
2043 case 3003: testFlagC(marina); break; // 23-Apr (+verilog)
2044 case 3004: testFlagD(marina); break; // 23-Apr (+verilog)
2045 case 3005: testFlagDRecomputationTime(marina); break;
2047 case 3006: testTailWaitsForHead(marina); break;
2048 case 3007: testTailWithoutHead(marina); break;
2049 case 3008: testHeadWaitsForTail(marina); break; // 22-Apr (+verilog)
2050 case 3009: testAbort(marina); break; // 22-Apr (+verilog)
2052 case 3010: sendData(marina); break; // passes, 24-Mar (+verilog)
2053 case 3011: recvData(marina); break; // 21-Apr (+verilog)
2054 case 3012: sendDataWithPath(marina); break; // passes, 13-Apr (+verilog)
2056 case 3013: testSignExtendedLiteral(marina); break; // 20-Apr (+verilog)
2057 case 3014: testShiftedLiteral(marina); break; // 20-Apr (+verilog)
2058 case 3015: testSendAndRecvToken(marina); break; // 21-Apr (+verilog)
2060 case 3016: sendDataIlcInfinite(marina); break; // 22-Apr (+verilog)
2061 case 3017: testFlagTruthTable(marina); break; // 23-Apr (+verilog)
2063 case 3019: setOlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2064 case 3020: setIlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2065 case 3021: recvPath(marina); break; // 22-Apr (+verilog)
2066 case 3022: testILC(marina); break; // 23-Apr (+verilog)
2067 case 3023: testTorpedoOnAnInfinite(marina); break; // 23-Apr (+verilog)
2068 case 3024: testRecvAndSendWalkingOne(marina); break; // 21-Apr (+verilog)
2069 case 3025: testOlcDecrementAtHighSpeed(marina); break; // 23-Apr (+verilog)
2071 case 3026: testNonTorpedoableMoveDoesNotResetDFlag(marina); break; // 23-Apr (+verilog)
2072 case 3027: testILCZero(marina); break;
2073 case 3028: testAbortOutsideOfLoop(marina); break;
2076 fatal(true, "Test number: "+testNum+" doesn't exist.");
2079 // If we get here then test passed
2080 prln("Test Result: Passed");
2082 //Infrastructure.exit(0);
2083 } catch (MarinaUtils.FailureException fe) {
2084 fe.printStackTrace();
2089 //============================ for public use =============================
2092 * 0: test detected success
2093 * 2: test detected failure
2096 public static void main(String[] args) {
2097 startTime = System.currentTimeMillis();
2098 new MarinaTest(args);