1 package edu.berkeley.fleet.two;
3 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.util.*;
5 import edu.berkeley.fleet.api.Instruction.Set;
6 import static edu.berkeley.fleet.api.Instruction.Set.*;
7 import static edu.berkeley.fleet.api.Instruction.*;
8 import static edu.berkeley.fleet.api.Predicate.*;
10 /** common subclass for the "FleetTwo" generation of processors, all 37-bit wide, with AM33 encoding */
11 public abstract class FleetTwoFleet extends Fleet {
13 public final Mask PACKET_TOKEN;
14 public final Mask PACKET_DATA;
15 public final Mask PACKET_SIGNAL;
16 public final Mask PACKET_DEST;
18 public final Mask CBD_SIZE;
19 public final Mask CBD_OFFSET;
21 public final Mask WHOLE_WORD;
22 public final Mask DISPATCH_PATH;
23 public final Mask DISPATCH_INSTR;
24 public final Mask NOT_INTERRUPTIBLE;
27 public final Mask P_NOT_A;
28 public final Mask P_A;
29 public final Mask P_NOT_B;
30 public final Mask P_B;
31 public final Mask P_UNUSED;
32 public final Mask P_OLC_ZERO;
33 public final Mask P_OLC_NONZERO;
34 public final Mask P_ALWAYS;
36 public final Mask SHIFT;
38 public final Mask TAIL;
40 public final Mask MOVE;
43 public final Mask FLUSH;
47 public final Mask PATH_IMMEDIATE;
48 public final Mask PATH_DATA;
49 public final Mask PATH_NOCHANGE;
51 public final Mask SET_OLC_FROM_IMMEDIATE;
52 public final Mask SET_OLC_FROM_DATA_LATCH;
53 public final Mask SET_OLC_FROM_OLC_MINUS_ONE;
55 public final Mask SET_ILC_FROM_IMMEDIATE;
56 public final Mask SET_ILC_FROM_INFINITY;
57 public final Mask SET_ILC_FROM_DATA_LATCH;
59 public final Mask SET_IMMEDIATE;
60 public final Mask SET_IMMEDIATE_EXTEND;
62 public final Mask SET_FLAGS;
63 public final Mask SET_FLAGS_A;
64 public final Mask SET_FLAGS_B;
65 public final Mask SET_FLAGS_VALUE_A;
66 public final Mask SET_FLAGS_VALUE_NOT_A;
67 public final Mask SET_FLAGS_VALUE_B;
68 public final Mask SET_FLAGS_VALUE_NOT_B;
69 public final Mask SET_FLAGS_VALUE_C;
70 public final Mask SET_FLAGS_VALUE_NOT_C;
72 public final int WIDTH_WORD;
73 public final int WIDTH_PACKET;
75 public final long DataLatch_WIDTH;
76 private final long mask;
78 public FleetTwoFleet() { this(false); }
80 public FleetTwoFleet(boolean useInternalEncoding) {
81 PACKET_TOKEN = new Mask("v.................................................");
82 PACKET_DATA = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
83 PACKET_SIGNAL = new Mask("......................................v...........");
84 PACKET_DEST = new Mask(".......................................vvvvvvvvvvv");
86 CBD_SIZE = new Mask("...............................vvvvvv");
87 CBD_OFFSET = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv......");
89 WHOLE_WORD = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
91 if (useInternalEncoding) {
93 DISPATCH_PATH = new Mask("v....................................");
94 DISPATCH_INSTR = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
95 NOT_INTERRUPTIBLE = new Mask(".................1...................");
96 OS = new Mask(".......1.............................");
97 P = new Mask(".vvvvvv..............................");
98 P_NOT_A = new Mask(".100001..............................");
99 P_A = new Mask(".100010..............................");
100 P_NOT_B = new Mask(".100100..............................");
101 P_B = new Mask(".101000..............................");
102 P_UNUSED = new Mask(".111111..............................");
103 P_OLC_ZERO = new Mask(".010000..............................");
104 P_OLC_NONZERO = new Mask(".100000..............................");
105 P_ALWAYS = new Mask(".000000..............................");
107 SHIFT = new Mask("..........101111.1vvvvvvvvvvvvvvvvvvv");
109 TAIL = new Mask("................1....................");
111 MOVE = new Mask("..........110111.....................");
112 TI = new Mask("..........110111..1..................");
113 DI = new Mask("..........110111...1.................");
114 FLUSH = new Mask("..........110111...01................");
115 DC = new Mask("..........110111...11................");
116 DO = new Mask("..........110111.....1...............");
117 TO = new Mask("..........110111......1..............");
118 PATH_IMMEDIATE = new Mask("..........110111.......0vvvvvvvvvvvvv");
119 PATH_DATA = new Mask("..........110111.......11............");
120 PATH_NOCHANGE = new Mask("..........110111.......10............");
122 SET_OLC_FROM_IMMEDIATE = new Mask("..........111101.0.............vvvvvv");
123 SET_OLC_FROM_DATA_LATCH = new Mask("..........111101.1...................");
124 SET_OLC_FROM_OLC_MINUS_ONE = new Mask("..........111011.....................");
126 SET_ILC_FROM_IMMEDIATE = new Mask("..........011111.0...........0.vvvvvv");
127 SET_ILC_FROM_INFINITY = new Mask("..........011111.............1.......");
128 SET_ILC_FROM_DATA_LATCH = new Mask("..........011111.1...................");
130 SET_IMMEDIATE = new Mask("..........101111.0.....vvvvvvvvvvvvvv");
131 SET_IMMEDIATE_EXTEND = new Mask("..........101111.0....v..............");
133 SET_FLAGS = new Mask("..........111110.....................");
134 SET_FLAGS_A = new Mask("..........111110.........vvvvvv......");
135 SET_FLAGS_B = new Mask("..........111110...............vvvvvv");
137 DISPATCH_PATH = new Mask("vvvvvvvvvvv..........................");
138 DISPATCH_INSTR = new Mask("...........vvvvvvvvvvvvvvvvvvvvvvvvvv");
139 NOT_INTERRUPTIBLE = new Mask("...........1.........................");
140 OS = new Mask("............1........................");
141 P = new Mask(".............vvv.....................");
142 P_NOT_A = new Mask(".............000.....................");
143 P_A = new Mask(".............001.....................");
144 P_NOT_B = new Mask(".............010.....................");
145 P_B = new Mask(".............011.....................");
146 P_UNUSED = new Mask(".............100.....................");
147 P_OLC_ZERO = new Mask(".............101.....................");
148 P_OLC_NONZERO = new Mask(".............110.....................");
149 P_ALWAYS = new Mask(".............111.....................");
151 SHIFT = new Mask("................00vvvvvvvvvvvvvvvvvvv");
153 TAIL = new Mask("................11...................");
155 MOVE = new Mask("................01...................");
156 TI = new Mask("................011..................");
157 DI = new Mask("................01.1.................");
158 FLUSH = new Mask("................01.01................");
159 DC = new Mask("................01.11................");
160 DO = new Mask("................01...1...............");
161 TO = new Mask("................01....1..............");
162 PATH_IMMEDIATE = new Mask("................01.....1vvvvvvvvvvvvv");
163 PATH_DATA = new Mask("................01.....01............");
164 PATH_NOCHANGE = new Mask("................01.....00............");
166 SET_OLC_FROM_IMMEDIATE = new Mask("................101000100......vvvvvv");
167 SET_OLC_FROM_DATA_LATCH = new Mask("................101000010............");
168 SET_OLC_FROM_OLC_MINUS_ONE = new Mask("................101000001............");
170 SET_ILC_FROM_IMMEDIATE = new Mask("................10010010......0vvvvvv");
171 SET_ILC_FROM_INFINITY = new Mask("................10010010......1......");
172 SET_ILC_FROM_DATA_LATCH = new Mask("................10010001.............");
174 SET_IMMEDIATE = new Mask("................100010.vvvvvvvvvvvvvv");
175 SET_IMMEDIATE_EXTEND = new Mask("................100010v..............");
177 SET_FLAGS = new Mask("................100001...............");
178 SET_FLAGS_A = new Mask("................100001...vvvvvv......");
179 SET_FLAGS_B = new Mask("................100001.........vvvvvv");
181 SET_FLAGS_VALUE_A = new Mask("1.....");
182 SET_FLAGS_VALUE_NOT_A = new Mask(".1....");
183 SET_FLAGS_VALUE_B = new Mask("..1...");
184 SET_FLAGS_VALUE_NOT_B = new Mask("...1..");
185 SET_FLAGS_VALUE_C = new Mask("....1.");
186 SET_FLAGS_VALUE_NOT_C = new Mask(".....1");
188 WIDTH_WORD = PACKET_DATA.valmaskwidth;
189 WIDTH_PACKET = PACKET_TOKEN.width;
190 DataLatch_WIDTH = SET_IMMEDIATE.valmaskmax-SET_IMMEDIATE.valmaskmin+1; // FIXME: this is an abstraction breakage
191 mask = ~(-1L << DataLatch_WIDTH);
194 // Misc //////////////////////////////////////////////////////////////////////////////
196 public boolean isSmallEnoughToFit(long immediate) {
197 if ((immediate & ~mask) == 0) return true;
198 if ((immediate | mask) == -1L) return true;
202 public int getWordWidth() { return 37; }
204 //////////////////////////////////////////////////////////////////////////////
206 /** get the bits describing this box's location on the DESTINATION HORN */
207 protected abstract BitVector getDestAddr(Path box);
209 private static final BitVector SIGNAL_ZERO = new BitVector(1);
210 private static final BitVector SIGNAL_ONE = new BitVector(1).set(0,true);
212 /** decode a path, given the starting point and the bits that comprise it */
213 public Path getPathByAddr(Dock source, BitVector dest) {
214 for(Ship ship : this)
215 for(Dock bb : ship) {
216 for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {
217 for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) {
218 Path p = (Path)source.getPath(d, signal);
219 if (getDestAddr(p).equals(dest)) return p;
226 public Instruction decodeInstruction(BitVector instruction, Dock dispatchFrom) {
227 return readInstruction(instruction.toLong(), dispatchFrom);
230 public BitVector encodeInstruction(Instruction instr, Dock dispatchFrom) {
231 return new BitVector(getWordWidth()).set(writeInstruction(instr, dispatchFrom));
234 public int getShiftWidth() { return SHIFT.valmaskwidth; }
235 public int getSetWidth() { return SET_IMMEDIATE.valmaskwidth+1; }
237 // FIXME: should use BitVector here
238 public Instruction readInstruction(long inst, Dock dispatchFrom) {
239 Dock dock = getPathByAddr(dispatchFrom, DISPATCH_PATH.getvalAsBitVector(inst)).getDestination().getDock();
241 if (TAIL.get(inst)) return new Tail(dock);
243 Predicate predicate = Default;
244 if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
245 if (P_OLC_NONZERO.get(inst)) predicate = Default;
246 if (P_OLC_ZERO.get(inst)) predicate = OLCZero;
247 if (P_A.get(inst)) predicate = FlagA;
248 if (P_B.get(inst)) predicate = FlagB;
249 if (P_NOT_A.get(inst)) predicate = NotFlagA;
250 if (P_NOT_B.get(inst)) predicate = NotFlagB;
252 boolean looping = !OS.get(inst);
254 return new Flush(dock, looping, predicate);
255 if (SHIFT.get(inst)) return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
256 if (SET_IMMEDIATE.get(inst)) {
257 boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
258 long immediate = SET_IMMEDIATE.getval(inst);
259 if (extend) immediate |= (-1L << DataLatch_WIDTH);
260 return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
263 if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
264 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
265 if (SET_OLC_FROM_IMMEDIATE.get(inst))
266 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
267 if (SET_ILC_FROM_IMMEDIATE.get(inst))
268 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
269 if (SET_OLC_FROM_DATA_LATCH.get(inst))
270 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
271 if (SET_ILC_FROM_DATA_LATCH.get(inst))
272 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
273 if (SET_ILC_FROM_INFINITY.get(inst))
274 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
275 if (SET_FLAGS.get(inst)) {
276 long flag_a = SET_FLAGS_A.getval(inst);
277 long flag_b = SET_FLAGS_B.getval(inst);
278 FlagFunction ap = FlagFunction.ZERO;
279 FlagFunction bp = FlagFunction.ZERO;
280 if (SET_FLAGS_VALUE_A .get(flag_a)) ap = ap.add(FlagA );
281 if (SET_FLAGS_VALUE_NOT_A.get(flag_a)) ap = ap.add(NotFlagA );
282 if (SET_FLAGS_VALUE_B .get(flag_a)) ap = ap.add(FlagB );
283 if (SET_FLAGS_VALUE_NOT_B.get(flag_a)) ap = ap.add(NotFlagB );
284 if (SET_FLAGS_VALUE_C .get(flag_a)) ap = ap.add(FlagC );
285 if (SET_FLAGS_VALUE_NOT_C.get(flag_a)) ap = ap.add(NotFlagC );
286 if (SET_FLAGS_VALUE_A .get(flag_b)) bp = bp.add(FlagA );
287 if (SET_FLAGS_VALUE_NOT_A.get(flag_b)) bp = bp.add(NotFlagA );
288 if (SET_FLAGS_VALUE_B .get(flag_b)) bp = bp.add(FlagB );
289 if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
290 if (SET_FLAGS_VALUE_C .get(flag_b)) bp = bp.add(FlagC );
291 if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
292 return new Set(dock, looping, predicate, ap, bp);
295 return new Move(dock,
298 !NOT_INTERRUPTIBLE.get(inst),
299 getPathByAddr(dock, PATH_IMMEDIATE.getvalAsBitVector(inst)),
307 throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
310 // FIXME: should use BitVector here
311 public long writeInstruction(Instruction d, Dock dispatchFrom) {
314 if (d.dock != null) {
315 BitVector bv = getDestAddr(dispatchFrom.getPath(d.dock.getInstructionDestination(),null));
316 BitVector bv2 = new BitVector(DISPATCH_PATH.valmaskwidth);
317 for(int i=0; i<Math.min(bv.length(),bv2.length()); i++)
318 bv2.set(i, bv.get(i));
319 instr = DISPATCH_PATH.setval(instr, bv2);
324 if (!pi.looping) instr = OS.set(instr);
325 switch(pi.predicate) {
326 case IgnoreOLC: instr = P_ALWAYS.set(instr); break;
327 case OLCZero: instr = P_OLC_ZERO.set(instr); break;
328 case Default: instr = P_OLC_NONZERO.set(instr); break;
329 case FlagA: instr = P_A.set(instr); break;
330 case FlagB: instr = P_B.set(instr); break;
331 case NotFlagA: instr = P_NOT_A.set(instr); break;
332 case NotFlagB: instr = P_NOT_B.set(instr); break;
333 default: throw new RuntimeException("error!");
336 if (d instanceof Tail) {
337 instr = TAIL.set(instr);
339 } else if (d instanceof Shift) {
340 Shift shift = (Shift)d;
341 instr = SHIFT.set(instr);
342 instr = SHIFT.setval(instr, shift.immediate);
344 } else if (d instanceof Flush) {
345 instr = FLUSH.set(instr);
347 } else if (d instanceof Set) {
350 case InnerLoopCounter:
353 instr = SET_ILC_FROM_DATA_LATCH.set(instr);
356 instr = SET_ILC_FROM_IMMEDIATE.setval(SET_ILC_FROM_IMMEDIATE.set(instr), s.immediate);
359 instr = SET_ILC_FROM_INFINITY.set(instr);
363 case OuterLoopCounter:
366 instr = SET_OLC_FROM_OLC_MINUS_ONE.set(instr);
369 instr = SET_OLC_FROM_DATA_LATCH.set(instr);
372 instr = SET_OLC_FROM_IMMEDIATE.setval(SET_OLC_FROM_IMMEDIATE.set(instr), s.immediate);
377 instr = SET_FLAGS.set(instr);
378 instr = SET_FLAGS_A.setval(instr, flagFunctionToLong(s.newFlagA));
379 instr = SET_FLAGS_B.setval(instr, flagFunctionToLong(s.newFlagB));
383 instr = SET_IMMEDIATE.set(instr);
384 instr = SET_IMMEDIATE_EXTEND.setval(instr, s.immediate < 0 ? 1 : 0);
385 instr = SET_IMMEDIATE.setval(instr, s.immediate & ~(-1L << DataLatch_WIDTH));
390 } else if (d instanceof Move) {
392 instr = MOVE.set(instr);
393 if (inst.tokenIn) instr = TI.set(instr);
394 if (inst.dataIn) instr = DI.set(instr);
395 if (inst.latchData) instr = DC.set(instr);
396 if (inst.dataOut) instr = DO.set(instr);
397 if (inst.tokenOut) instr = TO.set(instr);
398 if (!inst.interruptible) instr = NOT_INTERRUPTIBLE.set(instr);
400 if (inst.latchPath) instr = PATH_DATA.set(instr);
402 instr = PATH_IMMEDIATE.set(instr);
403 if (inst.path != null) {
404 BitVector bv = getDestAddr(inst.path);
405 BitVector bv2 = new BitVector(PATH_IMMEDIATE.valmaskwidth);
406 for(int i=0; i<Math.min(bv.length(),bv2.length()); i++)
407 bv2.set(i, bv.get(i));
408 instr = PATH_IMMEDIATE.setval(instr, bv2);
413 throw new RuntimeException("unrecognized instruction " + d.getClass().getName());
419 private long flagFunctionToLong(FlagFunction ff) {
421 for(Predicate p : ff)
423 case FlagA : ret = SET_FLAGS_VALUE_A .set(ret); break;
424 case NotFlagA : ret = SET_FLAGS_VALUE_NOT_A.set(ret); break;
425 case FlagB : ret = SET_FLAGS_VALUE_B .set(ret); break;
426 case NotFlagB : ret = SET_FLAGS_VALUE_NOT_B.set(ret); break;
427 case FlagC : ret = SET_FLAGS_VALUE_C .set(ret); break;
428 case NotFlagC : ret = SET_FLAGS_VALUE_NOT_C.set(ret); break;
429 default: throw new RuntimeException();