formatting changes
[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
9 import edu.berkeley.fleet.api.Instruction;
10
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. */
14 public class Marina {
15
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";
19         
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";
26
27     private static final String INSTR_RING_CONTROL_PATH = 
28         "southFif@1.tapPropS@1.tapStage@2";
29     private static final String TOK_FIFO_PATH =
30         "tokenFIF@1";
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";
37
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;
41
42     public static final int INSTRUCTION_LENGTH = 36;
43         
44     private static final int A_FLAG_NDX = 0;
45     private static final int B_FLAG_NDX = 1;
46         
47     public static final int SOUTH_RING_CAPACITY = 11;
48         
49     // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
50     public class Ilc {
51         // value is bit reversed and complemented
52         private int value;
53         private Ilc() {
54             shiftReport(true, false);
55             value = (int) cc.getOutBits(REPORT_CHAIN+"."+ILC_PATH).bitReverse().not().toLong();
56         }
57         /** Get the inner loop counter done bit. */
58         public boolean getDone() {
59             return (value & 0x100) != 0;
60         }
61         /** Get the inner loop counter infinity bit */
62         public boolean getInfinity() {
63             return (value & 0x80) == 0;
64         }
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;
70         }
71         /** Get the 6 bits of count of the inner loop counter */
72         public int getCount() {
73             return value & 0x3f;
74         }
75     }
76         
77     private final Indenter indenter;
78
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;
85     
86     private void prln(String msg) {indenter.prln(msg);}
87     private void pr(String msg) {indenter.pr(msg);}
88     
89     /** Shift the report scan chain */
90     private void shiftReport(boolean readEnable, boolean writeEnable) {
91         cc.shift(REPORT_CHAIN, readEnable, writeEnable);
92     }
93     
94     /** Shift the report scan chain */
95     private void shiftControl(boolean readEnable, boolean writeEnable) {
96         cc.shift(CONTROL_CHAIN, readEnable, writeEnable);
97     }
98         
99     /** Shift the data scan chain */
100     private void shiftData(boolean readEnable, boolean writeEnable) {
101         cc.shift(DATA_CHAIN, readEnable, writeEnable);
102     }
103
104     public Marina(ChainControls cc, ChipModel model, boolean clockHack, Indenter indenter) {
105         this.cc = cc;
106         this.model = model;
107         this.indenter = indenter;
108         data = new ProperStopper("northFif@1.fillDrai@1.properSt@1",
109                                  CONTROL_CHAIN, 
110                                  DATA_CHAIN,  
111                                  REPORT_CHAIN,
112                                  cc, model, clockHack, indenter);
113         instrIn = new InstructionStopper("southFif@1.tapPropS@1.properSt@1", 
114                                          CONTROL_CHAIN,
115                                          DATA_CHAIN,
116                                          REPORT_CHAIN,
117                                          cc, model, clockHack, indenter);
118     }
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);
130         nModel.waitNS(1);
131         resetAfterMasterClear();
132     }
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.
138         cc.resetInBits();
139
140         // For reset, I want to clear all the stoppers simultaneously
141         data.clear();
142         //tokOut.clear();
143         instrIn.clear();
144         
145         data.stop();
146         //tokOut.stop();
147         instrIn.stop();
148         
149         data.resetAfterMasterClear();
150         //tokOut.resetAfterMasterClear();
151         instrIn.resetAfterMasterClear();
152     }
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();
157     }
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() {
161         return new Ilc();
162     }
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);
167     }
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);
172     }
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();
184     }
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();
196     }
197     /** Fill the "North" Fifo ring */
198     public void fillNorthProperStopper(MarinaPacket mp) {
199         this.data.fill(mp.toSingleBitVector());
200     }
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)
206             instrIn.fill(i);
207         enableInstructionSend(true);
208     }
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);
216     } 
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);
223     }
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");
234         
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");
239
240         // concatenate them
241         bv = bv.cat(pred);
242         sz = bv.getNumBits();
243         prln("Token state wires: "+bv.getState());
244         
245         int nbTok = 0;
246         for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
247         return nbTok;
248     }
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);
255     }
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)
263      */
264     public void enableInstructionCounter(Boolean b) {
265         instrIn.setGeneralPurposeOutput(b);
266     }
267     
268 }