System.out.println("Test took: "+(endTime-startTime)/1000.0+" sec");
}
- private void doOneTest(int testNum) {
- prln("MarinaTest: performing test: "+testNum);
- masterClear();
- resetAfterMasterClear();
-
- switch (testNum) {
- case 0: stopToStopOneItem(); break;
- default:
- fatal(true, "Test number: "+testNum+" doesn't exist.");
- break;
- }
- }
// Tell user what we're about to do
private static void reportTask(MarinaUtils.CmdArgs args) {
System.out.println("Begin testing Marina");
fatal(true, "unrecognized CmdArgs.Mode");
return;
}
-
}
private static void standAlone(String[] args) {
}
return ans;
}
- /** Generate List of BitVectors where Token=true, high 25 data bits
- * are alternating ones and zeros, low 12 data bits increment from
- * zero, and address is given by random number generator. */
- private List<BitVector> makeIncrDataRandAdr(int num, Random rand) {
- List<BitVector> ans = new ArrayList<BitVector>();
- BitVector dHi = new BitVector(25, "dataHi");
- BitVector dLo = new BitVector(12, "dataLo");
- BitVector t = new BitVector("1", "token");
- BitVector a = new BitVector(14, "addr");
- dHi.setFromLong(0x00aaaaa);
- for (int i=0; i<num; i++) {
- dLo.setFromLong(i);
- a.setFromLong((long)rand.nextInt());
- ans.add(dHi.cat(dLo).cat(t).cat(a));
- dHi = dHi.not();
- }
- return ans;
- }
- /** Generate List of BitVectors where Token=true, all 37 data bits
- * are given by dat, and address is given by addr. */
- private List<BitVector> makeConstDataConstAdr(int num, long dat, boolean tok, int addr) {
- List<BitVector> ans = new ArrayList<BitVector>();
- BitVector d = new BitVector(37, "data");
- BitVector t = new BitVector(1, "token");
- BitVector a = new BitVector(14, "addr");
- d.setFromLong(dat);
- t.setFromLong(tok ? 0 : 1);
- a.setFromLong(addr);
- for (int i=0; i<num; i++) {
- ans.add(d.cat(t).cat(a));
- }
- return ans;
- }
-
- /** Generate List of BitVectors where Token=true, the address MSB
- * is given by addrMsb, all 37 data bits alternate between all ones
- * and all zeros, and 13 address LSBs alternate between count and
- * inverted count */
- private List<BitVector> makeAltCountCountBar(int num, int addrMsb) {
- List<BitVector> ans = new ArrayList<BitVector>();
- BitVector d = new BitVector(37, "data");
- BitVector t = new BitVector("1", "token");
- BitVector aHi = new BitVector(1, "addrHi");
- BitVector aLo = new BitVector(13, "addrLo");
- aHi.setFromLong(addrMsb);
- for (int i=0; i<num; i++) {
- d.setFromLong(0);
- aLo.setFromLong(i);
- if (i%2==1) {
- d = d.not();
- aLo = aLo.not();
- }
- ans.add(d.cat(t).cat(aHi).cat(aLo));
- }
- return ans;
- }
-
- /** Generate List of BitVectors where Token=true, the address MSB
- * is given by addrMsb, data bits alternate between 0xaaaa and 0x55555.
- * 13 address LSBs alternate between 0xaaaa and 0x5555 */
- private List<BitVector> makeAltAAA555(int num, int addrMsb) {
- List<BitVector> ans = new ArrayList<BitVector>();
- BitVector d = new BitVector(37, "data");
- BitVector t = new BitVector("1", "token");
- BitVector aHi = new BitVector(1, "addrHi");
- BitVector aLo = new BitVector(13, "addrLo");
- d.setFromLong(0xaaaaaaaaaaL);
- aHi.setFromLong(addrMsb);
- aLo.setFromLong(0xaaaaaaaa);
- for (int i=0; i<num; i++) {
- ans.add(d.cat(t).cat(aHi).cat(aLo));
- d = d.not();
- aLo = aLo.not();
- }
- return ans;
- }
-
private void stopToStop(ProperStopper s1, ProperStopper s2,
List<BitVector> din) {
prln("Begin stopToStop");
* is then run to allow the burst to flow. */
private void stopToStopBurst(ProperStopper src, ProperStopper gate,
ProperStopper dst,
- boolean ctrAChg, boolean ctrBChg,
List<BitVector> din) {
prln("Begin stopToStopBurst test");
adjustIndent(2);
gate.stop();
mar.shiftControl(false, true);
- mar.shiftData();
- long ctrAStart = mar.counter.getCount();
+// mar.shiftData();
+// long ctrAStart = mar.counter.getCount();
src.fillMany(din);
waitUntilQuiescent();
MarinaUtils.compareItemsOrdered(din, dout);
- mar.shiftData();
- long ctrAEnd = mar.counter.getCount();
- long deltaA = ctrAEnd - ctrAStart;
-
- long sz = din.size();
- long expectA = ctrAChg ? sz : 0;
- fatal(deltaA!=expectA,
- "counter A delta wrong: expected delta: "+expectA+
- " counter before:"+ctrAStart+" counter after:"+ctrAEnd);
+// mar.shiftData();
+// long ctrAEnd = mar.counter.getCount();
+// long deltaA = ctrAEnd - ctrAStart;
+//
+// long sz = din.size();
+// long expectA = ctrAChg ? sz : 0;
+// fatal(deltaA!=expectA,
+// "counter A delta wrong: expected delta: "+expectA+
+// " counter before:"+ctrAStart+" counter after:"+ctrAEnd);
adjustIndent(-2);
prln("End stopToStopOne");
}
+ private void stopToStopThree(ProperStopper s1, ProperStopper s2, int adr) {
+ prln("Begin stopToStopOne");
+ adjustIndent(2);
+
+ List<BitVector> din = makeIncrDataConstAdr(3, adr);
+ stopToStop(s1, s2, din);
+
+ adjustIndent(-2);
+ prln("End stopToStopOne");
+ }
+
private BitVector extractAddr(BitVector dataTokAddr) {
fatal(dataTokAddr.getNumBits()!=37+1+14, "wrong length for data token addr");
return dataTokAddr.get((37+1), 14);
}
return sb.toString();
}
- // Items in dIn must be unique
- private int checkRingData(String ringNm, List<BitVector> dIn,
- List<BitVector> dOut) {
- int sz = dIn.size();
-
- fatal(dOut.size()!=sz, ringNm+
- " wrong number of items. Expected:"+sz+", got:"+dOut.size()+"\n"+
- ringDump(dIn, dOut));
-
- // it's ok if both input and output are empty
- if (sz==0) return 0;
-
- // find offset
- BitVector first = dIn.get(0);
- int offset=0;
- for (; offset<sz; offset++) {
- if (dOut.get(offset).equals(first)) break;
- }
- fatal(offset==sz, ringNm+" first input item not found in output: "+first.getState()+"\n"+
- ringDump(dIn, dOut));
-
- prln("Output item offset: "+offset);
-
- // compare all items
- for (int i=0; i<sz; i++) {
- int outNdx = (i + offset + sz) % sz;
- BitVector out = dOut.get(outNdx);
- BitVector in = dIn.get(i);
-
- if (!in.equals(out)) {
- fatal(true, ringNm+" "+i+"th input item:"+in.getState()+"\n"+
- "doesn't match "+outNdx+"th output item: "+out.getState()+"\n"+
- ringDump(dIn, dOut));
- }
- }
- return offset;
- }
- // Weaker test because it allows arbitrary re-ordering
- private void checkUnorderedData(String ringNm, List<BitVector> dIn,
- List<BitVector> dOut, boolean token) {
- int sz = dIn.size();
-
- fatal(dOut.size()!=sz, ringNm+
- " wrong number of items. Expected:"+sz+", got:"+dOut.size()+"\n"+
- ringDump(dIn, dOut));
-
- // ignore data bits if token
- BitVector mask = new BitVector(37+1+14, "mask");
- mask.setFromLong(token ? 0x7fff : -1L);
-
- // compare all items
- for (BitVector in : dIn) {
- boolean found = false;
- for (Iterator<BitVector> oIt=dOut.iterator(); oIt.hasNext();) {
- BitVector out = oIt.next();
-// BitVector im = in.and(mask);
-// BitVector om = out.and(mask);
-// prln("Mask: "+mask.getState());
-// prln("oMask:"+om.getState());
-// prln("iMask:"+im.getState());
-
- if (in.and(mask).equals(out.and(mask))) {
- oIt.remove();
- found = true;
- break;
- }
- }
- if(!found) {
- fatal(true, "Input vector: "+in.getState()+" missing from output.\n"+
- ringDump(dIn, dOut));
- }
- }
- }
-
-// private RingResult throughputVsOccupancy(String ringNm, ProperStopper src,
-// Counter counter,
-// List<BitVector> items,
-// boolean token,
-// double runTimeNs) {
-// List<Long> counts = new ArrayList<Long>();
-// List<Double> currents = new ArrayList<Double>();
-// List<Double> voltErr = new ArrayList<Double>();
-//
-// prln("run all stoppers except the source stopper");
-// mar.stopper1.run();
-// mar.stopper2.run();
-// src.stop();
-// mar.shiftControl(false, true);
-//
-// // pause so we can measure quiescent current
-// model.waitNS(runTimeNs/2);
-// model.waitNS(runTimeNs/2);
-//
-// // count is zero for no items
-// counts.add((long)0);
-//
-// List<BitVector> someItems = new ArrayList<BitVector>();
-// for (int i=0; i<items.size(); i++) {
-// prln("---------------------------------------------------------");
-// someItems.add(items.get(i));
-//
-// prln("Run with "+(i+1)+" items");
-// src.fillMany(someItems);
-// src.stop();
-// mar.shiftControl(false, true);
-//
-// prln("Begin current run: "+runTimeNs+" nanoseconds");
-// adjustIndent(2);
-// src.run();
-// mar.shiftControl(false, true);
-//
-//
-// model.waitNS(runTimeNs/2);
-// currents.add(readCurrent());
-// model.waitNS(runTimeNs/2);
-//
-// src.stop();
-// mar.shiftControl(false, true);
-// adjustIndent(-2);
-// prln("End current run");
-//
-// prln("Begin throughput run: "+runTimeNs+" nanoseconds");
-// adjustIndent(2);
-// mar.shiftData();
-// long beforeCnt = counter.getCount();
-//
-// src.run();
-// mar.shiftControl(false, true);
-//
-// model.waitNS(runTimeNs);
-//
-// src.stop();
-// mar.shiftControl(false, true);
-//
-// mar.shiftData();
-// long afterCnt = counter.getCount();
-// counts.add(afterCnt - beforeCnt);
-// adjustIndent(-2);
-// prln("End throughput run");
-//
-// prln("Check data in Ring");
-// List<BitVector> dOut = src.drainMany();
-// checkUnorderedData(ringNm, someItems, dOut, token);
-// }
-//
-// List<Double> thruput = computeThroughput(counts, runTimeNs);
-// return new RingResult(thruput, currents, voltErr);
-// }
-// private void throughput(String resultsFile, boolean constDataAddr, boolean token, Select select) {
-// final double NS_PER_SEC = 1e9;
-// final int nbItems = 98;
-// final double wait = sim() ? 200 : 2 * NS_PER_SEC;
-//
-// prln("Measure throughput A. Oscillation time="+wait+"ns, max #items="+nbItems);
-// adjustIndent(2);
-// List<BitVector> d;
-// if (constDataAddr) {
-// d = makeConstDataConstAdr(nbItems, 0, token, 0);
-// } else {
-// d = makeAltAAA555(nbItems, 0);
-// }
-// RingResult resultA = throughputVsOccupancy("A", mar.stopper1,
-// mar.counter, d,
-// token, wait);
-// adjustIndent(-2);
-// prln("throughput A done");
-//
-//
-// List<RingResult> results = new ArrayList<RingResult>();
-// results.add(resultA);
-// saveThruputResults(resultsFile,
-// "number of items, ringA throughput, ringA current, ringA Vdd error,"+
-// " ringB throughput, ringB current, ringB Vdd error",
-// select, results);
-// }
-// // Run ring A half full to draw max current
-// private void maxCurrent() {
-// final double SEC_TO_NS = 1e9;
-// final int nbItems = 50;
-// final double runTimeNS = 10*SEC_TO_NS;
-// List<BitVector> aIn = makeAltCountCountBar(nbItems, 0);
-// prln("Begin: maxCurrent");
-// mar.stopper2.run();
-//
-// prln("Fill first stopper A1");
-// mar.stopper1.fillMany(aIn);
-// waitUntilQuiescent();
-//
-// mar.shiftData();
-// long aCnt0 = mar.counter.getCount();
-// prln("initial a counter="+aCnt0);
-//
-// prln("Let rings run for "+runTimeNS+" nanoseconds.");
-// mar.stopper1.run();
-// mar.shiftControl(false, true);
-//
-// model.waitNS(runTimeNS);
-//
-// prln("stop stopper A1");
-// mar.stopper1.stop();
-// mar.shiftControl(false, true);
-// waitUntilQuiescent();
-//
-// mar.shiftData();
-// long aCnt1 = mar.counter.getCount();
-// prln("final a counter="+aCnt1);
-//
-// prln("check ring data");
-// List<BitVector> aOut = mar.stopper1.drainMany();
-//
-// checkRingData("Ring A", aIn, aOut);
-// prln("Passed: maxCurrent");
-// }
private int[][] makeIntArray2D(int a, int b) {
int[][] ans = new int[a][];
private void stopToStopOneItem() {
stopToStopOne(mar.stopper1, mar.stopper2, -1);
}
+ private void stopToStopThreeItems() {
+ stopToStopThree(mar.stopper1, mar.stopper2, -1);
+ }
+ private void doOneTest(int testNum) {
+ prln("MarinaTest: performing test: "+testNum);
+ masterClear();
+ resetAfterMasterClear();
+
+ switch (testNum) {
+ case 0: stopToStopOneItem(); break;
+ case 1: stopToStopThreeItems(); break;
+ default:
+ fatal(true, "Test number: "+testNum+" doesn't exist.");
+ break;
+ }
+ }
+
//============================ for public use =============================
cc.shift(reportChain, readEnable, writeEnable);
}
+ private StateWireState boolToState(boolean b) {
+ return b ? StateWireState.FULL : StateWireState.EMPTY;
+ }
+
+ //-------------------------- public methods ----------------------------
+
+ /** Put stopper in RUN state */
public void run() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.RUN.bits());
}
+ /** Put stopper in IDLE state */
public void idle() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.IDLE.bits());
}
+ /** Put stopper in FILL state */
public void fill() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.FILL.bits());
}
+ /** Put stopper in BLOCK state */
public void block() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.BLOCK.bits());
}
+ /** Put stopper in STOP state */
public void stop() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.STOP.bits());
}
+ /** Put stopper in CLEAR state */
public void clear() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.CLEAR.bits());
}
+ /** Put stopper in SOURCE state */
public void source() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.SOURCE.bits());
}
+ /** Put stopper in STOPSOURCE state */
public void stopSource() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSOURCE.bits());
}
+ /** Put stopper in SINK state */
public void sink() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.SINK.bits());
}
+ /** Put stopper in STOPSINK state */
public void stopSink() {
cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSINK.bits());
}
idle(); // go = 0
shiftControl(false, true);
}
-
- private StateWireState boolToState(boolean b) {
- return b ? StateWireState.FULL : StateWireState.EMPTY;
- }
-
+ /** get value of the state wire preceeding the fill stage */
public StateWireState getPrevStateWire() {
BitVector b = cc.getOutBits(reportPath);
int n = b.getNumBits();
fatal(n!=4, "Bad number of Stopper report bits: "+n);
return boolToState(cc.getOutBits(reportPath).get(0));
}
- /** The fill wire will be interesting if we doubt that the
+ /** get the value of drain stage fill wire.
+ * The fill wire will be interesting if we doubt that the
* scan chain works. */
public boolean getFillWire() {
return cc.getOutBits(reportPath).get(1);
}
+ /** get value of state wire between the fill and drain stages */
public StateWireState getMyStateWire() {
return boolToState(cc.getOutBits(reportPath).get(2));
}
+ /** get value of drain stage stopped wire */
public boolean getStopped() {
return cc.getOutBits(reportPath).get(3);
}
sb.append(getStopped()+"\n");
return sb.toString();
}
-
+ /** construct a ProperStopper */
public ProperStopper(String controlChain, String controlInst,
String dataChain, String dataInst,
String reportChain, String reportInst,
this.model = model;
this.indenter = indenter;
}
-
+ /** Reset ProperStopper after the JTAG TRST has been pulsed */
public void resetAfterMasterClear() {
BitVector we = new BitVector(2, "write enable");
BitVector data = new BitVector(37, "data");
cc.setInBits(dataPath, wdta);
}
- /** You must stop stopper before calling fill.
+ /** Insert one item into the fill stage.
+ * Fill stage must be empty.
+ * You must stop stopper before calling fill.
* exit state: idle */
public void fill(BitVector dta) {
if (traceFill) prln("Begin fillStopper");
int n = dta.getNumBits();
fatal(n!=(37+1+14), "fillStopper: wrong num bits: "+n);
+ // make sure fill stage is empty
+ shiftReport(true, false);
+ StateWireState myState = getMyStateWire();
+ fatal(myState!=StateWireState.EMPTY,
+ "fillStopper: fill stage already full");
+
if (traceFill) prln("writing data: "+MarinaUtils.formatDataTokAddr(dta));
idle(); // block = 1, go = 0
cc.setInBits(dataPath, wrEn.cat(dta));
shiftData(false, true);
- fill(); // fire = 1
+ fill(); // fill = 1
shiftControl(false, true);
- idle(); // fire = 0
+ idle(); // fill = 0
shiftControl(false, true);
block(); // go = 1
shiftControl(false, true);
shiftControl(false, true);
model.waitNS(5);
-
- // make sure fill data was consumed
- shiftReport(true, false);
// debugging
if (traceFill) prln(getReportString());
- StateWireState myState = getMyStateWire();
- fatal(myState!=StateWireState.EMPTY,
- "fillStopper: fill data not consumed");
-
// if data chain is shifted in the future, don't write!
wrEn.setFromLong(0);
cc.setInBits(dataPath, wrEn.cat(dta));
adjustIndent(-2);
if (traceFill) prln("End fillStopper");
}
- /** You must stop stopper before calling fillMany()
+ /** Insert items from a list, one by one.
+ * You must stop stopper before calling fillMany()
* exit state: idle */
public void fillMany(List<BitVector> data) {
prln("begin fillMany "+data.size()+" words");
adjustIndent(-2);
prln("end fillMany");
}
- /** drain() will stop cleanly.
+ /** Remove one item from fill stage. Return that item.
+ * An item must be available.
+ * drain() will stop cleanly.
* exit state: stop */
public BitVector drain() {
stop(); // all zero, block = 0, go = 0
shiftControl(false, true);
+
+ // make sure an item is available
+ shiftReport(true, false);
+ StateWireState myState=getMyStateWire();
+ fatal(myState==StateWireState.EMPTY, "drain: fill stage empty");
shiftData(true, false);
BitVector ans = getDatTokAdr();
if (traceDrain) prln("drainStopper data: "+MarinaUtils.formatDataTokAddr(ans));
return ans;
}
- /** drainStopperMany() will stop cleanly.
+ /** Remove as many items as possible from the fill stage.
+ * drainStopperMany() will stop cleanly.
* exit state: stop */
public List<BitVector> drainMany() {
+ return drainMany(Integer.MAX_VALUE);
+ }
+
+ /** Remove up to maxNbItems items from the fill stage.
+ * drainStopperMany() will stop cleanly.
+ * exit state: stop */
+ public List<BitVector> drainMany(int maxNbItems) {
prln("begin drainStopperMany");
adjustIndent(2);
int cnt = 0;
while (true) {
shiftReport(true, false);
- MarinaUtils.StateWireState myState=getMyStateWire();
+ StateWireState myState=getMyStateWire();
// debugging
if (traceDrain) prln(getReportString());
- if (myState==MarinaUtils.StateWireState.EMPTY) break;
+ if (myState==StateWireState.EMPTY || cnt>maxNbItems) break;
if (traceDrain) prln("drainStopperMany: reading word number: "+cnt++);