From a3ce4c49073bcdc46b4694e67e356127a7bc10da Mon Sep 17 00:00:00 2001 From: rkao Date: Mon, 18 Aug 2008 18:21:07 +0000 Subject: [PATCH] Initial revision --- .../com/sun/vlsi/chips/marina/test/Counter.java | 19 + .../com/sun/vlsi/chips/marina/test/Indenter.java | 45 ++ .../com/sun/vlsi/chips/marina/test/Marina.java | 65 ++ .../com/sun/vlsi/chips/marina/test/MarinaTest.java | 715 ++++++++++++++++++++ .../sun/vlsi/chips/marina/test/MarinaUtils.java | 449 ++++++++++++ .../sun/vlsi/chips/marina/test/ProperStopper.java | 266 ++++++++ testCode/header.hsp | 33 + testCode/marina.bsh | 46 ++ testCode/marina.xml | 251 +++++++ 9 files changed, 1889 insertions(+) create mode 100644 testCode/com/sun/vlsi/chips/marina/test/Counter.java create mode 100644 testCode/com/sun/vlsi/chips/marina/test/Indenter.java create mode 100644 testCode/com/sun/vlsi/chips/marina/test/Marina.java create mode 100644 testCode/com/sun/vlsi/chips/marina/test/MarinaTest.java create mode 100644 testCode/com/sun/vlsi/chips/marina/test/MarinaUtils.java create mode 100644 testCode/com/sun/vlsi/chips/marina/test/ProperStopper.java create mode 100644 testCode/header.hsp create mode 100644 testCode/marina.bsh create mode 100644 testCode/marina.xml diff --git a/testCode/com/sun/vlsi/chips/marina/test/Counter.java b/testCode/com/sun/vlsi/chips/marina/test/Counter.java new file mode 100644 index 0000000..fe4b241 --- /dev/null +++ b/testCode/com/sun/vlsi/chips/marina/test/Counter.java @@ -0,0 +1,19 @@ +package com.sun.vlsi.chips.marina.test; +import com.sun.async.test.BitVector; +import com.sun.async.test.ChainControl; + + +public class Counter { + private final String path; + private final ChainControl cc; + public Counter(String path, ChainControl cc) { + this.path = path; + this.cc = cc; + } + public long getCount() { + return 0; + // do nothing because I counter schematics don't yet exist + //return cc.getOutBits(path).bitReverse().not().toLong(); + } + +} diff --git a/testCode/com/sun/vlsi/chips/marina/test/Indenter.java b/testCode/com/sun/vlsi/chips/marina/test/Indenter.java new file mode 100644 index 0000000..e7f9679 --- /dev/null +++ b/testCode/com/sun/vlsi/chips/marina/test/Indenter.java @@ -0,0 +1,45 @@ +package com.sun.vlsi.chips.marina.test; + +public class Indenter { + private static char NL = '\n'; + private int indent = 0; + private boolean beginLine = true; + + private void spaces(int n) { + StringBuffer sb = new StringBuffer(); + for (int i=0; i thruput, current, vddErr; + public RingResult(List t, List c, List v) { + thruput=t; current=c; vddErr=v; + } + public int size() {return Math.max(thruput.size(), current.size());} + } + + //-------------------------- private data -------------------------------- + private static long startTime; + + private Indenter indenter = new Indenter(); + private final Marina mar; + private final ChipModel model; + private final ChainControl cc; + private final JtagTester tester; + private final boolean wholeChipNetlist; + private PowerChannel corePowerSupply, padsPowerSupply; + private VoltageReadable coreVoltmeter, voltmeterForCurrent; + private final String dataOutDir; + + //-------------------------- private methods ----------------------------- + /** @return true if simulation. Return false if we're testing silicon. */ + private boolean sim() {return model instanceof SimulationModel;} + + private void prln(String msg) {indenter.prln(msg);} + private void pr(String msg) {indenter.pr(msg);} + private void adjustIndent(int n) {indenter.adjustIndent(n);} + + private static void fatal(boolean pred, String msg) { + if (pred) { + System.out.println("Test Failed"); + printTestTime(); + Infrastructure.fatal(msg); + } + } + private static void printTestTime() { + long endTime = System.currentTimeMillis(); + 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"); + switch (args.mode) { + case SIM_EXPERIMENT_SCHEMATIC: + System.out.println(" Simulation of Marina from schematics"); + break; + case SIM_EXPERIMENT_LAYOUT: + System.out.println(" Simulation of Marina from layout"); + break; + case SIM_CHIP_SCHEMATIC: + System.out.println(" Simulation of full chip from schematics"); + break; + case TEST_SILICON: + System.out.println(" Test silicon"); + break; + default: + fatal(true, "unrecognized CmdArgs.Mode"); + return; + } + + } + + private static void standAlone(String[] args) { + MarinaUtils.CmdArgs cmdArgs = new MarinaUtils.CmdArgs(args); + reportTask(cmdArgs); + ChipModel model; + JtagTester tester; + boolean sim = cmdArgs.mode != MarinaUtils.CmdArgs.Mode.TEST_SILICON; + if (sim) { + model = new NanosimModel(); + tester = ((SimulationModel)model).createJtagTester("TCK", "TMS", "TRSTb", "TDI", "TDO"); + } else { + model = new SiliconChip(); + String ip = cmdArgs.station.ipAddr; + tester = new Netscan4(ip, cmdArgs.station.jtagChannel); + } + tester.printInfo = false; + String xmlFileName = cmdArgs.wholeChipNetlist() ? + "../testCode/marinaWholeChip.xml" + : + "../testCode/marina.xml"; + + int khz = sim ? 1000000 : 1000; + ChainControl cc = new ChainControl(xmlFileName, tester, 1.8f, khz); + + + PowerChannel pc = new ManualPowerChannel("pc", false); + ChainTest ct = new ChainTest(cc, pc); + + String dataOutDir = cmdArgs.chipNum==-1 ? "" : ("chip"+cmdArgs.chipNum+"/infinity/"); + + MarinaTest it = new MarinaTest(model, cc, tester, cmdArgs.wholeChipNetlist(), + cmdArgs.station, dataOutDir); + String netListName; + switch (cmdArgs.mode) { + case SIM_EXPERIMENT_SCHEMATIC: + netListName = "marina.spi"; break; + case SIM_EXPERIMENT_LAYOUT: + netListName = "marinaFromLay.spi"; break; + case SIM_CHIP_SCHEMATIC: + case TEST_SILICON: + netListName = "marina_pads_guts.spi"; break; + default: + fatal(true, "unrecognized CmdArgs.Mode"); + return; + } + + if (sim) ((SimulationModel)model).start("nanosim -c cfg", netListName, 0, true); + ct.testAllChains("marina", Infrastructure.SEVERITY_WARNING); + + it.doOneTest(cmdArgs.testNum); + + if (sim) ((SimulationModel)model).finish(); + } + /** In the absence of looping, the longest path through Infinity is 4 column delays */ + private void waitUntilQuiescent() { + model.waitNS(4*COLUMN_LATENCY); + } + private void masterClear() { + final double WIDTH = 10; + if (model instanceof NanosimModel) { + NanosimModel nModel = (NanosimModel) model; + System.out.println("master clear"); + if (wholeChipNetlist) { + // Put a low going pulse on the chip's master clear pin. This clears + // the master clear register. The master clear register's output is + // inverted. This inverse drivers the chip's internal master clear + // signal. + nModel.setNodeVoltage("mc",0.0); + nModel.waitNS(WIDTH); + nModel.setNodeVoltage("mc",1.0); + } else { + // Put a high going pulse on the internal chip master clear signal + nModel.setNodeVoltage("scanInD[9]",1.0); + nModel.setNodeVoltage("scanInC[9]",1.0); + nModel.setNodeVoltage("scanInR[9]",1.0); + nModel.waitNS(WIDTH); + nModel.setNodeVoltage("scanInD[9]",0.0); + nModel.setNodeVoltage("scanInC[9]",0.0); + nModel.setNodeVoltage("scanInR[9]",0.0); + } + } else { + JtagLogicLevel jll = new JtagLogicLevel(tester, 0); + jll.setLogicState(false); + model.wait(0.100f); + jll.setLogicState(true); + + // Set the master clear register. This resets the chip's internal + // master clear. + cc.setInBits("Infinity.jtag_mc", "1"); + cc.shift("Infinity.jtag_mc", false, true); + } + } + + private double readCurrent() { + return voltmeterForCurrent.readVoltage() / station.ammeterShuntResistance; + } + + /** You must master clear before calling resetForTest */ + private void resetAfterMasterClear() { + prln("reset after master clear"); + mar.resetAfterMasterClear(); + } + + /** 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 addr. */ + private List makeIncrDataConstAdr(int num, int addr) { + List ans = new ArrayList(); + 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); + a.setFromLong(addr); + for (int i=0; i makeIncrDataRandAdr(int num, Random rand) { + List ans = new ArrayList(); + 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 makeConstDataConstAdr(int num, long dat, boolean tok, int addr) { + List ans = new ArrayList(); + 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 makeAltCountCountBar(int num, int addrMsb) { + List ans = new ArrayList(); + 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 makeAltAAA555(int num, int addrMsb) { + List ans = new ArrayList(); + 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 din) { + prln("Begin stopToStop"); + adjustIndent(2); + + s1.stop(); + mar.shiftControl(false, true); + +// mar.shiftData(); +// long ctrAStart = mar.counter.getCount(); + + s1.fillMany(din); + waitUntilQuiescent(); + + List dout = s2.drainMany(); + + 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); + + + adjustIndent(-2); + prln("End stopToStop"); + } + /** Burst data from src to dst. gate is stopped while loading src. gate + * is then run to allow the burst to flow. */ + private void stopToStopBurst(ProperStopper src, ProperStopper gate, + ProperStopper dst, + boolean ctrAChg, boolean ctrBChg, + List din) { + prln("Begin stopToStopBurst test"); + adjustIndent(2); + + src.stop(); + gate.stop(); + mar.shiftControl(false, true); + + mar.shiftData(); + long ctrAStart = mar.counter.getCount(); + + src.fillMany(din); + waitUntilQuiescent(); + + // open the gate to start the burst + gate.run(); + mar.shiftControl(false, true); + waitUntilQuiescent(); + + List dout = dst.drainMany(); + + 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); + + + adjustIndent(-2); + prln("End stopToStopBurst test"); +} + + private void stopToStopOne(ProperStopper s1, ProperStopper s2, int adr) { + prln("Begin stopToStopOne"); + adjustIndent(2); + + List din = makeIncrDataConstAdr(1, 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); + } + private BitVector extractToken(BitVector dataTokAddr) { + fatal(dataTokAddr.getNumBits()!=37+1+14, "wrong length for data token addr"); + return dataTokAddr.get(37, 1); + } + private BitVector extractData(BitVector dataTokAddr) { + fatal(dataTokAddr.getNumBits()!=37+1+14, "wrong length for data token addr"); + return dataTokAddr.get(0, 37); + } + private int indexOf(BitVector o, List dIn) { + for (int i=0; i dIn, List dOut) { + StringBuffer sb = new StringBuffer(); + sb.append(" ring dump: "); + for (BitVector o : dOut) { + sb.append(indexOf(o, dIn)+" "); + } + return sb.toString(); + } + // Items in dIn must be unique + private int checkRingData(String ringNm, List dIn, + List 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 dIn, + List 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 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 items, +// boolean token, +// double runTimeNs) { +// List counts = new ArrayList(); +// List currents = new ArrayList(); +// List voltErr = new ArrayList(); +// +// 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 someItems = new ArrayList(); +// for (int i=0; i dOut = src.drainMany(); +// checkUnorderedData(ringNm, someItems, dOut, token); +// } +// +// List 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 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 results = new ArrayList(); +// 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 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 aOut = mar.stopper1.drainMany(); +// +// checkRingData("Ring A", aIn, aOut); +// prln("Passed: maxCurrent"); +// } + + private int[][] makeIntArray2D(int a, int b) { + int[][] ans = new int[a][]; + for (int i=0; i select which test to run"); + System.out.println(" -vdd "); + System.out.println(" -temp "); + System.out.println(" -ringNum 1 for Left Ring and 2 for Right Ring (only for crosser experiment)"); + System.out.println(" -numTokensOther from 0:13, occupancy of ring NOT under throughput analysis"); + System.out.println(" -exptSch simulate netlist of experiment only, parasitics from schematic"); + System.out.println(" -exptSch simulate netlist of experiment only, parasitics from schematic"); + System.out.println(" -exptLay simulate netlist of experiment only, parasitics from layout"); + System.out.println(" -chipSch simulate netlist of entire chip, parasitics from schematic"); + System.out.println(" -silicon test the silicon"); + System.out.println(" -chipNum store test results according to chip number"); + System.out.println(" -station select test station"); + System.exit(-1); + } + + public CmdArgs(String[] args) { + int nbArgs = args.length; + for (int i=0; i=nbArgs) usage(); + testNum = Integer.parseInt(args[i]); + } else if (args[i].equals("-vdd")) { + i++; + if (i>=nbArgs) usage(); + vdd = Float.parseFloat(args[i]); + } else if (args[i].equals("-init")) { + i++; + if (i>=nbArgs) usage(); + init = Boolean.parseBoolean(args[i]); + } else if (args[i].equals("-temp")) { + i++; + if (i>=nbArgs) usage(); + temp = Float.parseFloat(args[i]); + } else if (args[i].equals("-ringNum")) { + i++; + if (i>=nbArgs) usage(); + ringNum = Integer.parseInt(args[i]); + } else if (args[i].equals("-numTokensOther")) { + i++; + if (i>=nbArgs) usage(); + numTokensOther = Integer.parseInt(args[i]); + } else if (args[i].equals("-chipNum")) { + i++; + if (i>=nbArgs) usage(); + chipNum = Integer.parseInt(args[i]); + } else if (args[i].equals("-station")) { + i++; + if (i>=nbArgs) usage(); + switch (Integer.parseInt(args[i])) { + case 1: station = Station.ONE; break; + case 2: station = Station.TWO; break; + default: System.out.println("Bad station: "+args[i]); usage(); + } + } else if (args[i].equals("-exptSch")) { + mode = CmdArgs.Mode.SIM_EXPERIMENT_SCHEMATIC; + } else if (args[i].equals("-exptLay")) { + mode = CmdArgs.Mode.SIM_EXPERIMENT_LAYOUT; + } else if (args[i].equals("-chipSch")) { + mode = CmdArgs.Mode.SIM_CHIP_SCHEMATIC; + } else if (args[i].equals("-chipLay")) { + mode = CmdArgs.Mode.SIM_CHIP_LAYOUT; + } else if (args[i].equals("-silicon")) { + mode = CmdArgs.Mode.TEST_SILICON; + } else { + System.out.println("Bad argument: "+args[i]); + usage(); + } + } + } + } + + public static enum Station { + ONE("152.70.25.42", 1, "H34401C", "H34401A", 24.98e-3), + TWO("152.70.25.27", 2, "H34401B", "H34401D", 26.47e-3); + public final String ipAddr, coreVoltmeter, currentVoltmenter; + public final int jtagChannel; + public final double ammeterShuntResistance; + private Station(String ip, int jtagChannel, String coreVoltmeter, + String currentVoltmeter, double ammeterShuntResistance) { + this.ipAddr = ip; + this.jtagChannel = jtagChannel; + this.coreVoltmeter = coreVoltmeter; + this.currentVoltmenter = currentVoltmeter; + this.ammeterShuntResistance = ammeterShuntResistance; + } + }; + + public static void fatal(boolean pred, String msg) { + if (pred) Infrastructure.fatal(msg); + } + + public static BitVector generateBits (int start, boolean alternate, int n){ + int temp = start; + String bits = Integer.toString(start); + if (alternate){ + for (int i = 2; i<= n; i++) { + temp = (temp+1)%2; + bits += Integer.toString (temp); + } + } + else { + for (int i = 2; i <= n; i++){ + bits += Integer.toString(start); + } + } + BitVector bv = new BitVector (n, bits); + bv.put(0,bits); + return bv; + } + + public static String generateTokenContent (int i){ + BitVector data0 = generateBits(0, true, 37); // 37 bits, alternating + BitVector tag0 = generateBits(1, false, 1); + BitVector addr0 = generateBits(0, true, 14); // 14 bits, alternating + //BitVector addr0 = new BitVector ("00000001111111", "addr0"); // 14 bits, alternating + BitVector data1 = generateBits(1, true, 37); // 37 bits, alternating + BitVector tag1 = generateBits(1, false, 1); + //BitVector addr1 = generateBits(1, true, 14); // 14 bits, alternating + BitVector addr1 = new BitVector ("00101010101011", "addr1"); // 14 bits, alternating + if (i==0){ + return generateBits(0, false, 37).getState()+"1"+addr0.getState(); + } + else if (i%4 == 1){ + return data1.getState()+tag1.getState()+addr1.getState();// the addr data MAY enable cross: bit 0 (cross active high for Ring 1) and 13 (cross active low for Ring 2) + //return data1.getState()+tag1.getState()+addr0.getState();// + } + else if (i%4 == 2){ + return data0.getState()+tag1.getState()+addr0.getState(); + } + else if (i%4 == 3){ + return data1.getState()+tag0.getState()+addr1.getState(); + //return data1.getState()+tag0.getState()+addr0.getState(); + } + else { + return data0.getState()+tag0.getState()+addr0.getState(); + } + } + public static boolean compareTags(BitVector inputContent, BitVector exitContent){ + return inputContent.get(37) == exitContent.get(37); //bit 37 is the tag bit + } + + public static boolean compareData(BitVector inputContent, BitVector exitContent){ + return inputContent.get(0, 37).getState().equals(exitContent.get(0, 37).getState()); //bits 0:36 are the data bits + } + + public static boolean compareAddress(BitVector inputContent, BitVector exitContent){ + return inputContent.get(38, 14).getState().equals(exitContent.get(38, 14).getState()); //bits 38:38+14 are the data bits + } + + public static boolean insertedVsRemoved(BitVector [] insertedTokenContent, BitVector [] removedTokenContent, int numTokens){ + for (int i = 0; i < numTokens; i++) { + if (insertedTokenContent[i].get(37)){ //tag = 1 meaning data is valid + + if (!insertedTokenContent[i].getState().equals(removedTokenContent[i].getState())){ + System.out.println ("Inserted vs removed data, tag and address @ stage " + i + " does NOT match!"); + return false; + } + System.out.println ("Inserted vs removed data, tag and address @ stage " + i + " matches!"); + } + else {//if tag=0, just need to make sure tag bit is still the same as inserted but data and address are no longer important + if (!compareTags(insertedTokenContent[i], removedTokenContent[i])){ + System.out.println ("Inserted vs removed tag @ stage " + i + " does NOT match!"); + return false; + } + System.out.println ("Inserted vs removed tag @ stage " + i + " matches!"); + } + } + System.out.println("Inserted tokens match removed tokens...All is well!"); + return true; + + } + + public static void checkRingData(String ringNm, List dIn, + List dOut) { + int sz = dIn.size(); + + fatal(dOut.size()!=sz, ringNm+ + " wrong number of items. Expected:"+sz+", got:"+dOut.size()); + + // find offset + BitVector first = dIn.get(0); + int offset=0; + for (; offset makeIncrDataRandAdr(int num, Random rand) { + List ans = new ArrayList(); + 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 makeIncrDataConstAdr(int num, int addr) { + List ans = new ArrayList(); + 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); + a.setFromLong(addr); + for (int i=0; i makeIncrDataConstAdr(int num, String addr) { + List ans = new ArrayList(); + BitVector dHi = new BitVector(25, "dataHi"); + BitVector dLo = new BitVector(12, "dataLo"); + BitVector t = new BitVector("1", "token"); + BitVector a = new BitVector(addr, "addr"); + dHi.setFromLong(0x00aaaaa); + //a.setFromLong(addr); + for (int i=0; i makeConstDataConstAdr(int num, boolean dataValue, String addr) { + List ans = new ArrayList(); + BitVector d = new BitVector(37, "dataHi"); + BitVector t = new BitVector("1", "token"); + BitVector a = new BitVector(addr, "addr"); + Long dat = dataValue ? -1L : 0L; + d.setFromLong(dat); + for (int i=0; i make0TokenAdd(int num, int addrMsb, int addrLsb) { + List ans = new ArrayList(); + BitVector d = new BitVector(37, "data"); + BitVector t = new BitVector("0", "token"); + BitVector aHi = new BitVector(1, "addrHi"); + BitVector aLo = new BitVector(1, "addrLo"); + BitVector aMid = new BitVector(12, "addrMid"); + d.setFromLong(0x0000000000L); + aHi.setFromLong(addrMsb); + aLo.setFromLong(addrLsb); + aMid.setFromLong(0x000); + for (int i=0; i makeAltDataAdd(int num, Long longValue, int addrMsb, int addrLsb, boolean crosser) { + List ans = new ArrayList(); + BitVector d = new BitVector(37, "data"); + BitVector t = new BitVector("1", "token"); + BitVector aHi = new BitVector(1, "addrHi"); + BitVector aLo = new BitVector(1, "addrLo"); + BitVector aMid = new BitVector(12, "addrMid"); + BitVector aRing = new BitVector(14, "addrRing"); //address bits for ring, bit 0 and 13 do not need to be anything specific b/c there isn't a cross element in the ring + //d.setFromLong(0xaaaaaaaaaaL); + d.setFromLong(longValue); + aHi.setFromLong(addrMsb); + aLo.setFromLong(addrLsb); + aMid.setFromLong(0xaaa); + aRing.setFromLong(0xaaaa); + for (int i=0; i din, List dout) { + fatal(din.size()!=dout.size(), + "in count="+din.size()+" out count="+dout.size()); + for (int i=0; i din, List dout) { + fatal(din.size()!=dout.size(), + "in count="+din.size()+" out count="+dout.size()); + for (int i=0; i din, List dout) { + int sz = din.size(); + fatal(dout.size()!=sz, "found "+dout.size()+" items, Expected: "+sz); + for (BitVector in : din) { + boolean found = false; + for (BitVector out : dout) { + if (in.equals(out)) { + found = true; + break; + } + } + fatal(!found, "Can't find vector in output: "+in.getState()); + } + } + public static void checkUnorderedJUSTDataTag(List din, List dout) { + int sz = din.size(); + fatal(dout.size()!=sz, "found "+dout.size()+" items, Expected: "+sz); + for (BitVector in : din) { + boolean found = false; + for (BitVector out : dout) { + if (in.get(0,37).equals(out.get(0,37))) { + found = true; + break; + } + } + fatal(!found, "Can't find vector in output: "+in.getState()); + } + } + + public static void checkToken0Add(List din, List dout) { + int sz = din.size(); + fatal(dout.size()!=sz, "found "+dout.size()+" items, Expected: "+sz); + for (BitVector in : din) { + boolean found = false; + for (BitVector out : dout) { + if (in.get(38,14).equals(out.get(38,14))) { + found = true; + break; + } + } + fatal(!found, "Can't find vector in output: "+in.getState()); + } + } + + public static int findBitVectorIndex(List din, BitVector findThis) { + int sz = din.size(); + boolean found=false; + int i=0; + for (BitVector in : din) { + if (in.equals(findThis)) { + found = true; + break; + } else {i++;} + } + fatal(!found, "Can't find vector in output: "+findThis.getState()); + return i; + + } + + public static String formatDataTokAddr(BitVector dta) { + if (dta.getNumBits()!=(37+1+14)) { + Infrastructure.fatal("wrong number of bits"); + } + return dta.get(0,37).getState() + " " + + dta.get(37,1).getState() + " " + + dta.get(38,14).getState(); + } +} \ No newline at end of file diff --git a/testCode/com/sun/vlsi/chips/marina/test/ProperStopper.java b/testCode/com/sun/vlsi/chips/marina/test/ProperStopper.java new file mode 100644 index 0000000..7577f81 --- /dev/null +++ b/testCode/com/sun/vlsi/chips/marina/test/ProperStopper.java @@ -0,0 +1,266 @@ +package com.sun.vlsi.chips.marina.test; +import java.util.ArrayList; +import java.util.List; + +import com.sun.async.test.BitVector; +import com.sun.async.test.ChainControl; +import com.sun.async.test.ChipModel; +import com.sun.async.test.Infrastructure; +import com.sun.vlsi.chips.marina.test.MarinaUtils.StateWireState; + +public class ProperStopper { + private boolean traceFill = true; + private boolean traceDrain = true; + + private final String controlChain, controlPath, + dataChain, dataPath, + reportChain, reportPath; + private final ChainControl cc; + private final ChipModel model; + private final Indenter indenter; + + private static void fatal(boolean pred, String msg) { + if (pred) Infrastructure.fatal(msg); + } + private void prln(String msg) {indenter.prln(msg);} + private void adjustIndent(int n) {indenter.adjustIndent(n);} + + private BitVector getDatTokAdr() { + // strip the two write enable bits + return cc.getOutBits(dataPath).get(2, 52); + } + + private void shiftControl(boolean readEnable, boolean writeEnable) { + cc.shift(controlChain, readEnable, writeEnable); + } + private void shiftData(boolean readEnable, boolean writeEnable) { + cc.shift(dataChain, readEnable, writeEnable); + } + private void shiftReport(boolean readEnable, boolean writeEnable) { + cc.shift(reportChain, readEnable, writeEnable); + } + + public void run() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.RUN.bits()); + } + public void idle() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.IDLE.bits()); + } + public void fill() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.FILL.bits()); + } + public void block() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.BLOCK.bits()); + } + public void stop() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.STOP.bits()); + } + public void clear() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.CLEAR.bits()); + } + public void source() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.SOURCE.bits()); + } + public void stopSource() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSOURCE.bits()); + } + public void sink() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.SINK.bits()); + } + public void stopSink() { + cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSINK.bits()); + } + /** Stop a running stopper in order to add items. Ensure that we don't + * lose the item in the fill stage. Wait long enough for ring to quiesce. + * Exit state: idle */ + public void stopToFill() { + stop(); // go = 0 + shiftControl(false, true); + + idle(); // block = 1 + shiftControl(false, true); + + block(); // go = 1 + shiftControl(false, true); + + idle(); // go = 0 + shiftControl(false, true); + } + + private StateWireState boolToState(boolean b) { + return b ? StateWireState.FULL : StateWireState.EMPTY; + } + + 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 + * scan chain works. */ + public boolean getFillWire() { + return cc.getOutBits(reportPath).get(1); + } + public StateWireState getMyStateWire() { + return boolToState(cc.getOutBits(reportPath).get(2)); + } + public boolean getStopped() { + return cc.getOutBits(reportPath).get(3); + } + public String getReportString() { + StringBuffer sb = new StringBuffer(); + sb.append("Stopper's prev state: "); + sb.append(getPrevStateWire()+"\n"); + sb.append("Stopper's state: "); + sb.append(getMyStateWire()+"\n"); + sb.append("Stopper's stopped: "); + sb.append(getStopped()+"\n"); + return sb.toString(); + } + + public ProperStopper(String controlChain, String controlInst, + String dataChain, String dataInst, + String reportChain, String reportInst, + ChainControl cc, ChipModel model, + Indenter indenter) { + this.controlChain = controlChain; + this.controlPath = controlChain+controlInst; + this.dataChain = dataChain; + this.dataPath = dataChain+dataInst; + this.reportChain = reportChain; + this.reportPath = reportChain+reportInst; + this.cc = cc; + this.model = model; + this.indenter = indenter; + } + + public void resetAfterMasterClear() { + BitVector we = new BitVector(2, "write enable"); + BitVector data = new BitVector(37, "data"); + BitVector tag = new BitVector(1, "tag"); + BitVector addr = new BitVector(14, "addr"); + we.setFromLong(0); + data.setFromLong(0); + tag.setFromLong(0); + addr.setFromLong(0); + BitVector wdta = we.cat(data).cat(tag).cat(addr); + + cc.setInBits(dataPath, wdta); + } + + /** You must stop stopper before calling fill. + * exit state: idle */ + public void fill(BitVector dta) { + if (traceFill) prln("Begin fillStopper"); + adjustIndent(2); + + int n = dta.getNumBits(); + fatal(n!=(37+1+14), "fillStopper: wrong num bits: "+n); + + if (traceFill) prln("writing data: "+MarinaUtils.formatDataTokAddr(dta)); + + idle(); // block = 1, go = 0 + shiftControl(false, true); + + BitVector wrEn = new BitVector(2, "write enable"); + wrEn.setFromLong(3); + cc.setInBits(dataPath, wrEn.cat(dta)); + shiftData(false, true); + + fill(); // fire = 1 + shiftControl(false, true); + idle(); // fire = 0 + shiftControl(false, true); + block(); // go = 1 + shiftControl(false, true); + idle(); + 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() + * exit state: idle */ + public void fillMany(List data) { + prln("begin fillMany "+data.size()+" words"); + adjustIndent(2); + int cnt = 0; + for (BitVector bv : data) { + if (traceFill) prln("fillStopperMany: writing word number: "+cnt++); + fill(bv); + } + adjustIndent(-2); + prln("end fillMany"); + } + /** drain() will stop cleanly. + * exit state: stop */ + public BitVector drain() { + stop(); // all zero, block = 0, go = 0 + shiftControl(false, true); + + shiftData(true, false); + BitVector ans = getDatTokAdr(); + + idle(); // block = 1 + shiftControl(false, true); + clear(); // clear = 1 + shiftControl(false, true); + idle(); // clear = 0 + shiftControl(false, true); + stop(); // block = 0 + shiftControl(false, true); + + if (traceDrain) prln("drainStopper data: "+MarinaUtils.formatDataTokAddr(ans)); + return ans; + } + /** drainStopperMany() will stop cleanly. + * exit state: stop */ + public List drainMany() { + prln("begin drainStopperMany"); + adjustIndent(2); + + List ans = new ArrayList(); + + int cnt = 0; + while (true) { + shiftReport(true, false); + MarinaUtils.StateWireState myState=getMyStateWire(); + + // debugging + if (traceDrain) prln(getReportString()); + + if (myState==MarinaUtils.StateWireState.EMPTY) break; + + if (traceDrain) prln("drainStopperMany: reading word number: "+cnt++); + + BitVector d = drain(); + + ans.add(d); + } + + adjustIndent(-2); + prln("end drainStopperMany, got "+ans.size()+" entries"); + + return ans; + } + + + +} diff --git a/testCode/header.hsp b/testCode/header.hsp new file mode 100644 index 0000000..5fa130f --- /dev/null +++ b/testCode/header.hsp @@ -0,0 +1,33 @@ +********************** TSMC 90nm Header ************************** + +****************************************************************** +* Set Process, Voltage and Temperature corner +****************************************************************** +.lib '/import/async/cad/process/tsmc090/spice_models/models/cln90g_lk.l' TT +.lib '/import/async/cad/process/tsmc090/spice_models/models/cln90g_lk.l' TT_RES +.lib '/import/async/cad/process/tsmc090/spice_models/models/cln90g_lk.l' TT_18 +.lib '/import/async/cad/process/tsmc090/spice_models/models/cln90g_lk.l' TT_na18 +.lib '/import/async/cad/process/tsmc090/spice_models/models/cln90g_lk.l' TT_DIO_esd +.lib '/import/async/cad/process/tsmc090/spice_models/models/cln90g_lk.l' TT_DIO_18 +.param sup=1.0 * Supply voltage +.temp 40 * Temperature + +****************************************************************** +* Standard Parameters and Options +****************************************************************** +.param vsupply=sup +.param vhi=sup +.param vlo=0 +.param strong0=0 * Used in verilog, just needs to be defined to run hspice +.param strong1=1 * Used in verilog, just needs to be defined to run hspice +vvdd vdd gnd 'sup' +.options ACCT OPTS post +*.option post probe +.opt scale=0.05u +.op + +.param AVT0N = AGAUSS(0.0, '0.01 / 0.1' , 1) +.param AVT0P = AGAUSS(0.0, '0.01 / 0.1' , 1) +.param ABN = AGAUSS(0.0, '0.02 / 0.1' , 1) +.param ABP = AGAUSS(0.0, '0.02 / 0.1' , 1) + diff --git a/testCode/marina.bsh b/testCode/marina.bsh new file mode 100644 index 0000000..3d51c7a --- /dev/null +++ b/testCode/marina.bsh @@ -0,0 +1,46 @@ +/* infinity.bsh */ + +import com.sun.electric.plugins.menus.ScanChainXML; + +/* + * Create a ScanChainXML object + */ + + ScanChainXML gen = new ScanChainXML(); + + // Add all the scan chain elements: name, access, clears, + // scan in port name, scan out port name, + // (optional:) data out port name (may be "" or null), + // data out bar port name (may be "" or null). + // Both data out and data out bar must be specified or left out. + gen.addScanChainElement("scanJ", "scanCellE", "R", "-", "sin", "sout", "dIn[1](R)", ""); + gen.addScanChainElement("scanJ", "scanCellF", "RW", "L", "sin", "sout", "out[1](R)", "pLO(WI)"); + gen.addScanChainElement("latchGroupsK", "latchWscan", "RW", "-", "sin", "sout", "pLO(WI)", "out[1](R)"); + + //gen.addScanChainElement("scanF", "iScanShift", "R", "-", "sdin", "sdout", "rddata(RI)", ""); + + // Add all the pass through elements: these pass scan data through, + // like inverters or buffers + //gen.addPassThroughCell("scanF", "scanAmp", "in[1]", "out[1]"); + + // Define the jtag controller by it's library, cell name, + // and the number of instruction register bits + gen.setJtagController("jtagController", "jtagCentral{sch}", 8); + + // Chip-specific configuration + gen.setChipName("marina"); + + // gen.addJtagPort(1, "leaf0[1]", "leaf0[8]", "jtag_lvds"); + // gen.addJtagPort(1, "leaf1[1]", "leaf1[8]", "jtag_noise"); + // gen.addJtagPort(2, "leaf2[1]", "leaf2[8]", "jtag_exp"); + + // Generate the XML file + // gen.setOutput("/import/async/cad/2007/stu/infinity/fleetF-05jul07s/crosser.xml"); + // gen.startFromExport("sin","samplers_5{sch}"); + // gen.start("sampler_float","samplers_5{sch}"); + + gen.setOutput("marina.xml"); + gen.startFromExport("scanInR[1]", "jtag_dockTest_report"); + gen.startFromExport("scanInC[1]", "jtag_dockTest_control"); + gen.startFromExport("scanInD[1]", "jtag_dockTest_data"); + gen.start("marina","dockTest{sch}"); diff --git a/testCode/marina.xml b/testCode/marina.xml new file mode 100644 index 0000000..a5ad6f6 --- /dev/null +++ b/testCode/marina.xml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + +'> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'> + + + + + + + + + + + + +'> + &scanJ_scanFx3hor_sic_1_; +'> + &scanJ_scanEx2vert_sir_1_; +'> + &scanJ_scanFx2vert_sic_1_; +'> + &scanJ_scanEx2vert_sir_1_; +'> + &scanJ_scanEx1vertA_sir_1_; +'> + +'> + ®istersJ_data1in38scan_sid_1_; + ®istersJ_addr1in14scan_sin; +'> + + + + +'> + +'> + + +'> + + +'> + + + +'> + &stagesJ_plainStage_sir_1_; + &stagesJ_plainStage_sir_1_; + &stagesJ_plainStage_sir_1_; + &stagesJ_plainStage_sir_1_; +'> + &stagesJ_fillStage_sic_1_; + &stagesJ_drainStage_sic_1_; +'> + &stagesJ_fillStage_sid_1_; +'> + &stagesJ_fillStage_sir_1_; + &stagesJ_drainStage_sir_1_; +'> + &gaspJ_gaspDrain_sic_1_; +'> + &gaspJ_gaspDrain_sir_1_; +'> + &gaspJ_gaspFill_sic_1_; +'> + ®istersJ_all1in52scan_sid_1_; +'> + &gaspJ_gaspFill_sir_1_; +'> + &gaspJ_gaspPlain_sir_1_; +'> +]> + + + + + + &stageGroupsJ_properStopper_sic_1_; + &stageGroupsJ_properStopper_sic_1_; + + + &stageGroupsJ_properStopper_sid_1_; + &stageGroupsJ_properStopper_sid_1_; + + + &stageGroupsJ_properStopper_sir_1_; + &stageGroupsJ_plainStageFour_rscanIn_1_; + &stageGroupsJ_properStopper_sir_1_; + + + + &marina_jtag_dockTest_control_dataNets; + &marina_jtag_dockTest_data_dataNets; + &marina_jtag_dockTest_report_dataNets; + + + -- 1.7.10.4