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