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;
8 import com.sun.async.test.VerilogModel;
10 import edu.berkeley.fleet.api.Instruction;
12 /** The Marina object will eventually represent the Marina test chip.
13 * Right now, it doesn't do much of anything. It just helps me exercise
14 * my test infrastructure. */
17 public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE = 5;
18 public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = 13;
20 public static final String DATA_CHAIN = "marina.marina_data";
21 public static final String CONTROL_CHAIN = "marina.marina_control";
22 public static final String REPORT_CHAIN = "marina.marina_report";
24 private static final String OLC_PATH_EVEN =
25 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@1"; // bits 2,4,6
26 private static final String OLC_PATH_ODD =
27 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.scanEx3h@2"; // bits 1,3,5
28 private static final String ILC_PATH_ODD =
29 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@0"; // bits 1,3,5,7
30 private static final String ILC_PATH_EVEN =
31 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx4h@1"; // bits 2,4,6,8
32 private static final String FLAGS_PATH =
33 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.scanEx3h@0";
35 private static final String INSTR_RING_CONTROL_PATH =
36 "southFif@1.tapPropS@1.tapStage@2";
37 private static final String TOK_FIFO_PATH =
39 private static final String INSTRUCTION_COUNTER_PATH =
40 "southFif@1.tapPropS@1.instruct@0";
41 private static final String DATA_COUNTER_PATH =
42 "northFif@1.fillDrai@1.instruct@0";
43 private static final String TOK_PRED_PATH =
44 "outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.scanEx2h@0.scanCell@10";
46 private static final int COUNTER_LENGTH = 34;
47 private static final int INSTRUCTION_SEND_NDX = 1;
48 private static final int INSTRUCTION_RECIRCULATE_NDX = 0;
50 public static final int INSTRUCTION_LENGTH = 36;
52 private static final int A_FLAG_NDX = 0;
53 private static final int B_FLAG_NDX = 1;
55 public static final int SOUTH_RING_CAPACITY = 11;
57 // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
59 // value is bit reversed and complemented
62 shiftReport(true, false);
63 BitVector odd = cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH_ODD).bitReverse().not();
64 BitVector even = cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH_EVEN).bitReverse().not();
65 BitVector ret = new BitVector(8, "olc");
66 for(int i=0; i<4; i++) {
67 ret.set(i*2+1, odd.get(i));
68 ret.set(i*2, even.get(i));
70 value = (int)ret.toLong();
72 /** Get the inner loop counter done bit. */
73 public boolean getDone() {
74 return (value & 0x40) != 0;
76 /** Get the inner loop counter infinity bit */
77 public boolean getInfinity() {
78 return (value & 0x80) != 0;
80 /** Get the 6 bits of count of the inner loop counter */
81 public int getCount() {
86 private final Indenter indenter;
88 // The name of the scan chain
89 // The instance path, from the top cell of the netlist, of the instance of infinityWithCover
90 private final ChainControls cc; // specifies the scan chain
91 private final ChipModel model;
92 public final ProperStopper data;
93 public final InstructionStopper instrIn;
95 private void prln(String msg) {indenter.prln(msg);}
96 private void pr(String msg) {indenter.pr(msg);}
98 /** Shift the report scan chain */
99 private void shiftReport(boolean readEnable, boolean writeEnable) {
100 cc.shift(REPORT_CHAIN, readEnable, writeEnable);
103 /** Shift the report scan chain */
104 private void shiftControl(boolean readEnable, boolean writeEnable) {
105 cc.shift(CONTROL_CHAIN, readEnable, writeEnable);
108 /** Shift the data scan chain */
109 private void shiftData(boolean readEnable, boolean writeEnable) {
110 cc.shift(DATA_CHAIN, readEnable, writeEnable);
113 public Marina(ChainControls cc, ChipModel model, boolean clockHack, Indenter indenter) {
116 this.indenter = indenter;
117 data = new ProperStopper("northFif@1.fillDrai@1.properSt@1",
121 cc, model, clockHack, indenter);
122 instrIn = new InstructionStopper("southFif@1.tapPropS@1.properSt@1",
126 cc, model, clockHack, indenter);
128 public void masterClear() {
129 final double WIDTH = 10; // ns
130 // Put a high going pulse on the internal chip master clear signal
131 if (model instanceof VerilogModel) {
136 VerilogModel vm = (VerilogModel)model;
138 // In real life the flags come up with some undefined
139 // value. In verilog we need to prevent the X'es from
140 // propagating, so we force the flags to a known value
142 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__set_", 0);
143 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__clr_", 1);
144 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__set_", 0);
145 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__clr_", 1);
146 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__set_", 0);
147 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__clr_", 1);
148 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@0.net_50", 0); // A
149 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@1.net_50", 0); // B
150 vm.setNodeState("outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_", 0); // C
152 // possible C-flag inputs
153 vm.setNodeState("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]", 0);
154 vm.setNodeState("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]", 0);
156 // force the OLC to zero
157 for(int i=1; i<=6; i++)
158 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
160 // set the ILC input to 1
161 for(int i=1; i<=8; i++) {
163 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
166 // pulse ilc[load] and olc[load]
167 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_", 1);
168 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_", 1);
169 vm.setNodeState("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.fire", 1);
171 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_", 0);
172 vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_", 0);
173 vm.setNodeState("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.fire", 0);
176 vm.setNodeState("sid[9]", 1);
177 vm.setNodeState("sic[9]", 1);
178 vm.setNodeState("sir[9]", 1);
180 vm.setNodeState("sid[9]", 0);
181 vm.setNodeState("sic[9]", 0);
182 vm.setNodeState("sir[9]", 0);
185 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__set_");
186 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_A__clr_");
187 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__set_");
188 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_B__clr_");
189 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__set_");
190 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flag_D__clr_");
191 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@0.net_50");
192 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.flags@0.aFlag@1.net_50");
194 // Every move instruction, even those with Ti=0,Di=0,
195 // loads the C-flag. It will get loaded with an "X",
196 // which will then leak into the flags and from there the
198 vm.releaseNode("outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_");
199 vm.releaseNode("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]");
200 vm.releaseNode("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]");
201 vm.releaseNode("southFif@1.tapPropS@1.tapStage@2.addr1in6@0.fire");
203 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.ilc_load_");
204 for(int i=1; i<=8; i++) {
206 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
209 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.olc_load_");
210 for(int i=1; i<=6; i++)
211 vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.olcWcont@0.olc@0.inLO["+i+"]");
213 // the proper stopper states come up in an undefined ("X")
214 // state, so under Verilog we need to force them to a
221 NanosimModel nModel = (NanosimModel) model;
222 nModel.setNodeVoltage("sid[9]",1.0);
223 nModel.setNodeVoltage("sic[9]",1.0);
224 nModel.setNodeVoltage("sir[9]",1.0);
225 nModel.waitNS(WIDTH);
226 nModel.setNodeVoltage("sid[9]",0.0);
227 nModel.setNodeVoltage("sic[9]",0.0);
228 nModel.setNodeVoltage("sir[9]",0.0);
231 resetAfterMasterClear();
233 private void resetAfterMasterClear() {
234 // The following call to ChainControl.resetInBits() is vital!
235 // If you forget, then the inBits member initializes
236 // with random data. Then when you do your first write,
237 // some bits are written randomly.
240 // For reset, I want to clear all the stoppers simultaneously
249 data.resetAfterMasterClear();
250 //tokOut.resetAfterMasterClear();
251 instrIn.resetAfterMasterClear();
253 /** Get the 6 bit outer loop counter. */
254 public int getOLC() {
255 shiftReport(true, false);
256 BitVector odd = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse().not();
257 BitVector even = cc.getOutBits(REPORT_CHAIN+"."+OLC_PATH_EVEN).bitReverse().not();
258 BitVector ret = new BitVector(6, "olc");
259 for(int i=0; i<3; i++) {
260 ret.set(i*2, odd.get(i));
261 ret.set(i*2+1, even.get(i));
263 return (int)ret.toLong();
265 /** Get the 7 bit inner loop counter. The MSB is the zero bit.
266 * The low order 6 bits are the count */
267 public Ilc getILC() {
270 /** Get the A flag */
271 public boolean getFlagA() {
272 shiftReport(true, false);
273 return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(A_FLAG_NDX);
275 /** Get the B flag */
276 public boolean getFlagB() {
277 shiftReport(true, false);
278 return cc.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(B_FLAG_NDX);
280 /** return value of instruction counter. Instruction counter counts
281 * the instructions flowing through 1/2 of alternating FIFO.
282 * Caution: instruction counter is written by all scans,
283 * regardless of readEnable or writeEnable! */
284 public long getInstructionCounter() {
285 shiftData(true, false);
286 BitVector count = cc.getOutBits(DATA_CHAIN+"."+INSTRUCTION_COUNTER_PATH);
287 int sz = count.getNumBits();
288 MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
289 " expected: "+COUNTER_LENGTH);
290 return count.bitReverse().toLong();
292 /** return value of data counter. Data counter counts items flowing
293 * through drain stage of data proper stopper.
294 * Caution: data counter is written by all scans,
295 * regardless of readEnable or writeEnable! */
296 public long getDataCounter() {
297 shiftData(true, false);
298 BitVector count = cc.getOutBits(DATA_CHAIN+"."+DATA_COUNTER_PATH);
299 int sz = count.getNumBits();
300 MarinaTest.fatal(sz!=COUNTER_LENGTH, "wrong number of counter bits: "+sz+
301 " expected: "+COUNTER_LENGTH);
302 return count.bitReverse().toLong();
304 /** Fill the "North" Fifo ring */
305 public void fillNorthProperStopper(MarinaPacket mp) {
306 this.data.fill(mp.toSingleBitVector());
308 /** Fill the "South" Fifo ring with instructions */
309 public void fillSouthProperStopper(Instruction[] instructions) {
310 enableInstructionSend(false);
311 enableInstructionRecirculate(false);
312 for(Instruction i : instructions)
314 enableInstructionSend(true);
316 /** Enable the transmission of instructions from the instruction
317 * ring test structure to the EPI FIFO. */
318 public void enableInstructionSend(boolean b) {
319 BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
320 bv.set(INSTRUCTION_SEND_NDX, b);
321 cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv);
322 shiftControl(false, true);
324 /** Enable the recirculation of instructions within the South FIFO */
325 public void enableInstructionRecirculate(boolean b) {
326 BitVector bv = cc.getInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH);
327 bv.set(INSTRUCTION_RECIRCULATE_NDX, b);
328 cc.setInBits(CONTROL_CHAIN+"."+INSTR_RING_CONTROL_PATH, bv);
329 shiftControl(false, true);
331 /** get the number of tokens in the token FIFO.
332 * This includes the Token successor wire, the token FIFO wires,
333 * and Token predecessor wire.
334 * Master clear clears the token FIFO. */
335 public int getNumTokens() {
336 shiftReport(true, false);
337 // get the token successor and token FIFO wires
338 BitVector bv = cc.getOutBits(REPORT_CHAIN+"."+TOK_FIFO_PATH);
339 int sz = bv.getNumBits();
340 MarinaTest.fatal(sz!=3, "wrong token FIFO size: "+sz+" expected: 3");
342 // get the token predecessor wire
343 BitVector pred = cc.getOutBits(REPORT_CHAIN+"."+TOK_PRED_PATH);
344 sz = pred.getNumBits();
345 MarinaTest.fatal(sz!=1, "wrong token predecessor size: "+sz+" expected: 1");
349 sz = bv.getNumBits();
350 prln("Token state wires: "+bv.getState());
353 for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
356 /** Configure the test probe so it measures the throughput of
357 * the north data FIFO. The test probe frequency is 8192
358 * times slower than the FIFO throughput. This control has
359 * highest priority. */
360 public void probeDataCounter(Boolean b) {
361 data.setGeneralPurposeOutput(b);
363 /** Configure the test probe so it measures the throughput of
364 * the alternating instruction FIFO. The test probe frequency is
365 * 1/16384 of the FIFO throughput. This control has second
366 * highest priority. Thus the following two calls probe the
367 * instruction counter:
368 * probeDataCounter(false);
369 * probeInstructionCounter(true)
371 public void enableInstructionCounter(Boolean b) {
372 instrIn.setGeneralPurposeOutput(b);