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;
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;
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 = data = new ProperStopper(prefix+"northFif@1.fillDrai@1",
43 prefix+"northFif@1.fillDrai@1.instruct@0.cntScnTh@1.cntScnOn@1");
44 southRing = instrIn = 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 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));
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 /** Shift the report scan chain */
116 public void shiftReport(boolean readEnable, boolean writeEnable) {
117 reportChain.shift(REPORT_CHAIN, readEnable, writeEnable);
120 /** Shift the report scan chain */
121 private void shiftControl(boolean readEnable, boolean writeEnable) {
122 controlChain.shift(CONTROL_CHAIN, readEnable, writeEnable);
125 /** Shift the data scan chain */
126 private void shiftData(boolean readEnable, boolean writeEnable) {
127 dataChain.shift(DATA_CHAIN, readEnable, writeEnable);
130 /** Shift the data scan chain */
131 public void shiftDuke(boolean readEnable, boolean writeEnable) {
132 dukeChain.shift(DUKE_CHAIN, readEnable, writeEnable);
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);
144 public void startCounters() { startCounters(true, true); }
145 public void startCounters(boolean south, boolean north) {
146 instrIn.setCounterEnable(south);
147 data.setCounterEnable(north);
149 public int getNorthCount() { return northCount; }
150 public int getSouthCount() { return southCount; }
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) {
160 VerilogModel vm = (VerilogModel)model;
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
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);
171 vm.setNodeState(CENTER_PATH+".flag_D__set_", 1);
172 vm.setNodeState(CENTER_PATH+".flag_D__clr_", 0);
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
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);
182 // force the OLC to zero
184 for(int i=1; i<=6; i++)
185 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
187 // set the ILC input to 1
188 for(int i=1; i<=8; i++) {
190 vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
193 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 1);
195 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 0);
198 vm.setNodeState(MASTER_CLEAR, 1);
200 vm.setNodeState(MASTER_CLEAR, 0);
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);
208 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.olc_load_", 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_");
215 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.olc_load_");
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_");
222 vm.releaseNode(CENTER_PATH+".flag_D__set_");
223 vm.releaseNode(CENTER_PATH+".flag_D__clr_");
225 vm.releaseNode(CENTER_PATH+".flags@0.aFlag@0.net_50");
226 vm.releaseNode(CENTER_PATH+".flags@0.aFlag@1.net_50");
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
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");
237 for(int i=1; i<=8; i++) {
239 vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
244 for(int i=1; i<=6; i++)
245 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]");
247 // the proper stopper states come up in an undefined ("X")
248 // state, so under Verilog we need to force them to a
254 } else if (model instanceof NanosimModel) {
255 NanosimModel nModel = (NanosimModel) model;
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);
266 nModel.setNodeVoltage(MASTER_CLEAR,1.0);
267 nModel.waitNS(WIDTH);
268 nModel.setNodeVoltage(MASTER_CLEAR,0.0);
272 mc0.setLogicState(true);
273 mc1.setLogicState(true);
275 mc0.setLogicState(false);
276 mc1.setLogicState(false);
280 resetAfterMasterClear();
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();
293 // For reset, I want to clear all the stoppers simultaneously
302 data.resetAfterMasterClear();
303 //tokOut.resetAfterMasterClear();
304 instrIn.resetAfterMasterClear();
308 /** Get the 6 bit outer loop counter. */
309 public int getOLC() {
310 shiftReport(true, false);
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);
318 System.out.print(" kesselsCounter = ");
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) {
327 System.out.print("2");
329 } else if (!zeroOrTwo && !zeroOrDone) {
331 System.out.print("1");
333 } else if ( zeroOrTwo && zeroOrDone) {
334 System.out.print("0");
337 } else if (!zeroOrTwo && zeroOrDone) {
338 System.out.print("_");
339 if (!done) bad = true;
341 // FIXME: check for unreduced counter and warn about it
343 if (bad) System.out.print(" WARNING: UNREDUCED COUNTER VALUE!!!!!!");
344 System.out.println();
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);
353 //System.out.println("kesselsCounter = " + bits);
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;
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"
371 latched = (bits.get(4+i*3+1) ? "0" : "1") + latched;
373 System.out.println("kesselsCounter: "+
376 " latched="+latched +
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")+
384 return (first+second);
386 BitVector odd = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_ODD).bitReverse();
387 BitVector even = reportChain.getOutBits(REPORT_CHAIN+"."+OLC_PATH_EVEN).bitReverse();
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));
395 return (int)bv.toLong();
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);
405 public boolean getFlagB() {
406 shiftReport(true, false);
407 return reportChain.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(1);
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");
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");
427 sz = bv.getNumBits();
430 for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;