1 package edu.berkeley.fleet.marina;
2 /* -*- tab-width: 4 -*- */
3 import java.util.ArrayList;
6 import com.sun.electric.tool.simulation.test.*;
7 import edu.berkeley.fleet.marina.CmdArgs;
8 import edu.berkeley.fleet.marina.CmdArgs.Mode;
10 import edu.berkeley.fleet.api.Dock;
11 import edu.berkeley.fleet.api.Instruction;
12 import edu.berkeley.fleet.api.Predicate;
13 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
14 import edu.berkeley.fleet.api.Instruction.Set.SetSource;
15 import edu.berkeley.fleet.marina.MarinaFleet;
16 import edu.berkeley.fleet.marina.MarinaPath;
23 public class MarinaTest {
24 public static final MarinaFleet marinaFleet = new MarinaFleet();
25 public static final Dock dock = marinaFleet.getOnlyInputDock();
27 public static float vdd = 1.0f;
29 //-------------------------- constants -----------------------------------
30 private static final String SCAN_CHAIN_XML = "marina.xml";
31 private static final String NET_LIST = "marina.spi";
33 public static final int INSTR_SZ = 36;
36 public static final Instruction.Set.FlagFunction CLEAR_FLAG
37 = Instruction.Set.FlagFunction.ZERO;
38 public static final Instruction.Set.FlagFunction SET_FLAG
39 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA)
40 .add(Predicate.NotFlagA);
41 public static final Instruction.Set.FlagFunction A_FLAG
42 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA);
44 public static final Instruction.Set.FlagFunction B_FLAG
45 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB);
47 // COLUMN_LATENCY is a delay that is larger than the latency through an Infinity column
48 private static final int COLUMN_LATENCY = 10; // nanoseconds
51 // Officially, this should be the number of requeueing no-ops that
52 // can be inserted into an idle dock whose OLC is nonzero.
54 // Less formally, this is roughly the number of stages of
55 // buffering between the instruction insertion point and the
56 // instruction ring, plus the capacity of the instruction ring.
57 private static final int INSTRUCTION_IN_SATURATION_AMOUNT = 19;
59 // This is some number which is significantly greater than
60 // INSTRUCTION_IN_SATURATION_AMOUNT. Increasing it may slow the tests down, but
61 // will never cause them to operate incorrectly.
62 private static final int MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT = 25;
64 // This is the number of items which can be in the instruction
65 // fifo ring WITHOUT causing it to stop circulating.
66 private static final int INSTRUCTION_RING_CAPACITY = 13;
68 // Officially, this should be the number of data items which can
69 // be sent from the dock while the "data" proper stopper is in
70 // the "stopped" state
72 // Less formally, this is roughly the number of stages of
73 // buffering between the dock's data successor and the "data"
76 FIXME: what is the correct value here?
77 private static final int DATA_OUT_SATURATION_AMOUNT = XXX;
80 // This is some number which is greater than
81 // DATA_OUT_SATURATION_AMOUNT, but less than the capacity of the
83 private static final int MORE_THAN_DATA_OUT_SATURATION_AMOUNT = 10;
85 // Nominal cycle time assuming 4 GHz throughput
86 public static double CYCLE_TIME_NS;
88 //-------------------------------- types ---------------------------------
90 //-------------------------- private data --------------------------------
91 private static long startTime;
93 public static Indenter indenter = new Indenter();
94 private Marina marina;
95 private ChipModel model;
96 //private ChainControl cc;
97 //private JtagTester tester;
98 private CmdArgs cmdArgs;
99 private PowerChannel corePowerSupply, padsPowerSupply;
100 private VoltageReadable coreVoltmeter, voltmeterForCurrent;
104 private ChainTest ctD, ctR, ctC, ct;
105 private ChainControl ccD, ccR, ccC, cc;
107 //-------------------------- private methods -----------------------------
108 /** @return true if simulation. Return false if we're testing silicon. */
109 private boolean sim() {return model instanceof SimulationModel;}
111 private void prln(String msg) {indenter.prln(msg);}
112 private void pr(String msg) {indenter.pr(msg);}
113 private void adjustIndent(int n) {indenter.adjustIndent(n);}
115 public static void fatal(boolean pred, String msg) { MarinaUtils.fatal(pred, msg); }
117 public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
118 // FIXME: better error reporting needed here
120 fatal(bv1.getNumBits()!=bv2.getNumBits(), "lengths do not match");
122 boolean mismatch = false;
124 for(int i=0; i<bv1.getNumBits(); i++) {
125 if (bv1.get(i) != bv2.get(i)) {
130 fatal(mismatch, "bit vectors do not match on bits " + err + "\n "+bv1+"\n "+bv2);
133 private static void printTestTime() {
134 long endTime = System.currentTimeMillis();
135 System.out.println("Test took: "+(endTime-startTime)/1000.0+" sec");
138 // Tell user what we're about to do
139 private static void reportTask(CmdArgs args) {
140 System.out.println("Begin testing Marina");
142 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
143 System.out.println(" Simulate whole chip, schematic parasitics");
145 case WHOLE_CHIP_LAYOUT_PARASITICS:
146 System.out.println(" Simulate whole chip, layout parasitics");
149 System.out.println(" Test silicon");
152 fatal(true, "unrecognized CmdArgs.Mode");
157 private MarinaTest(String[] args) throws Exception {
158 cmdArgs = new CmdArgs(args);
163 static PowerChannel vdd18;
164 static PowerChannel vdd10;
165 static PowerChannel vdds;
167 private void setVdd10(float v) {
168 if (vdd10==null) return;
169 vdd10.setVoltageWait(v);
172 private void doSim() throws Exception {
174 switch (cmdArgs.mode) {
175 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
176 netListName = NET_LIST;
178 case WHOLE_CHIP_LAYOUT_PARASITICS:
179 netListName = "marina_pads_guts.spi";
182 fatal(true, "unrecognized CmdArgs.Mode");
187 Infrastructure.gpibControllers = new int[]{1};
188 vdd18 = new Pst3202Channel("ch1", "tiPST3202", 1);
189 vdd18 = new Pst3202Channel("ch3", "tiPST3202", 3);
190 vdd10 = new PowerChannelResistorVoltageReadable(new Pst3202Channel("ch2", "tiPST3202", 2),
192 new HP34401A("HP34970"),
195 if (vdd10!=null) setVdd10(vdd);
196 if (vdd18!=null) vdd18.setVoltageNoWait(1.8f);
198 model = cmdArgs.useVerilog
204 : new NanosimModel();
206 if (model instanceof SimulationModel)
207 ((SimulationModel)model).setOptimizedDirectReadsWrites(true);
209 CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250;
211 model instanceof VerilogModel
215 : model instanceof ChipModel
219 System.err.println("constructing jtag controller");
221 model instanceof SimulationModel
222 ? ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO")
223 : new Netscan("jtag2");
224 //: new Netscan("10.0.0.200");
225 //: new Signalyzer();
226 //: new Netscan("jtag2");
227 JtagLogicLevel mc0=null;
228 JtagLogicLevel mc1=null;
229 if (tester instanceof NetscanGeneric) {
230 ((NetscanGeneric)tester).reset();
232 // not sure if "GPIO1" means "index 0" or not
233 mc0 = new JtagLogicLevel(tester, 0);
234 mc1 = new JtagLogicLevel(tester, 1);
236 mc0.setLogicState(true);
237 mc1.setLogicState(true);
240 Logger.setLogInits(true);
241 tester.setLogSets(true);
242 tester.setLogOthers(true);
243 tester.setAllLogging(true);
244 tester.printInfo = true;
246 tester.printInfo = false;
248 PowerChannel pc = new ManualPowerChannel("pc", false);
250 JtagTester testerD, testerR, testerC;
251 testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null);
252 testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null);
253 testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null);
254 testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
256 ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
257 ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
258 ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
259 ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
262 ctD = new ChainTest(ccD, pc);
263 ctR = new ChainTest(ccR, pc);
264 ctC = new ChainTest(ccC, pc);
267 ccs.addChain(Marina.DATA_CHAIN, ccD);
268 ccs.addChain(Marina.REPORT_CHAIN, ccR);
269 ccs.addChain(Marina.CONTROL_CHAIN, ccC);
272 PowerChannel ch2 = new Pst3202Channel("ch2", "tiPST3202", 2);
273 PowerChannel ch3 = new Pst3202Channel("ch3", "tiPST3202", 3);
274 Infrastructure.gpibControllers = new int[]{1};
275 ch2.setVoltageNoWait(1f);
276 ch3.setVoltageNoWait(1.8f);
280 cc = new ChainControl(SCAN_CHAIN_XML, tester, 1.8f, khz);
281 cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
282 ct = new ChainTest(cc, pc);
284 marina = new Marina(cc, cc, cc, cc, model, !cmdArgs.jtagShift, indenter);
288 if (model instanceof NanosimModel) {
289 NanosimLogicSettable mc = (NanosimLogicSettable)
290 ((SimulationModel)model).createLogicSettable(Marina.MASTER_CLEAR);
291 mc.setInitState(true);
294 prln("starting model");
295 if (model instanceof VerilogModel)
296 ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift);
297 else if (model instanceof HsimModel)
298 ((SimulationModel)model).start("hsim64", netListName, 0, !cmdArgs.jtagShift);
299 else if (model instanceof NanosimModel)
300 ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
303 prln("model started");
306 prln("deasserting master clear");
307 if (model instanceof SimulationModel)
308 ((SimulationModel)model).setNodeState(Marina.MASTER_CLEAR, 0);
310 marina.masterClear();
313 if (cmdArgs.testNum!=0 && cmdArgs.testNum!=1) {
315 cc.shift(Marina.CONTROL_CHAIN, false, true);
318 doOneTest(cmdArgs.testNum);
320 if (model instanceof SimulationModel)
321 ((SimulationModel)model).finish();
324 /** In the absence of looping, the longest path through Infinity is 4 column delays */
325 private void waitUntilQuiescent() {
326 model.waitNS(4*COLUMN_LATENCY);
330 /** Generate List of BitVectors where Token=true, high 25 data bits
331 * are alternating ones and zeros, low 12 data bits increment from
332 * zero, and address is given by addr. */
333 private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
334 List<BitVector> ans = new ArrayList<BitVector>();
335 BitVector dHi = new BitVector(25, "dataHi");
336 BitVector dLo = new BitVector(12, "dataLo");
337 BitVector t = new BitVector("1", "token");
338 BitVector a = new BitVector(14, "addr");
339 dHi.setFromLong(0x00aaaaa);
341 for (int i=0; i<num; i++) {
343 ans.add(dHi.cat(dLo).cat(t).cat(a));
348 private void stopToStop(ProperStopper s1, ProperStopper s2,
349 List<BitVector> din) {
350 prln("Begin stopToStop");
358 waitUntilQuiescent();
360 List<BitVector> dout = s2.drainMany();
362 MarinaUtils.compareItemsOrdered(din, dout);
365 prln("End stopToStop");
367 /** Burst data from src to dst. gate is stopped while loading src. gate
368 * is then run to allow the burst to flow. */
369 private void stopToStopBurst(ProperStopper src, ProperStopper gate,
371 List<BitVector> din) {
372 prln("Begin stopToStopBurst test");
381 waitUntilQuiescent();
383 // open the gate to start the burst
385 waitUntilQuiescent();
387 List<BitVector> dout = dst.drainMany();
389 MarinaUtils.compareItemsOrdered(din, dout);
392 prln("End stopToStopBurst test");
395 private void stopToStopOne(ProperStopper s1, ProperStopper s2,
397 prln("Begin stopToStopOne");
400 List<BitVector> din = makeIncrDataConstAdr(1, adr);
401 stopToStop(s1, s2, din);
404 prln("End stopToStopOne");
407 private void stopToStopThree(ProperStopper s1, ProperStopper s2,
409 prln("Begin stopToStopOne");
412 List<BitVector> din = makeIncrDataConstAdr(3, adr);
413 stopToStop(s1, s2, din);
416 prln("End stopToStopOne");
419 private int indexOf(BitVector o, List<BitVector> dIn) {
420 for (int i=0; i<dIn.size(); i++) {
421 if (o.equals(dIn.get(i))) return i;
425 private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
426 StringBuffer sb = new StringBuffer();
427 sb.append(" ring dump: ");
428 for (BitVector o : dOut) {
429 sb.append(indexOf(o, dIn)+" ");
431 return sb.toString();
434 private int[][] makeIntArray2D(int a, int b) {
435 int[][] ans = new int[a][];
436 for (int i=0; i<a; i++) ans[i] = new int[b];
440 //=========================================================================
441 // Put top level tests here
443 private void testChains(Marina marina) {
445 prln("Testing control chain...");
446 ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
448 ccC.shift(Marina.CONTROL_CHAIN, false, true);
452 prln("Testing data chain...");
453 ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
455 //ccD.shift(Marina.DATA_CHAIN, false, true);
459 prln("Testing report chain...");
460 ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
462 //ccR.shift(Marina.REPORT_CHAIN, false, true);
466 prln("Testing control chain...");
467 ct.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
469 cc.shift(Marina.CONTROL_CHAIN, false, true);
470 prln("Testing data chain...");
471 ct.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
472 prln("Testing report chain...");
473 ct.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
477 private void testProperStoppers(Marina marina) {
478 prln("Begin testProperStoppers");
481 for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) {
483 prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper");
486 prln("un-stopping stopper");
488 fatal( ps.getStopped(), "stopper should not have been stopped, but was");
490 prln("stopping stopper");
492 fatal( !ps.getStopped(), "stopper should have been stopped, but was not");
500 private void sendInstructions(Marina marina) {
501 prln("Begin sendInstructions");
504 List<BitVector> din = new ArrayList<BitVector>();
506 BitVector count = new BitVector(MarinaPacket.WORD_WIDTH,"count");
507 BitVector one = new BitVector(MarinaPacket.WORD_WIDTH, "one");
508 count.setFromLong(0);
510 for (int i=0; i<3; i++) {
512 count = count.add(one);
515 for(BitVector d : din)
516 marina.instrIn.fill(new MarinaPacket(d, false, MarinaPacket.null_path));
519 prln("End sendInstructions");
522 private void sendToken(Marina marina) {
523 prln("Begin sendToken");
526 //getCtrsFlags(marina);
528 int nbToks = marina.getNumTokens();
529 fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens");
531 marina.instrIn.fill(setIlc(1));
532 marina.instrIn.fill(SEND_TOKEN);
533 nbToks = marina.getNumTokens();
534 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
537 prln("End sendToken");
540 private void sendData(Marina marina) {
541 prln("Begin sendData");
544 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
545 for(int i=0; i<bv.length(); i+=2) bv.set(i, false);
546 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
548 marina.instrIn.fill(setIlc(1));
549 marina.instrIn.fill(SEND_DATA);
551 List<BitVector> dataItems = marina.data.drainMany();
552 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
554 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
555 fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token");
558 prln("End sendData");
561 private void sendDataIlcInfinite(Marina marina) {
562 prln("Begin sendDataIlcInfinite");
565 marina.southRing.fill(new Instruction[] {
566 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
572 List<BitVector> dataItems = marina.data.drainMany(howmany);
573 fatal(dataItems.size()!=howmany,
574 "Expected an unending supply of data items to emerge but only got got: "+dataItems.size());
577 prln("End sendDataIlcInfinite");
580 private Instruction setOlc(int olc) {
581 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc);
583 private Instruction setOlcIfZero(int olc) {
584 return new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, olc);
586 private Instruction setIlc(int ilc) {
587 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, ilc);
590 private void testFlagD(Marina marina) {
591 prln("Begin testFlagD");
594 List<BitVector> toks;
596 Predicate only_if_olc_zero = Predicate.FlagD;
597 Predicate only_if_olc_nonzero = Predicate.Default;
599 marina.instrIn.fill(setIlc(1));
601 for(int olc : new int[] { 1, 0 }) {
602 for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
603 prln("Attempting send data item with "+
605 "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
608 marina.southRing.fill(new Instruction[] {
610 new Instruction.Move(dock,
611 predicate_olc_nonzero // predicate
612 ? only_if_olc_nonzero
615 false, // torpedoable
625 expectNorthFifoExactly((predicate_olc_nonzero == (olc!=0)) ? 1 : 0);
627 for(int i=0; i<olc; i++)
628 marina.instrIn.fill(DEC);
634 prln("End testFlagD");
637 private void testPredicationOnAB(Marina marina) {
638 prln("Begin testPredicationOnAB");
641 List<BitVector> dItems;
643 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
644 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
646 for(boolean flag_a : new boolean[] { false, true }) {
647 for(boolean flag_b : new boolean[] { false, true }) {
648 prln("Setting flags, a="+flag_a+" b="+flag_b);
649 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
651 ? Instruction.Set.FlagFunction.ONE
652 : Instruction.Set.FlagFunction.ZERO,
654 ? Instruction.Set.FlagFunction.ONE
655 : Instruction.Set.FlagFunction.ZERO
657 getCtrsFlags(marina);
660 for(Predicate predicate : new Predicate[] {
668 prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate);
670 marina.instrIn.fill(new Instruction.Move(dock,
671 predicate, // predicate
672 false, // torpedoable
682 dItems = marina.data.drainMany();
683 int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
684 fatal(dItems.size()!=expected, "Expected "+expected+" data items to emerge but got: "+
685 dItems.size()+" items(s)");
691 prln("End testPredicationOnAB");
695 private void showOlc() {
696 prln("OLC=="+marina.getOLC());
698 private void expectOlc(int x) {
699 int olc = marina.getOLC();
700 fatal(x!=olc, "expected OLC=="+x+", but scanned out OLC=="+olc);
703 private void getCtrsFlags(Marina marina) {
704 prln("begin getCtrsFlags");
708 prln("ILC.done=="+marina.getILCDone()+
709 " ILC.infinity=="+marina.getILCInfinity()+
710 " ILC.count=="+marina.getILC());
711 prln("flagA=="+marina.getFlagA());
712 prln("flagB=="+marina.getFlagB());
714 prln("end getCtrsFlags");
717 private void walkOneOLC(Marina marina) {
718 prln("Begin walkOneOLC");
721 //for (int i=-1; i<6; i++) {
722 marina.southRing.fill(new Instruction[] {
724 new Instruction.Head(dock),
726 // new Instruction.Set(dock,Predicate.IgnoreFlagD, SetDest.OuterLoopCounter, 1),
730 TORPEDOABLE_RECV_DATA,
736 //new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement),
738 new Instruction.Tail(dock),
740 marina.southRing.fill(new Instruction[] {
745 BitVector bits = null;
746 marina.shiftReport(true, false);
747 for(int i=0; i<4; i++) {
748 BitVector x = marina.cc.getOutBits(marina.REPORT_CHAIN+"."+marina.OLC_PATH_KESSEL+i);
749 //System.out.println("bits are: " + x);
750 bits = bits==null ? x : bits.cat(x);
752 System.out.println("dec="+bits.get(0));
753 if (bits.get(1)) throw new RuntimeException();
756 /* for (int i=0; i<64; i++) {
758 if (marina.kesselsCounter) {
759 System.out.println("master-clearing...");
760 // master clear on each iteration; otherwise we'd need to "run down" the olc
761 marina.masterClear();
762 marina.southRing.enableInstructionSend(true);
765 expectTokensExactly(0);
768 int inOlc = i==-1 ? 0 : (1<<i);
770 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
771 marina.instrIn.fill(SEND_DATA_IF_D_SET);
772 marina.instrIn.fill(SEND_DATA_IF_D_NOT_SET);
773 marina.instrIn.fill(SEND_DATA);
775 model.waitNS(128 * CYCLE_TIME_NS);
778 prln("walkOneOLC: "+inOlc+" checks out");
779 expectNorthFifoExactly(0);
782 prln("End walkOneOLC");
785 private void walkOneILC(Marina marina) {
786 prln("Begin walkOneILC");
788 for (int i=0; i<6; i++) {
789 // Mask off the "zero" bit position
791 prln("inIlc="+inIlc);
792 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
793 int outIlc = marina.getILC();
794 fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc);
795 fatal(marina.getILCInfinity(), "bad Infinity bit: true");
797 prln("Now test the infinity bit");
798 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
799 fatal(!marina.getILCInfinity(), "bad Infinity bit: false");
801 prln("End walkOneILC");
803 private void countIlc(Marina marina) {
804 final int maxIlc = 63;
805 prln("Begin countIlc");
808 marina.instrIn.fill(new
809 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
811 int ilc = marina.getILC();
812 fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
814 prln("execute a move instruction that does nothing except decrement the ILC to zero");
816 new Instruction.Move(dock,
817 Predicate.IgnoreFlagD, // predicate
818 false, // torpedoable
828 // wait for ILC to count from 63 to 0
829 model.waitNS(128 * CYCLE_TIME_NS);
830 //model.waitNS(10000);
832 prln("Check that ILC==0");
833 ilc = marina.getILC();
834 fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
837 prln("End countIlc");
839 // Note: countOlc takes 44 minutes to run on nanosim
840 private void countOlc(Marina marina) {
842 prln("Begin countOlc");
845 marina.instrIn.fill(setOlc(maxOlc));
847 for (int i=maxOlc; i>=0; i--) {
848 model.waitNS(128 * CYCLE_TIME_NS);
849 prln("OLC should be: "+i);
851 marina.instrIn.fill(new
852 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
856 prln("End countOlc");
858 private void loadEveryValueOLC(Marina marina) {
861 for (int i=0; i<(1<<6); i++) {
863 if (marina.kesselsCounter) {
864 System.out.println("master-clearing...");
865 // master clear on each iteration; otherwise we'd need to "run down" the olc
866 marina.masterClear();
867 marina.southRing.enableInstructionSend(true);
871 marina.southRing.fill(new Instruction[] {
875 // to ensure that instruction is bubble-limited
878 // the Set-OLC instruction
879 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc),
881 // put a Set-ILC instruction right behind it with inverted bits to be sure we're
882 // not capturing the instruction-latch value too late in the cycle
883 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, (inOlc ^ (~(-1<<6)))),
887 model.waitNS(128 * CYCLE_TIME_NS);
888 marina.northRing.fill();
889 model.waitNS(128 * CYCLE_TIME_NS);
892 prln("loadEveryValueOLC: "+inOlc+" checks out");
897 private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
898 prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
901 for(i=0; i<quantity; i++) {
902 prln("Inserting instruction " + (i+1) +"/"+ quantity);
903 marina.instrIn.fill(instruction);
904 boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
905 if (jammed && expect_it_to_jam_up) {
906 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
910 fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
912 fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
914 prln("Successfully inserted " + i + " instructions");
917 private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(),
918 MarinaUtils.sunToBerk(MarinaPacket.null_path));
920 private static final Instruction DEC =
921 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, SetSource.Decrement);
923 private static final Instruction FLAG_NOP =
924 new Instruction.Set(dock, Predicate.IgnoreFlagD,
925 CLEAR_FLAG.add(Predicate.FlagA),
926 CLEAR_FLAG.add(Predicate.FlagB));
928 private static final Instruction FLAG_NOP_IF_FLAG_A =
929 new Instruction.Set(dock, Predicate.FlagA,
930 CLEAR_FLAG.add(Predicate.FlagA),
931 CLEAR_FLAG.add(Predicate.FlagB));
933 private static final Instruction NOP =
934 new Instruction.Move(dock,
935 Predicate.IgnoreFlagD, /* predicate */
936 false, /* torpedoable */
940 false, /* latchData */
941 false, /* latchPath */
946 private static final Instruction SEND_DATA =
947 new Instruction.Move(dock,
948 Predicate.IgnoreFlagD, /* predicate */
949 false, /* torpedoable */
950 null_path, /* path */
953 false, /* latchData */
954 false, /* latchPath */
959 private static final Instruction SEND_DATA_IF_D_NOT_SET =
960 new Instruction.Move(dock,
961 Predicate.Default, /* predicate */
962 false, /* torpedoable */
963 null_path, /* path */
966 false, /* latchData */
967 false, /* latchPath */
972 private static final Instruction SEND_DATA_IF_A_SET_AND_D_NOT_SET =
973 new Instruction.Move(dock,
974 Predicate.FlagA, /* predicate */
975 false, /* torpedoable */
976 null_path, /* path */
979 false, /* latchData */
980 false, /* latchPath */
985 private static final Instruction SEND_DATA_IF_D_SET =
986 new Instruction.Move(dock,
987 Predicate.FlagD, /* predicate */
988 false, /* torpedoable */
989 null_path, /* path */
992 false, /* latchData */
993 false, /* latchPath */
998 private static final Instruction SEND_TOKEN_IF_D_SET =
999 new Instruction.Move(dock,
1000 Predicate.FlagD, /* predicate */
1001 false, /* torpedoable */
1002 null_path, /* path */
1003 false, /* tokenIn */
1005 false, /* latchData */
1006 false, /* latchPath */
1007 false, /* dataOut */
1011 private static final Instruction SEND_TOKEN_IF_D_NOT_SET =
1012 new Instruction.Move(dock,
1013 Predicate.Default, /* predicate */
1014 false, /* torpedoable */
1015 null_path, /* path */
1016 false, /* tokenIn */
1018 false, /* latchData */
1019 false, /* latchPath */
1020 false, /* dataOut */
1024 private static final Instruction TORPEDOABLE_RECV_DATA =
1025 new Instruction.Move(dock,
1026 Predicate.IgnoreFlagD, /* predicate */
1027 true, /* torpedoable */
1029 false, /* tokenIn */
1031 true, /* latchData */
1032 false, /* latchPath */
1033 false, /* dataOut */
1034 false /* tokenOut */
1037 private static final Instruction RECV_DATA =
1038 new Instruction.Move(dock,
1039 Predicate.IgnoreFlagD, /* predicate */
1040 false, /* torpedoable */
1042 false, /* tokenIn */
1044 true, /* latchData */
1045 false, /* latchPath */
1046 false, /* dataOut */
1047 false /* tokenOut */
1050 private static final Instruction SEND_TOKEN =
1051 new Instruction.Move(dock,
1052 Predicate.IgnoreFlagD, /* predicate */
1053 false, /* torpedoable */
1054 null_path, /* path */
1055 false, /* tokenIn */
1057 false, /* latchData */
1058 false, /* latchPath */
1059 false, /* dataOut */
1063 private static final Instruction RECV_TOKEN =
1064 new Instruction.Move(dock,
1065 Predicate.IgnoreFlagD, /* predicate */
1066 false, /* torpedoable */
1070 false, /* latchData */
1071 false, /* latchPath */
1072 false, /* dataOut */
1073 false /* tokenOut */
1077 private void expectNorthFifoNoMoreThan(int num) {
1078 model.waitNS(128 * CYCLE_TIME_NS);
1079 List<BitVector> dataItems = marina.data.drainMany(num+1);
1080 fatal(dataItems.size()>num,
1081 "Expected no more than "+num+
1082 " data items to emerge but got at least: "+dataItems.size());
1084 private void expectNorthFifoExactly(int num) {
1085 model.waitNS(128 * CYCLE_TIME_NS);
1086 List<BitVector> dataItems = marina.data.drainMany(num+1);
1087 fatal(dataItems.size()!=num,
1088 "Expected exactly "+num+
1089 " data items to emerge but got at least: "+dataItems.size());
1091 private void expectNorthFifoAtLeast(int num) {
1092 model.waitNS(128 * CYCLE_TIME_NS);
1093 List<BitVector> dataItems = marina.data.drainMany(num);
1094 fatal(dataItems.size()<num,
1095 "Expected at least "+num+
1096 " data items to emerge but got only: "+dataItems.size());
1098 private void expectTokensNoMoreThan(int num) {
1099 int x = marina.getNumTokens();
1100 List<BitVector> dataItems = marina.data.drainMany(num+1);
1102 "Expected no more than "+num+
1103 " tokens to emerge but got at least: "+x);
1105 private void expectTokensExactly(int num) {
1106 int x = marina.getNumTokens();
1108 "Expected exactly "+num+
1109 " tokens but got at least: "+x);
1112 private void testFlagDRecomputationTime(Marina marina) {
1113 marina.instrIn.fill(setIlc(1));
1114 marina.southRing.fill(new Instruction[] {
1116 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
1117 SEND_DATA_IF_D_NOT_SET
1119 marina.northRing.fill();
1120 expectNorthFifoNoMoreThan(0);
1122 marina.southRing.fill(new Instruction[] {
1124 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
1125 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
1126 SEND_DATA_IF_D_NOT_SET
1128 marina.northRing.fill();
1129 expectNorthFifoNoMoreThan(0);
1131 marina.southRing.fill(new Instruction[] {
1133 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1134 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
1135 SEND_DATA_IF_D_NOT_SET
1137 marina.northRing.fill();
1138 expectNorthFifoExactly(1);
1139 marina.instrIn.fill(DEC);
1141 marina.southRing.fill(new Instruction[] {
1143 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
1144 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
1145 SEND_DATA_IF_D_NOT_SET
1147 marina.northRing.fill();
1148 expectNorthFifoExactly(1);
1151 private void testTailWaitsForHead(Marina marina) {
1152 marina.instrIn.fill(setIlc(1));
1153 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1155 marina.southRing.enableInstructionSend(false);
1156 marina.southRing.enableInstructionRecirculate(true);
1158 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1159 marina.instrIn.fill(new Instruction.Head(dock));
1160 marina.instrIn.fill(SEND_DATA);
1161 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1162 marina.instrIn.fill(SEND_TOKEN);
1163 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1164 marina.instrIn.fill(new Instruction.Tail(dock));
1165 marina.instrIn.fillTorpedo();
1167 marina.southRing.enableInstructionRecirculate(false);
1168 marina.southRing.enableInstructionSend(true);
1169 marina.instrIn.run();
1171 expectNorthFifoNoMoreThan(0);
1172 prln("inserting into north proper stopper");
1173 marina.northRing.fill();
1174 expectNorthFifoExactly(1);
1175 int nbToks = marina.getNumTokens();
1176 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
1180 marina.instrIn.fill(setIlc(1));
1181 marina.instrIn.fill(setOlc(1));
1183 // this makes the head wait for the torpedo
1184 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1186 // the head should wait for the tail
1187 marina.instrIn.fill(new Instruction.Head(dock));
1188 marina.instrIn.fill(NOP);
1189 marina.instrIn.fill(SEND_DATA);
1190 marina.instrIn.fill(RECV_DATA);
1192 expectNorthFifoNoMoreThan(0);
1194 marina.instrIn.fillTorpedo();
1195 expectNorthFifoNoMoreThan(0);
1197 marina.instrIn.fill(new Instruction.Tail(dock));
1198 expectNorthFifoExactly(1);
1201 private void testTailWithoutHead(Marina marina) {
1202 marina.instrIn.fill(setIlc(1));
1203 marina.southRing.fill(new Instruction[] {
1204 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
1205 new Instruction.Tail(dock),
1208 List<BitVector> dataItems = marina.data.drainMany(1);
1209 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
1212 private void testHeadWaitsForTail(Marina marina) {
1213 List<BitVector> dataItems;
1215 prln("Begin testHeadWaitsForTail");
1218 marina.instrIn.fill(setIlc(1));
1219 marina.southRing.fill(new Instruction[] {
1220 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
1221 new Instruction.Head(dock),
1222 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1226 expectNorthFifoExactly(0);
1227 marina.instrIn.fill(new Instruction.Tail(dock));
1228 expectNorthFifoAtLeast(1);
1231 prln("End testHeadWaitsForTail");
1234 private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) {
1235 marina.instrIn.fill(setIlc(1));
1236 marina.southRing.fill(new Instruction[] {
1237 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,63),
1238 new Instruction.Move(dock,
1239 Predicate.IgnoreFlagD, // predicate
1240 true, // torpedoable
1249 new Instruction.Move(dock,
1250 Predicate.FlagD, // predicate
1251 false, // torpedoable
1261 marina.instrIn.fillTorpedo();
1262 expectNorthFifoExactly(1);
1263 marina.southRing.fill(new Instruction[] {
1264 new Instruction.Move(dock,
1265 Predicate.Default, // predicate
1266 false, // torpedoable
1276 expectNorthFifoNoMoreThan(0);
1279 private void testAbort(Marina marina) {
1281 marina.instrIn.fill(setIlc(1));
1282 marina.southRing.fill(new Instruction[] {
1283 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1),
1284 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1285 SEND_DATA_IF_D_NOT_SET,
1286 new Instruction.Head(dock),
1287 SEND_DATA_IF_D_NOT_SET,
1288 new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2),
1289 new Instruction.Abort(dock, Predicate.FlagD),
1290 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement),
1291 new Instruction.Tail(dock),
1294 for(int i=0; i<4; i++) {
1297 model.waitNS(128 * CYCLE_TIME_NS);
1298 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1299 fatal(bv==null, "no data item found");
1300 prln("got " + bv.toLong());
1301 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1303 model.waitNS(128 * CYCLE_TIME_NS);
1304 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1305 fatal(bv==null, "no data item found");
1306 prln("got " + bv.toLong());
1307 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1309 model.waitNS(128 * CYCLE_TIME_NS);
1310 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1311 fatal(bv==null, "no data item found");
1312 prln("got " + bv.toLong());
1313 fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong());
1318 private void testAbortOutsideOfLoop(Marina marina) {
1319 marina.instrIn.fill(setIlc(1));
1320 marina.southRing.fill(new Instruction[] {
1321 // ensure that an abort doesn't cause problems if no loop is in progress
1322 new Instruction.Abort(dock, Predicate.IgnoreFlagD),
1325 expectNorthFifoExactly(1);
1328 private void testFlagAB(Marina marina) {
1329 prln("Begin testFlagAB");
1332 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1333 Instruction.Set.FlagFunction one = zero;
1336 // we should be able to use any pair of FlagX+NotFlagX,
1337 // but we toss them all in to maximize the chances of the
1338 // test passing (later we will try the individual
1339 // combinations to maximize the chances of failure).
1340 one = one.add(Predicate.FlagA);
1341 one = one.add(Predicate.NotFlagA);
1342 one = one.add(Predicate.FlagB);
1343 one = one.add(Predicate.NotFlagB);
1344 one = one.add(Predicate.FlagC);
1345 one = one.add(Predicate.NotFlagC);
1347 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1348 for(boolean fast : new boolean[] { true, false }) {
1349 // clear the flags to a known state, then check both 0->1 and 1->0 transitions
1350 for(boolean b : new boolean[] { false, true, false }) {
1351 prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
1352 prln((b?"Setting":"Clearing")+" flags");
1354 Instruction inst = new Instruction.Set(dock,Predicate.IgnoreFlagD,
1359 marina.southRing.fill(new Instruction[] {
1364 model.waitNS(64 * CYCLE_TIME_NS);
1365 marina.northRing.fill();
1367 marina.instrIn.fill(inst);
1370 fatal(marina.getFlagA()!=b,
1371 "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
1372 fatal(marina.getFlagB()!=b,
1373 "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
1378 prln("End testFlagAB");
1382 * WARNING: this is a very, very, very long test case -- it goes
1383 * through 216 iterations.
1385 private void testFlagTruthTable(Marina marina) {
1386 prln("Begin testFlagTruthTable");
1389 marina.instrIn.fill(setIlc(1));
1390 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1391 Instruction.Set.FlagFunction one = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
1393 for(Predicate a_input : new Predicate[] { null, Predicate.FlagA, Predicate.NotFlagA })
1394 for(Predicate b_input : new Predicate[] { null, Predicate.FlagB, Predicate.NotFlagB })
1395 for(Predicate c_input : new Predicate[] { null, Predicate.FlagC, Predicate.NotFlagC })
1396 for(boolean a_state : new boolean[] { false, true })
1397 for(boolean b_state : new boolean[] { false, true })
1398 for(boolean c_state : new boolean[] { false, true }) {
1399 for(boolean which : new boolean[] { false, true }) {
1401 prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
1402 // set A,B flags to a_state and b_state
1403 marina.instrIn.fill(new
1404 Instruction.Set(dock,Predicate.IgnoreFlagD,
1405 a_state ? one : zero,
1406 b_state ? one : zero
1409 // set C flag to c_state
1410 BitVector data = new BitVector(37, "empty");
1411 BitVector addr = new BitVector(14, "empty");
1412 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1413 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1414 addr.set(Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
1415 marina.northRing.fill(new MarinaPacket(data, false, addr));
1416 marina.instrIn.fill(RECV_DATA);
1418 Instruction.Set.FlagFunction func = zero;
1419 if (a_input!=null) func = func.add(a_input);
1420 if (b_input!=null) func = func.add(b_input);
1421 if (c_input!=null) func = func.add(c_input);
1423 Instruction inst = new
1424 Instruction.Set(dock,Predicate.IgnoreFlagD,
1425 !which ? func : zero.add(Predicate.FlagA),
1426 which ? func : zero.add(Predicate.FlagB)
1429 marina.instrIn.fill(inst);
1431 boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
1432 boolean expected_b = which ? func.evaluate(a_state, b_state, c_state, false) : b_state;
1433 fatal(expected_a != marina.getFlagA(),
1434 "expected A="+expected_a+", but got "+marina.getFlagA());
1435 fatal(expected_b != marina.getFlagB(),
1436 "expected B="+expected_b+", but got "+marina.getFlagB());
1440 prln("End testFlagTruthTable");
1443 private void recvData(Marina marina) {
1444 prln("Begin recvData");
1447 marina.instrIn.fill(setIlc(1));
1448 marina.southRing.fill(new Instruction[] {
1449 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1450 new Instruction.Move(dock,
1451 Predicate.IgnoreFlagD, // predicate
1452 false, // torpedoable
1461 new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG),
1463 model.waitNS(64 * CYCLE_TIME_NS);
1465 prln("checking to confirm that A flag is cleared");
1466 fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1468 prln("inserting data item in north fifo ring");
1469 BitVector data = new BitVector(37, "empty");
1470 BitVector addr = new BitVector(14, "empty");
1471 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1472 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1473 marina.northRing.fill(new MarinaPacket(data, false, addr));
1474 model.waitNS(64 * CYCLE_TIME_NS);
1476 prln("checking to see if A flag got set");
1477 fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1480 prln("End recvData");
1484 private void testRecvAndSendWalkingOne(Marina marina) {
1485 prln("Begin testRecvAndSendWalkingOne");
1488 marina.instrIn.fill(setIlc(1));
1490 List<BitVector> dataItems;
1491 for(int bit=0; bit<37; bit++) {
1493 BitVector data = new BitVector(37, "empty");
1494 BitVector addr = new BitVector(14, "empty");
1495 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1496 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1497 data.set(bit, true);
1498 prln("testing with bit pattern " + data);
1500 prln("inserting data item into north fifo ring");
1501 marina.northRing.fill(new MarinaPacket(data, false, addr));
1503 prln("stopping the north proper stopper");
1506 dataItems = marina.data.drainMany(1);
1507 fatal(dataItems.size()!=0,
1508 "found a data item waiting in the north proper stopper, but should not have");
1510 marina.instrIn.fill(new Instruction.Move(dock,
1511 Predicate.IgnoreFlagD, // predicate
1512 false, // torpedoable
1522 dataItems = marina.data.drainMany(2);
1523 fatal(dataItems.size()!=1,
1524 "found "+dataItems.size()+" data items in north fifo; expected one");
1525 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1526 fatalIfBitVectorsDoNotMatch(mp.data, data);
1530 prln("End testRecvAndSendWalkingOne");
1535 private void setOlcFromDataLatch(Marina marina) {
1536 prln("Begin setOlcFromDataLatch");
1539 marina.instrIn.fill(setIlc(1));
1541 // walk a bit from 0 to 5
1542 for(int bit=0; bit<6; bit++) {
1543 prln("inserting data item in north fifo ring");
1544 BitVector data = new BitVector(37, "empty");
1545 BitVector addr = new BitVector(14, "empty");
1546 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1547 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1548 data.set(bit, true);
1549 marina.northRing.fill(new MarinaPacket(data, false, addr));
1551 marina.southRing.fill(new Instruction[] {
1553 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch),
1554 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,-1),
1557 model.waitNS(CYCLE_TIME_NS * 64);
1561 if (marina.kesselsCounter) {
1562 // master clear on each iteration; otherwise we'd need to "run down" the olc
1563 marina.masterClear();
1564 marina.southRing.enableInstructionSend(true);
1569 prln("End setOlcFromDataLatch");
1572 private void setIlcFromDataLatch(Marina marina) {
1573 prln("Begin setIlcFromDataLatch");
1576 marina.instrIn.fill(setIlc(1));
1578 // walk a bit from 0 to 5
1579 for(int bit=5; bit>=0; bit--) {
1580 prln("inserting data item in north fifo ring");
1581 BitVector data = new BitVector(37, "empty");
1582 BitVector addr = new BitVector(14, "empty");
1583 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1584 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1585 data.set(bit, true);
1586 marina.northRing.fill(new MarinaPacket(data, false, addr));
1588 marina.southRing.fill(new Instruction[] {
1589 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1591 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch),
1593 model.waitNS(CYCLE_TIME_NS * 64);
1595 int ilc = marina.getILC();
1596 fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc);
1600 prln("End setIlcFromDataLatch");
1603 private void testSendAndRecvToken(Marina marina) {
1604 prln("Begin testSendAndRecvToken");
1607 marina.instrIn.fill(setIlc(1));
1608 marina.southRing.fill(new Instruction[] {
1613 expectNorthFifoExactly(1);
1616 prln("End testSendAndRecvToken");
1619 private void testSignExtendedLiteral(Marina marina) {
1620 prln("Begin testSignExtendedLiteral");
1623 marina.instrIn.fill(setIlc(1));
1624 for(long val : new long[] { (-1L << 14), -1, 0, 1 }) {
1626 marina.southRing.fill(new Instruction[] {
1627 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1628 Instruction.Set.SetDest.DataLatch,
1632 model.waitNS(CYCLE_TIME_NS * 64);
1634 List<BitVector> dataItems = marina.data.drainMany(3);
1635 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1637 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1638 BitVector bv = mp.data;
1639 prln("got back " + mp);
1641 boolean mismatch = false;
1643 for(int i=0; i<37; i++) {
1644 if (bv.get(i) != ( (val & (1L << i)) != 0 )) {
1649 fatal(mismatch, "data read back did not match inserted literal; mismatch on bits " + err);
1653 prln("End testSignExtendedLiteral");
1656 private void testShiftedLiteral(Marina marina) {
1657 prln("Begin testShiftedLiteral");
1660 marina.instrIn.fill(setIlc(1));
1661 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
1662 Instruction.Set.SetDest.DataLatch,
1665 BitVector dreg = new BitVector(37, "what we think is in the d-register");
1666 for(int i=0; i<37; i++) dreg.set(i, false);
1668 for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
1670 edu.berkeley.fleet.api.BitVector immediate =
1671 new edu.berkeley.fleet.api.BitVector(19);
1672 for(int i=0; i<immediate.length(); i++)
1673 immediate.set(i, (val & (1L << i)) != 0);
1675 // shift over 19 LSB's towards MSB
1676 for(int i=0; i<19; i++)
1677 if (i+19 <= 36) dreg.set(i+19, dreg.get(i));
1678 for(int i=0; i<19; i++)
1679 dreg.set(i, immediate.get(i));
1681 marina.southRing.fill(new Instruction[] {
1682 new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate),
1686 model.waitNS(CYCLE_TIME_NS * 64);
1687 List<BitVector> dataItems = marina.data.drainMany(3);
1688 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1690 BitVector bv = new MarinaPacket(dataItems.get(0)).data;
1691 fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" +
1692 "got: "+bv.bitReverse().getState()+"\n"+
1693 "expected:"+dreg.bitReverse().getState());
1697 prln("End testShiftedLiteral");
1700 private void testFlagC(Marina marina) {
1701 prln("Begin testFlagC");
1709 // Dc=1 => sigS is copied into C-flag
1710 // Dc=0 => sigA is copied into C-flag
1712 marina.instrIn.fill(setIlc(1));
1713 for(boolean dc : new boolean[] { false, true }) {
1714 for(boolean c_flag : new boolean[] { true, false, true }) {
1717 prln("****** checking case where dc="+dc+", cflag="+c_flag);
1718 BitVector data = new BitVector(37, "empty");
1719 BitVector addr = new BitVector(14, "empty");
1720 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1721 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1724 ? Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
1725 : Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
1726 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
1727 addr.set(whichbit, c_flag);
1729 prln("... and filling north fifo proper stopper");
1730 marina.northRing.fill(new MarinaPacket(data, false, addr));
1732 prln("clearing flags");
1733 prln("executing recv data with Dc="+dc);
1734 prln("copying c-flag to a-flag");
1735 marina.southRing.fill(new Instruction[] {
1736 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1737 new Instruction.Move(dock,
1738 Predicate.IgnoreFlagD, /* predicate */
1739 true, /* torpedoable */
1741 false, /* tokenIn */
1744 false, /* latchPath */
1745 false, /* dataOut */
1746 false /* tokenOut */
1749 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1750 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
1755 model.waitNS(CYCLE_TIME_NS * 64);
1757 prln("checking to confirm that A flag is " + c_flag);
1758 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
1762 prln("End testFlagC");
1765 private void sendDataWithPath(Marina marina) {
1766 prln("Begin sendDataWithPath");
1769 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
1770 marina.instrIn.fill(setIlc(1));
1772 // alternating ones and zeroes
1773 for(int i=0; i<bv.length(); i+=2)
1775 // and then ones in the lower four bits so it's not symmetric
1776 for(int i=0; i<4; i++)
1779 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
1781 marina.southRing.fill(new Instruction[] {
1782 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1783 new Instruction.Move(dock,
1784 Predicate.IgnoreFlagD, /* predicate */
1785 false, /* torpedoable */
1787 false, /* tokenIn */
1789 false, /* latchData */
1790 false, /* latchPath */
1792 false /* tokenOut */
1796 List<BitVector> dataItems;
1799 dataItems = marina.data.drainMany();
1800 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1801 mp = new MarinaPacket(dataItems.get(0));
1803 // the 14th bit of the outbound address cannot be set by the
1804 // ship, so we don't care about it
1805 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1807 prln("send data with no change to path");
1808 marina.instrIn.fill(new Instruction.Move(dock,
1809 Predicate.IgnoreFlagD, /* predicate */
1810 false, /* torpedoable */
1812 false, /* tokenIn */
1814 false, /* latchData */
1815 false, /* latchPath */
1817 false /* tokenOut */
1820 dataItems = marina.data.drainMany();
1821 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1822 mp = new MarinaPacket(dataItems.get(0));
1824 // the 14th bit of the outbound address cannot be set by the
1825 // ship, so we don't care about it
1826 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1829 prln("End sendDataWithPath");
1832 private void recvPath(Marina marina) {
1833 prln("Begin recvPath");
1836 marina.instrIn.fill(setIlc(1));
1837 for(int bit=0; bit<11; bit++) {
1838 BitVector packet_data = new BitVector(37, "inbound data item");
1839 for(int i=0; i<37; i++) packet_data.set(i, false);
1840 packet_data.set(27+bit, true);
1841 BitVector packet_path = new BitVector(14, "inbound data item");
1842 for(int i=0; i<14; i++) packet_path.set(i, false);
1844 marina.northRing.fill(new MarinaPacket(packet_data, false, packet_path));
1846 prln("recv path, send data (using recv'd path)");
1847 marina.instrIn.fill(new Instruction.Move(dock,
1848 Predicate.IgnoreFlagD, /* predicate */
1849 false, /* torpedoable */
1851 false, /* tokenIn */
1853 true, /* latchData */
1854 true, /* latchPath */
1856 false /* tokenOut */
1859 List<BitVector> dataItems = marina.data.drainMany();
1860 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1861 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1863 fatalIfBitVectorsDoNotMatch(packet_data.get(25,11), mp.path.get(0,11));
1864 fatalIfBitVectorsDoNotMatch(packet_data, mp.data);
1868 prln("End recvPath");
1871 private void testILC(Marina marina) {
1872 prln("Begin testILC");
1875 for(int bit=0; bit<6; bit++) {
1876 int ilc = bit<0 ? 0 : (1<<bit);
1877 marina.southRing.fill(new Instruction[] {
1878 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc),
1881 List<BitVector> dataItems = marina.data.drainMany();
1882 fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
1886 prln("End testILC");
1889 private void testILCZero(Marina marina) {
1891 marina.southRing.fill(new Instruction[] {
1892 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0),
1896 expectNorthFifoNoMoreThan(0);
1897 expectTokensExactly(1);
1901 private void sendTorpedo(Marina marina) {
1902 prln("Begin sendTorpedo");
1904 marina.instrIn.fill(setIlc(1));
1905 marina.instrIn.fill(setOlc(63));
1907 model.waitNS(128 * CYCLE_TIME_NS);
1910 marina.instrIn.fill(new
1911 Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1912 fatal(marina.getFlagA(), "bad A flag: true");
1913 fatal(marina.getFlagB(), "bad B flag: true");
1915 prln("execute a move instruction that does nothing but loops until torpedo arrives");
1916 prln("A=1, B=B This instruction should not execute because D-flag is set");
1917 prln("Set A=A, B=1 This instruction should execute because D-flag is set");
1919 model.waitNS(128 * CYCLE_TIME_NS);
1921 marina.southRing.fill(new Instruction[] {
1922 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity),
1923 new Instruction.Move(dock,
1924 Predicate.IgnoreFlagD, // predicate
1925 true, // torpedoable
1934 new Instruction.Set(dock,Predicate.Default,
1936 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB)
1938 new Instruction.Set(dock, Predicate.FlagD,
1939 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA),
1944 model.waitNS(128 * CYCLE_TIME_NS);
1946 prln("send torpedo. This should clear the OLC");
1947 marina.instrIn.fillTorpedo();
1948 model.waitNS(128 * CYCLE_TIME_NS);
1950 model.waitNS(128 * CYCLE_TIME_NS);
1952 prln("A should remain false, B should be true");
1953 fatal(marina.getFlagA(), "bad A flag: true");
1954 fatal(!marina.getFlagB(), "bad B flag: false");
1956 model.waitNS(128 * CYCLE_TIME_NS);
1958 prln("Reload OLC after torpedo, clears D-flag");
1959 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1961 // FIXME: find another way to test this
1962 model.waitNS(128 * CYCLE_TIME_NS);
1965 prln("Set A=1, B=1 This instruction should execute because OLC!=0");
1966 marina.instrIn.fill(new
1967 Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
1969 prln("A and B should be true");
1970 fatal(!marina.getFlagA(), "bad A flag: false");
1971 fatal(!marina.getFlagB(), "bad B flag: false");
1974 prln("End sendTorpedo");
1977 private void testTorpedoOnAnInfinite(Marina marina) {
1978 prln("Begin testTorpedoOnAnInfinite");
1981 List<BitVector> dataItems;
1983 marina.instrIn.fill(setIlc(1));
1984 for(boolean torpedoable : new boolean[] { true, false }) {
1986 marina.southRing.fill(new Instruction[] {
1987 new Instruction.Move(dock,
1988 Predicate.IgnoreFlagD, // predicate
1989 false, // torpedoable
1998 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
1999 new Instruction.Move(dock,
2000 Predicate.IgnoreFlagD, // predicate
2001 torpedoable, // torpedoable
2010 // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior
2011 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
2016 // expect nothing to come out, because the NOP is executing
2017 dataItems = marina.data.drainMany(2);
2018 fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
2020 marina.instrIn.fillTorpedo();
2022 int expected = torpedoable?1:0;
2023 dataItems = marina.data.drainMany(2);
2024 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
2026 fatal(!marina.getILCDone(), "Expected ilc=done, but got "+marina.getILC());
2030 prln("End testTorpedoOnAnInfinite");
2033 private void testDFlagWhenTorpedoLyingInWait(Marina marina) {
2034 marina.southRing.fill(new Instruction[] {
2037 TORPEDOABLE_RECV_DATA,
2041 SEND_TOKEN_IF_D_SET,
2044 expectTokensExactly(0);
2046 // changing the order of these lines should work, but it does not
2047 marina.northRing.fill();
2048 marina.instrIn.fillTorpedo();
2050 expectTokensExactly(1);
2053 private void testSetOlcFollowedByDPredicated(Marina marina) {
2054 for(boolean d_set : new boolean[] { false, true }) {
2056 marina.southRing.fill(new Instruction[] {
2058 marina.kesselsCounter ? null : FLAG_NOP,
2059 d_set ? SEND_DATA_IF_D_SET : SEND_DATA_IF_D_NOT_SET,
2061 expectNorthFifoExactly(d_set ? 1 : 0);
2064 marina.southRing.fill(new Instruction[] {
2066 marina.kesselsCounter ? null : FLAG_NOP,
2067 d_set ? SEND_DATA_IF_D_SET : SEND_DATA_IF_D_NOT_SET,
2069 expectNorthFifoExactly(d_set ? 0 : 1);
2071 if (marina.kesselsCounter) {
2072 marina.masterClear();
2073 marina.southRing.enableInstructionSend(true);
2078 private void testOlcDecrementAtHighSpeed(Marina marina) {
2079 prln("Begin testOlcDecrementAtHighSpeed");
2082 List<BitVector> dataItems;
2084 // Each element of the following pair of arrays is one "test".
2085 // The OLC will be loaded with olcs[i] and then decremented
2086 // decr_amounts[i] times; after that has happened the zeroness
2087 // of the OLC will be checked by executing a MOVE with
2088 // [olc!=0] as the predicate.
2090 int[] olcs = new int[] { 3, 3, 3, 10, 41 };
2091 int[] decr_amounts = new int[] { 2, 3, 4, 9, 9 };
2093 for(int which=0; which<olcs.length; which++) {
2094 int olc = olcs[which];
2095 int decr_amount = decr_amounts[which];
2097 prln("inserting set olc="+olc);
2098 prln("inserting set ilc=1");
2099 marina.southRing.fill(new Instruction[] {
2100 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
2101 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc),
2104 // commenting the following four lines causes this test to pass
2106 prln("inserting: "+decr_amount+" olc-- instructions");
2107 prln("inserting: [!d] send data");
2108 Instruction[] instructions = new Instruction[decr_amount+1];
2109 for(int i=0; i<decr_amount; i++)
2111 new Instruction.Set(dock,
2113 SetDest.OuterLoopCounter,
2114 SetSource.Decrement);
2115 instructions[instructions.length-1] =
2116 new Instruction.Move(dock,
2117 Predicate.Default, // predicate
2118 false, // torpedoable
2128 marina.southRing.fill(instructions);
2129 model.waitNS(64 * CYCLE_TIME_NS);
2131 int expected = decr_amount>=olc ? 0 : 1;
2132 dataItems = marina.data.drainMany(2);
2133 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
2134 expectOlc(Math.max(0,olc-decr_amount));
2136 if (marina.kesselsCounter) {
2137 // master clear on each iteration; otherwise we'd need to "run down" the olc
2138 marina.masterClear();
2139 marina.southRing.enableInstructionSend(true);
2144 prln("End testOlcDecrementAtHighSpeed");
2147 private void flipIlcBit(Marina marina) {
2148 prln("Begin flipIlcBit");
2150 prln("Using the set ILC instruction, toggle a single bit between zero and one. \n" +
2151 "Check correct setting of the ILC zero bit");
2153 for (int i=0; i<6; i++) {
2156 prln("Then immediately set ILC="+notZero);
2157 marina.southRing.fill(new Instruction[] {
2158 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
2159 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
2162 model.waitNS(64 * CYCLE_TIME_NS);
2164 prln("Verify ILC using scan chain");
2165 int ilcCount = marina.getILC();
2166 fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
2167 fatal(marina.getILCInfinity(), "bad ILC Infinity bit: true");
2169 marina.southRing.fill(new Instruction[] {
2170 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
2171 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
2174 model.waitNS(64 * CYCLE_TIME_NS);
2176 prln("Verify ILC using scan chain");
2177 ilcCount = marina.getILC();
2178 fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
2179 fatal(marina.getILCInfinity(), "bad ILC Infinity bit: true");
2183 prln("End flipIlcBit");
2185 private void flipOlcBit(Marina marina) {
2186 prln("Begin flipOlcBit");
2188 prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
2189 "Check correct setting of the OLC zero bit");
2191 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
2193 for (int i=0; i<6; i++) {
2194 int notZero = 32 >> i;
2196 if (marina.kesselsCounter) {
2197 // master clear on each iteration; otherwise we'd need to "run down" the olc
2198 marina.masterClear();
2199 marina.southRing.enableInstructionSend(true);
2204 prln("Then immediately set OLC="+notZero);
2205 marina.southRing.fill(new Instruction[] {
2206 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
2207 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
2210 model.waitNS(64 * CYCLE_TIME_NS);
2211 prln("Verify OLC count using scan chain");
2214 if (!marina.kesselsCounter) {
2215 prln("Set OLC="+notZero);
2216 prln("Then immediately set OLC=0");
2217 marina.southRing.fill(new Instruction[] {
2218 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
2219 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
2222 model.waitNS(64 * CYCLE_TIME_NS);
2223 prln("Verify OLC count using scan chain");
2229 prln("End flipOlcBit");
2231 private void testSouthRecirculate(Marina marina, int AMOUNT) {
2232 prln("Begin testSouthRecirculate("+AMOUNT+")");
2235 marina.southRing.enableInstructionSend(false);
2236 marina.southRing.enableInstructionRecirculate(true);
2238 prln("Completely fill south ring");
2240 for (int i=0; i<AMOUNT; i++) {
2241 prln("inserting item " + (i+1) + " / " + AMOUNT);
2242 BitVector path = new BitVector(MarinaPacket.PATH_WIDTH, "path");
2243 BitVector data = new BitVector(MarinaPacket.WORD_WIDTH, "path");
2244 path.set(0, MarinaPacket.PATH_WIDTH, false);
2245 data.setFromLong(i+9);
2246 marina.instrIn.fill(new MarinaPacket(data, false, path));
2250 prln("Drain south ring and check contents");
2252 List<BitVector> out = marina.instrIn.drainMany();
2253 boolean bad = false;
2254 for (int i=0; i<AMOUNT; i++) {
2255 prln("extracting item " + (i+1) + " / " + AMOUNT);
2256 //int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
2258 long got = new MarinaPacket(out.get(i)).data.toLong();
2261 prln(" bad instruction: "+got+" expected: "+expect);
2263 prln(" good instruction.");
2266 fatal(bad, "data inserted does not match data retrieved");
2269 for (int i=0; i<5; i++) {}
2272 prln("End testSouthRecirculate("+AMOUNT+")");
2276 private void testOverfillTokens(Marina marina) {
2277 prln("Begin testOverfillTokens");
2280 for(int i=0; i<marina.TOKEN_FIFO_CAPACITY + 3; i++)
2281 marina.instrIn.fill(SEND_TOKEN);
2282 marina.instrIn.fill(SEND_DATA);
2283 expectNorthFifoExactly(0);
2286 prln("End testSouthRecirculate");
2291 private void doOneTest(int testNum) throws Exception {
2293 doOneTest_(testNum);
2294 } catch (MarinaUtils.FailureException fe) {
2295 System.out.println("******************************************************************************");
2296 System.out.println("******************************************************************************");
2297 System.out.println("******************************************************************************");
2298 System.out.println("******************************************************************************");
2299 fe.printStackTrace();
2304 private void doOneTest_(int testNum) throws Exception {
2306 prln("============================================================");
2307 prln("MarinaTest: performing test: "+testNum);
2312 int[] tests = new int[] { 1002, 1003, 1005, 3002, 3004, 3005, 3006, 3008, 3009, 3025, 3026, 3029 };
2314 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("test.out")));
2315 while(vdd <= 1.3f) {
2316 vdd10.setVoltageWait(vdd);
2317 System.out.println("vdd10 = " + vdd10.readVoltage());
2319 for(int i=0; i<tests.length; i++) {
2321 doOneTest_(tests[i]);
2322 pw.println(vdd + " " + i + " " + "1");
2323 } catch (MarinaUtils.FailureException fe) {
2324 pw.println(vdd + " " + i + " " + "0");
2330 } catch (Exception e) { throw new RuntimeException(e); }
2334 marina.masterClear();
2335 marina.southRing.enableInstructionSend(true);
2338 MarinaUtils.testnum = testNum;
2343 doOneTest(1); // passes extracted parasitics
2344 doOneTest(2); // passes extracted parasitics
2345 doOneTest(3); // passes extracted parasitics
2346 doOneTest(4); // passes extracted parasitics
2347 doOneTest(5); // passes extracted parasitics
2350 doOneTest(1000); // passes extracted parasitics
2351 doOneTest(1001); // passes extracted parasitics
2352 doOneTest(1003); // passes extracted parasitics
2354 doOneTest(3000); // passes extracted parasitics
2355 doOneTest(3001); // passes extracted parasitics
2356 doOneTest(3003); // passes extracted parasitics
2357 doOneTest(3004); // passes extracted parasitics
2358 doOneTest(3005); // passes extracted parasitics
2359 doOneTest(3006); // passes extracted parasitics
2360 doOneTest(3007); // passes extracted parasitics
2361 doOneTest(3008); // passes extracted parasitics
2362 doOneTest(3009); // passes extracted parasitics
2363 doOneTest(3010); // passes extracted parasitics
2364 doOneTest(3011); // passes extracted parasitics
2365 doOneTest(3012); // passes extracted parasitics
2366 doOneTest(3013); // passes extracted parasitics
2367 doOneTest(3014); // passes extracted parasitics
2368 doOneTest(3015); // passes extracted parasitics
2369 doOneTest(3019); // passes extracted parasitics
2370 doOneTest(3020); // passes extracted parasitics
2371 doOneTest(3022); // passes extracted parasitics
2372 doOneTest(3023); // passes extracted parasitics
2373 doOneTest(3025); // passes extracted parasitics
2374 doOneTest(3026); // passes extracted parasitics
2375 doOneTest(3027); // passes extracted parasitics
2376 doOneTest(3028); // passes extracted parasitics
2377 doOneTest(3029); // passes extracted parasitics
2378 //doOneTest(3030); // passes extracted parasitics (questionable)
2379 //doOneTest(3031); // passes extracted parasitics should not pass!
2381 // these tests take a while and usually pass
2393 // this takes an insanely long time
2397 case 1: testChains(marina); break; // passes, 24-Mar (+verilog)
2398 case 2: testProperStoppers(marina); break; // passes, 24-Mar (+verilog)
2399 case 3: testSouthRecirculate(marina, 1); break; // passes, 24-Mar (+verilog)
2400 case 4: getCtrsFlags(marina); break; // 20-Apr (+verilog)
2401 case 5: sendInstructions(marina); break; // passes, 24-Mar (+verilog)
2402 case 6: walkOneOLC(marina); break; // 21-Apr (+verilog)
2404 // Russell's tests begin with 1000
2405 case 1000: walkOneILC(marina); break; // 20-Apr (+verilog)
2406 case 1001: countIlc(marina); break; // 20-Apr (+verilog)
2407 case 1002: countOlc(marina); break; // 23-Apr (+verilog)
2409 case 1003: sendTorpedo(marina); break; // 23-Apr (+verilog) [with wor-hack]
2411 case 1004: flipIlcBit(marina); break; // 20-Apr (+verilog)
2412 case 1005: flipOlcBit(marina); break; // 21-Apr (+verilog)
2414 case 1006: testSouthRecirculate(marina, Marina.SOUTH_RING_CAPACITY-1); break; // passes, 24-Mar (+verilog)
2416 // Adam's tests begin with 3000
2417 case 3000: sendToken(marina); break; // passes, 24-Mar (+verilog)
2418 case 3001: testFlagAB(marina); break; // passes, 08-Apr (+verilog)
2419 case 3002: testPredicationOnAB(marina); break; // 22-Apr (+verilog)
2420 case 3003: testFlagC(marina); break; // 23-Apr (+verilog)
2421 case 3004: testFlagD(marina); break; // 23-Apr (+verilog)
2422 case 3005: testFlagDRecomputationTime(marina); break;
2424 case 3006: testTailWaitsForHead(marina); break;
2425 case 3007: testTailWithoutHead(marina); break;
2426 case 3008: testHeadWaitsForTail(marina); break; // 22-Apr (+verilog)
2427 case 3009: testAbort(marina); break; // 22-Apr (+verilog)
2429 case 3010: sendData(marina); break; // passes, 24-Mar (+verilog)
2430 case 3011: recvData(marina); break; // 21-Apr (+verilog)
2431 case 3012: sendDataWithPath(marina); break; // passes, 13-Apr (+verilog)
2433 case 3013: testSignExtendedLiteral(marina); break; // 20-Apr (+verilog)
2434 case 3014: testShiftedLiteral(marina); break; // 20-Apr (+verilog)
2435 case 3015: testSendAndRecvToken(marina); break; // 21-Apr (+verilog)
2437 case 3016: sendDataIlcInfinite(marina); break; // 22-Apr (+verilog)
2438 case 3017: testFlagTruthTable(marina); break; // 23-Apr (+verilog)
2440 case 3019: setOlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2441 case 3020: setIlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2442 case 3021: recvPath(marina); break; // 22-Apr (+verilog)
2443 case 3022: testILC(marina); break; // 23-Apr (+verilog)
2444 case 3023: testTorpedoOnAnInfinite(marina); break; // 23-Apr (+verilog)
2445 case 3024: testRecvAndSendWalkingOne(marina); break; // 21-Apr (+verilog)
2446 case 3025: testOlcDecrementAtHighSpeed(marina); break; // 23-Apr (+verilog)
2448 case 3026: testNonTorpedoableMoveDoesNotResetDFlag(marina); break; // 23-Apr (+verilog)
2449 case 3027: testILCZero(marina); break;
2450 case 3028: testAbortOutsideOfLoop(marina); break;
2451 case 3029: testDFlagWhenTorpedoLyingInWait(marina); break;
2452 case 3030: testSetOlcFollowedByDPredicated(marina); break;
2453 case 3031: testOverfillTokens(marina); break;
2455 case 3040: loadEveryValueOLC(marina); break;
2457 SubchainNode chainNode =
2458 (SubchainNode)marina.dukeChain
2459 .findNode("marina.duke.marinaGu@0.dukeAll@1.dukePart@0.ring37sW@1.scanner@0.scanFx1@1.scanCell@3");
2460 int bitIndex = chainNode.getBitIndex();
2461 ChainNode root = chainNode.getParentChain();
2463 for(int i=0; i<13; i++) {
2464 System.out.println("i="+i);
2465 for(int j=0; j<12; j++)
2466 root.getInBits().set(bitIndex+j, false);
2467 root.getInBits().set(bitIndex+i, true);
2468 marina.shiftDuke(false, true);
2478 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("out.dat")));
2481 vdd18.setVoltageWait((float)Math.max(1.8,vdd));
2482 //vdd10.setVoltageWait(vdd);
2484 if (!Marina.kesselsCounter) throw new RuntimeException();
2485 if (!Marina.omegaCounter) throw new RuntimeException();
2487 for(int xx=1; xx<65; xx++) {
2488 marina.masterClear();
2490 marina.stopAndResetCounters();
2492 marina.southRing.enableInstructionSend(true);
2493 marina.southRing.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
2494 Instruction.Set.FlagFunction.ZERO
2495 .add(Predicate.FlagA).add(Predicate.NotFlagA),
2496 Instruction.Set.FlagFunction.ZERO));
2497 //int xx = 63; // 1.802ms
2498 //int xx = 1; // 0.207ms => 24.3ns for 62 counts => 390ps cycle time => 2.5Ghz
2499 marina.southRing.fill(new Instruction[] {
2500 new Instruction.Head(dock),
2504 TORPEDOABLE_RECV_DATA,
2508 new Instruction.Tail(dock),
2511 marina.southRing.fill(new Instruction[] {
2513 new Instruction.Set(dock,Predicate.FlagD,
2514 Instruction.Set.FlagFunction.ZERO.add(Predicate.NotFlagA),
2515 Instruction.Set.FlagFunction.ZERO),
2518 SEND_DATA_IF_A_SET_AND_D_NOT_SET,
2520 SEND_DATA_IF_A_SET_AND_D_NOT_SET,
2523 SEND_DATA_IF_A_SET_AND_D_NOT_SET,
2537 //marina.startCounters(false, false);
2539 marina.instrIn.run();
2541 vdd10.setVoltageWait(vdd);
2542 marina.startCounters(false, true);
2544 try { Thread.sleep(wait); } catch (Exception e) { }
2545 //marina.instrIn.stop();
2547 marina.stopAndResetCounters();
2548 int countNorth = marina.getNorthCount();
2549 int countSouth = marina.getSouthCount();
2550 pw.println(xx + " " + countNorth + " " + vdd + " " + vdd10.readCurrent());
2552 System.out.println(xx + " " + countNorth + " " + vdd + " " + vdd10.readCurrent());
2563 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("out.dat")));
2564 for(double myvdd = 1.00; myvdd<1.01; myvdd += 0.05) {
2566 vdd18.setVoltageWait((float)Math.max(1.8,vdd));
2567 vdd10.setVoltageWait(vdd);
2570 for(int toks = 0; toks < 13; toks++) {
2573 for(int iter = 0; iter < MAX_ITER; iter++) {
2575 marina.masterClear();
2577 marina.stopAndResetCounters();
2579 marina.southRing.enableInstructionSend(true);
2580 marina.southRing.fill(setOlc(1));
2581 marina.southRing.fill(new Instruction.Head(dock));
2582 for(int i=0; i<toks; i++)
2583 marina.southRing.fill(/*SEND_DATA*/NOP);
2584 marina.southRing.fill(new Instruction[] {
2585 new Instruction.Tail(dock),
2588 marina.instrIn.run();
2590 // have to set the voltage while drawing current
2591 vdd10.setVoltageWait(vdd);
2593 marina.startCounters();
2594 try { Thread.sleep(wait); } catch (Exception e) { }
2595 marina.stopAndResetCounters();
2596 //marina.instrIn.stop();
2598 int countNorth = marina.getNorthCount();
2599 int countSouth = marina.getSouthCount();
2600 System.out.println();
2601 System.out.println();
2602 if (countSouth > (2<<29))
2603 System.out.println("warning: count was greater than 2^29...");
2604 double gst = ((((double)countSouth*2)) / (1000000. * wait /* * toks*/));
2605 System.out.println("south counter is: " + countSouth + ", which is " + gst + "Ginst/sec with toks="+toks + " @vdd="+vdd);
2608 System.out.println();
2609 System.out.println();
2611 System.out.println("counters are " + count + " and " + countNorth + "; ratio is "+
2612 (((double)countNorth)/((double)(count*2))) + " " +
2613 (((double)countNorth)/((double)(count*2+1))) + " " +
2617 float vdd10v = vdd10.readVoltage();
2618 float vdd18v = vdd18.readVoltage();
2619 float vddsv = vdds.readCurrent();
2620 float vdd10c = vdd10.readCurrent();
2621 float vdd18c = vdd18.readCurrent();
2622 pw.println(vdd + " " +
2624 (((double)total) / MAX_ITER) + " " +
2641 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("out.dat")));
2642 for(int toks = 0; toks < 13; toks++) {
2645 for(int iter = 0; iter < MAX_ITER; iter++) {
2647 marina.masterClear();
2649 marina.stopAndResetCounters();
2651 marina.southRing.enableInstructionSend(true);
2652 marina.southRing.fill(setOlc(1));
2653 marina.southRing.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
2654 Instruction.Set.FlagFunction.ZERO,
2655 Instruction.Set.FlagFunction.ZERO));
2656 marina.southRing.fill(new Instruction.Head(dock));
2657 //marina.southRing.fill(setIlc(31));
2658 marina.southRing.fill(SEND_DATA);
2659 for(int i=0; i<toks+1; i++) {
2660 //marina.southRing.fill(FLAG_NOP_IF_FLAG_A);
2661 marina.southRing.fill(FLAG_NOP);
2663 marina.southRing.fill(new Instruction[] {
2664 new Instruction.Tail(dock),
2666 marina.startCounters();
2668 marina.instrIn.run();
2669 try { Thread.sleep(wait); } catch (Exception e) { }
2671 marina.stopAndResetCounters();
2672 int countNorth = marina.getNorthCount();
2673 int count = marina.getSouthCount();
2674 System.out.println();
2675 System.out.println();
2676 if (count > (2<<29))
2677 System.out.println("warning: count was greater than 2^29...");
2678 double gst = ((((double)count*2)) / (1000000. * wait /* * toks*/));
2679 System.out.println("south counter is: " + count + ", which is " + gst + "Ginst/sec with toks="+toks + " @vdd="+vdd);
2682 System.out.println();
2683 System.out.println();
2685 pw.println(vdd + " " + toks + " " + (((double)total) / MAX_ITER));
2691 loadEveryValueOLC(marina);
2696 fatal(true, "Test number: "+testNum+" doesn't exist.");
2699 // If we get here then test passed
2700 prln("Test Result: Passed");
2702 //Infrastructure.exit(0);
2706 //============================ for public use =============================
2709 * 0: test detected success
2710 * 2: test detected failure
2713 public static void main(String[] args) throws Exception {
2714 startTime = System.currentTimeMillis();
2715 new MarinaTest(args);