1 package com.sun.vlsi.chips.marina.test;
2 /* -*- tab-width: 4 -*- */
3 import java.util.ArrayList;
6 import com.sun.electric.tool.simulation.test.*;
7 import com.sun.vlsi.chips.marina.test.Marina.Ilc;
8 import com.sun.vlsi.chips.marina.test.CmdArgs;
9 import com.sun.vlsi.chips.marina.test.CmdArgs.Mode;
11 import edu.berkeley.fleet.api.Dock;
12 import edu.berkeley.fleet.api.Instruction;
13 import edu.berkeley.fleet.api.Predicate;
14 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
15 import edu.berkeley.fleet.api.Instruction.Set.SetSource;
16 import edu.berkeley.fleet.marina.MarinaFleet;
17 import edu.berkeley.fleet.marina.MarinaPath;
24 public class MarinaTest {
25 public static final MarinaFleet marinaFleet = new MarinaFleet();
26 public static final Dock dock = marinaFleet.getOnlyInputDock();
28 public static float vdd = 1.0f;
30 //-------------------------- constants -----------------------------------
31 private static final String SCAN_CHAIN_XML = "marina.xml";
32 private static final String NET_LIST = "marina.spi";
34 public static final int INSTR_SZ = 36;
37 public static final Instruction.Set.FlagFunction CLEAR_FLAG
38 = Instruction.Set.FlagFunction.ZERO;
39 public static final Instruction.Set.FlagFunction SET_FLAG
40 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA)
41 .add(Predicate.NotFlagA);
42 public static final Instruction.Set.FlagFunction A_FLAG
43 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA);
45 public static final Instruction.Set.FlagFunction B_FLAG
46 = Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB);
48 // COLUMN_LATENCY is a delay that is larger than the latency through an Infinity column
49 private static final int COLUMN_LATENCY = 10; // nanoseconds
52 // Officially, this should be the number of requeueing no-ops that
53 // can be inserted into an idle dock whose OLC is nonzero.
55 // Less formally, this is roughly the number of stages of
56 // buffering between the instruction insertion point and the
57 // instruction ring, plus the capacity of the instruction ring.
58 private static final int INSTRUCTION_IN_SATURATION_AMOUNT = 19;
60 // This is some number which is significantly greater than
61 // INSTRUCTION_IN_SATURATION_AMOUNT. Increasing it may slow the tests down, but
62 // will never cause them to operate incorrectly.
63 private static final int MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT = 25;
65 // This is the number of items which can be in the instruction
66 // fifo ring WITHOUT causing it to stop circulating.
67 private static final int INSTRUCTION_RING_CAPACITY = 13;
69 // Officially, this should be the number of data items which can
70 // be sent from the dock while the "data" proper stopper is in
71 // the "stopped" state
73 // Less formally, this is roughly the number of stages of
74 // buffering between the dock's data successor and the "data"
77 FIXME: what is the correct value here?
78 private static final int DATA_OUT_SATURATION_AMOUNT = XXX;
81 // This is some number which is greater than
82 // DATA_OUT_SATURATION_AMOUNT, but less than the capacity of the
84 private static final int MORE_THAN_DATA_OUT_SATURATION_AMOUNT = 10;
86 // Nominal cycle time assuming 4 GHz throughput
87 public static double CYCLE_TIME_NS;
89 //-------------------------------- types ---------------------------------
91 //-------------------------- private data --------------------------------
92 private static long startTime;
94 public static Indenter indenter = new Indenter();
95 private Marina marina;
96 private ChipModel model;
97 //private ChainControl cc;
98 //private JtagTester tester;
99 private CmdArgs cmdArgs;
100 private PowerChannel corePowerSupply, padsPowerSupply;
101 private VoltageReadable coreVoltmeter, voltmeterForCurrent;
105 private ChainTest ctD, ctR, ctC, ct;
106 private ChainControl ccD, ccR, ccC, cc;
108 //-------------------------- private methods -----------------------------
109 /** @return true if simulation. Return false if we're testing silicon. */
110 private boolean sim() {return model instanceof SimulationModel;}
112 private void prln(String msg) {indenter.prln(msg);}
113 private void pr(String msg) {indenter.pr(msg);}
114 private void adjustIndent(int n) {indenter.adjustIndent(n);}
116 public static void fatal(boolean pred, String msg) { MarinaUtils.fatal(pred, msg); }
118 public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) {
119 // FIXME: better error reporting needed here
121 fatal(bv1.getNumBits()!=bv2.getNumBits(), "lengths do not match");
123 boolean mismatch = false;
125 for(int i=0; i<bv1.getNumBits(); i++) {
126 if (bv1.get(i) != bv2.get(i)) {
131 fatal(mismatch, "bit vectors do not match on bits " + err + "\n "+bv1+"\n "+bv2);
134 private static void printTestTime() {
135 long endTime = System.currentTimeMillis();
136 System.out.println("Test took: "+(endTime-startTime)/1000.0+" sec");
139 // Tell user what we're about to do
140 private static void reportTask(CmdArgs args) {
141 System.out.println("Begin testing Marina");
143 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
144 System.out.println(" Simulate whole chip, schematic parasitics");
146 case WHOLE_CHIP_LAYOUT_PARASITICS:
147 System.out.println(" Simulate whole chip, layout parasitics");
150 System.out.println(" Test silicon");
153 fatal(true, "unrecognized CmdArgs.Mode");
157 private void setUpSuppliesAndMeters(Station station) {
158 // set up power supplies and meters
160 prln("Testing station: "+station);
161 Infrastructure.gpibControllers = new int[] {0};
162 switch (cmdArgs.station) {
164 corePowerSupply = new Pst3202Channel("ch1", "HPST3202", 1);
165 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202", 2);
168 corePowerSupply = new Pst3202Channel("ch1", "HPST3202B", 1);
169 padsPowerSupply = new Pst3202Channel("ch2", "HPST3202B", 2);
172 fatal(true, "Unrecognized station: "+cmdArgs.station);
174 corePowerSupply.setCurrent((float)1.7);
175 corePowerSupply.setVoltageWait((float)1.0);
177 padsPowerSupply.setCurrent((float)0.100);
178 padsPowerSupply.setVoltageWait((float)1.8);
180 coreVoltmeter = new HP34401A(station.coreVoltmeter);
181 voltmeterForCurrent = new HP34401A(station.currentVoltmenter);
185 private MarinaTest(String[] args) throws Exception {
186 cmdArgs = new CmdArgs(args);
188 if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim();
191 static PowerChannel vdd18;
192 static PowerChannel vdd10;
194 private void doSim() throws Exception {
196 switch (cmdArgs.mode) {
197 case WHOLE_CHIP_SCHEMATIC_PARASITICS:
198 netListName = NET_LIST;
200 case WHOLE_CHIP_LAYOUT_PARASITICS:
201 netListName = "marina_pads_guts.spi";
204 fatal(true, "unrecognized CmdArgs.Mode");
208 Infrastructure.gpibControllers = new int[]{1};
209 vdd18 = new Pst3202Channel("ch2", "tiPST3202", 2);
210 vdd10 = new Pst3202Channel("ch3", "tiPST3202", 3);
211 vdd10.setVoltageNoWait(vdd);
212 vdd18.setVoltageNoWait(1.8f);
214 model = cmdArgs.useVerilog
220 : new NanosimModel();
222 if (model instanceof SimulationModel)
223 ((SimulationModel)model).setOptimizedDirectReadsWrites(true);
225 CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250;
227 model instanceof VerilogModel
231 : model instanceof ChipModel
235 System.err.println("constructing jtag controller");
237 model instanceof SimulationModel
238 ? ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO")
239 : new Netscan("jtag2"); // bad kessels counter
240 //: new Netscan4("jtag3", 4); // good kessels counter
241 JtagLogicLevel mc0=null;
242 JtagLogicLevel mc1=null;
243 if (tester instanceof Netscan) {
244 ((Netscan)tester).reset();
246 // not sure if "GPIO1" means "index 0" or not
247 mc0 = new JtagLogicLevel(tester, 0);
248 mc1 = new JtagLogicLevel(tester, 1);
249 mc0.setLogicState(true);
250 mc1.setLogicState(true);
253 Logger.setLogInits(true);
254 tester.setLogSets(true);
255 tester.setLogOthers(true);
256 tester.setAllLogging(true);
257 tester.printInfo = true;
259 tester.printInfo = false;
261 ChainControls ccs = new ChainControls();
262 PowerChannel pc = new ManualPowerChannel("pc", false);
264 JtagTester testerD, testerR, testerC;
265 testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null);
266 testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null);
267 testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null);
268 testerD.printInfo = testerR.printInfo = testerC.printInfo = false;
270 ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz);
271 ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz);
272 ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz);
273 ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
276 ctD = new ChainTest(ccD, pc);
277 ctR = new ChainTest(ccR, pc);
278 ctC = new ChainTest(ccC, pc);
281 ccs.addChain(Marina.DATA_CHAIN, ccD);
282 ccs.addChain(Marina.REPORT_CHAIN, ccR);
283 ccs.addChain(Marina.CONTROL_CHAIN, ccC);
286 PowerChannel ch2 = new Pst3202Channel("ch2", "tiPST3202", 2);
287 PowerChannel ch3 = new Pst3202Channel("ch3", "tiPST3202", 3);
288 Infrastructure.gpibControllers = new int[]{1};
289 ch2.setVoltageNoWait(1f);
290 ch3.setVoltageNoWait(1.8f);
294 cc = new ChainControl(SCAN_CHAIN_XML, tester, 1.8f, khz);
295 cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
296 ct = new ChainTest(cc, pc);
297 ccs.addChain(Marina.DATA_CHAIN, cc);
298 ccs.addChain(Marina.REPORT_CHAIN, cc);
299 ccs.addChain(Marina.CONTROL_CHAIN, cc);
300 ccs.addChain(Marina.DUKE_CHAIN, cc);
302 marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter);
306 if (model instanceof NanosimModel) {
307 NanosimLogicSettable mc = (NanosimLogicSettable)
308 ((SimulationModel)model).createLogicSettable(Marina.MASTER_CLEAR);
309 mc.setInitState(true);
312 prln("starting model");
313 if (model instanceof VerilogModel)
314 ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift);
315 else if (model instanceof HsimModel)
316 ((SimulationModel)model).start("hsim64", netListName, 0, !cmdArgs.jtagShift);
317 else if (model instanceof NanosimModel)
318 ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift);
321 prln("model started");
324 prln("deasserting master clear");
325 if (model instanceof SimulationModel)
326 ((SimulationModel)model).setNodeState(Marina.MASTER_CLEAR, 0);
328 marina.masterClear();
331 if (cmdArgs.testNum!=0 && cmdArgs.testNum!=1) {
333 cc.shift(Marina.CONTROL_CHAIN, false, true);
336 doOneTest(cmdArgs.testNum);
338 if (model instanceof SimulationModel)
339 ((SimulationModel)model).finish();
341 private void doSilicon() throws Exception {
342 model = new SiliconChip();
343 String ip = cmdArgs.station.ipAddr;
344 JtagTester tester = new Netscan4(ip, cmdArgs.station.jtagChannel);
345 tester.printInfo = false;
347 ChainControl cc = new ChainControl("???", tester, 1.8f, khz);
348 cc.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE;
349 ChainControls ccs = new ChainControls();
350 ccs.addChain(Marina.DATA_CHAIN, cc);
351 ccs.addChain(Marina.REPORT_CHAIN, cc);
352 ccs.addChain(Marina.CONTROL_CHAIN, cc);
353 marina = new Marina(ccs, model, false, indenter);
354 PowerChannel pc = new ManualPowerChannel("pc", false);
355 ChainTest ct = new ChainTest(cc, pc);
356 ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING);
357 doOneTest(cmdArgs.testNum);
358 setUpSuppliesAndMeters(cmdArgs.station);
361 /** In the absence of looping, the longest path through Infinity is 4 column delays */
362 private void waitUntilQuiescent() {
363 model.waitNS(4*COLUMN_LATENCY);
366 private double readCurrent() {
367 return voltmeterForCurrent.readVoltage() / cmdArgs.station.ammeterShuntResistance;
370 /** Generate List of BitVectors where Token=true, high 25 data bits
371 * are alternating ones and zeros, low 12 data bits increment from
372 * zero, and address is given by addr. */
373 private List<BitVector> makeIncrDataConstAdr(int num, int addr) {
374 List<BitVector> ans = new ArrayList<BitVector>();
375 BitVector dHi = new BitVector(25, "dataHi");
376 BitVector dLo = new BitVector(12, "dataLo");
377 BitVector t = new BitVector("1", "token");
378 BitVector a = new BitVector(14, "addr");
379 dHi.setFromLong(0x00aaaaa);
381 for (int i=0; i<num; i++) {
383 ans.add(dHi.cat(dLo).cat(t).cat(a));
388 private void stopToStop(ProperStopper s1, ProperStopper s2,
390 List<BitVector> din) {
391 prln("Begin stopToStop");
396 long ctrStart = ctr==null ? 0 : ctr.getCount();
399 waitUntilQuiescent();
401 List<BitVector> dout = s2.drainMany();
403 MarinaUtils.compareItemsOrdered(din, dout);
406 long ctrEnd = ctr.getCount();
407 long delta = ctrEnd - ctrStart;
408 long expect = din.size();
410 "counter delta wrong: expected delta: "+expect+
411 " counter before:"+ctrStart+" counter after:"+ctrEnd);
415 prln("End stopToStop");
417 /** Burst data from src to dst. gate is stopped while loading src. gate
418 * is then run to allow the burst to flow. */
419 private void stopToStopBurst(ProperStopper src, ProperStopper gate,
422 List<BitVector> din) {
423 prln("Begin stopToStopBurst test");
429 long ctrStart = ctr==null ? 0 : ctr.getCount();
432 waitUntilQuiescent();
434 // open the gate to start the burst
436 waitUntilQuiescent();
438 List<BitVector> dout = dst.drainMany();
440 MarinaUtils.compareItemsOrdered(din, dout);
443 long ctrEnd = ctr.getCount();
444 long delta = ctrEnd - ctrStart;
446 long expectA = din.size();
447 fatal(delta!=expectA,
448 "counter delta wrong: expected delta: "+expectA+
449 " counter before:"+ctrStart+" counter after:"+ctrEnd);
453 prln("End stopToStopBurst test");
456 private void stopToStopOne(ProperStopper s1, ProperStopper s2,
457 Counter ctr, int adr) {
458 prln("Begin stopToStopOne");
461 List<BitVector> din = makeIncrDataConstAdr(1, adr);
462 stopToStop(s1, s2, ctr, din);
465 prln("End stopToStopOne");
468 private void stopToStopThree(ProperStopper s1, ProperStopper s2,
469 Counter ctr, int adr) {
470 prln("Begin stopToStopOne");
473 List<BitVector> din = makeIncrDataConstAdr(3, adr);
474 stopToStop(s1, s2, ctr, din);
477 prln("End stopToStopOne");
480 private int indexOf(BitVector o, List<BitVector> dIn) {
481 for (int i=0; i<dIn.size(); i++) {
482 if (o.equals(dIn.get(i))) return i;
486 private String ringDump(List<BitVector> dIn, List<BitVector> dOut) {
487 StringBuffer sb = new StringBuffer();
488 sb.append(" ring dump: ");
489 for (BitVector o : dOut) {
490 sb.append(indexOf(o, dIn)+" ");
492 return sb.toString();
495 private int[][] makeIntArray2D(int a, int b) {
496 int[][] ans = new int[a][];
497 for (int i=0; i<a; i++) ans[i] = new int[b];
501 //=========================================================================
502 // Put top level tests here
504 private void testChains(Marina marina) {
506 prln("Testing control chain...");
507 ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
509 ccC.shift(Marina.CONTROL_CHAIN, false, true);
513 prln("Testing data chain...");
514 ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
516 //ccD.shift(Marina.DATA_CHAIN, false, true);
520 prln("Testing report chain...");
521 ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
523 //ccR.shift(Marina.REPORT_CHAIN, false, true);
527 prln("Testing control chain...");
528 ct.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING);
530 cc.shift(Marina.CONTROL_CHAIN, false, true);
531 prln("Testing data chain...");
532 ct.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING);
533 prln("Testing report chain...");
534 ct.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING);
538 private void testProperStoppers(Marina marina) {
539 prln("Begin testProperStoppers");
542 for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) {
544 prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper");
547 prln("un-stopping stopper");
549 fatal( ps.getStopped(), "stopper should not have been stopped, but was");
551 prln("stopping stopper");
553 fatal( !ps.getStopped(), "stopper should have been stopped, but was not");
561 private void sendInstructions(Marina marina) {
562 prln("Begin sendInstructions");
565 List<BitVector> din = new ArrayList<BitVector>();
567 BitVector count = new BitVector(MarinaPacket.WORD_WIDTH,"count");
568 BitVector one = new BitVector(MarinaPacket.WORD_WIDTH, "one");
569 count.setFromLong(0);
571 for (int i=0; i<3; i++) {
573 count = count.add(one);
576 for(BitVector d : din)
577 marina.instrIn.fill(new MarinaPacket(d, false, MarinaPacket.null_path));
580 prln("End sendInstructions");
583 private void sendToken(Marina marina) {
584 prln("Begin sendToken");
587 //getCtrsFlags(marina);
589 int nbToks = marina.getNumTokens();
590 fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens");
592 marina.instrIn.fill(setIlc(1));
593 marina.instrIn.fill(SEND_TOKEN);
594 nbToks = marina.getNumTokens();
595 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
598 prln("End sendToken");
601 private void sendData(Marina marina) {
602 prln("Begin sendData");
605 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
606 for(int i=0; i<bv.length(); i+=2) bv.set(i, false);
607 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
609 marina.instrIn.fill(setIlc(1));
610 marina.instrIn.fill(SEND_DATA);
612 List<BitVector> dataItems = marina.data.drainMany();
613 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
615 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
616 fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token");
619 prln("End sendData");
622 private void sendDataIlcInfinite(Marina marina) {
623 prln("Begin sendDataIlcInfinite");
626 marina.fillSouthProperStopper(new Instruction[] {
627 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
633 List<BitVector> dataItems = marina.data.drainMany(howmany);
634 fatal(dataItems.size()!=howmany,
635 "Expected an unending supply of data items to emerge but only got got: "+dataItems.size());
638 prln("End sendDataIlcInfinite");
641 private Instruction setOlc(int olc) {
642 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc);
644 private Instruction setOlcIfZero(int olc) {
645 return new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, olc);
647 private Instruction setIlc(int ilc) {
648 return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, ilc);
651 private void testFlagD(Marina marina) {
652 prln("Begin testFlagD");
655 List<BitVector> toks;
657 Predicate only_if_olc_zero = Predicate.FlagD;
658 Predicate only_if_olc_nonzero = Predicate.Default;
660 marina.instrIn.fill(setIlc(1));
662 for(int olc : new int[] { 1, 0 }) {
663 for(boolean predicate_olc_nonzero : new boolean[] { true, false }) {
664 prln("Attempting send data item with "+
666 "predicate olc"+(predicate_olc_nonzero?"!=0":"==0"));
669 marina.fillSouthProperStopper(new Instruction[] {
671 new Instruction.Move(dock,
672 predicate_olc_nonzero // predicate
673 ? only_if_olc_nonzero
676 false, // torpedoable
686 expectNorthFifoExactly((predicate_olc_nonzero == (olc!=0)) ? 1 : 0);
688 for(int i=0; i<olc; i++)
689 marina.instrIn.fill(DEC);
695 prln("End testFlagD");
698 private void testPredicationOnAB(Marina marina) {
699 prln("Begin testPredicationOnAB");
702 List<BitVector> dItems;
704 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1));
705 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1));
707 for(boolean flag_a : new boolean[] { false, true }) {
708 for(boolean flag_b : new boolean[] { false, true }) {
709 prln("Setting flags, a="+flag_a+" b="+flag_b);
710 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
712 ? Instruction.Set.FlagFunction.ONE
713 : Instruction.Set.FlagFunction.ZERO,
715 ? Instruction.Set.FlagFunction.ONE
716 : Instruction.Set.FlagFunction.ZERO
718 getCtrsFlags(marina);
721 for(Predicate predicate : new Predicate[] {
729 prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate);
731 marina.instrIn.fill(new Instruction.Move(dock,
732 predicate, // predicate
733 false, // torpedoable
743 dItems = marina.data.drainMany();
744 int expected = predicate.evaluate(flag_a, flag_b, false, false) ? 1 : 0;
745 fatal(dItems.size()!=expected, "Expected "+expected+" data items to emerge but got: "+
746 dItems.size()+" items(s)");
752 prln("End testPredicationOnAB");
756 private void showOlc() {
757 prln("OLC=="+marina.getOLC());
759 private void expectOlc(int x) {
760 int olc = marina.getOLC();
761 fatal(x!=olc, "expected OLC=="+x+", but scanned out OLC=="+olc);
764 private void getCtrsFlags(Marina marina) {
765 prln("begin getCtrsFlags");
769 Ilc ilc = marina.getILC();
770 prln("ILC.done=="+ilc.getDone()+
771 " ILC.infinity=="+ilc.getInfinity()+
772 " ILC.count=="+ilc.getCount());
773 prln("flagA=="+marina.getFlagA());
774 prln("flagB=="+marina.getFlagB());
776 prln("end getCtrsFlags");
779 private void walkOneOLC(Marina marina) {
780 prln("Begin walkOneOLC");
783 //for (int i=-1; i<6; i++) {
784 marina.fillSouthProperStopper(new Instruction[] {
786 new Instruction.Head(dock),
788 // new Instruction.Set(dock,Predicate.IgnoreFlagD, SetDest.OuterLoopCounter, 1),
792 TORPEDOABLE_RECV_DATA,
798 //new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement),
800 new Instruction.Tail(dock),
802 marina.fillSouthProperStopper(new Instruction[] {
807 BitVector bits = null;
808 marina.shiftReport(true, false);
809 for(int i=0; i<4; i++) {
810 BitVector x = marina.cc.getOutBits(marina.REPORT_CHAIN+"."+marina.OLC_PATH_KESSEL+i);
811 //System.out.println("bits are: " + x);
812 bits = bits==null ? x : bits.cat(x);
814 System.out.println("dec="+bits.get(0));
815 if (bits.get(1)) throw new RuntimeException();
818 /* for (int i=0; i<64; i++) {
820 if (marina.kesselsCounter) {
821 System.out.println("master-clearing...");
822 // master clear on each iteration; otherwise we'd need to "run down" the olc
823 marina.masterClear();
824 marina.enableInstructionSend(true);
827 expectTokensExactly(0);
830 int inOlc = i==-1 ? 0 : (1<<i);
832 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc));
833 marina.instrIn.fill(SEND_DATA_IF_D_SET);
834 marina.instrIn.fill(SEND_DATA_IF_D_NOT_SET);
835 marina.instrIn.fill(SEND_DATA);
837 model.waitNS(128 * CYCLE_TIME_NS);
840 prln("walkOneOLC: "+inOlc+" checks out");
841 expectNorthFifoExactly(0);
844 prln("End walkOneOLC");
847 private void walkOneILC(Marina marina) {
848 prln("Begin walkOneILC");
850 for (int i=0; i<6; i++) {
851 // Mask off the "zero" bit position
853 prln("inIlc="+inIlc);
854 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc));
855 Ilc ilc = marina.getILC();
856 int outIlc = ilc.getCount();
857 fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc);
858 fatal(ilc.getInfinity(), "bad Infinity bit: true");
860 prln("Now test the infinity bit");
861 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity));
862 Ilc ilc = marina.getILC();
863 fatal(!ilc.getInfinity(), "bad Infinity bit: false");
865 prln("End walkOneILC");
867 private void countIlc(Marina marina) {
868 final int maxIlc = 63;
869 prln("Begin countIlc");
872 marina.instrIn.fill(new
873 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc));
875 int ilc = marina.getILC().getCount();
876 fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc);
878 prln("execute a move instruction that does nothing except decrement the ILC to zero");
880 new Instruction.Move(dock,
881 Predicate.IgnoreFlagD, // predicate
882 false, // torpedoable
892 // wait for ILC to count from 63 to 0
893 model.waitNS(128 * CYCLE_TIME_NS);
894 //model.waitNS(10000);
896 prln("Check that ILC==0");
897 ilc = marina.getILC().getCount();
898 fatal(ilc!=0, "bad ILC count: "+ilc+" expected: "+0);
901 prln("End countIlc");
903 // Note: countOlc takes 44 minutes to run on nanosim
904 private void countOlc(Marina marina) {
906 prln("Begin countOlc");
909 marina.instrIn.fill(setOlc(maxOlc));
911 for (int i=maxOlc; i>=0; i--) {
912 model.waitNS(128 * CYCLE_TIME_NS);
913 prln("OLC should be: "+i);
915 marina.instrIn.fill(new
916 Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement));
920 prln("End countOlc");
922 private void loadEveryValueOLC(Marina marina) {
925 for (int i=0; i<(1<<6); i++) {
927 if (marina.kesselsCounter) {
928 System.out.println("master-clearing...");
929 // master clear on each iteration; otherwise we'd need to "run down" the olc
930 marina.masterClear();
931 marina.enableInstructionSend(true);
935 marina.fillSouthProperStopper(new Instruction[] {
939 // to ensure that instruction is bubble-limited
942 // the Set-OLC instruction
943 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc),
945 // put a Set-ILC instruction right behind it with inverted bits to be sure we're
946 // not capturing the instruction-latch value too late in the cycle
947 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, (inOlc ^ (~(-1<<6)))),
951 model.waitNS(128 * CYCLE_TIME_NS);
952 marina.fillNorthProperStopper();
953 model.waitNS(128 * CYCLE_TIME_NS);
956 prln("loadEveryValueOLC: "+inOlc+" checks out");
961 private void saturateInstructionFifo(Marina marina, Instruction instruction, int quantity, boolean expect_it_to_jam_up) {
962 prln("Inserting "+quantity+" copies of \"" + instruction + "\"");
965 for(i=0; i<quantity; i++) {
966 prln("Inserting instruction " + (i+1) +"/"+ quantity);
967 marina.instrIn.fill(instruction);
968 boolean jammed = (marina.instrIn.getFillStateWire()==MarinaUtils.StateWireState.FULL);
969 if (jammed && expect_it_to_jam_up) {
970 prln("Stopper remained full after inserting instruction; this was expected; we are happy.");
974 fatal(jammed, "Instruction stopper did not drain after inserting " + (i+1) + " instructions; not good!");
976 fatal(expect_it_to_jam_up, "Expected instruction stopper to jam up, but it did not");
978 prln("Successfully inserted " + i + " instructions");
981 private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(),
982 MarinaUtils.sunToBerk(MarinaPacket.null_path));
984 private static final Instruction DEC =
985 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, SetSource.Decrement);
987 private static final Instruction FLAG_NOP =
988 new Instruction.Set(dock, Predicate.IgnoreFlagD,
989 CLEAR_FLAG.add(Predicate.FlagA),
990 CLEAR_FLAG.add(Predicate.FlagB));
992 private static final Instruction NOP =
993 new Instruction.Move(dock,
994 Predicate.IgnoreFlagD, /* predicate */
995 false, /* torpedoable */
999 false, /* latchData */
1000 false, /* latchPath */
1001 false, /* dataOut */
1002 false /* tokenOut */
1005 private static final Instruction SEND_DATA =
1006 new Instruction.Move(dock,
1007 Predicate.IgnoreFlagD, /* predicate */
1008 false, /* torpedoable */
1009 null_path, /* path */
1010 false, /* tokenIn */
1012 false, /* latchData */
1013 false, /* latchPath */
1015 false /* tokenOut */
1018 private static final Instruction SEND_DATA_IF_D_NOT_SET =
1019 new Instruction.Move(dock,
1020 Predicate.Default, /* predicate */
1021 false, /* torpedoable */
1022 null_path, /* path */
1023 false, /* tokenIn */
1025 false, /* latchData */
1026 false, /* latchPath */
1028 false /* tokenOut */
1031 private static final Instruction SEND_DATA_IF_D_SET =
1032 new Instruction.Move(dock,
1033 Predicate.FlagD, /* predicate */
1034 false, /* torpedoable */
1035 null_path, /* path */
1036 false, /* tokenIn */
1038 false, /* latchData */
1039 false, /* latchPath */
1041 false /* tokenOut */
1044 private static final Instruction SEND_TOKEN_IF_D_SET =
1045 new Instruction.Move(dock,
1046 Predicate.FlagD, /* predicate */
1047 false, /* torpedoable */
1048 null_path, /* path */
1049 false, /* tokenIn */
1051 false, /* latchData */
1052 false, /* latchPath */
1053 false, /* dataOut */
1057 private static final Instruction SEND_TOKEN_IF_D_NOT_SET =
1058 new Instruction.Move(dock,
1059 Predicate.Default, /* predicate */
1060 false, /* torpedoable */
1061 null_path, /* path */
1062 false, /* tokenIn */
1064 false, /* latchData */
1065 false, /* latchPath */
1066 false, /* dataOut */
1070 private static final Instruction TORPEDOABLE_RECV_DATA =
1071 new Instruction.Move(dock,
1072 Predicate.IgnoreFlagD, /* predicate */
1073 true, /* torpedoable */
1075 false, /* tokenIn */
1077 true, /* latchData */
1078 false, /* latchPath */
1079 false, /* dataOut */
1080 false /* tokenOut */
1083 private static final Instruction RECV_DATA =
1084 new Instruction.Move(dock,
1085 Predicate.IgnoreFlagD, /* predicate */
1086 false, /* torpedoable */
1088 false, /* tokenIn */
1090 true, /* latchData */
1091 false, /* latchPath */
1092 false, /* dataOut */
1093 false /* tokenOut */
1096 private static final Instruction SEND_TOKEN =
1097 new Instruction.Move(dock,
1098 Predicate.IgnoreFlagD, /* predicate */
1099 false, /* torpedoable */
1100 null_path, /* path */
1101 false, /* tokenIn */
1103 false, /* latchData */
1104 false, /* latchPath */
1105 false, /* dataOut */
1109 private static final Instruction RECV_TOKEN =
1110 new Instruction.Move(dock,
1111 Predicate.IgnoreFlagD, /* predicate */
1112 false, /* torpedoable */
1116 false, /* latchData */
1117 false, /* latchPath */
1118 false, /* dataOut */
1119 false /* tokenOut */
1123 private void expectNorthFifoNoMoreThan(int num) {
1124 model.waitNS(128 * CYCLE_TIME_NS);
1125 List<BitVector> dataItems = marina.data.drainMany(num+1);
1126 fatal(dataItems.size()>num,
1127 "Expected no more than "+num+
1128 " data items to emerge but got at least: "+dataItems.size());
1130 private void expectNorthFifoExactly(int num) {
1131 model.waitNS(128 * CYCLE_TIME_NS);
1132 List<BitVector> dataItems = marina.data.drainMany(num+1);
1133 fatal(dataItems.size()!=num,
1134 "Expected exactly "+num+
1135 " data items to emerge but got at least: "+dataItems.size());
1137 private void expectNorthFifoAtLeast(int num) {
1138 model.waitNS(128 * CYCLE_TIME_NS);
1139 List<BitVector> dataItems = marina.data.drainMany(num);
1140 fatal(dataItems.size()<num,
1141 "Expected at least "+num+
1142 " data items to emerge but got only: "+dataItems.size());
1144 private void expectTokensNoMoreThan(int num) {
1145 int x = marina.getNumTokens();
1146 List<BitVector> dataItems = marina.data.drainMany(num+1);
1148 "Expected no more than "+num+
1149 " tokens to emerge but got at least: "+x);
1151 private void expectTokensExactly(int num) {
1152 int x = marina.getNumTokens();
1154 "Expected exactly "+num+
1155 " tokens but got at least: "+x);
1158 private void testFlagDRecomputationTime(Marina marina) {
1159 marina.instrIn.fill(setIlc(1));
1160 marina.fillSouthProperStopper(new Instruction[] {
1162 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
1163 SEND_DATA_IF_D_NOT_SET
1165 marina.fillNorthProperStopper();
1166 expectNorthFifoNoMoreThan(0);
1168 marina.fillSouthProperStopper(new Instruction[] {
1170 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
1171 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
1172 SEND_DATA_IF_D_NOT_SET
1174 marina.fillNorthProperStopper();
1175 expectNorthFifoNoMoreThan(0);
1177 marina.fillSouthProperStopper(new Instruction[] {
1179 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1180 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement),
1181 SEND_DATA_IF_D_NOT_SET
1183 marina.fillNorthProperStopper();
1184 expectNorthFifoExactly(1);
1185 marina.instrIn.fill(DEC);
1187 marina.fillSouthProperStopper(new Instruction[] {
1189 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0),
1190 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1),
1191 SEND_DATA_IF_D_NOT_SET
1193 marina.fillNorthProperStopper();
1194 expectNorthFifoExactly(1);
1197 private void testTailWaitsForHead(Marina marina) {
1198 marina.instrIn.fill(setIlc(1));
1199 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
1201 marina.enableInstructionSend(false);
1202 marina.enableInstructionRecirculate(true);
1204 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1205 marina.instrIn.fill(new Instruction.Head(dock));
1206 marina.instrIn.fill(SEND_DATA);
1207 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1208 marina.instrIn.fill(SEND_TOKEN);
1209 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1210 marina.instrIn.fill(new Instruction.Tail(dock));
1211 marina.instrIn.fillTorpedo();
1213 marina.enableInstructionRecirculate(false);
1214 marina.enableInstructionSend(true);
1215 marina.instrIn.run();
1217 expectNorthFifoNoMoreThan(0);
1218 prln("inserting into north proper stopper");
1219 marina.fillNorthProperStopper();
1220 expectNorthFifoExactly(1);
1221 int nbToks = marina.getNumTokens();
1222 fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens");
1226 marina.instrIn.fill(setIlc(1));
1227 marina.instrIn.fill(setOlc(1));
1229 // this makes the head wait for the torpedo
1230 marina.instrIn.fill(TORPEDOABLE_RECV_DATA);
1232 // the head should wait for the tail
1233 marina.instrIn.fill(new Instruction.Head(dock));
1234 marina.instrIn.fill(NOP);
1235 marina.instrIn.fill(SEND_DATA);
1236 marina.instrIn.fill(RECV_DATA);
1238 expectNorthFifoNoMoreThan(0);
1240 marina.instrIn.fillTorpedo();
1241 expectNorthFifoNoMoreThan(0);
1243 marina.instrIn.fill(new Instruction.Tail(dock));
1244 expectNorthFifoExactly(1);
1247 private void testTailWithoutHead(Marina marina) {
1248 marina.instrIn.fill(setIlc(1));
1249 marina.fillSouthProperStopper(new Instruction[] {
1250 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
1251 new Instruction.Tail(dock),
1254 List<BitVector> dataItems = marina.data.drainMany(1);
1255 fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size());
1258 private void testHeadWaitsForTail(Marina marina) {
1259 List<BitVector> dataItems;
1261 prln("Begin testHeadWaitsForTail");
1264 marina.instrIn.fill(setIlc(1));
1265 marina.fillSouthProperStopper(new Instruction[] {
1266 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63),
1267 new Instruction.Head(dock),
1268 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1272 expectNorthFifoExactly(0);
1273 marina.instrIn.fill(new Instruction.Tail(dock));
1274 expectNorthFifoAtLeast(1);
1277 prln("End testHeadWaitsForTail");
1280 private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) {
1281 marina.instrIn.fill(setIlc(1));
1282 marina.fillSouthProperStopper(new Instruction[] {
1283 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,63),
1284 new Instruction.Move(dock,
1285 Predicate.IgnoreFlagD, // predicate
1286 true, // torpedoable
1295 new Instruction.Move(dock,
1296 Predicate.FlagD, // predicate
1297 false, // torpedoable
1307 marina.instrIn.fillTorpedo();
1308 expectNorthFifoExactly(1);
1309 marina.fillSouthProperStopper(new Instruction[] {
1310 new Instruction.Move(dock,
1311 Predicate.Default, // predicate
1312 false, // torpedoable
1322 expectNorthFifoNoMoreThan(0);
1325 private void testAbort(Marina marina) {
1327 marina.instrIn.fill(setIlc(1));
1328 marina.fillSouthProperStopper(new Instruction[] {
1329 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1),
1330 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2),
1331 SEND_DATA_IF_D_NOT_SET,
1332 new Instruction.Head(dock),
1333 SEND_DATA_IF_D_NOT_SET,
1334 new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2),
1335 new Instruction.Abort(dock, Predicate.FlagD),
1336 new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement),
1337 new Instruction.Tail(dock),
1340 for(int i=0; i<4; i++) {
1343 model.waitNS(128 * CYCLE_TIME_NS);
1344 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1345 fatal(bv==null, "no data item found");
1346 prln("got " + bv.toLong());
1347 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1349 model.waitNS(128 * CYCLE_TIME_NS);
1350 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1351 fatal(bv==null, "no data item found");
1352 prln("got " + bv.toLong());
1353 fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong());
1355 model.waitNS(128 * CYCLE_TIME_NS);
1356 bv = new MarinaPacket(marina.data.drain()).data.bitReverse();
1357 fatal(bv==null, "no data item found");
1358 prln("got " + bv.toLong());
1359 fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong());
1364 private void testAbortOutsideOfLoop(Marina marina) {
1365 marina.instrIn.fill(setIlc(1));
1366 marina.fillSouthProperStopper(new Instruction[] {
1367 // ensure that an abort doesn't cause problems if no loop is in progress
1368 new Instruction.Abort(dock, Predicate.IgnoreFlagD),
1371 expectNorthFifoExactly(1);
1374 private void testFlagAB(Marina marina) {
1375 prln("Begin testFlagAB");
1378 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1379 Instruction.Set.FlagFunction one = zero;
1382 // we should be able to use any pair of FlagX+NotFlagX,
1383 // but we toss them all in to maximize the chances of the
1384 // test passing (later we will try the individual
1385 // combinations to maximize the chances of failure).
1386 one = one.add(Predicate.FlagA);
1387 one = one.add(Predicate.NotFlagA);
1388 one = one.add(Predicate.FlagB);
1389 one = one.add(Predicate.NotFlagB);
1390 one = one.add(Predicate.FlagC);
1391 one = one.add(Predicate.NotFlagC);
1393 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1));
1394 for(boolean fast : new boolean[] { true, false }) {
1395 // clear the flags to a known state, then check both 0->1 and 1->0 transitions
1396 for(boolean b : new boolean[] { false, true, false }) {
1397 prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB());
1398 prln((b?"Setting":"Clearing")+" flags");
1400 Instruction inst = new Instruction.Set(dock,Predicate.IgnoreFlagD,
1405 marina.fillSouthProperStopper(new Instruction[] {
1410 model.waitNS(64 * CYCLE_TIME_NS);
1411 marina.fillNorthProperStopper();
1413 marina.instrIn.fill(inst);
1416 fatal(marina.getFlagA()!=b,
1417 "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set"));
1418 fatal(marina.getFlagB()!=b,
1419 "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set"));
1424 prln("End testFlagAB");
1428 * WARNING: this is a very, very, very long test case -- it goes
1429 * through 216 iterations.
1431 private void testFlagTruthTable(Marina marina) {
1432 prln("Begin testFlagTruthTable");
1435 marina.instrIn.fill(setIlc(1));
1436 Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO;
1437 Instruction.Set.FlagFunction one = zero.add(Predicate.FlagA).add(Predicate.NotFlagA);
1439 for(Predicate a_input : new Predicate[] { null, Predicate.FlagA, Predicate.NotFlagA })
1440 for(Predicate b_input : new Predicate[] { null, Predicate.FlagB, Predicate.NotFlagB })
1441 for(Predicate c_input : new Predicate[] { null, Predicate.FlagC, Predicate.NotFlagC })
1442 for(boolean a_state : new boolean[] { false, true })
1443 for(boolean b_state : new boolean[] { false, true })
1444 for(boolean c_state : new boolean[] { false, true }) {
1445 for(boolean which : new boolean[] { false, true }) {
1447 prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state);
1448 // set A,B flags to a_state and b_state
1449 marina.instrIn.fill(new
1450 Instruction.Set(dock,Predicate.IgnoreFlagD,
1451 a_state ? one : zero,
1452 b_state ? one : zero
1455 // set C flag to c_state
1456 BitVector data = new BitVector(37, "empty");
1457 BitVector addr = new BitVector(14, "empty");
1458 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1459 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1460 addr.set(Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE, c_state);
1461 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1462 marina.instrIn.fill(RECV_DATA);
1464 Instruction.Set.FlagFunction func = zero;
1465 if (a_input!=null) func = func.add(a_input);
1466 if (b_input!=null) func = func.add(b_input);
1467 if (c_input!=null) func = func.add(c_input);
1469 Instruction inst = new
1470 Instruction.Set(dock,Predicate.IgnoreFlagD,
1471 !which ? func : zero.add(Predicate.FlagA),
1472 which ? func : zero.add(Predicate.FlagB)
1475 marina.instrIn.fill(inst);
1477 boolean expected_a = !which ? func.evaluate(a_state, b_state, c_state, false) : a_state;
1478 boolean expected_b = which ? func.evaluate(a_state, b_state, c_state, false) : b_state;
1479 fatal(expected_a != marina.getFlagA(),
1480 "expected A="+expected_a+", but got "+marina.getFlagA());
1481 fatal(expected_b != marina.getFlagB(),
1482 "expected B="+expected_b+", but got "+marina.getFlagB());
1486 prln("End testFlagTruthTable");
1489 private void recvData(Marina marina) {
1490 prln("Begin recvData");
1493 marina.instrIn.fill(setIlc(1));
1494 marina.fillSouthProperStopper(new Instruction[] {
1495 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1496 new Instruction.Move(dock,
1497 Predicate.IgnoreFlagD, // predicate
1498 false, // torpedoable
1507 new Instruction.Set(dock,Predicate.IgnoreFlagD, SET_FLAG, SET_FLAG),
1509 model.waitNS(64 * CYCLE_TIME_NS);
1511 prln("checking to confirm that A flag is cleared");
1512 fatal(marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1514 prln("inserting data item in north fifo ring");
1515 BitVector data = new BitVector(37, "empty");
1516 BitVector addr = new BitVector(14, "empty");
1517 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1518 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1519 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1520 model.waitNS(64 * CYCLE_TIME_NS);
1522 prln("checking to see if A flag got set");
1523 fatal(!marina.getFlagA(), "bad A flag: "+marina.getFlagA());
1526 prln("End recvData");
1530 private void testRecvAndSendWalkingOne(Marina marina) {
1531 prln("Begin testRecvAndSendWalkingOne");
1534 marina.instrIn.fill(setIlc(1));
1536 List<BitVector> dataItems;
1537 for(int bit=0; bit<37; bit++) {
1539 BitVector data = new BitVector(37, "empty");
1540 BitVector addr = new BitVector(14, "empty");
1541 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1542 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1543 data.set(bit, true);
1544 prln("testing with bit pattern " + data);
1546 prln("inserting data item into north fifo ring");
1547 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1549 prln("stopping the north proper stopper");
1552 dataItems = marina.data.drainMany(1);
1553 fatal(dataItems.size()!=0,
1554 "found a data item waiting in the north proper stopper, but should not have");
1556 marina.instrIn.fill(new Instruction.Move(dock,
1557 Predicate.IgnoreFlagD, // predicate
1558 false, // torpedoable
1568 dataItems = marina.data.drainMany(2);
1569 fatal(dataItems.size()!=1,
1570 "found "+dataItems.size()+" data items in north fifo; expected one");
1571 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1572 fatalIfBitVectorsDoNotMatch(mp.data, data);
1576 prln("End testRecvAndSendWalkingOne");
1581 private void setOlcFromDataLatch(Marina marina) {
1582 prln("Begin setOlcFromDataLatch");
1585 marina.instrIn.fill(setIlc(1));
1587 // walk a bit from 0 to 5
1588 for(int bit=0; bit<6; bit++) {
1589 prln("inserting data item in north fifo ring");
1590 BitVector data = new BitVector(37, "empty");
1591 BitVector addr = new BitVector(14, "empty");
1592 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1593 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1594 data.set(bit, true);
1595 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1597 marina.fillSouthProperStopper(new Instruction[] {
1599 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch),
1600 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,-1),
1603 model.waitNS(CYCLE_TIME_NS * 64);
1607 if (marina.kesselsCounter) {
1608 // master clear on each iteration; otherwise we'd need to "run down" the olc
1609 marina.masterClear();
1610 marina.enableInstructionSend(true);
1615 prln("End setOlcFromDataLatch");
1618 private void setIlcFromDataLatch(Marina marina) {
1619 prln("Begin setIlcFromDataLatch");
1622 marina.instrIn.fill(setIlc(1));
1624 // walk a bit from 0 to 5
1625 for(int bit=5; bit>=0; bit--) {
1626 prln("inserting data item in north fifo ring");
1627 BitVector data = new BitVector(37, "empty");
1628 BitVector addr = new BitVector(14, "empty");
1629 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1630 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1631 data.set(bit, true);
1632 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1634 marina.fillSouthProperStopper(new Instruction[] {
1635 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1637 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch),
1639 model.waitNS(CYCLE_TIME_NS * 64);
1641 int ilc = marina.getILC().getCount();
1642 fatal(ilc != (1<<bit), "expected ilc to be " + (1<<bit) + ", but got " + ilc);
1646 prln("End setIlcFromDataLatch");
1649 private void testSendAndRecvToken(Marina marina) {
1650 prln("Begin testSendAndRecvToken");
1653 marina.instrIn.fill(setIlc(1));
1654 marina.fillSouthProperStopper(new Instruction[] {
1659 expectNorthFifoExactly(1);
1662 prln("End testSendAndRecvToken");
1665 private void testSignExtendedLiteral(Marina marina) {
1666 prln("Begin testSignExtendedLiteral");
1669 marina.instrIn.fill(setIlc(1));
1670 for(long val : new long[] { (-1L << 14), -1, 0, 1 }) {
1672 marina.fillSouthProperStopper(new Instruction[] {
1673 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1674 Instruction.Set.SetDest.DataLatch,
1678 model.waitNS(CYCLE_TIME_NS * 64);
1680 List<BitVector> dataItems = marina.data.drainMany(3);
1681 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1683 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1684 BitVector bv = mp.data;
1685 prln("got back " + mp);
1687 boolean mismatch = false;
1689 for(int i=0; i<37; i++) {
1690 if (bv.get(i) != ( (val & (1L << i)) != 0 )) {
1695 fatal(mismatch, "data read back did not match inserted literal; mismatch on bits " + err);
1699 prln("End testSignExtendedLiteral");
1702 private void testShiftedLiteral(Marina marina) {
1703 prln("Begin testShiftedLiteral");
1706 marina.instrIn.fill(setIlc(1));
1707 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,
1708 Instruction.Set.SetDest.DataLatch,
1711 BitVector dreg = new BitVector(37, "what we think is in the d-register");
1712 for(int i=0; i<37; i++) dreg.set(i, false);
1714 for(long val : new long[] { -1, 0, 1, (-1L << 18) }) {
1716 edu.berkeley.fleet.api.BitVector immediate =
1717 new edu.berkeley.fleet.api.BitVector(19);
1718 for(int i=0; i<immediate.length(); i++)
1719 immediate.set(i, (val & (1L << i)) != 0);
1721 // shift over 19 LSB's towards MSB
1722 for(int i=0; i<19; i++)
1723 if (i+19 <= 36) dreg.set(i+19, dreg.get(i));
1724 for(int i=0; i<19; i++)
1725 dreg.set(i, immediate.get(i));
1727 marina.fillSouthProperStopper(new Instruction[] {
1728 new Instruction.Shift(dock,Predicate.IgnoreFlagD,immediate),
1732 model.waitNS(CYCLE_TIME_NS * 64);
1733 List<BitVector> dataItems = marina.data.drainMany(3);
1734 fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size());
1736 BitVector bv = new MarinaPacket(dataItems.get(0)).data;
1737 fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" +
1738 "got: "+bv.bitReverse().getState()+"\n"+
1739 "expected:"+dreg.bitReverse().getState());
1743 prln("End testShiftedLiteral");
1746 private void testFlagC(Marina marina) {
1747 prln("Begin testFlagC");
1755 // Dc=1 => sigS is copied into C-flag
1756 // Dc=0 => sigA is copied into C-flag
1758 marina.instrIn.fill(setIlc(1));
1759 for(boolean dc : new boolean[] { false, true }) {
1760 for(boolean c_flag : new boolean[] { true, false, true }) {
1763 prln("****** checking case where dc="+dc+", cflag="+c_flag);
1764 BitVector data = new BitVector(37, "empty");
1765 BitVector addr = new BitVector(14, "empty");
1766 for(int i=0; i<data.getNumBits(); i++) data.set(i, false);
1767 for(int i=0; i<addr.getNumBits(); i++) addr.set(i, false);
1770 ? Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE
1771 : Marina.INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO;
1772 prln("setting addr["+whichbit+"] to "+(c_flag?"1":"0"));
1773 addr.set(whichbit, c_flag);
1775 prln("... and filling north fifo proper stopper");
1776 marina.fillNorthProperStopper(new MarinaPacket(data, false, addr));
1778 prln("clearing flags");
1779 prln("executing recv data with Dc="+dc);
1780 prln("copying c-flag to a-flag");
1781 marina.fillSouthProperStopper(new Instruction[] {
1782 new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG),
1783 new Instruction.Move(dock,
1784 Predicate.IgnoreFlagD, /* predicate */
1785 true, /* torpedoable */
1787 false, /* tokenIn */
1790 false, /* latchPath */
1791 false, /* dataOut */
1792 false /* tokenOut */
1795 new Instruction.Set(dock,Predicate.IgnoreFlagD,
1796 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagC),
1801 model.waitNS(CYCLE_TIME_NS * 64);
1803 prln("checking to confirm that A flag is " + c_flag);
1804 fatal(marina.getFlagA()!=c_flag, "bad A flag: "+marina.getFlagA());
1808 prln("End testFlagC");
1811 private void sendDataWithPath(Marina marina) {
1812 prln("Begin sendDataWithPath");
1815 edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13);
1816 marina.instrIn.fill(setIlc(1));
1818 // alternating ones and zeroes
1819 for(int i=0; i<bv.length(); i+=2)
1821 // and then ones in the lower four bits so it's not symmetric
1822 for(int i=0; i<4; i++)
1825 MarinaPath path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), bv);
1827 marina.fillSouthProperStopper(new Instruction[] {
1828 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
1829 new Instruction.Move(dock,
1830 Predicate.IgnoreFlagD, /* predicate */
1831 false, /* torpedoable */
1833 false, /* tokenIn */
1835 false, /* latchData */
1836 false, /* latchPath */
1838 false /* tokenOut */
1842 List<BitVector> dataItems;
1845 dataItems = marina.data.drainMany();
1846 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1847 mp = new MarinaPacket(dataItems.get(0));
1849 // the 14th bit of the outbound address cannot be set by the
1850 // ship, so we don't care about it
1851 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1853 prln("send data with no change to path");
1854 marina.instrIn.fill(new Instruction.Move(dock,
1855 Predicate.IgnoreFlagD, /* predicate */
1856 false, /* torpedoable */
1858 false, /* tokenIn */
1860 false, /* latchData */
1861 false, /* latchPath */
1863 false /* tokenOut */
1866 dataItems = marina.data.drainMany();
1867 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1868 mp = new MarinaPacket(dataItems.get(0));
1870 // the 14th bit of the outbound address cannot be set by the
1871 // ship, so we don't care about it
1872 fatalIfBitVectorsDoNotMatch(MarinaUtils.berkToSun(bv), mp.path.get(0,13));
1875 prln("End sendDataWithPath");
1878 private void recvPath(Marina marina) {
1879 prln("Begin recvPath");
1882 marina.instrIn.fill(setIlc(1));
1883 for(int bit=0; bit<11; bit++) {
1884 BitVector packet_data = new BitVector(37, "inbound data item");
1885 for(int i=0; i<37; i++) packet_data.set(i, false);
1886 packet_data.set(27+bit, true);
1887 BitVector packet_path = new BitVector(14, "inbound data item");
1888 for(int i=0; i<14; i++) packet_path.set(i, false);
1890 marina.fillNorthProperStopper(new MarinaPacket(packet_data, false, packet_path));
1892 prln("recv path, send data (using recv'd path)");
1893 marina.instrIn.fill(new Instruction.Move(dock,
1894 Predicate.IgnoreFlagD, /* predicate */
1895 false, /* torpedoable */
1897 false, /* tokenIn */
1899 true, /* latchData */
1900 true, /* latchPath */
1902 false /* tokenOut */
1905 List<BitVector> dataItems = marina.data.drainMany();
1906 fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items");
1907 MarinaPacket mp = new MarinaPacket(dataItems.get(0));
1909 fatalIfBitVectorsDoNotMatch(packet_data.get(25,11), mp.path.get(0,11));
1910 fatalIfBitVectorsDoNotMatch(packet_data, mp.data);
1914 prln("End recvPath");
1917 private void testILC(Marina marina) {
1918 prln("Begin testILC");
1921 for(int bit=0; bit<6; bit++) {
1922 int ilc = bit<0 ? 0 : (1<<bit);
1923 marina.fillSouthProperStopper(new Instruction[] {
1924 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,ilc),
1927 List<BitVector> dataItems = marina.data.drainMany();
1928 fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items");
1932 prln("End testILC");
1935 private void testILCZero(Marina marina) {
1937 marina.fillSouthProperStopper(new Instruction[] {
1938 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0),
1942 expectNorthFifoNoMoreThan(0);
1943 expectTokensExactly(1);
1947 private void sendTorpedo(Marina marina) {
1948 prln("Begin sendTorpedo");
1950 marina.instrIn.fill(setIlc(1));
1951 marina.instrIn.fill(setOlc(63));
1953 model.waitNS(128 * CYCLE_TIME_NS);
1956 marina.instrIn.fill(new
1957 Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
1958 fatal(marina.getFlagA(), "bad A flag: true");
1959 fatal(marina.getFlagB(), "bad B flag: true");
1961 prln("execute a move instruction that does nothing but loops until torpedo arrives");
1962 prln("A=1, B=B This instruction should not execute because D-flag is set");
1963 prln("Set A=A, B=1 This instruction should execute because D-flag is set");
1965 model.waitNS(128 * CYCLE_TIME_NS);
1967 marina.fillSouthProperStopper(new Instruction[] {
1968 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity),
1969 new Instruction.Move(dock,
1970 Predicate.IgnoreFlagD, // predicate
1971 true, // torpedoable
1980 new Instruction.Set(dock,Predicate.Default,
1982 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB)
1984 new Instruction.Set(dock, Predicate.FlagD,
1985 Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA),
1990 model.waitNS(128 * CYCLE_TIME_NS);
1992 prln("send torpedo. This should clear the OLC");
1993 marina.instrIn.fillTorpedo();
1994 model.waitNS(128 * CYCLE_TIME_NS);
1996 model.waitNS(128 * CYCLE_TIME_NS);
1998 prln("A should remain false, B should be true");
1999 fatal(marina.getFlagA(), "bad A flag: true");
2000 fatal(!marina.getFlagB(), "bad B flag: false");
2002 model.waitNS(128 * CYCLE_TIME_NS);
2004 prln("Reload OLC after torpedo, clears D-flag");
2005 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63));
2007 // FIXME: find another way to test this
2008 model.waitNS(128 * CYCLE_TIME_NS);
2011 prln("Set A=1, B=1 This instruction should execute because OLC!=0");
2012 marina.instrIn.fill(new
2013 Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG));
2015 prln("A and B should be true");
2016 fatal(!marina.getFlagA(), "bad A flag: false");
2017 fatal(!marina.getFlagB(), "bad B flag: false");
2020 prln("End sendTorpedo");
2023 private void testTorpedoOnAnInfinite(Marina marina) {
2024 prln("Begin testTorpedoOnAnInfinite");
2027 List<BitVector> dataItems;
2029 marina.instrIn.fill(setIlc(1));
2030 for(boolean torpedoable : new boolean[] { true, false }) {
2032 marina.fillSouthProperStopper(new Instruction[] {
2033 new Instruction.Move(dock,
2034 Predicate.IgnoreFlagD, // predicate
2035 false, // torpedoable
2044 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity),
2045 new Instruction.Move(dock,
2046 Predicate.IgnoreFlagD, // predicate
2047 torpedoable, // torpedoable
2056 // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior
2057 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
2062 // expect nothing to come out, because the NOP is executing
2063 dataItems = marina.data.drainMany(2);
2064 fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items");
2066 marina.instrIn.fillTorpedo();
2068 int expected = torpedoable?1:0;
2069 dataItems = marina.data.drainMany(2);
2070 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
2072 fatal(!marina.getILC().getDone(), "Expected ilc=done, but got "+marina.getILC());
2076 prln("End testTorpedoOnAnInfinite");
2079 private void testDFlagWhenTorpedoLyingInWait(Marina marina) {
2080 marina.fillSouthProperStopper(new Instruction[] {
2083 TORPEDOABLE_RECV_DATA,
2087 SEND_TOKEN_IF_D_SET,
2090 expectTokensExactly(0);
2092 // changing the order of these lines should work, but it does not
2093 marina.fillNorthProperStopper();
2094 marina.instrIn.fillTorpedo();
2096 expectTokensExactly(1);
2099 private void testSetOlcFollowedByDPredicated(Marina marina) {
2100 for(boolean d_set : new boolean[] { false, true }) {
2102 marina.fillSouthProperStopper(new Instruction[] {
2104 marina.kesselsCounter ? null : FLAG_NOP,
2105 d_set ? SEND_DATA_IF_D_SET : SEND_DATA_IF_D_NOT_SET,
2107 expectNorthFifoExactly(d_set ? 1 : 0);
2110 marina.fillSouthProperStopper(new Instruction[] {
2112 marina.kesselsCounter ? null : FLAG_NOP,
2113 d_set ? SEND_DATA_IF_D_SET : SEND_DATA_IF_D_NOT_SET,
2115 expectNorthFifoExactly(d_set ? 0 : 1);
2117 if (marina.kesselsCounter) {
2118 marina.masterClear();
2119 marina.enableInstructionSend(true);
2124 private void testOlcDecrementAtHighSpeed(Marina marina) {
2125 prln("Begin testOlcDecrementAtHighSpeed");
2128 List<BitVector> dataItems;
2130 // Each element of the following pair of arrays is one "test".
2131 // The OLC will be loaded with olcs[i] and then decremented
2132 // decr_amounts[i] times; after that has happened the zeroness
2133 // of the OLC will be checked by executing a MOVE with
2134 // [olc!=0] as the predicate.
2136 int[] olcs = new int[] { 3, 3, 3, 10, 41 };
2137 int[] decr_amounts = new int[] { 2, 3, 4, 9, 9 };
2139 for(int which=0; which<olcs.length; which++) {
2140 int olc = olcs[which];
2141 int decr_amount = decr_amounts[which];
2143 prln("inserting set olc="+olc);
2144 prln("inserting set ilc=1");
2145 marina.fillSouthProperStopper(new Instruction[] {
2146 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1),
2147 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,olc),
2150 // commenting the following four lines causes this test to pass
2152 prln("inserting: "+decr_amount+" olc-- instructions");
2153 prln("inserting: [!d] send data");
2154 Instruction[] instructions = new Instruction[decr_amount+1];
2155 for(int i=0; i<decr_amount; i++)
2157 new Instruction.Set(dock,
2159 SetDest.OuterLoopCounter,
2160 SetSource.Decrement);
2161 instructions[instructions.length-1] =
2162 new Instruction.Move(dock,
2163 Predicate.Default, // predicate
2164 false, // torpedoable
2174 marina.fillSouthProperStopper(instructions);
2175 model.waitNS(64 * CYCLE_TIME_NS);
2177 int expected = decr_amount>=olc ? 0 : 1;
2178 dataItems = marina.data.drainMany(2);
2179 fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items");
2180 expectOlc(Math.max(0,olc-decr_amount));
2182 if (marina.kesselsCounter) {
2183 // master clear on each iteration; otherwise we'd need to "run down" the olc
2184 marina.masterClear();
2185 marina.enableInstructionSend(true);
2190 prln("End testOlcDecrementAtHighSpeed");
2193 private void flipIlcBit(Marina marina) {
2194 prln("Begin flipIlcBit");
2196 prln("Using the set ILC instruction, toggle a single bit between zero and one. \n" +
2197 "Check correct setting of the ILC zero bit");
2199 for (int i=0; i<6; i++) {
2202 prln("Then immediately set ILC="+notZero);
2203 marina.fillSouthProperStopper(new Instruction[] {
2204 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
2205 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
2208 model.waitNS(64 * CYCLE_TIME_NS);
2210 prln("Verify ILC using scan chain");
2211 Ilc ilc = marina.getILC();
2212 int ilcCount = ilc.getCount();
2213 fatal(ilcCount!=notZero, "bad ILC count: "+ilcCount+" expected: "+notZero);
2214 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
2216 marina.fillSouthProperStopper(new Instruction[] {
2217 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, notZero),
2218 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0),
2221 model.waitNS(64 * CYCLE_TIME_NS);
2223 prln("Verify ILC using scan chain");
2224 ilc = marina.getILC();
2225 ilcCount = ilc.getCount();
2226 fatal(ilcCount!=0, "bad ILC count: "+ilcCount+" expected: 0");
2227 fatal(ilc.getInfinity(), "bad ILC Infinity bit: true");
2231 prln("End flipIlcBit");
2233 private void flipOlcBit(Marina marina) {
2234 prln("Begin flipOlcBit");
2236 prln("Using the set OLC instruction, toggle a single bit between zero and one. \n" +
2237 "Check correct setting of the OLC zero bit");
2239 marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG));
2241 for (int i=0; i<6; i++) {
2242 int notZero = 32 >> i;
2244 if (marina.kesselsCounter) {
2245 // master clear on each iteration; otherwise we'd need to "run down" the olc
2246 marina.masterClear();
2247 marina.enableInstructionSend(true);
2252 prln("Then immediately set OLC="+notZero);
2253 marina.fillSouthProperStopper(new Instruction[] {
2254 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
2255 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
2258 model.waitNS(64 * CYCLE_TIME_NS);
2259 prln("Verify OLC count using scan chain");
2262 if (!marina.kesselsCounter) {
2263 prln("Set OLC="+notZero);
2264 prln("Then immediately set OLC=0");
2265 marina.fillSouthProperStopper(new Instruction[] {
2266 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero),
2267 new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0),
2270 model.waitNS(64 * CYCLE_TIME_NS);
2271 prln("Verify OLC count using scan chain");
2277 prln("End flipOlcBit");
2279 private void testSouthRecirculate(Marina marina, int AMOUNT) {
2280 prln("Begin testSouthRecirculate("+AMOUNT+")");
2283 marina.enableInstructionSend(false);
2284 marina.enableInstructionRecirculate(true);
2286 prln("Completely fill south ring");
2288 for (int i=0; i<AMOUNT; i++) {
2289 prln("inserting item " + (i+1) + " / " + AMOUNT);
2290 BitVector path = new BitVector(MarinaPacket.PATH_WIDTH, "path");
2291 BitVector data = new BitVector(MarinaPacket.WORD_WIDTH, "path");
2292 path.set(0, MarinaPacket.PATH_WIDTH, false);
2293 data.setFromLong(i+9);
2294 marina.instrIn.fill(new MarinaPacket(data, false, path));
2298 prln("Drain south ring and check contents");
2300 List<BitVector> out = marina.instrIn.drainMany();
2301 boolean bad = false;
2302 for (int i=0; i<AMOUNT; i++) {
2303 prln("extracting item " + (i+1) + " / " + AMOUNT);
2304 //int expect = (i+Marina.SOUTH_RING_CAPACITY-1) % Marina.SOUTH_RING_CAPACITY;
2306 long got = new MarinaPacket(out.get(i)).data.toLong();
2309 prln(" bad instruction: "+got+" expected: "+expect);
2311 prln(" good instruction.");
2314 fatal(bad, "data inserted does not match data retrieved");
2317 for (int i=0; i<5; i++) {}
2320 prln("End testSouthRecirculate("+AMOUNT+")");
2324 private void testOverfillTokens(Marina marina) {
2325 prln("Begin testOverfillTokens");
2328 for(int i=0; i<marina.TOKEN_FIFO_CAPACITY + 3; i++)
2329 marina.instrIn.fill(SEND_TOKEN);
2330 marina.instrIn.fill(SEND_DATA);
2331 expectNorthFifoExactly(0);
2334 prln("End testSouthRecirculate");
2339 private void doOneTest(int testNum) throws Exception {
2341 doOneTest_(testNum);
2342 } catch (MarinaUtils.FailureException fe) {
2343 System.out.println("******************************************************************************");
2344 System.out.println("******************************************************************************");
2345 System.out.println("******************************************************************************");
2346 System.out.println("******************************************************************************");
2347 fe.printStackTrace();
2351 private void doOneTest_(int testNum) throws Exception {
2353 prln("============================================================");
2354 prln("MarinaTest: performing test: "+testNum);
2359 int[] tests = new int[] { 1002, 1003, 1005, 3002, 3004, 3005, 3006, 3008, 3009, 3025, 3026, 3029 };
2361 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("test.out")));
2362 while(vdd <= 1.3f) {
2363 vdd10.setVoltageWait(vdd);
2364 System.out.println("vdd10 = " + vdd10.readVoltage());
2366 for(int i=0; i<tests.length; i++) {
2368 doOneTest_(tests[i]);
2369 pw.println(vdd + " " + i + " " + "1");
2370 } catch (MarinaUtils.FailureException fe) {
2371 pw.println(vdd + " " + i + " " + "0");
2377 } catch (Exception e) { throw new RuntimeException(e); }
2381 marina.masterClear();
2382 marina.enableInstructionSend(true);
2385 MarinaUtils.testnum = testNum;
2390 doOneTest(1); // passes extracted parasitics
2391 doOneTest(2); // passes extracted parasitics
2392 doOneTest(3); // passes extracted parasitics
2393 doOneTest(4); // passes extracted parasitics
2394 doOneTest(5); // passes extracted parasitics
2397 doOneTest(1000); // passes extracted parasitics
2398 doOneTest(1001); // passes extracted parasitics
2399 doOneTest(1003); // passes extracted parasitics
2401 doOneTest(3000); // passes extracted parasitics
2402 doOneTest(3001); // passes extracted parasitics
2403 doOneTest(3003); // passes extracted parasitics
2404 doOneTest(3004); // passes extracted parasitics
2405 doOneTest(3005); // passes extracted parasitics
2406 doOneTest(3006); // passes extracted parasitics
2407 doOneTest(3007); // passes extracted parasitics
2408 doOneTest(3008); // passes extracted parasitics
2409 doOneTest(3009); // passes extracted parasitics
2410 doOneTest(3010); // passes extracted parasitics
2411 doOneTest(3011); // passes extracted parasitics
2412 doOneTest(3012); // passes extracted parasitics
2413 doOneTest(3013); // passes extracted parasitics
2414 doOneTest(3014); // passes extracted parasitics
2415 doOneTest(3015); // passes extracted parasitics
2416 doOneTest(3019); // passes extracted parasitics
2417 doOneTest(3020); // passes extracted parasitics
2418 doOneTest(3022); // passes extracted parasitics
2419 doOneTest(3023); // passes extracted parasitics
2420 doOneTest(3025); // passes extracted parasitics
2421 doOneTest(3026); // passes extracted parasitics
2422 doOneTest(3027); // passes extracted parasitics
2423 doOneTest(3028); // passes extracted parasitics
2424 doOneTest(3029); // passes extracted parasitics
2425 //doOneTest(3030); // passes extracted parasitics (questionable)
2426 //doOneTest(3031); // passes extracted parasitics should not pass!
2428 // these tests take a while and usually pass
2440 // this takes an insanely long time
2444 case 1: testChains(marina); break; // passes, 24-Mar (+verilog)
2445 case 2: testProperStoppers(marina); break; // passes, 24-Mar (+verilog)
2446 case 3: testSouthRecirculate(marina, 1); break; // passes, 24-Mar (+verilog)
2447 case 4: getCtrsFlags(marina); break; // 20-Apr (+verilog)
2448 case 5: sendInstructions(marina); break; // passes, 24-Mar (+verilog)
2449 case 6: walkOneOLC(marina); break; // 21-Apr (+verilog)
2451 // Russell's tests begin with 1000
2452 case 1000: walkOneILC(marina); break; // 20-Apr (+verilog)
2453 case 1001: countIlc(marina); break; // 20-Apr (+verilog)
2454 case 1002: countOlc(marina); break; // 23-Apr (+verilog)
2456 case 1003: sendTorpedo(marina); break; // 23-Apr (+verilog) [with wor-hack]
2458 case 1004: flipIlcBit(marina); break; // 20-Apr (+verilog)
2459 case 1005: flipOlcBit(marina); break; // 21-Apr (+verilog)
2461 case 1006: testSouthRecirculate(marina, Marina.SOUTH_RING_CAPACITY-1); break; // passes, 24-Mar (+verilog)
2463 // Adam's tests begin with 3000
2464 case 3000: sendToken(marina); break; // passes, 24-Mar (+verilog)
2465 case 3001: testFlagAB(marina); break; // passes, 08-Apr (+verilog)
2466 case 3002: testPredicationOnAB(marina); break; // 22-Apr (+verilog)
2467 case 3003: testFlagC(marina); break; // 23-Apr (+verilog)
2468 case 3004: testFlagD(marina); break; // 23-Apr (+verilog)
2469 case 3005: testFlagDRecomputationTime(marina); break;
2471 case 3006: testTailWaitsForHead(marina); break;
2472 case 3007: testTailWithoutHead(marina); break;
2473 case 3008: testHeadWaitsForTail(marina); break; // 22-Apr (+verilog)
2474 case 3009: testAbort(marina); break; // 22-Apr (+verilog)
2476 case 3010: sendData(marina); break; // passes, 24-Mar (+verilog)
2477 case 3011: recvData(marina); break; // 21-Apr (+verilog)
2478 case 3012: sendDataWithPath(marina); break; // passes, 13-Apr (+verilog)
2480 case 3013: testSignExtendedLiteral(marina); break; // 20-Apr (+verilog)
2481 case 3014: testShiftedLiteral(marina); break; // 20-Apr (+verilog)
2482 case 3015: testSendAndRecvToken(marina); break; // 21-Apr (+verilog)
2484 case 3016: sendDataIlcInfinite(marina); break; // 22-Apr (+verilog)
2485 case 3017: testFlagTruthTable(marina); break; // 23-Apr (+verilog)
2487 case 3019: setOlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2488 case 3020: setIlcFromDataLatch(marina); break; // 23-Apr (+verilog)
2489 case 3021: recvPath(marina); break; // 22-Apr (+verilog)
2490 case 3022: testILC(marina); break; // 23-Apr (+verilog)
2491 case 3023: testTorpedoOnAnInfinite(marina); break; // 23-Apr (+verilog)
2492 case 3024: testRecvAndSendWalkingOne(marina); break; // 21-Apr (+verilog)
2493 case 3025: testOlcDecrementAtHighSpeed(marina); break; // 23-Apr (+verilog)
2495 case 3026: testNonTorpedoableMoveDoesNotResetDFlag(marina); break; // 23-Apr (+verilog)
2496 case 3027: testILCZero(marina); break;
2497 case 3028: testAbortOutsideOfLoop(marina); break;
2498 case 3029: testDFlagWhenTorpedoLyingInWait(marina); break;
2499 case 3030: testSetOlcFollowedByDPredicated(marina); break;
2500 case 3031: testOverfillTokens(marina); break;
2502 case 3040: loadEveryValueOLC(marina); break;
2509 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("out.dat")));
2510 for(double myvdd = 1.0; myvdd<2.0; myvdd += 0.05) {
2512 vdd18.setVoltageWait((float)Math.max(1.8,vdd));
2513 vdd10.setVoltageWait(vdd);
2516 for(int toks = 0; toks < 13; toks++) {
2519 for(int iter = 0; iter < MAX_ITER; iter++) {
2521 marina.masterClear();
2523 marina.stopAndResetCounters();
2525 marina.enableInstructionSend(true);
2526 marina.fillSouthProperStopper(setOlc(1));
2527 marina.fillSouthProperStopper(new Instruction.Head(dock));
2528 for(int i=0; i<toks; i++)
2529 marina.fillSouthProperStopper(/*SEND_DATA*/NOP);
2530 marina.fillSouthProperStopper(new Instruction[] {
2531 new Instruction.Tail(dock),
2533 marina.startCounters();
2535 marina.instrIn.run();
2536 try { Thread.sleep(wait); } catch (Exception e) { }
2537 //marina.instrIn.stop();
2539 marina.stopAndResetCounters();
2540 int countNorth = marina.getNorthCount();
2541 int count = marina.getSouthCount();
2542 System.out.println();
2543 System.out.println();
2544 if (count > (2<<29))
2545 System.out.println("warning: count was greater than 2^29...");
2546 double gst = ((((double)count*2)) / (1000000. * wait /* * toks*/));
2547 System.out.println("south counter is: " + count + ", which is " + gst + "Ginst/sec with toks="+toks + " @vdd="+vdd);
2550 System.out.println();
2551 System.out.println();
2553 System.out.println("counters are " + count + " and " + countNorth + "; ratio is "+
2554 (((double)countNorth)/((double)(count*2))) + " " +
2555 (((double)countNorth)/((double)(count*2+1))) + " " +
2559 pw.println(vdd + " " + toks + " " + (((double)total) / MAX_ITER));
2566 loadEveryValueOLC(marina);
2571 fatal(true, "Test number: "+testNum+" doesn't exist.");
2574 // If we get here then test passed
2575 prln("Test Result: Passed");
2577 //Infrastructure.exit(0);
2581 //============================ for public use =============================
2584 * 0: test detected success
2585 * 2: test detected failure
2588 public static void main(String[] args) throws Exception {
2589 startTime = System.currentTimeMillis();
2590 new MarinaTest(args);