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;
6 public class Marina extends MarinaFleet {
10 private final Indenter indenter;
12 public final ChainControl controlChain;
13 public final ChainControl dataChain;
14 public final ChainControl dukeChain;
15 public final ChainControl reportChain;
17 private final ChipModel model;
18 public final ProperStopper northRing;
19 public final InstructionStopper southRing;
23 public Marina(ChainControl controlChain,
24 ChainControl dataChain,
25 ChainControl dukeChain,
26 ChainControl reportChain,
30 this.controlChain = controlChain;
31 this.dataChain = dataChain;
32 this.dukeChain = dukeChain;
33 this.reportChain = reportChain;
35 this.indenter = indenter;
36 northRing = new ProperStopper(prefix+"northFif@1.fillDrai@1",
43 prefix+"northFif@1.fillDrai@1.instruct@0.cntScnTh@1.cntScnOn@1");
44 southRing = new InstructionStopper(prefix+"southFif@1.tapPropS@1",
51 prefix+"southFif@1.tapPropS@1.instruct@0.cntScnTh@1.cntScnOn@1");
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;
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";
68 public static String prefix = "marinaGu@0.outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@"+(kesselsCounter?"1":"0")+".";
69 public static String MASTER_CLEAR = "mc";
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";
83 // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
85 // value is bit reversed and complemented
88 reportChain.shift(REPORT_CHAIN, 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));
96 value = (int)ret.toLong();
98 /** Get the inner loop counter done bit. */
99 public boolean getDone() {
100 return (value & 0x40) != 0;
102 /** Get the inner loop counter infinity bit */
103 public boolean getInfinity() {
104 return (value & 0x80) != 0;
106 /** Get the 6 bits of count of the inner loop counter */
107 public int getCount() {
110 public String toString() {
111 return "[ilc, count="+getCount()+", infinity="+getInfinity()+", done="+getDone()+"]";
115 public void stopAndResetCounters() {
116 southRing.setCounterEnable(false);
117 northRing.setCounterEnable(false);
118 dataChain.shift(DATA_CHAIN, true, false);
119 northCount = northRing.getCounterValue();
120 southCount = southRing.getCounterValue();
121 northRing.setCounterValue(0);
122 southRing.setCounterValue(0);
124 public void startCounters() { startCounters(true, true); }
125 public void startCounters(boolean south, boolean north) {
126 southRing.setCounterEnable(south);
127 northRing.setCounterEnable(north);
129 public int getNorthCount() { return northCount; }
130 public int getSouthCount() { return southCount; }
132 public void masterClear() {
133 final double WIDTH = 10; // ns
134 // Put a high going pulse on the internal chip master clear signal
135 if (model instanceof VerilogModel) {
140 VerilogModel vm = (VerilogModel)model;
142 // In real life the flags come up with some undefined
143 // value. In verilog we need to prevent the X'es from
144 // propagating, so we force the flags to a known value
146 vm.setNodeState(CENTER_PATH+".flag_A__set_", 0);
147 vm.setNodeState(CENTER_PATH+".flag_A__clr_", 1);
148 vm.setNodeState(CENTER_PATH+".flag_B__set_", 0);
149 vm.setNodeState(CENTER_PATH+".flag_B__clr_", 1);
151 vm.setNodeState(CENTER_PATH+".flag_D__set_", 1);
152 vm.setNodeState(CENTER_PATH+".flag_D__clr_", 0);
154 vm.setNodeState(CENTER_PATH+".flags@0.aFlag@0.net_50", 0); // A
155 vm.setNodeState(CENTER_PATH+".flags@0.aFlag@1.net_50", 0); // B
156 vm.setNodeState(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_", 0); // C
158 // possible C-flag inputs
159 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]", 0);
160 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]", 0);
162 // force the OLC to zero
164 for(int i=1; i<=6; i++)
165 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
167 // set the ILC input to 1
168 for(int i=1; i<=8; i++) {
170 vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
173 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 1);
175 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 0);
178 vm.setNodeState(MASTER_CLEAR, 1);
180 vm.setNodeState(MASTER_CLEAR, 0);
183 // pulse ilc[load] and olc[load]
184 vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_load_", 1);
185 vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_decLO_", 1);
186 vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_torpLO_", 1);
188 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.olc_load_", 1);
191 vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_load_");
192 vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_decLO_");
193 vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.ilc_torpLO_");
195 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.olc_load_");
197 vm.releaseNode(CENTER_PATH+".flag_A__set_");
198 vm.releaseNode(CENTER_PATH+".flag_A__clr_");
199 vm.releaseNode(CENTER_PATH+".flag_B__set_");
200 vm.releaseNode(CENTER_PATH+".flag_B__clr_");
202 vm.releaseNode(CENTER_PATH+".flag_D__set_");
203 vm.releaseNode(CENTER_PATH+".flag_D__clr_");
205 vm.releaseNode(CENTER_PATH+".flags@0.aFlag@0.net_50");
206 vm.releaseNode(CENTER_PATH+".flags@0.aFlag@1.net_50");
208 // Every move instruction, even those with Ti=0,Di=0,
209 // loads the C-flag. It will get loaded with an "X",
210 // which will then leak into the flags and from there the
212 vm.releaseNode(prefix+"outputDo@0.outM1Pre@0.litDandP@0.latch2in@0.hi2inLat@0.latchKee@0.out_B_");
213 vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ONE+1)+"]");
214 vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.ain["+(INDEX_OF_ADDRESS_BIT_COPIED_TO_C_FLAG_WHEN_DC_EQUALS_ZERO+1)+"]");
215 vm.releaseNode(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire");
217 for(int i=1; i<=8; i++) {
219 vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
224 for(int i=1; i<=6; i++)
225 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]");
227 // the proper stopper states come up in an undefined ("X")
228 // state, so under Verilog we need to force them to a
234 } else if (model instanceof NanosimModel) {
235 NanosimModel nModel = (NanosimModel) model;
237 nModel.setNodeVoltage(prefix+"sid[9]",1.0);
238 nModel.setNodeVoltage(prefix+"sic[9]",1.0);
239 nModel.setNodeVoltage(prefix+"sir[9]",1.0);
240 nModel.waitNS(WIDTH);
241 nModel.setNodeVoltage(prefix+"sid[9]",0.0);
242 nModel.setNodeVoltage(prefix+"sic[9]",0.0);
243 nModel.setNodeVoltage(prefix+"sir[9]",0.0);
246 nModel.setNodeVoltage(MASTER_CLEAR,1.0);
247 nModel.waitNS(WIDTH);
248 nModel.setNodeVoltage(MASTER_CLEAR,0.0);
252 mc0.setLogicState(true);
253 mc1.setLogicState(true);
255 mc0.setLogicState(false);
256 mc1.setLogicState(false);
261 // The following call to ChainControl.resetInBits() is vital!
262 // If you forget, then the inBits member initializes
263 // with random northRing. Then when you do your first write,
264 // some bits are written randomly.
265 controlChain.resetInBits();
266 dataChain.resetInBits();
267 dukeChain.resetInBits();
268 reportChain.resetInBits();
277 /** Get the 6 bit outer loop counter. */
278 public int getOLC() {
279 reportChain.shift(REPORT_CHAIN, true, false);
281 BitVector bits = null;
282 for(int i=0; i<4; i++) {
283 BitVector x = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
284 //System.out.println("bits are: " + x);
285 bits = bits==null ? x : bits.cat(x);
287 System.out.print(" kesselsCounter = ");
291 for(int bit=5; bit>=0; bit--) {
292 boolean zeroOrTwo = bits.get(4+bit*3);
293 boolean zeroOrDone = bits.get(4+bit*3+1);
294 if ( zeroOrTwo && !zeroOrDone) {
296 System.out.print("2");
298 } else if (!zeroOrTwo && !zeroOrDone) {
300 System.out.print("1");
302 } else if ( zeroOrTwo && zeroOrDone) {
303 System.out.print("0");
306 } else if (!zeroOrTwo && zeroOrDone) {
307 System.out.print("_");
308 if (!done) bad = true;
310 // FIXME: check for unreduced counter and warn about it
312 if (bad) System.out.print(" WARNING: UNREDUCED COUNTER VALUE!!!!!!");
313 System.out.println();
315 } else if (kesselsCounter) {
316 BitVector bits = null;
317 for(int i=0; i<4; i++) {
318 BitVector x = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_KESSEL+i);
319 //System.out.println("bits are: " + x);
320 bits = bits==null ? x : bits.cat(x);
322 //System.out.println("kesselsCounter = " + bits);
329 for(int i=0; i<6; i++) {
330 first |= bits.get(4+i*3) ? (1<<i) : 0;
331 second |= bits.get(4+i*3+2) ? (1<<i) : 0;
332 hi = (bits.get(4+i*3) ? "1" : "0") + hi;
333 lo = (bits.get(4+i*3+2) ? "1" : "0") + lo;
335 ( bits.get(4+i*3) && !bits.get(4+i*3+2) ? "X"
336 : !bits.get(4+i*3) && !bits.get(4+i*3+2) ? "0"
337 : !bits.get(4+i*3) && bits.get(4+i*3+2) ? "1"
340 latched = (bits.get(4+i*3+1) ? "0" : "1") + latched;
342 System.out.println("kesselsCounter: "+
345 " latched="+latched +
347 " do[ins]="+(bits.get(0) ? "1" : "0")+
348 " dec="+(bits.get(1) ? "1" : "0")+
349 " flag[D][set]="+(bits.get(2) ? "1" : "0")+
350 " resetting="+(bits.get(3) ? "1" : "0")+
353 return (first+second);
355 BitVector odd = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse();
356 BitVector even = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_EVEN).bitReverse();
359 BitVector bv = new BitVector(6, "olc");
360 for(int i=0; i<3; i++) {
361 bv.set(i*2, odd.get(i));
362 bv.set(i*2+1, even.get(i));
364 return (int)bv.toLong();
367 public boolean getILCInfinity() { return new Ilc().getInfinity(); }
368 public boolean getILCDone() { return new Ilc().getDone(); }
369 public int getILC() { return new Ilc().getCount(); }
370 public boolean getFlagA() {
371 reportChain.shift(REPORT_CHAIN, true, false);
372 return reportChain.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(0);
374 public boolean getFlagB() {
375 reportChain.shift(REPORT_CHAIN, true, false);
376 return reportChain.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(1);
378 /** get the number of tokens in the token FIFO.
379 * This includes the Token successor wire, the token FIFO wires,
380 * and Token predecessor wire.
381 * Master clear clears the token FIFO. */
382 public int getNumTokens() {
383 reportChain.shift(REPORT_CHAIN, true, false);
384 // get the token successor and token FIFO wires
385 BitVector bv = reportChain.getOutBits(REPORT_CHAIN+"."+TOK_FIFO_PATH);
386 int sz = bv.getNumBits();
387 MarinaTest.fatal(sz!=3, "wrong token FIFO size: "+sz+" expected: 3");
389 // get the token predecessor wire
390 BitVector pred = reportChain.getOutBits(REPORT_CHAIN+"."+TOK_PRED_PATH);
391 sz = pred.getNumBits();
392 MarinaTest.fatal(sz!=1, "wrong token predecessor size: "+sz+" expected: 1");
396 sz = bv.getNumBits();
399 for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;