6da458e0be5d767bef8f8f4aee87dde203130fd2
[fleet.git] / src / edu / berkeley / fleet / marina / Marina.java
1 package edu.berkeley.fleet.marina;
2 import edu.berkeley.fleet.api.*;
3 import com.sun.electric.tool.simulation.test.*;
4 import com.sun.electric.tool.simulation.test.BitVector;
5
6 public class Marina {
7
8     JtagLogicLevel mc0;
9     JtagLogicLevel mc1;
10     private final Indenter indenter;
11     public final ChainControl controlChain;
12     public final ChainControl dataChain;
13     public final ChainControl dukeChain;
14     public final ChainControl reportChain;
15     private final ChipModel model;
16     public final ProperStopper data;
17     public final InstructionStopper instrIn;
18     public final ProperStopper      northRing;
19     public final InstructionStopper southRing;
20     int northCount = 0;
21     int southCount = 0;
22
23     public Marina(ChainControl controlChain,
24                   ChainControl dataChain,
25                   ChainControl dukeChain,
26                   ChainControl reportChain,
27                   ChipModel model,
28                   boolean clockHack,
29                   Indenter indenter) {
30         this.controlChain = controlChain;
31         this.dataChain = dataChain;
32         this.dukeChain = dukeChain;
33         this.reportChain = reportChain;
34         this.model = model;
35         this.indenter = indenter;
36         northRing = data = new ProperStopper(prefix+"northFif@1.fillDrai@1",
37                                  controlChain,
38                                  dataChain,
39                                  reportChain,
40                                  model,
41                                  clockHack,
42                                  indenter,
43                                  prefix+"northFif@1.fillDrai@1.instruct@0.cntScnTh@1.cntScnOn@1");
44         southRing = instrIn = new InstructionStopper(prefix+"southFif@1.tapPropS@1", 
45                                          controlChain,
46                                          dataChain,
47                                          reportChain,
48                                          model,
49                                          clockHack,
50                                          indenter,
51                                          prefix+"southFif@1.tapPropS@1.instruct@0.cntScnTh@1.cntScnOn@1");
52     }
53
54     public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE  = 5;
55     public static final int INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO = MarinaPath.SIGNAL_BIT_INDEX;
56        
57     private static final int COUNTER_LENGTH = 34;
58     public static final int INSTRUCTION_LENGTH = 36;
59     public static final int SOUTH_RING_CAPACITY = 11;
60     public static final int TOKEN_FIFO_CAPACITY = 3;
61     public static final boolean kesselsCounter = false;
62     public static final boolean omegaCounter = false;
63     public static final String DATA_CHAIN =    kesselsCounter ? "marina.marina_data" : "marina.ivan_data";      
64     public static final String CONTROL_CHAIN = kesselsCounter ? "marina.marina_control" : "marina.ivan_control";
65     public static final String REPORT_CHAIN =  kesselsCounter ? "marina.marina_report" : "marina.ivan_report";
66     public static final String DUKE_CHAIN   = "marina.duke";
67
68     public static String prefix = "marinaGu@0.outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@"+(kesselsCounter?"1":"0")+".";
69     public static String MASTER_CLEAR = "mc";
70
71     private static final String CENTER_PATH = prefix+"outputDo@0.outM1Pre@0.outDockP@0.outDockC@0";
72     private static final String OLC_PATH_EVEN = CENTER_PATH+".olcWcont@0.scanEx3h@1"; // bits 2,4,6
73     private static final String OLC_PATH_ODD = CENTER_PATH+".olcWcont@0.scanEx3h@2"; // bits 1,3,5
74     private static final String OLC_PATH_KESSEL = CENTER_PATH+".counte@0.adamScan@1.scanEx6h@";
75     private static final String ILC_PATH_ODD = CENTER_PATH+".ilcMoveO@0.scanEx4h@0"; // bits 1,3,5,7
76     private static final String ILC_PATH_EVEN = CENTER_PATH+".ilcMoveO@0.scanEx4h@1"; // bits 2,4,6,8
77     private static final String FLAGS_PATH = CENTER_PATH+".flags@0.scanEx3h@0";
78     private static final String TOK_FIFO_PATH = prefix+"tokenFIF@1";
79     private static final String INSTRUCTION_COUNTER_PATH = prefix+"southFif@1.tapPropS@1.instruct@0";
80     private static final String DATA_COUNTER_PATH =prefix+"northFif@1.fillDrai@1.instruct@0";
81     private static final String TOK_PRED_PATH = CENTER_PATH+".ilcMoveO@0.scanEx2h@0.scanCell@10";
82         
83     // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
84     private class Ilc {
85         // value is bit reversed and complemented
86         private int value;
87         private Ilc() {
88             shiftReport(true, false);
89             BitVector odd  = reportChain.getOutBits(REPORT_CHAIN+"."+ILC_PATH_ODD).bitReverse().not();
90             BitVector even = reportChain.getOutBits(REPORT_CHAIN+"."+ILC_PATH_EVEN).bitReverse().not();
91             BitVector ret  = new BitVector(8, "olc");
92             for(int i=0; i<4; i++) {
93                 ret.set(i*2+1, odd.get(i));
94                 ret.set(i*2,   even.get(i));
95             }
96             value = (int)ret.toLong();
97         }
98         /** Get the inner loop counter done bit. */
99         public boolean getDone() {
100             return (value & 0x40) != 0;
101         }
102         /** Get the inner loop counter infinity bit */
103         public boolean getInfinity() {
104             return (value & 0x80) != 0;
105         }
106         /** Get the 6 bits of count of the inner loop counter */
107         public int getCount() {
108             return value & 0x3f;
109         }
110         public String toString() {
111             return "[ilc, count="+getCount()+", infinity="+getInfinity()+", done="+getDone()+"]";
112         }
113     }
114         
115     /** Shift the report scan chain */
116     public void shiftReport(boolean readEnable, boolean writeEnable) {
117         reportChain.shift(REPORT_CHAIN, readEnable, writeEnable);
118     }
119     
120     /** Shift the report scan chain */
121     private void shiftControl(boolean readEnable, boolean writeEnable) {
122         controlChain.shift(CONTROL_CHAIN, readEnable, writeEnable);
123     }
124         
125     /** Shift the data scan chain */
126     private void shiftData(boolean readEnable, boolean writeEnable) {
127         dataChain.shift(DATA_CHAIN, readEnable, writeEnable);
128     }
129
130     /** Shift the data scan chain */
131     public void shiftDuke(boolean readEnable, boolean writeEnable) {
132         dukeChain.shift(DUKE_CHAIN, readEnable, writeEnable);
133     }
134
135     public void stopAndResetCounters() {
136         instrIn.setCounterEnable(false);
137         data.setCounterEnable(false);
138         dataChain.shift(DATA_CHAIN, true, false);        
139         northCount = data.getCounterValue();
140         southCount = instrIn.getCounterValue();
141         data.setCounterValue(0);
142         instrIn.setCounterValue(0);
143     }
144     public void startCounters() { startCounters(true, true); }
145     public void startCounters(boolean south, boolean north) {
146         instrIn.setCounterEnable(south);
147         data.setCounterEnable(north);
148     }
149     public int getNorthCount() { return northCount; }
150     public int getSouthCount() { return southCount; }
151
152     public void masterClear() {
153         final double WIDTH = 10; // ns
154         // Put a high going pulse on the internal chip master clear signal
155         if (model instanceof VerilogModel) {
156
157             data.clear();
158             instrIn.clear();
159
160             VerilogModel vm = (VerilogModel)model;
161             //
162             // In real life the flags come up with some undefined
163             // value.  In verilog we need to prevent the X'es from
164             // propagating, so we force the flags to a known value
165             //
166             vm.setNodeState(CENTER_PATH+".flag_A__set_", 0);
167             vm.setNodeState(CENTER_PATH+".flag_A__clr_", 1);
168             vm.setNodeState(CENTER_PATH+".flag_B__set_", 0);
169             vm.setNodeState(CENTER_PATH+".flag_B__clr_", 1);
170
171             vm.setNodeState(CENTER_PATH+".flag_D__set_", 1);
172             vm.setNodeState(CENTER_PATH+".flag_D__clr_", 0);
173
174             vm.setNodeState(CENTER_PATH+".flags@0.aFlag@0.net_50", 0);       // A
175             vm.setNodeState(CENTER_PATH+".flags@0.aFlag@1.net_50", 0);       // B
176             vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_", 0); // C
177
178             // possible C-flag inputs
179             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]", 0);
180             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]", 0);
181
182             // force the OLC to zero
183             if (!kesselsCounter)
184                 for(int i=1; i<=6; i++)
185                     vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
186
187             // set the ILC input to 1
188             for(int i=1; i<=8; i++) {
189                 if (i!=7)
190                     vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
191             }
192
193             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 1);
194             model.waitNS(1000);
195             vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 0);
196             model.waitNS(1000);
197
198             vm.setNodeState(MASTER_CLEAR, 1);
199             model.waitNS(1000);
200             vm.setNodeState(MASTER_CLEAR, 0);
201             model.waitNS(1000);
202
203             // pulse ilc[load] and olc[load]
204             vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_load_", 1);
205             vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_decLO_", 1);
206             vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_torpLO_", 1);
207             if (!kesselsCounter)
208                 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.olc_load_", 1);
209             model.waitNS(100);
210             model.waitNS(1);
211             vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_load_");
212             vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_decLO_");
213             vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_torpLO_");
214             if (!kesselsCounter)
215                 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.olc_load_");
216
217             vm.releaseNode(CENTER_PATH+".flag_A__set_");
218             vm.releaseNode(CENTER_PATH+".flag_A__clr_");
219             vm.releaseNode(CENTER_PATH+".flag_B__set_");
220             vm.releaseNode(CENTER_PATH+".flag_B__clr_");
221
222             vm.releaseNode(CENTER_PATH+".flag_D__set_");
223             vm.releaseNode(CENTER_PATH+".flag_D__clr_");
224
225             vm.releaseNode(CENTER_PATH+".flags@0.aFlag@0.net_50");
226             vm.releaseNode(CENTER_PATH+".flags@0.aFlag@1.net_50");
227
228             // Every move instruction, even those with Ti=0,Di=0,
229             // loads the C-flag.  It will get loaded with an "X",
230             // which will then leak into the flags and from there the
231             // predicate.
232             vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_");
233             vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]");
234             vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]");
235             vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire");
236
237             for(int i=1; i<=8; i++) {
238                 if (i!=7)
239                     vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
240             }
241             model.waitNS(1000);
242
243             if (!kesselsCounter)
244                 for(int i=1; i<=6; i++)
245                     vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]");
246
247             // the proper stopper states come up in an undefined ("X")
248             // state, so under Verilog we need to force them to a
249             // known state
250
251             data.idle();
252             instrIn.idle();
253
254         } else if (model instanceof NanosimModel) {
255             NanosimModel nModel = (NanosimModel) model;
256             /*
257             nModel.setNodeVoltage(prefix+"sid[9]",1.0);
258             nModel.setNodeVoltage(prefix+"sic[9]",1.0);
259             nModel.setNodeVoltage(prefix+"sir[9]",1.0);
260             nModel.waitNS(WIDTH);
261             nModel.setNodeVoltage(prefix+"sid[9]",0.0);
262             nModel.setNodeVoltage(prefix+"sic[9]",0.0);
263             nModel.setNodeVoltage(prefix+"sir[9]",0.0);
264             nModel.waitNS(1);
265             */
266             nModel.setNodeVoltage(MASTER_CLEAR,1.0);
267             nModel.waitNS(WIDTH);
268             nModel.setNodeVoltage(MASTER_CLEAR,0.0);
269             nModel.waitNS(1);
270         } else {
271
272             mc0.setLogicState(true);
273             mc1.setLogicState(true);
274             model.waitNS(1000);
275             mc0.setLogicState(false);
276             mc1.setLogicState(false);
277             model.waitNS(1000);
278
279         }
280         resetAfterMasterClear();
281     }
282
283     private void resetAfterMasterClear() {
284         // The following call to ChainControl.resetInBits() is vital!
285         // If you forget, then the inBits member initializes 
286         // with random data. Then when you do your first write,
287         // some bits are written randomly.
288         dataChain.resetInBits();
289         dukeChain.resetInBits();
290         reportChain.resetInBits();
291         controlChain.resetInBits();
292
293         // For reset, I want to clear all the stoppers simultaneously
294         data.clear();
295         //tokOut.clear();
296         instrIn.clear();
297         
298         data.stop();
299         //tokOut.stop();
300         instrIn.stop();
301         
302         data.resetAfterMasterClear();
303         //tokOut.resetAfterMasterClear();
304         instrIn.resetAfterMasterClear();
305     }
306
307
308     /** Get the 6 bit outer loop counter. */
309     public int getOLC() {
310         shiftReport(true, false);
311         if (omegaCounter) {
312             BitVector bits = null;
313             for(int i=0; i<4; i++) {
314                 BitVector x = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
315                 //System.out.println("bits are: " + x);
316                 bits = bits==null ? x : bits.cat(x);
317             }
318             System.out.print("  kesselsCounter = ");
319             int ret = 0;
320             boolean done = true;
321             boolean bad = false;
322             for(int bit=5; bit>=0; bit--) {
323                 boolean zeroOrTwo  = bits.get(4+bit*3);
324                 boolean zeroOrDone = bits.get(4+bit*3+1);
325                 if      ( zeroOrTwo && !zeroOrDone) {
326                     ret += (2<<bit);
327                     System.out.print("2");
328                     done = false;
329                 } else if (!zeroOrTwo && !zeroOrDone) {
330                     ret += (1<<bit);
331                     System.out.print("1");
332                     done = false;
333                 } else if ( zeroOrTwo &&  zeroOrDone) {
334                     System.out.print("0");
335                     bad = true;
336                     done = false;
337                 } else if (!zeroOrTwo &&  zeroOrDone) {
338                     System.out.print("_");
339                     if (!done) bad = true;
340                 }
341                 // FIXME: check for unreduced counter and warn about it
342             }
343             if (bad) System.out.print("  WARNING: UNREDUCED COUNTER VALUE!!!!!!");
344             System.out.println();
345             return ret;
346         } else if (kesselsCounter) {
347             BitVector bits = null;
348             for(int i=0; i<4; i++) {
349                 BitVector x = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
350                 //System.out.println("bits are: " + x);
351                 bits = bits==null ? x : bits.cat(x);
352             }
353             //System.out.println("kesselsCounter = " + bits);
354             int first = 0;
355             int second = 0;
356             String hi="";
357             String lo="";
358             String latched="";
359             String res="";
360             for(int i=0; i<6; i++) {
361                 first  |= bits.get(4+i*3)   ? (1<<i) : 0;
362                 second |= bits.get(4+i*3+2) ? (1<<i) : 0;
363                 hi = (bits.get(4+i*3)   ? "1" : "0") + hi;
364                 lo = (bits.get(4+i*3+2)   ? "1" : "0") + lo;
365                 res =
366                     (   bits.get(4+i*3) && !bits.get(4+i*3+2) ? "X"
367                      : !bits.get(4+i*3) && !bits.get(4+i*3+2) ? "0"
368                      : !bits.get(4+i*3) &&  bits.get(4+i*3+2) ? "1"
369                      : "2")
370                     +res;
371                 latched = (bits.get(4+i*3+1)   ? "0" : "1") + latched;
372             }
373             System.out.println("kesselsCounter: "+
374                                "s[1]="+hi+
375                                " s[3]="+lo+
376                                " latched="+latched +
377                                " res="+res+
378                                " do[ins]="+(bits.get(0) ? "1" : "0")+
379                                " dec="+(bits.get(1) ? "1" : "0")+
380                                " flag[D][set]="+(bits.get(2) ? "1" : "0")+
381                                " resetting="+(bits.get(3) ? "1" : "0")+
382                                ""
383                                );
384             return (first+second);
385         } else {
386             BitVector odd = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse();
387             BitVector even = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_EVEN).bitReverse();
388             odd = odd.not();
389             even = even.not();
390             BitVector bv = new BitVector(6, "olc");
391             for(int i=0; i<3; i++) {
392                 bv.set(i*2,   odd.get(i));
393                 bv.set(i*2+1, even.get(i));
394             }
395             return (int)bv.toLong();
396         }
397     }
398     public boolean getILCInfinity() { return new Ilc().getInfinity(); }
399     public boolean getILCDone() { return new Ilc().getDone(); }
400     public int getILC() { return new Ilc().getCount(); }
401     public boolean getFlagA() {
402         shiftReport(true, false);
403         return reportChain.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(0);
404     }
405     public boolean getFlagB() {
406         shiftReport(true, false);
407         return reportChain.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(1);
408     }
409     /** get the number of tokens in the token FIFO.
410      * This includes the Token successor wire, the token FIFO wires,
411      * and Token predecessor wire.
412      * Master clear clears the token FIFO. */
413     public int getNumTokens() {
414         shiftReport(true, false);
415         // get the token successor and token FIFO wires
416         BitVector bv = reportChain.getOutBits(REPORT_CHAIN+"."+TOK_FIFO_PATH);
417         int sz = bv.getNumBits();
418         MarinaTest.fatal(sz!=3, "wrong token FIFO size: "+sz+" expected: 3");
419         
420         // get the token predecessor wire
421         BitVector pred = reportChain.getOutBits(REPORT_CHAIN+"."+TOK_PRED_PATH);
422         sz = pred.getNumBits();
423         MarinaTest.fatal(sz!=1, "wrong token predecessor size: "+sz+" expected: 1");
424
425         // concatenate them
426         bv = bv.cat(pred);
427         sz = bv.getNumBits();
428         
429         int nbTok = 0;
430         for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;
431         return nbTok;
432     }
433 }