1 package com.sun.vlsi.chips.marina.test;
2 /* -*- tab-width: 4 -*- */
3 import com.sun.async.test.BitVector;
4 import com.sun.async.test.ChainControl;
5 import com.sun.async.test.ChipModel;
6 import com.sun.async.test.JtagTester;
7 import com.sun.async.test.NanosimModel;
9 import edu.berkeley.fleet.api.Instruction;
11 /** The Marina object will eventually represent the Marina test chip.
12 * Right now, it doesn't do much of anything. It just helps me exercise
13 * my test infrastructure. */
16 public static final String DATA_CHAIN = "marina.marina_data";
17 public static final String CONTROL_CHAIN = "marina.marina_control";
18 public static final String REPORT_CHAIN = "marina.marina_report";
20 private static final String OLC_PATH =
21 "dataPath@0.ringSkip@1.skipCoun@1.skipCoun@0.scanKx6@0";
22 private static final String ILC_PATH =
23 "dataPath@0.ringSkip@1.skipCoun@1.skipCoun@0.scanKx9@0";
24 private static final String FLAGS_PATH =
25 "dataPath@0.ringSkip@1.skipCoun@1.skipCoun@0.scanKx2@0";
27 private static final String INSTR_RING_CONTROL_PATH =
28 "southFif@1.tapPropS@1.tapStage@2";
29 private static final String TOK_FIFO_PATH =
31 private static final String INSTRUCTION_COUNTER_PATH =
32 "southFif@1.tapPropS@1.instruct@0";
33 private static final String DATA_COUNTER_PATH =
34 "northFif@1.fillDrai@1.instruct@0";
35 private static final String TOK_PRED_PATH =
36 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx2h@0.scanCell@10";
38 private static final int COUNTER_LENGTH = 34;
39 private static final int INSTRUCTION_SEND_NDX = 1;
40 private static final int INSTRUCTION_RECIRCULATE_NDX = 0;
42 public static final int INSTRUCTION_LENGTH = 36;
44 private static final int A_FLAG_NDX = 0;
45 private static final int B_FLAG_NDX = 1;
47 public static final int SOUTH_RING_CAPACITY = 11;
49 // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
51 // value is bit reversed and complemented
54 shiftReport(true, false);
55 value = (int) cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH).bitReverse().not().toLong();
57 /** Get the inner loop counter done bit. */
58 public boolean getDone() {
59 return (value & 0x100) != 0;
61 /** Get the inner loop counter infinity bit */
62 public boolean getInfinity() {
63 return (value & 0x80) == 0;
65 /** Get the inner loop counter zero bit. If the zero bit is true
66 * then the hardware considers the inner loop counter to be zero
67 * regardless of the state of the count bits */
68 public boolean getZero() {
69 return (value & 0x40) != 0;
71 /** Get the 6 bits of count of the inner loop counter */
72 public int getCount() {
77 private final Indenter indenter;
79 // The name of the scan chain
80 // The instance path, from the top cell of the netlist, of the instance of infinityWithCover
81 private final ChainControls cc; // specifies the scan chain
82 private final ChipModel model;
83 public final ProperStopper data;
84 public final InstructionStopper instrIn;
86 private void prln(String msg) {indenter.prln(msg);}
87 private void pr(String msg) {indenter.pr(msg);}
89 /** Shift the report scan chain */
90 private void shiftReport(boolean readEnable, boolean writeEnable) {
91 cc.shift(REPORT_CHAIN, readEnable, writeEnable);
94 /** Shift the report scan chain */
95 private void shiftControl(boolean readEnable, boolean writeEnable) {
96 cc.shift(CONTROL_CHAIN, readEnable, writeEnable);
99 /** Shift the data scan chain */
100 private void shiftData(boolean readEnable, boolean writeEnable) {
101 cc.shift(DATA_CHAIN, readEnable, writeEnable);
104 public Marina(ChainControls cc, ChipModel model, boolean clockHack, Indenter indenter) {
107 this.indenter = indenter;
108 data = new ProperStopper("northFif@1.fillDrai@1.properSt@1",
112 cc, model, clockHack, indenter);
113 instrIn = new InstructionStopper("southFif@1.tapPropS@1.properSt@1",
117 cc, model, clockHack, indenter);
119 public void masterClear() {
120 final double WIDTH = 10; // ns
121 NanosimModel nModel = (NanosimModel) model;
122 // Put a high going pulse on the internal chip master clear signal
123 nModel.setNodeVoltage("sid[9]",1.0);
124 nModel.setNodeVoltage("sic[9]",1.0);
125 nModel.setNodeVoltage("sir[9]",1.0);
126 nModel.waitNS(WIDTH);
127 nModel.setNodeVoltage("sid[9]",0.0);
128 nModel.setNodeVoltage("sic[9]",0.0);
129 nModel.setNodeVoltage("sir[9]",0.0);
131 resetAfterMasterClear();
133 private void resetAfterMasterClear() {
134 // The following call to ChainControl.resetInBits() is vital!
135 // If you forget, then the inBits member initializes
136 // with random data. Then when you do your first write,
137 // some bits are written randomly.
140 // For reset, I want to clear all the stoppers simultaneously
149 data.resetAfterMasterClear();
150 //tokOut.resetAfterMasterClear();
151 instrIn.resetAfterMasterClear();
153 /** Get the 6 bit outer loop counter. */
154 public int getOLC() {
155 shiftReport(true, false);
156 return (int) cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH).bitReverse().not().toLong();
158 /** Get the 7 bit inner loop counter. The MSB is the zero bit.
159 * The low order 6 bits are the count */
160 public Ilc getILC() {
163 /** Get the A flag */
164 public boolean getFlagA() {
165 shiftReport(true, false);
166 return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(A_FLAG_NDX);
168 /** Get the B flag */
169 public boolean getFlagB() {
170 shiftReport(true, false);
171 return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(B_FLAG_NDX);
173 /** return value of instruction counter. Instruction counter counts
174 * the instructions flowing through 1/2 of alternating FIFO.
175 * Caution: instruction counter is written by all scans,
176 * regardless of readEnable or writeEnable! */
177 public long getInstructionCounter() {
178 shiftData(true, false);
179 BitVector count = cc.getOutBits(DATA_CHAIN+"."+INSTRUCTION_COUNTER_PATH);
180 int sz = count.getNumBits();
181 MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
182 " expected: "+COUNTER_LENGTH);
183 return count.bitReverse().toLong();
185 /** return value of data counter. Data counter counts items flowing
186 * through drain stage of data proper stopper.
187 * Caution: data counter is written by all scans,
188 * regardless of readEnable or writeEnable! */
189 public long getDataCounter() {
190 shiftData(true, false);
191 BitVector count = cc.getOutBits(DATA_CHAIN+"."+DATA_COUNTER_PATH);
192 int sz = count.getNumBits();
193 MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
194 " expected: "+COUNTER_LENGTH);
195 return count.bitReverse().toLong();
197 /** Fill the "North" Fifo ring */
198 public void fillNorthProperStopper(MarinaPacket mp) {
199 this.data.fill(mp.toSingleBitVector());
201 /** Fill the "South" Fifo ring with instructions */
202 public void fillSouthProperStopper(Instruction[] instructions) {
203 enableInstructionSend(false);
204 enableInstructionRecirculate(false);
205 for(Instruction i : instructions)
207 enableInstructionSend(true);
209 /** Enable the transmission of instructions from the instruction
210 * ring test structure to the EPI FIFO. */
211 public void enableInstructionSend(boolean b) {
212 BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
213 bv.set(INSTRUCTION_SEND_NDX, b);
214 cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv);
215 shiftControl(false, true);
217 /** Enable the recirculation of instructions within the South FIFO */
218 public void enableInstructionRecirculate(boolean b) {
219 BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
220 bv.set(INSTRUCTION_RECIRCULATE_NDX, b);
221 cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv);
222 shiftControl(false, true);
224 /** get the number of tokens in the token FIFO.
225 * This includes the Token successor wire, the token FIFO wires,
226 * and Token predecessor wire.
227 * Master clear clears the token FIFO. */
228 public int getNumTokens() {
229 shiftReport(true, false);
230 // get the token successor and token FIFO wires
231 BitVector bv = cc.getOutBits(REPORT_CHAIN+"."+TOK_FIFO_PATH);
232 int sz = bv.getNumBits();
233 MarinaTest.fatal(sz!=3, "wrong token FIFO size: "+sz+" expected: 3");
235 // get the token predecessor wire
236 BitVector pred = cc.getOutBits(REPORT_CHAIN+"."+TOK_PRED_PATH);
237 sz = pred.getNumBits();
238 MarinaTest.fatal(sz!=1, "wrong token predecessor size: "+sz+" expected: 1");
242 sz = bv.getNumBits();
243 prln("Token state wires: "+bv.getState());
246 for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
249 /** Configure the test probe so it measures the throughput of
250 * the north data FIFO. The test probe frequency is 8192
251 * times slower than the FIFO throughput. This control has
252 * highest priority. */
253 public void probeDataCounter(Boolean b) {
254 data.setGeneralPurposeOutput(b);
256 /** Configure the test probe so it measures the throughput of
257 * the alternating instruction FIFO. The test probe frequency is
258 * 1/16384 of the FIFO throughput. This control has second
259 * highest priority. Thus the following two calls probe the
260 * instruction counter:
261 * probeDataCounter(false);
262 * probeInstructionCounter(true)
264 public void enableInstructionCounter(Boolean b) {
265 instrIn.setGeneralPurposeOutput(b);