all tests pass except requeue stage tests
[fleet.git] / testCode / com / sun / vlsi / chips / marina / test / Marina.java
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;
9
10 import edu.berkeley.fleet.api.Instruction;
11
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. */
15 public class Marina {
16
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;
19
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";
23         
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";
34
35     private static final String INSTR_RING_CONTROL_PATH = 
36         "southFif@1.tapPropS@1.tapStage@2";
37     private static final String TOK_FIFO_PATH =
38         "tokenFIF@1";
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";
45
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;
49
50     public static final int INSTRUCTION_LENGTH = 36;
51         
52     private static final int A_FLAG_NDX = 0;
53     private static final int B_FLAG_NDX = 1;
54         
55     public static final int SOUTH_RING_CAPACITY = 11;
56         
57     // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
58     public class Ilc {
59         // value is bit reversed and complemented
60         private int value;
61         private Ilc() {
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));
69             }
70             value = (int)ret.toLong();
71         }
72         /** Get the inner loop counter done bit. */
73         public boolean getDone() {
74             return (value & 0x40) != 0;
75         }
76         /** Get the inner loop counter infinity bit */
77         public boolean getInfinity() {
78             return (value & 0x80) != 0;
79         }
80         /** Get the 6 bits of count of the inner loop counter */
81         public int getCount() {
82             return value & 0x3f;
83         }
84     }
85         
86     private final Indenter indenter;
87
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;
94     
95     private void prln(String msg) {indenter.prln(msg);}
96     private void pr(String msg) {indenter.pr(msg);}
97     
98     /** Shift the report scan chain */
99     private void shiftReport(boolean readEnable, boolean writeEnable) {
100         cc.shift(REPORT_CHAIN, readEnable, writeEnable);
101     }
102     
103     /** Shift the report scan chain */
104     private void shiftControl(boolean readEnable, boolean writeEnable) {
105         cc.shift(CONTROL_CHAIN, readEnable, writeEnable);
106     }
107         
108     /** Shift the data scan chain */
109     private void shiftData(boolean readEnable, boolean writeEnable) {
110         cc.shift(DATA_CHAIN, readEnable, writeEnable);
111     }
112
113     public Marina(ChainControls cc, ChipModel model, boolean clockHack, Indenter indenter) {
114         this.cc = cc;
115         this.model = model;
116         this.indenter = indenter;
117         data = new ProperStopper("northFif@1.fillDrai@1.properSt@1",
118                                  CONTROL_CHAIN, 
119                                  DATA_CHAIN,  
120                                  REPORT_CHAIN,
121                                  cc, model, clockHack, indenter);
122         instrIn = new InstructionStopper("southFif@1.tapPropS@1.properSt@1", 
123                                          CONTROL_CHAIN,
124                                          DATA_CHAIN,
125                                          REPORT_CHAIN,
126                                          cc, model, clockHack, indenter);
127     }
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) {
132
133             data.clear();
134             instrIn.clear();
135
136             VerilogModel vm = (VerilogModel)model;
137             //
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
141             //
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
151
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);
155
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);
159
160             // set the ILC input to 1
161             for(int i=1; i<=8; i++) {
162                 if (i!=7)
163                     vm.setNodeState("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
164             }
165
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);
170             model.waitNS(1000);
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);
174             model.waitNS(1000);
175
176             vm.setNodeState("sid[9]", 1);
177             vm.setNodeState("sic[9]", 1);
178             vm.setNodeState("sir[9]", 1);
179             model.waitNS(1000);
180             vm.setNodeState("sid[9]", 0);
181             vm.setNodeState("sic[9]", 0);
182             vm.setNodeState("sir[9]", 0);
183             model.waitNS(1000);
184
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");
193
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
197             // predicate.
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");
202
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++) {
205                 if (i!=7)
206                     vm.releaseNode("outputDo@0.outM1Pre@0.outDockP@0.outDockC@0.ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
207             }
208             model.waitNS(1000);
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+"]");
212
213             // the proper stopper states come up in an undefined ("X")
214             // state, so under Verilog we need to force them to a
215             // known state
216
217             data.idle();
218             instrIn.idle();
219
220         } else {
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);
229             nModel.waitNS(1);
230         }
231         resetAfterMasterClear();
232     }
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.
238         cc.resetInBits();
239
240         // For reset, I want to clear all the stoppers simultaneously
241         data.clear();
242         //tokOut.clear();
243         instrIn.clear();
244         
245         data.stop();
246         //tokOut.stop();
247         instrIn.stop();
248         
249         data.resetAfterMasterClear();
250         //tokOut.resetAfterMasterClear();
251         instrIn.resetAfterMasterClear();
252     }
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));
262         }
263         return (int)ret.toLong();
264     }
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() {
268         return new Ilc();
269     }
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);
274     }
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);
279     }
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();
291     }
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();
303     }
304     /** Fill the "North" Fifo ring */
305     public void fillNorthProperStopper(MarinaPacket mp) {
306         this.data.fill(mp.toSingleBitVector());
307     }
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)
313             instrIn.fill(i);
314         enableInstructionSend(true);
315     }
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);
323     } 
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);
330     }
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");
341         
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");
346
347         // concatenate them
348         bv = bv.cat(pred);
349         sz = bv.getNumBits();
350         prln("Token state wires: "+bv.getState());
351         
352         int nbTok = 0;
353         for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
354         return nbTok;
355     }
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);
362     }
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)
370      */
371     public void enableInstructionCounter(Boolean b) {
372         instrIn.setGeneralPurposeOutput(b);
373     }
374     
375 }