1 package edu.berkeley.fleet.interpreter;
3 import edu.berkeley.sbp.util.ANSI;
4 import edu.berkeley.fleet.two.*;
5 import edu.berkeley.fleet.api.*;
6 import edu.berkeley.fleet.api.Instruction;
7 import static edu.berkeley.fleet.api.Predicate.*;
8 import static edu.berkeley.fleet.two.FleetTwoFleet.SHIFT;
10 /** anything that has a source (instruction horn) address on the switch fabric */
11 class InterpreterDock extends FleetTwoDock {
13 // Dock State //////////////////////////////////////////////////////////////////////////////
15 public boolean flag_a = false;
16 public boolean flag_b = false;
17 public boolean flag_c = false;
20 public BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth());
21 public InterpreterPath pathLatch = null;
22 public InterpreterPath tapl = null;
23 public boolean hatchIsOpen = true;
24 private Instruction executing = null;
25 private Queue<Instruction> instructions = new LinkedList<Instruction>();
26 private Queue<Instruction> epilogue = new LinkedList<Instruction>();
27 private boolean dataReadyForShip = false;
28 private boolean readyForDataFromShip = true;
29 private long dataFromShip;
30 private boolean torpedoWaiting = false;
32 protected void reset() {
38 dataLatch = new BitVector(getShip().getFleet().getWordWidth());
44 dataReadyForShip = false;
45 readyForDataFromShip = true;
47 torpedoWaiting = false;
50 // Destinations //////////////////////////////////////////////////////////////////////////////
52 /** includes the epilogue fifo */
53 public InterpreterDestination instructionDestination = new InterpreterDestination(this, true);
54 public InterpreterDestination dataDestination = new InterpreterDestination(this, false);
56 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
60 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
61 public Destination getInstructionDestination() { return instructionDestination; }
62 public Destination getDataDestination() { return dataDestination; }
63 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
64 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
66 // interface to subclass ///////////////////////////////////////////////////////////////////////
68 /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
70 public boolean dataReadyForShip() { return dataReadyForShip; }
71 public final boolean readyForDataFromShip() { return readyForDataFromShip; }
73 public long removeDataForShip() {
74 long val = peekDataForShip();
75 dataReadyForShip = false;
78 public long peekDataForShip() {
79 if (!dataReadyForShip) throw new RuntimeException();
80 BitVector bv = dataLatch;
82 for(int i=0; i<bv.length(); i++)
87 public void addDataFromShip(long data) {
88 if (!readyForDataFromShip()) throw new RuntimeException();
89 readyForDataFromShip = false;
93 protected final void service() {
95 if (instructionDestination.packets.size() > 0) {
96 Packet p = instructionDestination.packets.remove();
98 if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
99 torpedoWaiting = true;
101 BitVector bv = p.value;
103 for(int i=0; i<bv.length(); i++)
106 epilogue.add(getInterpreter().readInstruction(val, this));
110 if (hatchIsOpen && epilogue.size() > 0) {
111 Instruction inst = epilogue.remove();
112 if (inst instanceof Instruction.Tail)
115 instructions.add(inst);
118 if (dataReadyForShip) return;
120 if (executing==null && instructions.size() > 0) executing = instructions.remove();
121 if (executing==null) return;
123 if (executing.looping && hatchIsOpen && olc>0) return;
125 boolean enabled = true;
126 switch(executing.predicate) {
127 case IgnoreOLC: enabled = true; break;
128 case Default: enabled = olc>0; break;
129 case FlagA: enabled = flag_a; break;
130 case FlagB: enabled = flag_b; break;
131 case FlagC: enabled = flag_c; break;
132 case NotFlagA: enabled = !flag_a; break;
133 case NotFlagB: enabled = !flag_b; break;
134 case NotFlagC: enabled = !flag_c; break;
135 default: throw new RuntimeException();
138 if (executing.looping && olc>0)
139 instructions.add(executing);
144 if (executing instanceof Instruction.Move) {
145 Instruction.Move move = (Instruction.Move)executing;
147 if (move.interruptible && torpedoWaiting) {
148 torpedoWaiting = false;
153 new Packet(tapl, new BitVector(getInterpreter().getWordWidth()), true).send();
158 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
159 if (move.dataIn && isInputDock() && dataDestination.packets.size()==0) return;
160 if (move.tokenIn && dataDestination.packets.size()==0) return;
163 if (executing.looping && olc>0)
164 instructions.add(executing);
166 if (executing instanceof Instruction.Shift) {
167 Instruction.Shift shift = (Instruction.Shift)executing;
168 for(int i=dataLatch.length()-1; i>=SHIFT.valmaskwidth; i--)
169 dataLatch.set(i, dataLatch.get(i-SHIFT.valmaskwidth));
170 for(int i=SHIFT.valmaskwidth-1; i>=0; i--)
171 dataLatch.set(i, shift.immediate.get(i));
176 if (executing instanceof Instruction.Set) {
177 Instruction.Set set = (Instruction.Set)executing;
180 dataLatch = new BitVector(getInterpreter().getWordWidth()).setAndSignExtend(set.immediate);
182 case InnerLoopCounter:
189 for(int i=0; i<FleetTwoFleet.SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
190 if (dataLatch.get(i))
194 ilc = (int)set.immediate;
197 throw new RuntimeException("FIXME!");
200 case OuterLoopCounter:
203 olc = Math.max(0,olc-1);
204 if (olc==0) hatchIsOpen = true;
208 for(int i=0; i<FleetTwoFleet.SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
209 if (dataLatch.get(i))
211 if (olc==0) hatchIsOpen = true;
214 olc = (int)set.immediate;
215 if (olc==0) hatchIsOpen = true;
218 throw new RuntimeException("FIXME!");
223 boolean new_flag_a = false;
224 boolean new_flag_b = false;
225 for(Predicate p : set.newFlagA)
227 case FlagA: new_flag_a |= flag_a; break;
228 case FlagB: new_flag_a |= flag_b; break;
229 case FlagC: new_flag_a |= flag_c; break;
230 case NotFlagA: new_flag_a |= !flag_a; break;
231 case NotFlagB: new_flag_a |= !flag_b; break;
232 case NotFlagC: new_flag_a |= !flag_c; break;
234 for(Predicate p : set.newFlagB)
236 case FlagA: new_flag_b |= flag_a; break;
237 case FlagB: new_flag_b |= flag_b; break;
238 case FlagC: new_flag_b |= flag_c; break;
239 case NotFlagA: new_flag_b |= !flag_a; break;
240 case NotFlagB: new_flag_b |= !flag_b; break;
241 case NotFlagC: new_flag_b |= !flag_c; break;
248 throw new RuntimeException("FIXME!");
254 Instruction.Move move = (Instruction.Move)executing;
256 // if ILC==0, don't even bother
257 if (ilc==0) { ilc = 1; executing = null; return; }
260 else if (ilc==1) executing = null;
265 p = dataDestination.packets.remove();
266 if (p.path.signal != null) flag_c = p.path.signal.get(0);
271 p = dataDestination.packets.remove();
272 bv = new BitVector(p.value);
273 if (p.path.signal != null) flag_c = p.path.signal.get(0);
275 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
276 readyForDataFromShip = true;
278 if (move.latchData) dataLatch = bv;
280 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, FleetTwoFleet.DISPATCH_PATH.getval(bv));
281 // FIXME: c-flag at output docks
284 if (move.path != null) pathLatch = (InterpreterPath)move.path;
286 if (move.dataOut && isInputDock()) dataReadyForShip = true;
287 if (move.dataOut && !isInputDock())
288 new Packet(pathLatch, new BitVector(dataLatch), true).send();
290 new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();