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 static final Mask PACKET_TOKEN = new Mask("v.................................................");
14 public static final Mask PACKET_DATA = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
15 public static final Mask PACKET_SIGNAL = new Mask("......................................v...........");
16 public static final Mask PACKET_DEST = new Mask(".......................................vvvvvvvvvvv");
18 public static final Mask CBD_SIZE = new Mask("...............................vvvvvv");
19 public static final Mask CBD_OFFSET = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv......");
21 public static final int WIDTH_WORD = PACKET_DATA.valmaskwidth;
22 public static final int WIDTH_PACKET = PACKET_TOKEN.width;
24 public static final Mask WHOLE_WORD = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
25 public static final Mask DISPATCH_PATH = new Mask("vvvvvvvvvvv..........................");
26 public static final Mask DISPATCH_INSTR = new Mask("...........vvvvvvvvvvvvvvvvvvvvvvvvvv");
27 public static final Mask I = new Mask("...........1.........................");
28 public static final Mask OS = new Mask("............1........................");
29 public static final Mask P = new Mask(".............vvv.....................");
30 public static final Mask P_NOT_A = new Mask(".............000.....................");
31 public static final Mask P_A = new Mask(".............001.....................");
32 public static final Mask P_NOT_B = new Mask(".............010.....................");
33 public static final Mask P_B = new Mask(".............011.....................");
34 public static final Mask P_UNUSED = new Mask(".............100.....................");
35 public static final Mask P_OLC_ZERO = new Mask(".............101.....................");
36 public static final Mask P_OLC_NONZERO = new Mask(".............110.....................");
37 public static final Mask P_ALWAYS = new Mask(".............111.....................");
39 public static final Mask SHIFT = new Mask("................00vvvvvvvvvvvvvvvvvvv");
41 public static final Mask TAIL = new Mask("................11...................");
43 public static final Mask MOVE = new Mask("................01...................");
44 public static final Mask TI = new Mask("................011..................");
45 public static final Mask DI = new Mask("................01.1.................");
46 public static final Mask FLUSH = new Mask("................01.01................");
47 public static final Mask DC = new Mask("................01.11................");
48 public static final Mask DO = new Mask("................01...1...............");
49 public static final Mask TO = new Mask("................01....1..............");
50 public static final Mask PATH_IMMEDIATE = new Mask("................01.....1vvvvvvvvvvvvv");
51 public static final Mask PATH_DATA = new Mask("................01.....01............");
52 public static final Mask PATH_NOCHANGE = new Mask("................01.....00............");
54 public static final Mask SET_OLC_FROM_IMMEDIATE = new Mask("................101000100......vvvvvv");
55 public static final Mask SET_OLC_FROM_DATA_LATCH = new Mask("................101000010............");
56 public static final Mask SET_OLC_FROM_OLC_MINUS_ONE = new Mask("................101000001............");
58 public static final Mask SET_ILC_FROM_IMMEDIATE = new Mask("................10010010......0vvvvvv");
59 public static final Mask SET_ILC_FROM_INFINITY = new Mask("................10010010......1......");
60 public static final Mask SET_ILC_FROM_DATA_LATCH = new Mask("................10010001.............");
62 public static final Mask SET_IMMEDIATE = new Mask("................100010.vvvvvvvvvvvvvv");
63 public static final Mask SET_IMMEDIATE_EXTEND = new Mask("................100010v..............");
65 public static final Mask SET_FLAGS = new Mask("................100001...............");
66 public static final Mask SET_FLAGS_A = new Mask("................100001...vvvvvv......");
67 public static final Mask SET_FLAGS_B = new Mask("................100001.........vvvvvv");
68 public static final Mask SET_FLAGS_VALUE_A = new Mask("1.....");
69 public static final Mask SET_FLAGS_VALUE_NOT_A = new Mask(".1....");
70 public static final Mask SET_FLAGS_VALUE_B = new Mask("..1...");
71 public static final Mask SET_FLAGS_VALUE_NOT_B = new Mask("...1..");
72 public static final Mask SET_FLAGS_VALUE_C = new Mask("....1.");
73 public static final Mask SET_FLAGS_VALUE_NOT_C = new Mask(".....1");
75 // Misc //////////////////////////////////////////////////////////////////////////////
77 public static final long DataLatch_WIDTH = SET_IMMEDIATE.valmaskmax-SET_IMMEDIATE.valmaskmin+1; // FIXME: this is an abstraction breakage
78 private static final long mask = ~(-1L << DataLatch_WIDTH);
79 public static boolean isSmallEnoughToFit(long immediate) {
80 if ((immediate & ~mask) == 0) return true;
81 if ((immediate | mask) == -1L) return true;
85 public int getWordWidth() { return 37; }
87 //////////////////////////////////////////////////////////////////////////////
89 /** get the bits describing this box's location on the DESTINATION HORN */
90 protected abstract BitVector getDestAddr(Path box);
92 private static final BitVector SIGNAL_ZERO = new BitVector(1);
93 private static final BitVector SIGNAL_ONE = new BitVector(1).set(0,true);
95 /** decode a path, given the starting point and the bits that comprise it */
96 public Path getPathByAddr(Dock source, BitVector dest) {
99 for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {
100 for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) {
101 Path p = (Path)source.getPath(d, signal);
102 if (getDestAddr(p).equals(dest)) return p;
109 public Instruction decodeInstruction(BitVector instruction, Dock dispatchFrom) {
110 return readInstruction(instruction.toLong(), dispatchFrom);
113 public BitVector encodeInstruction(Instruction instr, Dock dispatchFrom) {
114 return new BitVector(getWordWidth()).set(writeInstruction(instr, dispatchFrom));
117 public int getShiftWidth() { return SHIFT.valmaskwidth; }
118 public int getSetWidth() { return SET_IMMEDIATE.valmaskwidth+1; }
120 // FIXME: should use BitVector here
121 public Instruction readInstruction(long inst, Dock dispatchFrom) {
122 Dock dock = getPathByAddr(dispatchFrom, DISPATCH_PATH.getvalAsBitVector(inst)).getDestination().getDock();
124 if (TAIL.get(inst)) return new Tail(dock);
126 Predicate predicate = Default;
127 if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
128 if (P_OLC_NONZERO.get(inst)) predicate = Default;
129 if (P_OLC_ZERO.get(inst)) predicate = OLCZero;
130 if (P_A.get(inst)) predicate = FlagA;
131 if (P_B.get(inst)) predicate = FlagB;
132 if (P_NOT_A.get(inst)) predicate = NotFlagA;
133 if (P_NOT_B.get(inst)) predicate = NotFlagB;
135 boolean looping = !OS.get(inst);
137 return new Flush(dock, looping, predicate);
138 if (SHIFT.get(inst)) return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
139 if (SET_IMMEDIATE.get(inst)) {
140 boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
141 long immediate = SET_IMMEDIATE.getval(inst);
142 if (extend) immediate |= (-1L << DataLatch_WIDTH);
143 return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
146 if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
147 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
148 if (SET_OLC_FROM_IMMEDIATE.get(inst))
149 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
150 if (SET_ILC_FROM_IMMEDIATE.get(inst))
151 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
152 if (SET_OLC_FROM_DATA_LATCH.get(inst))
153 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
154 if (SET_ILC_FROM_DATA_LATCH.get(inst))
155 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
156 if (SET_ILC_FROM_INFINITY.get(inst))
157 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
158 if (SET_FLAGS.get(inst)) {
159 long flag_a = SET_FLAGS_A.getval(inst);
160 long flag_b = SET_FLAGS_B.getval(inst);
161 FlagFunction ap = FlagFunction.ZERO;
162 FlagFunction bp = FlagFunction.ZERO;
163 if (SET_FLAGS_VALUE_A .get(flag_a)) ap = ap.add(FlagA );
164 if (SET_FLAGS_VALUE_NOT_A.get(flag_a)) ap = ap.add(NotFlagA );
165 if (SET_FLAGS_VALUE_B .get(flag_a)) ap = ap.add(FlagB );
166 if (SET_FLAGS_VALUE_NOT_B.get(flag_a)) ap = ap.add(NotFlagB );
167 if (SET_FLAGS_VALUE_C .get(flag_a)) ap = ap.add(FlagC );
168 if (SET_FLAGS_VALUE_NOT_C.get(flag_a)) ap = ap.add(NotFlagC );
169 if (SET_FLAGS_VALUE_A .get(flag_b)) bp = bp.add(FlagA );
170 if (SET_FLAGS_VALUE_NOT_A.get(flag_b)) bp = bp.add(NotFlagA );
171 if (SET_FLAGS_VALUE_B .get(flag_b)) bp = bp.add(FlagB );
172 if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
173 if (SET_FLAGS_VALUE_C .get(flag_b)) bp = bp.add(FlagC );
174 if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
175 return new Set(dock, looping, predicate, ap, bp);
178 return new Move(dock,
182 getPathByAddr(dock, PATH_IMMEDIATE.getvalAsBitVector(inst)),
190 throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
193 public long writeInstruction(Instruction d, Dock dispatchFrom) {
196 if (d.dock != null) {
197 BitVector bv = getDestAddr(dispatchFrom.getPath(d.dock.getInstructionDestination(),null));
198 BitVector bv2 = new BitVector(DISPATCH_PATH.valmaskwidth);
199 for(int i=0; i<bv2.length(); i++)
200 bv2.set(i, bv.get(i));
201 instr = DISPATCH_PATH.setval(instr, bv2);
206 if (!pi.looping) instr = OS.set(instr);
207 switch(pi.predicate) {
208 case IgnoreOLC: instr = P_ALWAYS.set(instr); break;
209 case OLCZero: instr = P_OLC_ZERO.set(instr); break;
210 case Default: instr = P_OLC_NONZERO.set(instr); break;
211 case FlagA: instr = P_A.set(instr); break;
212 case FlagB: instr = P_B.set(instr); break;
213 case NotFlagA: instr = P_NOT_A.set(instr); break;
214 case NotFlagB: instr = P_NOT_B.set(instr); break;
215 default: throw new RuntimeException("error!");
218 if (d instanceof Tail) {
219 instr = TAIL.set(instr);
221 } else if (d instanceof Shift) {
222 Shift shift = (Shift)d;
223 instr = SHIFT.set(instr);
224 instr = SHIFT.setval(instr, shift.immediate);
226 } else if (d instanceof Flush) {
227 instr = FLUSH.set(instr);
229 } else if (d instanceof Set) {
232 case InnerLoopCounter:
235 instr = SET_ILC_FROM_DATA_LATCH.set(instr);
238 instr = SET_ILC_FROM_IMMEDIATE.setval(SET_ILC_FROM_IMMEDIATE.set(instr), s.immediate);
241 instr = SET_ILC_FROM_INFINITY.set(instr);
245 case OuterLoopCounter:
248 instr = SET_OLC_FROM_OLC_MINUS_ONE.set(instr);
251 instr = SET_OLC_FROM_DATA_LATCH.set(instr);
254 instr = SET_OLC_FROM_IMMEDIATE.setval(SET_OLC_FROM_IMMEDIATE.set(instr), s.immediate);
259 instr = SET_FLAGS.set(instr);
260 instr = SET_FLAGS_A.setval(instr, flagFunctionToLong(s.newFlagA));
261 instr = SET_FLAGS_B.setval(instr, flagFunctionToLong(s.newFlagB));
265 instr = SET_IMMEDIATE.set(instr);
266 instr = SET_IMMEDIATE_EXTEND.setval(instr, s.immediate < 0 ? 1 : 0);
267 instr = SET_IMMEDIATE.setval(instr, s.immediate & ~(-1L << DataLatch_WIDTH));
272 } else if (d instanceof Move) {
274 instr = MOVE.set(instr);
275 if (inst.tokenIn) instr = TI.set(instr);
276 if (inst.dataIn) instr = DI.set(instr);
277 if (inst.latchData) instr = DC.set(instr);
278 if (inst.dataOut) instr = DO.set(instr);
279 if (inst.tokenOut) instr = TO.set(instr);
280 if (inst.interruptible) instr = I.set(instr);
282 if (inst.latchPath) instr = PATH_DATA.set(instr);
284 instr = PATH_IMMEDIATE.set(instr);
285 if (inst.path != null) {
286 BitVector bv = getDestAddr(inst.path);
287 BitVector bv2 = new BitVector(PATH_IMMEDIATE.valmaskwidth);
288 for(int i=0; i<Math.min(bv.length(),bv2.length()); i++)
289 bv2.set(i, bv.get(i));
290 instr = PATH_IMMEDIATE.setval(instr, bv2);
295 throw new RuntimeException("unrecognized instruction " + d.getClass().getName());
301 private long flagFunctionToLong(FlagFunction ff) {
303 for(Predicate p : ff)
305 case FlagA : ret = SET_FLAGS_VALUE_A .set(ret); break;
306 case NotFlagA : ret = SET_FLAGS_VALUE_NOT_A.set(ret); break;
307 case FlagB : ret = SET_FLAGS_VALUE_B .set(ret); break;
308 case NotFlagB : ret = SET_FLAGS_VALUE_NOT_B.set(ret); break;
309 case FlagC : ret = SET_FLAGS_VALUE_C .set(ret); break;
310 case NotFlagC : ret = SET_FLAGS_VALUE_NOT_C.set(ret); break;
311 default: throw new RuntimeException();