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.*;
9 public class Marina extends FleetTwoFleet {
11 MarinaShip fakeShip = new MarinaShip(this);
12 MarinaDock onlyDock = new MarinaDock(fakeShip, true);
14 public BitVector encodeInstruction(Dock dispatchFrom, Instruction instruction) {
15 return encodeInstruction(instruction, dispatchFrom);
18 public Iterator<Ship> iterator() {
19 HashSet hs = new HashSet<Ship>();
24 public Ship getShip(String type, int ordinal) {
25 throw new RuntimeException("not implemented");
28 public FleetProcess run(Instruction[] instructions) {
29 throw new RuntimeException("not implemented");
32 public BitVector getDestAddr(Path path) {
33 if (path==null) return new BitVector(0);
34 return ((MarinaPath)path).bv;
37 public Dock getOnlyDock() {
41 ////////////////////////////////////////////////////////////////////////////////
45 private final Indenter indenter;
47 public final ChainControl controlChain;
48 public final ChainControl dataChain;
49 public final ChainControl dukeChain;
50 public final ChainControl reportChain;
52 private final ChipModel model;
53 public final ProperStopper northRing;
54 public final InstructionStopper southRing;
58 public Marina(ChainControl controlChain,
59 ChainControl dataChain,
60 ChainControl dukeChain,
61 ChainControl reportChain,
65 // use "internal encoding"
68 this.controlChain = controlChain;
69 this.dataChain = dataChain;
70 this.dukeChain = dukeChain;
71 this.reportChain = reportChain;
73 this.indenter = indenter;
74 northRing = new ProperStopper(prefix+"northFif@1.fillDrai@1",
81 prefix+"northFif@1.fillDrai@1.instruct@0.cntScnTh@1.cntScnOn@1");
82 southRing = new InstructionStopper(prefix+"southFif@1.tapPropS@1",
89 prefix+"southFif@1.tapPropS@1.instruct@0.cntScnTh@1.cntScnOn@1");
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;
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";
106 public static String prefix = "marinaGu@0.outDockW@"+(kesselsCounter?"3":"0")+".marinaOu@"+(kesselsCounter?"1":"0")+".";
107 public static String MASTER_CLEAR = "mc";
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";
121 // ILC appears in scan chain as "count[1:6], zLo, i, dLo"
123 // value is bit reversed and complemented
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));
134 value = (int)ret.toLong();
136 /** Get the inner loop counter done bit. */
137 public boolean getDone() {
138 return (value & 0x40) != 0;
140 /** Get the inner loop counter infinity bit */
141 public boolean getInfinity() {
142 return (value & 0x80) != 0;
144 /** Get the 6 bits of count of the inner loop counter */
145 public int getCount() {
148 public String toString() {
149 return "[ilc, count="+getCount()+", infinity="+getInfinity()+", done="+getDone()+"]";
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);
162 public void startCounters() { startCounters(true, true); }
163 public void startCounters(boolean south, boolean north) {
164 southRing.setCounterEnable(south);
165 northRing.setCounterEnable(north);
167 public int getNorthCount() { return northCount; }
168 public int getSouthCount() { return southCount; }
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) {
178 VerilogModel vm = (VerilogModel)model;
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
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);
189 vm.setNodeState(CENTER_PATH+".flag_D__set_", 1);
190 vm.setNodeState(CENTER_PATH+".flag_D__clr_", 0);
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
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);
200 // force the OLC to zero
202 for(int i=1; i<=6; i++)
203 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]", (i==1)?0:1);
205 // set the ILC input to 1
206 for(int i=1; i<=8; i++) {
208 vm.setNodeState(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"]", (i==1)?0:1);
211 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 1);
213 vm.setNodeState(prefix+"northFif@1.upDown8w@2.weakStag@22.addr1in2@0.fire", 0);
216 vm.setNodeState(MASTER_CLEAR, 1);
218 vm.setNodeState(MASTER_CLEAR, 0);
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);
226 vm.setNodeState(CENTER_PATH+".olcWcont@0.olc@0.olc_load_", 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_");
233 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.olc_load_");
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_");
240 vm.releaseNode(CENTER_PATH+".flag_D__set_");
241 vm.releaseNode(CENTER_PATH+".flag_D__clr_");
243 vm.releaseNode(CENTER_PATH+".flags@0.aFlag@0.net_50");
244 vm.releaseNode(CENTER_PATH+".flags@0.aFlag@1.net_50");
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
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");
255 for(int i=1; i<=8; i++) {
257 vm.releaseNode(CENTER_PATH+".ilcMoveO@0.ilc@0.\\inLO["+i+"] ");
262 for(int i=1; i<=6; i++)
263 vm.releaseNode(CENTER_PATH+".olcWcont@0.olc@0.inLO["+i+"]");
265 // the proper stopper states come up in an undefined ("X")
266 // state, so under Verilog we need to force them to a
272 } else if (model instanceof NanosimModel) {
273 NanosimModel nModel = (NanosimModel) model;
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);
284 nModel.setNodeVoltage(MASTER_CLEAR,1.0);
285 nModel.waitNS(WIDTH);
286 nModel.setNodeVoltage(MASTER_CLEAR,0.0);
290 mc0.setLogicState(true);
291 mc1.setLogicState(true);
293 mc0.setLogicState(false);
294 mc1.setLogicState(false);
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();
315 /** Get the 6 bit outer loop counter. */
316 public int getOLC() {
317 reportChain.shift(REPORT_CHAIN, true, false);
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);
325 System.out.print(" kesselsCounter = ");
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) {
334 System.out.print("2");
336 } else if (!zeroOrTwo && !zeroOrDone) {
338 System.out.print("1");
340 } else if ( zeroOrTwo && zeroOrDone) {
341 System.out.print("0");
344 } else if (!zeroOrTwo && zeroOrDone) {
345 System.out.print("_");
346 if (!done) bad = true;
348 // FIXME: check for unreduced counter and warn about it
350 if (bad) System.out.print(" WARNING: UNREDUCED COUNTER VALUE!!!!!!");
351 System.out.println();
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);
360 //System.out.println("kesselsCounter = " + bits);
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;
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"
378 latched = (bits.get(4+i*3+1) ? "0" : "1") + latched;
380 System.out.println("kesselsCounter: "+
383 " latched="+latched +
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")+
391 return (first+second);
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();
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));
402 return (int)bv.toLong();
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);
412 public boolean getFlagB() {
413 reportChain.shift(REPORT_CHAIN, true, false);
414 return reportChain.getOutBits(REPORT_CHAIN+"."+FLAGS_PATH).get(1);
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");
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");
434 sz = bv.getNumBits();
437 for (int i=0; i<sz; i++) if (bv.get(i)) nbTok++;