Clean up and document interfaces for Adam
[fleet.git] / testCode / com / sun / vlsi / chips / marina / test / ProperStopper.java
1 package com.sun.vlsi.chips.marina.test;
2 import java.util.ArrayList;
3 import java.util.List;
4
5 import com.sun.async.test.BitVector;
6 import com.sun.async.test.ChainControl;
7 import com.sun.async.test.ChipModel;
8 import com.sun.async.test.Infrastructure;
9 import com.sun.vlsi.chips.marina.test.MarinaUtils.StateWireState;
10
11 public class ProperStopper {
12         private boolean traceFill = true;
13         private boolean traceDrain = true;
14         
15     private final String controlChain, controlPath, 
16                          dataChain, dataPath, 
17                          reportChain, reportPath;
18     private final ChainControl cc;
19     private final ChipModel model;
20         private final Indenter indenter;
21
22         private static void fatal(boolean pred, String msg) {
23                 if (pred) Infrastructure.fatal(msg);
24         }
25         private void prln(String msg) {indenter.prln(msg);}
26         private void adjustIndent(int n) {indenter.adjustIndent(n);}
27
28     private BitVector getDatTokAdr() {
29         // strip the two write enable bits
30         return cc.getOutBits(dataPath).get(2, 52);
31     }
32     
33     private void shiftControl(boolean readEnable, boolean writeEnable) {
34         cc.shift(controlChain, readEnable, writeEnable);
35     }
36     private void shiftData(boolean readEnable, boolean writeEnable) {
37         cc.shift(dataChain, readEnable, writeEnable);
38     }
39     private void shiftReport(boolean readEnable, boolean writeEnable) {
40         cc.shift(reportChain, readEnable, writeEnable);
41     }
42
43     private StateWireState boolToState(boolean b) {
44         return b ? StateWireState.FULL : StateWireState.EMPTY;
45     }
46     
47     //-------------------------- public methods ----------------------------
48
49     /** Put stopper in RUN state */
50     public void run() {
51         cc.setInBits(controlPath, MarinaUtils.RingIfc.RUN.bits());
52     }
53     /** Put stopper in IDLE state */
54     public void idle() {
55         cc.setInBits(controlPath, MarinaUtils.RingIfc.IDLE.bits());
56     }
57     /** Put stopper in FILL state */
58     public void fill() {
59         cc.setInBits(controlPath, MarinaUtils.RingIfc.FILL.bits());
60     }
61     /** Put stopper in BLOCK state */
62     public void block() {
63         cc.setInBits(controlPath, MarinaUtils.RingIfc.BLOCK.bits());
64     }
65     /** Put stopper in STOP state */
66     public void stop() {
67         cc.setInBits(controlPath, MarinaUtils.RingIfc.STOP.bits());
68     }
69     /** Put stopper in CLEAR state */
70     public void clear() {
71         cc.setInBits(controlPath, MarinaUtils.RingIfc.CLEAR.bits());
72     }
73     /** Put stopper in SOURCE state */
74     public void source() {
75         cc.setInBits(controlPath, MarinaUtils.RingIfc.SOURCE.bits());
76     }
77     /** Put stopper in STOPSOURCE state */
78     public void stopSource() {
79         cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSOURCE.bits());
80     }
81     /** Put stopper in SINK state */
82     public void sink() {
83         cc.setInBits(controlPath, MarinaUtils.RingIfc.SINK.bits());
84     }
85     /** Put stopper in STOPSINK state */
86     public void stopSink() {
87         cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSINK.bits());
88     }
89     /** Stop a running stopper in order to add items.  Ensure that we don't
90      * lose the item in the fill stage.  Wait long enough for ring to quiesce.
91      * Exit state: idle */
92     public void stopToFill() {
93         stop();                                 // go = 0
94         shiftControl(false, true);
95
96         idle();                                 // block = 1
97         shiftControl(false, true);
98
99         block();                                // go = 1
100         shiftControl(false, true);
101
102         idle();                                 // go = 0
103         shiftControl(false, true);
104     }
105     /** get value of the state wire preceeding the fill stage */
106     public StateWireState getPrevStateWire() {
107         BitVector b = cc.getOutBits(reportPath);
108         int n = b.getNumBits(); 
109         fatal(n!=4, "Bad number of Stopper report bits: "+n);
110         return boolToState(cc.getOutBits(reportPath).get(0));
111     }
112     /** get the value of drain stage fill wire.
113      * The fill wire will be interesting if we doubt that the
114      * scan chain works. */
115     public boolean getFillWire() {
116         return cc.getOutBits(reportPath).get(1);
117     }
118     /** get value of state wire between the fill and drain stages */
119     public StateWireState getMyStateWire() {
120         return boolToState(cc.getOutBits(reportPath).get(2));
121     }
122     /** get value of drain stage stopped wire */
123     public boolean getStopped() {
124         return cc.getOutBits(reportPath).get(3);
125     }
126     public String getReportString() {
127         StringBuffer sb = new StringBuffer();
128         sb.append("Stopper's prev state: ");
129         sb.append(getPrevStateWire()+"\n");
130         sb.append("Stopper's state: ");
131         sb.append(getMyStateWire()+"\n");
132         sb.append("Stopper's stopped: ");
133         sb.append(getStopped()+"\n");
134         return sb.toString();
135     }
136     /** construct a ProperStopper */
137     public ProperStopper(String controlChain, String controlInst, 
138                                          String dataChain, String dataInst, 
139                              String reportChain, String reportInst, 
140                              ChainControl cc, ChipModel model,
141                              Indenter indenter) {
142         this.controlChain = controlChain;
143         this.controlPath = controlChain+controlInst;
144         this.dataChain = dataChain;
145         this.dataPath = dataChain+dataInst;
146         this.reportChain = reportChain;
147         this.reportPath = reportChain+reportInst;
148         this.cc = cc;
149         this.model = model;
150         this.indenter = indenter;
151     }
152     /** Reset ProperStopper after the JTAG TRST has been pulsed */
153     public void resetAfterMasterClear() {
154         BitVector we = new BitVector(2, "write enable");
155         BitVector data = new BitVector(37, "data");
156         BitVector tag = new BitVector(1, "tag");
157         BitVector addr = new BitVector(14, "addr");
158         we.setFromLong(0);
159         data.setFromLong(0);
160         tag.setFromLong(0);
161         addr.setFromLong(0);
162         BitVector wdta = we.cat(data).cat(tag).cat(addr);
163         
164         cc.setInBits(dataPath, wdta);
165     }
166     
167     /** Insert one item into the fill stage.
168      * Fill stage must be empty. 
169      * You must stop stopper before calling fill.
170      * exit state: idle */
171     public void fill(BitVector dta) {
172         if (traceFill) prln("Begin fillStopper");
173         adjustIndent(2);
174         
175         int n = dta.getNumBits();
176         fatal(n!=(37+1+14), "fillStopper: wrong num bits: "+n);
177         
178         // make sure fill stage is empty
179         shiftReport(true, false);
180         StateWireState myState = getMyStateWire();
181         fatal(myState!=StateWireState.EMPTY, 
182                   "fillStopper: fill stage already full");
183         
184         if (traceFill) prln("writing data: "+MarinaUtils.formatDataTokAddr(dta));
185         
186         idle();                                 // block = 1, go = 0
187         shiftControl(false, true);
188
189         BitVector wrEn = new BitVector(2, "write enable");
190         wrEn.setFromLong(3);
191         cc.setInBits(dataPath, wrEn.cat(dta));
192         shiftData(false, true);
193         
194         fill();                                 // fill = 1
195         shiftControl(false, true);
196         idle();                                 // fill = 0
197         shiftControl(false, true);
198         block();                                // go = 1
199         shiftControl(false, true);
200         idle();
201         shiftControl(false, true);
202         
203         model.waitNS(5);
204
205         // debugging
206         if (traceFill) prln(getReportString());
207         
208         // if data chain is shifted in the future, don't write!
209         wrEn.setFromLong(0);
210         cc.setInBits(dataPath, wrEn.cat(dta));
211         
212         adjustIndent(-2);
213         if (traceFill) prln("End fillStopper");
214     }
215     /** Insert items from a list, one by one. 
216      * You must stop stopper before calling fillMany()
217      * exit state: idle */
218     public void fillMany(List<BitVector> data) {
219         prln("begin fillMany "+data.size()+" words");
220         adjustIndent(2);
221         int cnt = 0;
222         for (BitVector bv : data) {
223                 if (traceFill) prln("fillStopperMany: writing word number: "+cnt++);
224                 fill(bv);
225         }
226         adjustIndent(-2);
227         prln("end fillMany");
228     }
229     /** Remove one item from fill stage. Return that item.
230      * An item must be available.
231      * drain() will stop cleanly.
232      * exit state: stop */
233     public BitVector drain() {
234         stop();                                 // all zero, block = 0, go = 0
235         shiftControl(false, true);
236         
237         // make sure an item is available
238         shiftReport(true, false);
239         StateWireState myState=getMyStateWire();
240         fatal(myState==StateWireState.EMPTY, "drain: fill stage empty");
241
242         shiftData(true, false);
243         BitVector ans = getDatTokAdr();
244
245         idle();                                 // block = 1
246         shiftControl(false, true);
247         clear();                                // clear = 1
248         shiftControl(false, true);
249         idle();                                 // clear = 0
250         shiftControl(false, true);
251         stop();                                 // block = 0
252         shiftControl(false, true);
253
254         if (traceDrain) prln("drainStopper data: "+MarinaUtils.formatDataTokAddr(ans));
255         return ans;
256     }
257     /** Remove as many items as possible from the fill stage.
258      * drainStopperMany() will stop cleanly.
259      * exit state: stop */
260     public List<BitVector> drainMany() {
261         return drainMany(Integer.MAX_VALUE);
262     }
263
264     /** Remove up to maxNbItems items from the fill stage.
265      * drainStopperMany() will stop cleanly.
266      * exit state: stop */
267     public List<BitVector> drainMany(int maxNbItems) {
268         prln("begin drainStopperMany");
269         adjustIndent(2);
270         
271         List<BitVector> ans = new ArrayList<BitVector>();
272         
273         int cnt = 0;
274         while (true) {
275                 shiftReport(true, false);
276                 StateWireState myState=getMyStateWire();
277
278                 // debugging
279                 if (traceDrain) prln(getReportString());
280
281                 if (myState==StateWireState.EMPTY || cnt>maxNbItems) break;
282                 
283                 if (traceDrain) prln("drainStopperMany: reading word number: "+cnt++);
284                 
285                 BitVector d = drain();
286
287                 ans.add(d);
288         }
289         
290         adjustIndent(-2);
291         prln("end drainStopperMany, got "+ans.size()+" entries");
292         
293         return ans;
294     }
295
296
297
298 }