X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=testCode%2Fcom%2Fsun%2Fvlsi%2Fchips%2Fmarina%2Ftest%2FMarinaTest.java;h=9a5df19c51627c24b5c5a66d8f592643d02b23d4;hb=817e96628b71bf5936bcd541994614a1b9844853;hp=d249de0e7691d5836f0c964c66aea90182d0d531;hpb=24f3e6a3f01ad182da20bf6c1bce1c06978e7457;p=fleet.git diff --git a/testCode/com/sun/vlsi/chips/marina/test/MarinaTest.java b/testCode/com/sun/vlsi/chips/marina/test/MarinaTest.java index d249de0..9a5df19 100644 --- a/testCode/com/sun/vlsi/chips/marina/test/MarinaTest.java +++ b/testCode/com/sun/vlsi/chips/marina/test/MarinaTest.java @@ -14,6 +14,8 @@ import com.sun.async.test.JtagSubchainTesterModel; import com.sun.async.test.JtagTester; import com.sun.async.test.ManualPowerChannel; import com.sun.async.test.NanosimModel; +import com.sun.async.test.HsimModel; +import com.sun.async.test.VerilogModel; import com.sun.async.test.Netscan4; import com.sun.async.test.PowerChannel; import com.sun.async.test.Pst3202Channel; @@ -21,9 +23,8 @@ import com.sun.async.test.SiliconChip; import com.sun.async.test.SimulationModel; import com.sun.async.test.VoltageReadable; import com.sun.vlsi.chips.marina.test.Marina.Ilc; -import com.sun.vlsi.chips.marina.test.MarinaUtils.CmdArgs; -import com.sun.vlsi.chips.marina.test.MarinaUtils.Station; -import com.sun.vlsi.chips.marina.test.MarinaUtils.CmdArgs.Mode; +import com.sun.vlsi.chips.marina.test.CmdArgs; +import com.sun.vlsi.chips.marina.test.CmdArgs.Mode; import edu.berkeley.fleet.api.Dock; import edu.berkeley.fleet.api.Instruction; @@ -37,16 +38,16 @@ import edu.berkeley.fleet.marina.MarinaPath; * Tests for Marina */ public class MarinaTest { + public static final MarinaFleet marinaFleet = new MarinaFleet(); + public static final Dock dock = marinaFleet.getOnlyInputDock(); + //-------------------------- constants ----------------------------------- private static final String SCAN_CHAIN_XML = "marina.xml"; private static final String NET_LIST = "marina.spi"; public static final int INSTR_SZ = 36; - public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE = 13; - public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = 0; - - public static final Dock DOCK = InstructionStopper.DOCK; + public static final Instruction.Set.FlagFunction CLEAR_FLAG = Instruction.Set.FlagFunction.ZERO; public static final Instruction.Set.FlagFunction SET_FLAG @@ -97,14 +98,14 @@ public class MarinaTest { private static final int MORE_THAN_DATA_OUT_SATURATION_AMOUNT = 10; // Nominal cycle time assuming 4 GHz throughput - private static final double CYCLE_TIME_NS = 0.250; + public static double CYCLE_TIME_NS; //-------------------------------- types --------------------------------- //-------------------------- private data -------------------------------- private static long startTime; - private Indenter indenter = new Indenter(); + public static Indenter indenter = new Indenter(); private Marina marina; private ChipModel model; //private ChainControl cc; @@ -112,6 +113,9 @@ public class MarinaTest { private CmdArgs cmdArgs; private PowerChannel corePowerSupply, padsPowerSupply; private VoltageReadable coreVoltmeter, voltmeterForCurrent; + + private ChainTest ctD, ctR, ctC, ct; + private ChainControl ccD, ccR, ccC, cc; //-------------------------- private methods ----------------------------- /** @return true if simulation. Return false if we're testing silicon. */ @@ -121,16 +125,8 @@ public class MarinaTest { private void pr(String msg) {indenter.pr(msg);} private void adjustIndent(int n) {indenter.adjustIndent(n);} - public static void fatal(boolean pred, String msg) { - if (pred) { - Exception err = new Exception(msg); - err.printStackTrace(); - System.out.println("Test Result: Test Failed"); + public static void fatal(boolean pred, String msg) { MarinaUtils.fatal(pred, msg); } - printTestTime(); - Infrastructure.exit(2); - } - } public static void fatalIfBitVectorsDoNotMatch(BitVector bv1, BitVector bv2) { // FIXME: better error reporting needed here @@ -199,7 +195,7 @@ public class MarinaTest { } private MarinaTest(String[] args) { - cmdArgs = new MarinaUtils.CmdArgs(args); + cmdArgs = new CmdArgs(args); reportTask(cmdArgs); if (cmdArgs.mode==Mode.TEST_SILICON) doSilicon(); else doSim(); } @@ -217,49 +213,67 @@ public class MarinaTest { fatal(true, "unrecognized CmdArgs.Mode"); return; } - model = new NanosimModel(); - - //tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO"); + model = cmdArgs.useVerilog + ? new VerilogModel() + : cmdArgs.useHsim + ? new HsimModel() + : new NanosimModel(); + + ((SimulationModel)model).setOptimizedDirectReadsWrites(true); + + CYCLE_TIME_NS = cmdArgs.useVerilog ? (100*20) : 0.250; + int khz = model instanceof VerilogModel ? 100000 : 1000000; + + JtagTester tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO"); + tester.printInfo = false; ChainControls ccs = new ChainControls(); + PowerChannel pc = new ManualPowerChannel("pc", false); + /* JtagTester testerD, testerR, testerC; testerD = ((SimulationModel)model).createJtagSubchainTester("sid[1:9]", null); testerR = ((SimulationModel)model).createJtagSubchainTester("sir[1:9]", null); testerC = ((SimulationModel)model).createJtagSubchainTester("sic[1:9]", null); testerD.printInfo = testerR.printInfo = testerC.printInfo = false; - int khz = 1000000; - - ChainControl ccD, ccR, ccC; ccD = new ChainControl(SCAN_CHAIN_XML, testerD, 1.8f, khz); ccR = new ChainControl(SCAN_CHAIN_XML, testerR, 1.8f, khz); ccC = new ChainControl(SCAN_CHAIN_XML, testerC, 1.8f, khz); ccD.noTestSeverity = ccR.noTestSeverity = ccC.noTestSeverity = Infrastructure.SEVERITY_NOMESSAGE; + - PowerChannel pc = new ManualPowerChannel("pc", false); - - ChainTest ctD, ctR, ctC; ctD = new ChainTest(ccD, pc); ctR = new ChainTest(ccR, pc); ctC = new ChainTest(ccC, pc); - - ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift); - + */ /* - ctD.testAllChains("marina", Infrastructure.SEVERITY_WARNING); - ctR.testAllChains("marina", Infrastructure.SEVERITY_WARNING); - ctC.testAllChains("marina", Infrastructure.SEVERITY_WARNING); - */ - ccs.addChain(Marina.DATA_CHAIN, ccD); ccs.addChain(Marina.REPORT_CHAIN, ccR); ccs.addChain(Marina.CONTROL_CHAIN, ccC); - + */ + + cc = new ChainControl(SCAN_CHAIN_XML, tester, 1.8f, khz); + ct = new ChainTest(cc, pc); + ccs.addChain(Marina.DATA_CHAIN, cc); + ccs.addChain(Marina.REPORT_CHAIN, cc); + ccs.addChain(Marina.CONTROL_CHAIN, cc); + marina = new Marina(ccs, model, !cmdArgs.jtagShift, indenter); - //System.out.println("launching"); - //ChainG.createAndShowGUI(marina.cc.getChainControlFromPath(Marina.REPORT_CHAIN)); - //System.out.println(" launched."); + if (model instanceof VerilogModel) + ((SimulationModel)model).start("verilog", "marina.v", VerilogModel.DUMPVARS, !cmdArgs.jtagShift); + else if (model instanceof HsimModel) + ((SimulationModel)model).start("hsim64", netListName, 0, !cmdArgs.jtagShift); + else + ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, !cmdArgs.jtagShift); + + /* + ccC.resetInBits(); + ccC.shift(Marina.CONTROL_CHAIN, false, true); + */ + cc.resetInBits(); + cc.shift(Marina.CONTROL_CHAIN, false, true); + doOneTest(cmdArgs.testNum); ((SimulationModel)model).finish(); @@ -280,11 +294,8 @@ public class MarinaTest { PowerChannel pc = new ManualPowerChannel("pc", false); ChainTest ct = new ChainTest(cc, pc); ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING); - doOneTest(cmdArgs.testNum); - setUpSuppliesAndMeters(cmdArgs.station); - } /** In the absence of looping, the longest path through Infinity is 4 column delays */ @@ -430,11 +441,46 @@ public class MarinaTest { //========================================================================= // Put top level tests here + private void testChains(Marina marina) { + if (ctC!=null) { + prln("Testing control chain..."); + ctC.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING); + ccC.resetInBits(); + ccC.shift(Marina.CONTROL_CHAIN, false, true); + } + + if (ctD!=null) { + prln("Testing data chain..."); + ctD.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING); + //ccD.resetInBits(); + //ccD.shift(Marina.DATA_CHAIN, false, true); + } + + if (ctR!=null) { + prln("Testing report chain..."); + ctR.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING); + //ccR.resetInBits(); + //ccR.shift(Marina.REPORT_CHAIN, false, true); + } + + if (ct!=null) { + prln("Testing control chain..."); + ct.testOneChain(Marina.CONTROL_CHAIN, Infrastructure.SEVERITY_WARNING); + cc.resetInBits(); + cc.shift(Marina.CONTROL_CHAIN, false, true); + prln("Testing data chain..."); + ct.testOneChain(Marina.DATA_CHAIN, Infrastructure.SEVERITY_WARNING); + prln("Testing report chain..."); + ct.testOneChain(Marina.REPORT_CHAIN, Infrastructure.SEVERITY_WARNING); + } + } + private void testProperStoppers(Marina marina) { prln("Begin testProperStoppers"); adjustIndent(2); for(ProperStopper ps : new ProperStopper[] { marina.data, marina.instrIn }) { + prln("testing " + (ps == marina.data ? "data" : "instruction") + " stopper"); adjustIndent(2); @@ -458,8 +504,8 @@ public class MarinaTest { List din = new ArrayList(); - BitVector count = new BitVector(36,"count"); - BitVector one = new BitVector(36, "one"); + BitVector count = new BitVector(MarinaPacket.WORD_WIDTH,"count"); + BitVector one = new BitVector(MarinaPacket.WORD_WIDTH, "one"); count.setFromLong(0); one.setFromLong(1); for (int i=0; i<3; i++) { @@ -467,7 +513,8 @@ public class MarinaTest { count = count.add(one); } - marina.instrIn.fillMany(din); + for(BitVector d : din) + marina.instrIn.fill(new MarinaPacket(d, false, MarinaPacket.null_path)); adjustIndent(-2); prln("End sendInstructions"); @@ -479,24 +526,12 @@ public class MarinaTest { //getCtrsFlags(marina); - prln("send token"); - marina.instrIn.fill( - new Instruction.Move(DOCK, - false, /* requeueing */ - Predicate.IgnoreFlagD, /* predicate */ - false, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - false, /* dataOut */ - true /* tokenOut */ - )); - - //getCtrsFlags(marina); - int nbToks = marina.getNumTokens(); + fatal(nbToks!=0, "Expected no tokens on initialization but got: "+nbToks+" tokens"); + + marina.instrIn.fill(setIlc(1)); + marina.instrIn.fill(SEND_TOKEN); + nbToks = marina.getNumTokens(); fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens"); adjustIndent(-2); @@ -507,33 +542,18 @@ public class MarinaTest { prln("Begin sendData"); adjustIndent(2); - prln("ILC=1"); - marina.instrIn.fill( - new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1)); + edu.berkeley.fleet.api.BitVector bv = new edu.berkeley.fleet.api.BitVector(13); + for(int i=0; i dataItems = marina.data.drainMany(); fatal(dataItems.size()!=1, "Expected one data item to emerge but got: "+dataItems.size()+" data items"); - - prln("Datum="+MarinaUtils.formatDataTokAddr(dataItems.get(0))); + + MarinaPacket mp = new MarinaPacket(dataItems.get(0)); + fatal(mp.tokenhood, "Expected tokenhood=data, but got tokenhood=token"); adjustIndent(-2); prln("End sendData"); @@ -543,16 +563,10 @@ public class MarinaTest { prln("Begin sendDataIlcInfinite"); adjustIndent(2); - prln("ILC=\\infty"); - marina.instrIn.fill( - new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity)); - - getCtrsFlags(marina); - - prln("send data"); - marina.instrIn.fill(SEND_DATA); - - getCtrsFlags(marina); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity), + SEND_DATA, + }); // more than MAX_ILC int howmany = 70; @@ -564,15 +578,18 @@ public class MarinaTest { prln("End sendDataIlcInfinite"); } - private void setOLC(Marina marina, int olc) { - // ugly hack, to be removed when we fix the zero-detect circuit - for(int i=0; i<2; i++) { - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc)); - } + private Instruction setOlc(int olc) { + return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, olc); + } + private Instruction setOlcIfZero(int olc) { + return new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, olc); + } + private Instruction setIlc(int ilc) { + return new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, ilc); } - private void testFlagZ(Marina marina) { - prln("Begin testFlagZ"); + private void testFlagD(Marina marina) { + prln("Begin testFlagD"); adjustIndent(2); List toks; @@ -580,40 +597,42 @@ public class MarinaTest { Predicate only_if_olc_zero = Predicate.FlagD; Predicate only_if_olc_nonzero = Predicate.Default; + marina.instrIn.fill(setIlc(1)); + for(int olc : new int[] { 1, 0 }) { for(boolean predicate_olc_nonzero : new boolean[] { true, false }) { - prln("Attempting send token with "+ + prln("Attempting send data item with "+ "olc=="+olc+" and "+ "predicate olc"+(predicate_olc_nonzero?"!=0":"==0")); adjustIndent(2); - prln("Inserting Set OLC="+olc); - setOLC(marina, olc); - - prln("Inserting ["+(predicate_olc_nonzero?"olc!=0":"olc==0")+"] send data"); - marina.instrIn.fill(new Instruction.Move(DOCK, - false, /* requeueing */ - predicate_olc_nonzero /* predicate */ - ? only_if_olc_nonzero - : only_if_olc_zero - , - false, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - true, /* dataOut */ - false /* tokenOut */ - )); - toks = marina.data.drainMany(); - int expected = (predicate_olc_nonzero == (olc!=0)) ? 1 : 0; - fatal(toks.size()!=expected, "Expected "+expected+" token to emerge but got: "+toks.size()+" token(s)"); + marina.fillSouthProperStopper(new Instruction[] { + setOlc(olc), + new Instruction.Move(dock, + predicate_olc_nonzero // predicate + ? only_if_olc_nonzero + : only_if_olc_zero + , + false, // torpedoable + null, // path + false, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + true, // dataOut + false // tokenOut + ), + }); + expectNorthFifoExactly((predicate_olc_nonzero == (olc!=0)) ? 1 : 0); + + for(int i=0; i dItems; - prln("Setting OLC=63"); - setOLC(marina, 63); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1)); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1)); for(boolean flag_a : new boolean[] { false, true }) { for(boolean flag_b : new boolean[] { false, true }) { prln("Setting flags, a="+flag_a+" b="+flag_b); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, flag_a ? Instruction.Set.FlagFunction.ONE : Instruction.Set.FlagFunction.ZERO, @@ -647,20 +666,18 @@ public class MarinaTest { Predicate.NotFlagB, }) { - prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate.getClass().getName()); + prln("Attempting send data with a="+flag_a+", b="+flag_b+", predicate="+predicate); adjustIndent(2); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1)); - marina.instrIn.fill(new Instruction.Move(DOCK, - false, /* requeueing */ - predicate, /* predicate */ - false, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - true, /* dataOut */ - false /* tokenOut */ + marina.instrIn.fill(new Instruction.Move(dock, + predicate, // predicate + false, // torpedoable + null, // path + false, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + true, // dataOut + false // tokenOut )); adjustIndent(-2); dItems = marina.data.drainMany(); @@ -676,39 +693,48 @@ public class MarinaTest { } + private void showOlc() { + prln("OLC=="+marina.getOLC()); + } + private void expectOlc(int x) { + int olc = marina.getOLC(); + fatal(x!=olc, "expected OLC=="+x+", but scanned out OLC=="+olc); + } private void getCtrsFlags(Marina marina) { prln("begin getCtrsFlags"); adjustIndent(2); - int olc = marina.getOLC(); - prln("OLC=="+olc); - + showOlc(); Ilc ilc = marina.getILC(); prln("ILC.done=="+ilc.getDone()+ " ILC.infinity=="+ilc.getInfinity()+ - " ILC.zero=="+ilc.getZero()+ " ILC.count=="+ilc.getCount()); - - boolean a = marina.getFlagA(); - prln("flagA=="+a); - - boolean b = marina.getFlagB(); - prln("flagB=="+b); - + prln("flagA=="+marina.getFlagA()); + prln("flagB=="+marina.getFlagB()); adjustIndent(-2); prln("end getCtrsFlags"); } + private void walkOneOLC(Marina marina) { prln("Begin walkOneOLC"); adjustIndent(2); - for (int i=0; i<7; i++) { - int inOlc = 0x20 >> i; - prln("Set inOlc="+inOlc); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, inOlc)); - int outOlc = marina.getOLC(); - fatal(outOlc!=inOlc, "walkOneOLC: got="+outOlc+" expected="+inOlc); + for (int i=0; i<6; i++) { + + if (marina.kesselsCounter) { + System.out.println("master-clearing..."); + // master clear on each iteration; otherwise we'd need to "run down" the olc + marina.masterClear(); + marina.enableInstructionSend(true); + } + + int inOlc = i==-1 ? 0 : (1<> i; + int inIlc = 1 << i; prln("inIlc="+inIlc); - - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc)); - + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, inIlc)); Ilc ilc = marina.getILC(); int outIlc = ilc.getCount(); - fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+outIlc); - - boolean inZero = inIlc==0; - boolean outZero = ilc.getZero(); - fatal(outZero!=inZero, "bad ILC zero: "+outZero); + fatal(outIlc!=inIlc, "bad ILC count: "+outIlc+" expected: "+inIlc); fatal(ilc.getInfinity(), "bad Infinity bit: true"); } prln("Now test the infinity bit"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity)); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity)); Ilc ilc = marina.getILC(); fatal(!ilc.getInfinity(), "bad Infinity bit: false"); adjustIndent(-2); @@ -746,30 +764,29 @@ public class MarinaTest { prln("Begin countIlc"); adjustIndent(2); - prln("Set ILC=63"); marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc)); + Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, maxIlc)); int ilc = marina.getILC().getCount(); fatal(ilc!=maxIlc, "bad ILC count: "+ilc+" expected: "+maxIlc); prln("execute a move instruction that does nothing except decrement the ILC to zero"); marina.instrIn.fill( - new Instruction.Move(DOCK, - false, /* requeueing */ - Predicate.IgnoreFlagD, /* predicate */ - false, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - false, /* dataOut */ - false /* tokenOut */ + new Instruction.Move(dock, + Predicate.IgnoreFlagD, // predicate + false, // torpedoable + null, // path + false, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + false, // dataOut + false // tokenOut )); // wait for ILC to count from 63 to 0 - model.waitNS(64 * CYCLE_TIME_NS); + model.waitNS(128 * CYCLE_TIME_NS); + //model.waitNS(10000); prln("Check that ILC==0"); ilc = marina.getILC().getCount(); @@ -780,18 +797,18 @@ public class MarinaTest { } // Note: countOlc takes 44 minutes to run on nanosim private void countOlc(Marina marina) { - final int maxOlc = 63; + int maxOlc = 63; prln("Begin countOlc"); adjustIndent(2); - - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, maxOlc)); + + marina.instrIn.fill(setOlc(maxOlc)); + for (int i=maxOlc; i>=0; i--) { + model.waitNS(128 * CYCLE_TIME_NS); prln("OLC should be: "+i); - int olc = marina.getOLC(); - fatal(olc!=i, "bad OLC: "+olc+" expected: "+i); + expectOlc(i); marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement)); + Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, SetSource.Decrement)); } adjustIndent(-2); @@ -818,9 +835,19 @@ public class MarinaTest { prln("Successfully inserted " + i + " instructions"); } + private static MarinaPath null_path = new MarinaPath((MarinaFleet)dock.getShip().getFleet(), + MarinaUtils.sunToBerk(MarinaPacket.null_path)); + + private static final Instruction DEC = + new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter, SetSource.Decrement); + + private static final Instruction FLAG_NOP = + new Instruction.Set(dock, Predicate.IgnoreFlagD, + CLEAR_FLAG.add(Predicate.FlagA), + CLEAR_FLAG.add(Predicate.FlagB)); + private static final Instruction NOP = - new Instruction.Move(DOCK, - false, /* requeueing */ + new Instruction.Move(dock, Predicate.IgnoreFlagD, /* predicate */ false, /* torpedoable */ null, /* path */ @@ -832,26 +859,24 @@ public class MarinaTest { false /* tokenOut */ ); - private static final Instruction REQUEUEING_NOP = - new Instruction.Move(DOCK, - true, /* requeueing */ + private static final Instruction SEND_DATA = + new Instruction.Move(dock, Predicate.IgnoreFlagD, /* predicate */ false, /* torpedoable */ - null, /* path */ + null_path, /* path */ false, /* tokenIn */ false, /* dataIn */ false, /* latchData */ false, /* latchPath */ - false, /* dataOut */ + true, /* dataOut */ false /* tokenOut */ ); - private static final Instruction SEND_DATA = - new Instruction.Move(DOCK, - false, /* requeueing */ - Predicate.IgnoreFlagD, /* predicate */ + private static final Instruction SEND_DATA_IF_D_NOT_SET = + new Instruction.Move(dock, + Predicate.Default, /* predicate */ false, /* torpedoable */ - null, /* path */ + null_path, /* path */ false, /* tokenIn */ false, /* dataIn */ false, /* latchData */ @@ -860,9 +885,21 @@ public class MarinaTest { false /* tokenOut */ ); + private static final Instruction TORPEDOABLE_RECV_DATA = + new Instruction.Move(dock, + Predicate.IgnoreFlagD, /* predicate */ + true, /* torpedoable */ + null, /* path */ + false, /* tokenIn */ + true, /* dataIn */ + true, /* latchData */ + false, /* latchPath */ + false, /* dataOut */ + false /* tokenOut */ + ); + private static final Instruction RECV_DATA = - new Instruction.Move(DOCK, - false, /* requeueing */ + new Instruction.Move(dock, Predicate.IgnoreFlagD, /* predicate */ false, /* torpedoable */ null, /* path */ @@ -875,11 +912,10 @@ public class MarinaTest { ); private static final Instruction SEND_TOKEN = - new Instruction.Move(DOCK, - false, /* requeueing */ + new Instruction.Move(dock, Predicate.IgnoreFlagD, /* predicate */ false, /* torpedoable */ - null, /* path */ + null_path, /* path */ false, /* tokenIn */ false, /* dataIn */ false, /* latchData */ @@ -889,8 +925,7 @@ public class MarinaTest { ); private static final Instruction RECV_TOKEN = - new Instruction.Move(DOCK, - false, /* requeueing */ + new Instruction.Move(dock, Predicate.IgnoreFlagD, /* predicate */ false, /* torpedoable */ null, /* path */ @@ -902,281 +937,253 @@ public class MarinaTest { false /* tokenOut */ ); - private static final Instruction REQUEUEING_SEND_DATA = - new Instruction.Move(DOCK, - true, /* requeueing */ - Predicate.IgnoreFlagD, /* predicate */ - false, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - true, /* dataOut */ - false /* tokenOut */ - ); - private void testRequeueStage0(Marina marina) { - prln("Begin testRequeueStage0"); - adjustIndent(2); - - prln("Executing Set OLC=0"); - setOLC(marina, 0); - saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false); - adjustIndent(-2); - prln("End testRequeueStage0"); + private void expectNorthFifoNoMoreThan(int num) { + model.waitNS(128 * CYCLE_TIME_NS); + List dataItems = marina.data.drainMany(num+1); + fatal(dataItems.size()>num, + "Expected no more than "+num+ + " data items to emerge but got at least: "+dataItems.size()); } - - private void testRequeueStage0to1(Marina marina) { - prln("Begin testRequeueStage0to1"); - adjustIndent(2); - - prln("Executing Set OLC=63"); - setOLC(marina, 63); - saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true); - adjustIndent(-2); - prln("End testRequeueStage0to1"); + private void expectNorthFifoExactly(int num) { + model.waitNS(128 * CYCLE_TIME_NS); + List dataItems = marina.data.drainMany(num+1); + fatal(dataItems.size()!=num, + "Expected exactly "+num+ + " data items to emerge but got at least: "+dataItems.size()); + } + private void expectTokensNoMoreThan(int num) { + int x = marina.getNumTokens(); + List dataItems = marina.data.drainMany(num+1); + fatal(x>num, + "Expected no more than "+num+ + " data items to emerge but got at least: "+x); + } + private void expectTokensExactly(int num) { + int x = marina.getNumTokens(); + fatal(x!=num, + "Expected exactly "+num+ + " data items to emerge but got at least: "+x); } - /** - * This test brings the requeue stage through the 0->1->3->0 state - * transition sequence. - * - - * According to the diagram in IES50, there are three transitions - * (0->1, 1->3, 3->0) to perform, and in each state there are two - * behaviors to verify (the two notations in each oval of the - * state diagram). The "OD->drain" behavior of state 0 is - * verified by testRequeueStage0(). - */ - private void testRequeueStage0to1to3to0(Marina marina) { - List dataItems; - - int extras = 5; - int olc_value = MORE_THAN_DATA_OUT_SATURATION_AMOUNT + extras; - - prln("Begin testRequeueStage0to1to3to0"); - adjustIndent(2); - - // State 0 ////////////////////////////////////////////////////////////////////////////// - - prln("Executing Set OLC="+olc_value); - setOLC(marina, olc_value); - prln("Executing Set ILC=1"); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1)); - - // verify state0 "EPI->ring" and 0->1 transition - prln("Executing Send Data (requeueable); this will cause 0->1 transition and be discarded"); - marina.instrIn.fill(REQUEUEING_SEND_DATA); - - // State 1 ////////////////////////////////////////////////////////////////////////////// - - // verify state1 "EPI->ring" - prln("Executing Set ILC=1; this will be recirculated"); - marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1)); - - prln("Executing Send Data; this will be recirculated"); - marina.instrIn.fill(REQUEUEING_SEND_DATA); - - prln("Executing Set OLC--; this will be recirculated"); - marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement)); - - // verify state1 "OD waits" - dataItems = marina.data.drainMany(2); - fatal(dataItems.size()!=1, "Expected exactly one data item to emerge but got: "+dataItems.size()+" data items"); + private void testFlagDRecomputationTime(Marina marina) { + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + RECV_DATA, + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0), + SEND_DATA_IF_D_NOT_SET + }); + marina.fillNorthProperStopper(); + expectNorthFifoNoMoreThan(0); + + marina.fillSouthProperStopper(new Instruction[] { + RECV_DATA, + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement), + SEND_DATA_IF_D_NOT_SET + }); + marina.fillNorthProperStopper(); + expectNorthFifoNoMoreThan(0); + + marina.fillSouthProperStopper(new Instruction[] { + RECV_DATA, + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.Decrement), + SEND_DATA_IF_D_NOT_SET + }); + marina.fillNorthProperStopper(); + expectNorthFifoExactly(1); + marina.instrIn.fill(DEC); + + marina.fillSouthProperStopper(new Instruction[] { + RECV_DATA, + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,0), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,1), + SEND_DATA_IF_D_NOT_SET + }); + marina.fillNorthProperStopper(); + expectNorthFifoExactly(1); + } - // verify 1->3 transition - prln("Executing Tail; this will cause the 2->3 transition and be discarded"); - marina.instrIn.fill(new Instruction.Tail(DOCK)); + private void testTailWaitsForHead(Marina marina) { + marina.instrIn.fill(setIlc(1)); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63)); + + marina.enableInstructionSend(false); + marina.enableInstructionRecirculate(true); + + marina.instrIn.fill(TORPEDOABLE_RECV_DATA); + marina.instrIn.fill(new Instruction.Head(dock)); + marina.instrIn.fill(SEND_DATA); + marina.instrIn.fill(TORPEDOABLE_RECV_DATA); + marina.instrIn.fill(SEND_TOKEN); + marina.instrIn.fill(TORPEDOABLE_RECV_DATA); + marina.instrIn.fill(new Instruction.Tail(dock)); + marina.instrIn.fillTorpedo(); + + marina.enableInstructionRecirculate(false); + marina.enableInstructionSend(true); + marina.instrIn.run(); + + expectNorthFifoNoMoreThan(0); + prln("inserting into north proper stopper"); + marina.fillNorthProperStopper(); + expectNorthFifoExactly(1); + int nbToks = marina.getNumTokens(); + fatal(nbToks!=1, "Expected one token to emerge but got: "+nbToks+" tokens"); + } - // State 3 ////////////////////////////////////////////////////////////////////////////// + /* + marina.instrIn.fill(setIlc(1)); + marina.instrIn.fill(setOlc(1)); - // verify state3 "OD->ring" - dataItems = marina.data.drainMany(MORE_THAN_DATA_OUT_SATURATION_AMOUNT); - fatal(dataItems.size()ring" - saturateInstructionFifo(marina, NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true); + // the head should wait for the tail + marina.instrIn.fill(new Instruction.Head(dock)); + marina.instrIn.fill(NOP); + marina.instrIn.fill(SEND_DATA); + marina.instrIn.fill(RECV_DATA); - // verify state3->state0 - dataItems = marina.data.drainMany(extras + 4); - fatal(dataItems.size()!=(extras+1), - "Expected exactly " + (extras+1) + " items to emerge, but got at least : "+dataItems.size()+" of them"); + expectNorthFifoNoMoreThan(0); - // State 0 ////////////////////////////////////////////////////////////////////////////// + marina.instrIn.fillTorpedo(); + expectNorthFifoNoMoreThan(0); - // verify that we are back in state0 - saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false); + marina.instrIn.fill(new Instruction.Tail(dock)); + expectNorthFifoExactly(1); + */ - adjustIndent(-2); - prln("End testRequeueStage0to1to3to0"); + private void testTailWithoutHead(Marina marina) { + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63), + new Instruction.Tail(dock), + SEND_DATA, + }); + List dataItems = marina.data.drainMany(1); + fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size()); } - /** - * This test brings the requeue stage through the 0->2->3->0 state - * transition sequence. - * - * According to the diagram in IES50, there are two transitions - * (0->2, 2->3, 3->0) to perform, and in each state there are two - * behaviors to verify (the two notations in each oval of the - * state diagram). The "OD->drain" behavior of state 0 is - * verified by testRequeueStage0(). - */ - private void testRequeueStage0to2to3to0(Marina marina) { + private void testHeadWaitsForTail(Marina marina) { List dataItems; - int olc_value = 10; - int number_of_non_requeueable_send_datas = INSTRUCTION_RING_CAPACITY; - - prln("Begin testRequeueStage0to2to3to0"); + prln("Begin testHeadWaitsForTail"); adjustIndent(2); - // State 0 ////////////////////////////////////////////////////////////////////////////// - - prln("Executing Set OLC="+olc_value); - setOLC(marina, olc_value); - - prln("Executing Set ILC=1"); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 1)); - - // insert many non-requeueing "send data item" instructions; - // this will let us single-step the execution point by - // extracting data items. - for(int i=0; i2 transition - prln("Inserting Tail"); - marina.instrIn.fill(new Instruction.Tail(DOCK)); - - // State 2 ////////////////////////////////////////////////////////////////////////////// - - // confirm state 2 "EPI waits" - prln("Saturating the instruction input to confirm that EPI waits"); - saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, true); - - // confirm state 2 "OD->drain" - prln("Draining data output to cause the 2->3 transition"); - dataItems = marina.data.drainMany(number_of_non_requeueable_send_datas); - fatal(dataItems.size()!=number_of_non_requeueable_send_datas, - "Expected at least " + number_of_non_requeueable_send_datas + - " items to emerge, but got only : "+dataItems.size()+" of them"); - - // State 3 ////////////////////////////////////////////////////////////////////////////// - - // verify state3 "EPI waits" - prln("Verifying that EPI still waits in state3"); - fatal(marina.instrIn.getFillStateWire()!=MarinaUtils.StateWireState.FULL, - "state3 EPI waits not verified"); - prln(" ok"); - prln(""); - - // verify state3 "OD->ring" and state3->state0 - prln("Removing data items to run down the OLC to zero and cause 3->0 transition"); - dataItems = marina.data.drainMany(olc_value+10); - fatal(dataItems.size()!=(olc_value+1), - "Expected exactly " + (olc_value+1) + " items to emerge, but got: "+dataItems.size()+" of them"); - - // State 0 ////////////////////////////////////////////////////////////////////////////// + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63), + new Instruction.Head(dock), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1), + SEND_DATA, + }); + dataItems = marina.data.drainMany(1); + fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size()); + marina.instrIn.fill(new Instruction.Tail(dock)); - // verify that we are back in state0 - prln("Confirming that we are back in state0"); - saturateInstructionFifo(marina, REQUEUEING_NOP, MORE_THAN_INSTRUCTION_IN_SATURATION_AMOUNT, false); + BitVector bv = marina.data.drain(); + fatal(bv==null, "Expected at least one data item to emerge but got none"); adjustIndent(-2); - prln("End testRequeueStage0to2to3to0"); + prln("End testHeadWaitsForTail"); } - private void testWaitForTail(Marina marina) { - List dataItems; - - prln("Begin testWaitForTail"); - adjustIndent(2); - - prln("inserting instruction: Set OLC=63"); - setOLC(marina, 63); - - prln("inserting instruction: [Rq] Nop; this will cause 0->1 transition and possibly be discarded"); - marina.instrIn.fill(REQUEUEING_NOP); + private void testNonTorpedoableMoveDoesNotResetDFlag(Marina marina) { + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,63), + new Instruction.Move(dock, + Predicate.IgnoreFlagD, // predicate + true, // torpedoable + null, // path + true, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + false, // dataOut + false // tokenOut + ), + new Instruction.Move(dock, + Predicate.FlagD, // predicate + false, // torpedoable + null, // path + false, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + true, // dataOut + false // tokenOut + ), + }); + marina.instrIn.fillTorpedo(); + expectNorthFifoExactly(1); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Move(dock, + Predicate.Default, // predicate + false, // torpedoable + null, // path + false, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + true, // dataOut + false // tokenOut + ), + }); + expectNorthFifoNoMoreThan(0); + } - // just in case there is some capacity between the execution - // stage and the requeue stage, we stick in a whole bunch of - // NOPs. + private void testAbort(Marina marina) { + + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,1), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,2), + SEND_DATA_IF_D_NOT_SET, + new Instruction.Head(dock), + SEND_DATA_IF_D_NOT_SET, + new Instruction.Set(dock,Predicate.Default,SetDest.DataLatch,2), + new Instruction.Abort(dock, Predicate.FlagD), + new Instruction.Set(dock,Predicate.Default,SetDest.OuterLoopCounter,SetSource.Decrement), + new Instruction.Tail(dock), + }, true); + for(int i=0; i<4; i++) { - prln("inserting instruction: [Rq] Nop; this (and subsequent instructions) should not execute until Tail is inserted"); - marina.instrIn.fill(REQUEUEING_NOP); + BitVector bv; + + model.waitNS(128 * CYCLE_TIME_NS); + bv = new MarinaPacket(marina.data.drain()).data.bitReverse(); + fatal(bv==null, "no data item found"); + prln("got " + bv.toLong()); + fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong()); + + model.waitNS(128 * CYCLE_TIME_NS); + bv = new MarinaPacket(marina.data.drain()).data.bitReverse(); + fatal(bv==null, "no data item found"); + prln("got " + bv.toLong()); + fatal(bv.toLong()!=1, "expected 1, got " + bv.toLong()); + + model.waitNS(128 * CYCLE_TIME_NS); + bv = new MarinaPacket(marina.data.drain()).data.bitReverse(); + fatal(bv==null, "no data item found"); + prln("got " + bv.toLong()); + fatal(bv.toLong()!=2, "expected 2, got " + bv.toLong()); + } - - prln("inserting instruction: [Rq] Set ILC=1"); - marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1)); - - prln("inserting instruction: [Rq] Send Data"); - marina.instrIn.fill(REQUEUEING_SEND_DATA); - - dataItems = marina.data.drainMany(1); - fatal(dataItems.size()!=0, "Expected exactly no data items to emerge but got at least: "+dataItems.size()); - - adjustIndent(-2); - prln("End testWaitForTail"); } - // This test case will FAIL if the requeue stage behaves as - // described in IES50. If we determine that the behavior - // described there is actually desirable, then this test should be - // modified. - private void testRequeueStageDrop(Marina marina) { - List dataItems; - - prln("Begin testRequeueStageDrop"); - adjustIndent(2); - - // We have decided that this issue will not be fixed in - // Marina. Therefore, the test is commented out. - - /* - prln("inserting instruction: Set OLC=63"); - setOLC(marina, 63); - - prln("inserting instruction: Set ILC=1"); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1)); - - // if you uncomment this, then the NOP will be dropped and the test will pass - //prln("inserting instruction: [Rq] Nop; this will cause 0->1 transition and possibly be discarded"); - //marina.instrIn.fill(REQUEUEING_NOP); - - prln("inserting instruction: [Rq] Send Data; this will cause 0->1 transition and be discarded"); - marina.instrIn.fill(REQUEUEING_SEND_DATA); - - prln("inserting instruction: [Rq] Set ILC=1"); - marina.instrIn.fill(new Instruction.Set(DOCK,true,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1)); - - prln("inserting instruction: Tail"); - marina.instrIn.fill(new Instruction.Tail(DOCK)); - - dataItems = marina.data.drainMany(3); - fatal(dataItems.size()<3, "Expected exactly unlimited data items to emerge but got only: "+dataItems.size()); - */ - - adjustIndent(-2); - prln("End testRequeueStageDrop"); + private void testAbortOutsideOfLoop(Marina marina) { + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + // ensure that an abort doesn't cause problems if no loop is in progress + new Instruction.Abort(dock, Predicate.IgnoreFlagD), + SEND_DATA, + }); + expectNorthFifoExactly(1); } - private void testFlagAB(Marina marina) { prln("Begin testFlagAB"); adjustIndent(2); @@ -1196,17 +1203,34 @@ public class MarinaTest { one = one.add(Predicate.FlagC); one = one.add(Predicate.NotFlagC); - // clear the flags to a known state, then check both 0->1 and 1->0 transitions - for(boolean b : new boolean[] { false, true, false }) { - prln((b?"Setting":"Clearing")+" flags"); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1)); + for(boolean fast : new boolean[] { true, false }) { + // clear the flags to a known state, then check both 0->1 and 1->0 transitions + for(boolean b : new boolean[] { false, true, false }) { + prln("state: a="+marina.getFlagA()+", b="+marina.getFlagB()); + prln((b?"Setting":"Clearing")+" flags"); + + Instruction inst = new Instruction.Set(dock,Predicate.IgnoreFlagD, + b ? one : zero, + b ? one : zero + ); + if (fast) { + marina.fillSouthProperStopper(new Instruction[] { + RECV_DATA, + inst, + NOP, + }); + model.waitNS(64 * CYCLE_TIME_NS); + marina.fillNorthProperStopper(); + } else { + marina.instrIn.fill(inst); + } - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, - b ? one : zero, - b ? one : zero - )); - fatal(marina.getFlagA()!=b, "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set")); - fatal(marina.getFlagB()!=b, "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set")); + fatal(marina.getFlagA()!=b, + "after "+(b?"setting":"clearing")+" FlagA, it was still "+(b?"clear":"set")); + fatal(marina.getFlagB()!=b, + "after "+(b?"setting":"clearing")+" FlagB, it was still "+(b?"clear":"set")); + } } adjustIndent(-2); @@ -1221,6 +1245,7 @@ public class MarinaTest { prln("Begin testFlagTruthTable"); adjustIndent(2); + marina.instrIn.fill(setIlc(1)); Instruction.Set.FlagFunction zero = Instruction.Set.FlagFunction.ZERO; Instruction.Set.FlagFunction one = zero.add(Predicate.FlagA).add(Predicate.NotFlagA); @@ -1233,10 +1258,9 @@ public class MarinaTest { for(boolean which : new boolean[] { false, true }) { prln("before instruction: a="+a_state+", b="+b_state+", c="+c_state); - // set A,B flags to a_state and b_state marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, + Instruction.Set(dock,Predicate.IgnoreFlagD, a_state ? one : zero, b_state ? one : zero )); @@ -1246,7 +1270,7 @@ public class MarinaTest { BitVector addr = new BitVector(14, "empty"); for(int i=0; i dataItems; for(int bit=0; bit<37; bit++) { @@ -1337,17 +1366,16 @@ public class MarinaTest { fatal(dataItems.size()!=0, "found a data item waiting in the north proper stopper, but should not have"); - marina.instrIn.fill(new Instruction.Move(DOCK, - false, // requeueing - Predicate.IgnoreFlagD, // predicate - true, // torpedoable - null, // path - false, // tokenIn - true, // dataIn - true, // latchData - false, // latchPath - true, // dataOut - false // tokenOut + marina.instrIn.fill(new Instruction.Move(dock, + Predicate.IgnoreFlagD, // predicate + false, // torpedoable + null_path, // path + false, // tokenIn + true, // dataIn + true, // latchData + false, // latchPath + true, // dataOut + false // tokenOut )); dataItems = marina.data.drainMany(2); @@ -1367,6 +1395,8 @@ public class MarinaTest { prln("Begin setOlcFromDataLatch"); adjustIndent(2); + marina.instrIn.fill(setIlc(1)); + // walk a bit from 0 to 5 for(int bit=0; bit<6; bit++) { prln("inserting data item in north fifo ring"); @@ -1377,11 +1407,21 @@ public class MarinaTest { data.set(bit, true); marina.fillNorthProperStopper(new MarinaPacket(data, false, addr)); - marina.instrIn.fill(RECV_DATA); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch)); + marina.fillSouthProperStopper(new Instruction[] { + RECV_DATA, + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter,SetSource.DataLatch), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.DataLatch,-1), + }); + + model.waitNS(CYCLE_TIME_NS * 64); + + expectOlc(1<=0; bit--) { prln("inserting data item in north fifo ring"); BitVector data = new BitVector(37, "empty"); BitVector addr = new BitVector(14, "empty"); @@ -1402,9 +1444,12 @@ public class MarinaTest { data.set(bit, true); marina.fillNorthProperStopper(new MarinaPacket(data, false, addr)); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1)); - marina.instrIn.fill(RECV_DATA); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch)); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1), + RECV_DATA, + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.DataLatch), + }); + model.waitNS(CYCLE_TIME_NS * 64); int ilc = marina.getILC().getCount(); fatal(ilc != (1< dataItems = marina.data.drainMany(3); - fatal(dataItems.size()!=1, - "expected exactly one data item, got " + dataItems.size()); + marina.instrIn.fill(setIlc(1)); + marina.fillSouthProperStopper(new Instruction[] { + SEND_TOKEN, + RECV_TOKEN, + SEND_DATA, + }); + expectNorthFifoExactly(1); adjustIndent(-2); prln("End testSendAndRecvToken"); @@ -1440,20 +1479,23 @@ public class MarinaTest { prln("Begin testSignExtendedLiteral"); adjustIndent(2); - for(long val : new long[] { -1, 0, 1, (-1L << 14) }) { - prln("inserting Set Data Latch (sign-extended) 37'b" + Long.toString(val, 1)); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, - Instruction.Set.SetDest.DataLatch, - val)); + marina.instrIn.fill(setIlc(1)); + for(long val : new long[] { (-1L << 14), -1, 0, 1 }) { - prln("sending data item"); - marina.instrIn.fill(SEND_DATA); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD, + Instruction.Set.SetDest.DataLatch, + val), + SEND_DATA, + }); + model.waitNS(CYCLE_TIME_NS * 64); List dataItems = marina.data.drainMany(3); fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size()); - BitVector bv = dataItems.get(0); - prln("got back " + MarinaUtils.extractData(bv).getState()); + MarinaPacket mp = new MarinaPacket(dataItems.get(0)); + BitVector bv = mp.data; + prln("got back " + mp); boolean mismatch = false; String err = ""; @@ -1474,8 +1516,8 @@ public class MarinaTest { prln("Begin testShiftedLiteral"); adjustIndent(2); - prln("clearing the D register"); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, + marina.instrIn.fill(setIlc(1)); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD, Instruction.Set.SetDest.DataLatch, 0)); @@ -1484,12 +1526,10 @@ public class MarinaTest { for(long val : new long[] { -1, 0, 1, (-1L << 18) }) { - prln("inserting Shift 19'b" + Long.toString(val, 1)); edu.berkeley.fleet.api.BitVector immediate = new edu.berkeley.fleet.api.BitVector(19); for(int i=0; i dataItems = marina.data.drainMany(3); fatal(dataItems.size()!=1, "expected exactly one data item, got " + dataItems.size()); - BitVector bv = MarinaUtils.extractData(dataItems.get(0)); + BitVector bv = new MarinaPacket(dataItems.get(0)).data; fatal(!bv.equals(dreg), "data read back did not match inserted literal.\n" + "got: "+bv.bitReverse().getState()+"\n"+ "expected:"+dreg.bitReverse().getState()); @@ -1525,6 +1568,7 @@ public class MarinaTest { // Dc=1 => sigS is copied into C-flag // Dc=0 => sigA is copied into C-flag + marina.instrIn.fill(setIlc(1)); for(boolean dc : new boolean[] { false, true }) { for(boolean c_flag : new boolean[] { true, false, true }) { @@ -1536,8 +1580,8 @@ public class MarinaTest { for(int i=0; i dataItems = marina.data.drainMany(); fatal(dataItems.size()!=ilc, "Expected "+ilc+" data item(s) to emerge but got: "+dataItems.size()+" data items"); } @@ -1701,69 +1745,85 @@ public class MarinaTest { prln("End testILC"); } + private void testILCZero(Marina marina) { + adjustIndent(2); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,0), + SEND_DATA, + SEND_TOKEN, + }); + expectNorthFifoNoMoreThan(0); + expectTokensExactly(1); + adjustIndent(-2); + } + private void sendTorpedo(Marina marina) { prln("Begin sendTorpedo"); adjustIndent(2); - - prln("Set OLC = 1"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 1)); + marina.instrIn.fill(setIlc(1)); + marina.instrIn.fill(setOlc(63)); - int olc = marina.getOLC(); - fatal(olc!=1, "bad OLC: "+olc+" expected: 1"); + model.waitNS(128 * CYCLE_TIME_NS); + expectOlc(63); - prln("Set A=0, B=0"); marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG)); - + Instruction.Set(dock,Predicate.IgnoreFlagD, CLEAR_FLAG, CLEAR_FLAG)); fatal(marina.getFlagA(), "bad A flag: true"); fatal(marina.getFlagB(), "bad B flag: true"); - - prln("Set ILC = Infinity"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity)); - + prln("execute a move instruction that does nothing but loops until torpedo arrives"); - marina.instrIn.fill( - new Instruction.Move(DOCK, - false, /* requeueing */ - Predicate.IgnoreFlagD, /* predicate */ - true, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - false, /* dataOut */ - false /* tokenOut */ - )); - - prln("A=1, B=1 This instruction should get torpedoed along with the Move"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG)); + prln("A=1, B=B This instruction should not execute because D-flag is set"); + prln("Set A=A, B=1 This instruction should execute because D-flag is set"); + + model.waitNS(128 * CYCLE_TIME_NS); + + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, SetSource.Infinity), + new Instruction.Move(dock, + Predicate.IgnoreFlagD, // predicate + true, // torpedoable + null, // path + false, // tokenIn + true, // dataIn + false, // latchData + false, // latchPath + false, // dataOut + false // tokenOut + ), + new Instruction.Set(dock,Predicate.Default, + SET_FLAG, + Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagB) + ), + new Instruction.Set(dock, Predicate.FlagD, + Instruction.Set.FlagFunction.ZERO.add(Predicate.FlagA), + SET_FLAG + ), + }); + + model.waitNS(128 * CYCLE_TIME_NS); prln("send torpedo. This should clear the OLC"); - marina.instrIn.fill(InstructionStopper.TORPEDO); - - getCtrsFlags(marina); - - // Note: It's tempting to test that OLC==0 here. However, hardware doesn't - // actually set counter bits to zero; it just sets the OLCZERO bit + marina.instrIn.fillTorpedo(); + model.waitNS(128 * CYCLE_TIME_NS); + + model.waitNS(128 * CYCLE_TIME_NS); - prln("A and B should remain false"); + prln("A should remain false, B should be true"); fatal(marina.getFlagA(), "bad A flag: true"); - fatal(marina.getFlagB(), "bad B flag: true"); + fatal(!marina.getFlagB(), "bad B flag: false"); - prln("OLC = 63. Reload OLC after torpedo"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63)); + model.waitNS(128 * CYCLE_TIME_NS); - olc = marina.getOLC(); - fatal(olc!=63, "bad OLC: "+olc+" expected: 63"); + prln("Reload OLC after torpedo, clears D-flag"); + marina.instrIn.fill(new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 63)); + + // FIXME: find another way to test this + model.waitNS(128 * CYCLE_TIME_NS); + expectOlc(63); prln("Set A=1, B=1 This instruction should execute because OLC!=0"); marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG)); + Instruction.Set(dock,Predicate.Default, SET_FLAG, SET_FLAG)); prln("A and B should be true"); fatal(!marina.getFlagA(), "bad A flag: false"); @@ -1773,46 +1833,60 @@ public class MarinaTest { prln("End sendTorpedo"); } - private void testTorpedoOnAnInfiniteNop(Marina marina) { - prln("Begin testTorpedoOnAnInfiniteNop"); + private void testTorpedoOnAnInfinite(Marina marina) { + prln("Begin testTorpedoOnAnInfinite"); adjustIndent(2); List dataItems; + marina.instrIn.fill(setIlc(1)); for(boolean torpedoable : new boolean[] { true, false }) { - prln("set ilc=\\infty"); - marina.instrIn.fill(new Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity)); - prln("nop"); - marina.instrIn.fill(new Instruction.Move(DOCK, - false, /* requeueing */ - Predicate.IgnoreFlagD, /* predicate */ - torpedoable, /* torpedoable */ - null, /* path */ - false, /* tokenIn */ - false, /* dataIn */ - false, /* latchData */ - false, /* latchPath */ - false, /* dataOut */ - false /* tokenOut */ - )); - prln("send data"); - marina.instrIn.fill(SEND_DATA); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Move(dock, + Predicate.IgnoreFlagD, // predicate + false, // torpedoable + null, // path + false, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + false, // dataOut + true // tokenOut + ), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,SetSource.Infinity), + new Instruction.Move(dock, + Predicate.IgnoreFlagD, // predicate + torpedoable, // torpedoable + null, // path + true, // tokenIn + false, // dataIn + false, // latchData + false, // latchPath + false, // dataOut + true // tokenOut + ), + // FIXME: this probably should be removed, unless Ivan doesn't want to change the behavior + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter,1), + + SEND_DATA, + }); // expect nothing to come out, because the NOP is executing - dataItems = marina.data.drainMany(10); + dataItems = marina.data.drainMany(2); fatal(dataItems.size()!=0, "Expected no data item(s) to emerge but got at least: "+dataItems.size()+" data items"); - prln("send torpedo"); - marina.instrIn.fill(InstructionStopper.TORPEDO); + marina.instrIn.fillTorpedo(); int expected = torpedoable?1:0; dataItems = marina.data.drainMany(2); fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items"); + + fatal(!marina.getILC().getDone(), "Expected ilc=done, but got "+marina.getILC()); } adjustIndent(-2); - prln("End testTorpedoOnAnInfiniteNop"); + prln("End testTorpedoOnAnInfinite"); } private void testOlcDecrementAtHighSpeed(Marina marina) { @@ -1827,56 +1901,56 @@ public class MarinaTest { // of the OLC will be checked by executing a MOVE with // [olc!=0] as the predicate. - int[] olcs = new int[] { 3 /*, 3, 3, 10, 41*/ }; - int[] decr_amounts = new int[] { 2 /*, 3, 4, 9, 10*/ }; + int[] olcs = new int[] { 3, 3, 3, 10, 41 }; + int[] decr_amounts = new int[] { 2, 3, 4, 9, 9 }; for(int which=0; which=olc ? 0 : 1; dataItems = marina.data.drainMany(2); fatal(dataItems.size()!=expected, "Expected "+expected+" item to emerge but got: "+dataItems.size()+" data items"); + + if (marina.kesselsCounter) { + // master clear on each iteration; otherwise we'd need to "run down" the olc + marina.masterClear(); + marina.enableInstructionSend(true); + } } adjustIndent(-2); @@ -1890,37 +1964,33 @@ public class MarinaTest { "Check correct setting of the ILC zero bit"); for (int i=0; i<6; i++) { - int notZero = 32 >> i; - prln("Set ILC=0"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.InnerLoopCounter, 0)); - + int notZero = 1<> i; + + if (marina.kesselsCounter) { + // master clear on each iteration; otherwise we'd need to "run down" the olc + marina.masterClear(); + marina.enableInstructionSend(true); + } + + int outOlc; prln("Set OLC=0"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0)); - prln("Then immediately set OLC="+notZero); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero)); - - prln("Verify OLC count using scan chain"); - int outOlc = marina.getOLC(); - fatal(outOlc!=notZero, "bad OLC count: "+outOlc+" expected: "+notZero); - - prln("Verify OLC zero bit using predication"); - prln("if (OLC==0) {A=1; B=1;} // should not get executed"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.FlagD, SET_FLAG, SET_FLAG)); - fatal(marina.getFlagA(), "bad A flag. expected: false"); - - prln("Set OLC="+notZero); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero)); - - prln("Then immediately set OLC=0"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0)); - + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero), + }); + + model.waitNS(64 * CYCLE_TIME_NS); prln("Verify OLC count using scan chain"); - outOlc = marina.getOLC(); - fatal(outOlc!=0, "bad OLC count: "+outOlc+" expected: 0"); - - prln("Verify OLC zero bit using predication"); - prln("if (OLC!=0) {A=1; B=1;} // should not get executed"); - marina.instrIn.fill(new - Instruction.Set(DOCK,false,Predicate.Default, SET_FLAG, SET_FLAG)); - fatal(marina.getFlagA(), "bad A flag. expected: false"); + expectOlc(notZero); + + if (!marina.kesselsCounter) { + prln("Set OLC="+notZero); + prln("Then immediately set OLC=0"); + marina.fillSouthProperStopper(new Instruction[] { + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, notZero), + new Instruction.Set(dock,Predicate.IgnoreFlagD,SetDest.OuterLoopCounter, 0), + }); + + model.waitNS(64 * CYCLE_TIME_NS); + prln("Verify OLC count using scan chain"); + expectOlc(0); + } } adjustIndent(-2); prln("End flipOlcBit"); } - private void testSouthRecirculate (Marina marina) { - prln("Begin testSouthRecirculate"); + private void testSouthRecirculate(Marina marina, int AMOUNT) { + prln("Begin testSouthRecirculate("+AMOUNT+")"); adjustIndent(2); - int AMOUNT = Marina.SOUTH_RING_CAPACITY; - marina.enableInstructionSend(false); marina.enableInstructionRecirculate(true); @@ -1992,90 +2054,177 @@ public class MarinaTest { adjustIndent(2); for (int i=0; i out = marina.instrIn.drainMany(); + boolean bad = false; for (int i=0; i