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.*;
9 /** anything that has a source (instruction horn) address on the switch fabric */
10 class InterpreterDock extends FleetTwoDock {
12 // Dock State //////////////////////////////////////////////////////////////////////////////
14 public boolean flag_a = false;
15 public boolean flag_b = false;
16 public boolean flag_c = false;
19 public BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth());
20 public InterpreterPath pathLatch = null;
21 public InterpreterPath tapl = null;
22 public boolean hatchIsOpen = true;
23 private Instruction executing = null;
24 private Queue<Instruction> instructions = new LinkedList<Instruction>();
25 private Queue<Instruction> epilogue = new LinkedList<Instruction>();
26 private boolean dataReadyForShip = false;
27 private boolean readyForDataFromShip = true;
28 private long dataFromShip;
29 private boolean torpedoWaiting = false;
31 protected void reset() {
37 dataLatch = new BitVector(getShip().getFleet().getWordWidth());
43 dataReadyForShip = false;
44 readyForDataFromShip = true;
46 torpedoWaiting = false;
49 // Destinations //////////////////////////////////////////////////////////////////////////////
51 /** includes the epilogue fifo */
52 public InterpreterDestination instructionDestination = new InterpreterDestination(this, true);
53 public InterpreterDestination dataDestination = new InterpreterDestination(this, false);
55 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
59 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
60 public Destination getInstructionDestination() { return instructionDestination; }
61 public Destination getDataDestination() { return dataDestination; }
62 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
63 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
65 // interface to subclass ///////////////////////////////////////////////////////////////////////
67 /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
69 public boolean dataReadyForShip() { return dataReadyForShip; }
70 public final boolean readyForDataFromShip() { return readyForDataFromShip; }
72 public long removeDataForShip() {
73 long val = peekDataForShip();
74 dataReadyForShip = false;
77 public long peekDataForShip() {
78 if (!dataReadyForShip) throw new RuntimeException();
79 BitVector bv = dataLatch;
81 for(int i=0; i<bv.length(); i++)
86 public void addDataFromShip(long data) {
87 if (!readyForDataFromShip()) throw new RuntimeException();
88 readyForDataFromShip = false;
92 protected final void service() {
94 if (instructionDestination.packets.size() > 0) {
95 Packet p = instructionDestination.packets.remove();
97 if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
98 torpedoWaiting = true;
100 BitVector bv = p.value;
102 for(int i=0; i<bv.length(); i++)
105 epilogue.add(getInterpreter().readInstruction(val, this));
109 if (hatchIsOpen && epilogue.size() > 0) {
110 Instruction inst = epilogue.remove();
111 if (inst instanceof Instruction.Tail)
114 instructions.add(inst);
117 if (dataReadyForShip) return;
119 if (executing==null && instructions.size() > 0) {
120 executing = instructions.remove();
124 if (executing==null) return;
126 if (executing.looping && hatchIsOpen && olc>0) return;
128 boolean enabled = true;
129 switch(executing.predicate) {
130 case IgnoreOLC: enabled = true; break;
131 case Default: enabled = olc>0; break;
132 case FlagA: enabled = flag_a; break;
133 case FlagB: enabled = flag_b; break;
134 case FlagC: enabled = flag_c; break;
135 case NotFlagA: enabled = !flag_a; break;
136 case NotFlagB: enabled = !flag_b; break;
137 case NotFlagC: enabled = !flag_c; break;
138 default: throw new RuntimeException();
141 if (executing.looping && olc>0)
142 instructions.add(executing);
147 if (executing instanceof Instruction.Move) {
148 Instruction.Move move = (Instruction.Move)executing;
150 if (move.interruptible && torpedoWaiting) {
151 torpedoWaiting = false;
156 new Packet(tapl, new BitVector(getInterpreter().getWordWidth()), true).send();
161 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
162 if (move.dataIn && isInputDock() && dataDestination.packets.size()==0) return;
163 if (move.tokenIn && dataDestination.packets.size()==0) return;
166 if (executing.looping && olc>0)
167 instructions.add(executing);
169 if (executing instanceof Instruction.Shift) {
171 Instruction.Shift shift = (Instruction.Shift)executing;
172 for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--)
173 dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth()));
174 for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
175 dataLatch.set(i, shift.immediate.get(i));
179 throw new RuntimeException("FIXME");
182 if (executing instanceof Instruction.Set) {
183 Instruction.Set set = (Instruction.Set)executing;
186 dataLatch = new BitVector(getInterpreter().getWordWidth()).setAndSignExtend(set.immediate);
188 case InnerLoopCounter:
195 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
196 if (dataLatch.get(i))
200 ilc = (int)set.immediate;
203 throw new RuntimeException("FIXME!");
206 case OuterLoopCounter:
209 olc = Math.max(0,olc-1);
210 if (olc==0) hatchIsOpen = true;
214 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
215 if (dataLatch.get(i))
217 if (olc==0) hatchIsOpen = true;
220 olc = (int)set.immediate;
221 if (olc==0) hatchIsOpen = true;
224 throw new RuntimeException("FIXME!");
229 boolean new_flag_a = false;
230 boolean new_flag_b = false;
231 for(Predicate p : set.newFlagA)
233 case FlagA: new_flag_a |= flag_a; break;
234 case FlagB: new_flag_a |= flag_b; break;
235 case FlagC: new_flag_a |= flag_c; break;
236 case NotFlagA: new_flag_a |= !flag_a; break;
237 case NotFlagB: new_flag_a |= !flag_b; break;
238 case NotFlagC: new_flag_a |= !flag_c; break;
240 for(Predicate p : set.newFlagB)
242 case FlagA: new_flag_b |= flag_a; break;
243 case FlagB: new_flag_b |= flag_b; break;
244 case FlagC: new_flag_b |= flag_c; break;
245 case NotFlagA: new_flag_b |= !flag_a; break;
246 case NotFlagB: new_flag_b |= !flag_b; break;
247 case NotFlagC: new_flag_b |= !flag_c; break;
254 throw new RuntimeException("FIXME!");
260 Instruction.Move move = (Instruction.Move)executing;
262 // if ILC==0, don't even bother
263 if (ilc==0) { ilc = 1; executing = null; return; }
266 else if (ilc==1) executing = null;
271 p = dataDestination.packets.remove();
272 if (p.path.signal != null) flag_c = p.path.signal.get(0);
277 p = dataDestination.packets.remove();
278 bv = new BitVector(p.value);
279 if (p.path.signal != null) flag_c = p.path.signal.get(0);
281 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
282 readyForDataFromShip = true;
284 if (move.latchData) dataLatch = bv;
286 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv.toLong()));
287 // FIXME: c-flag at output docks
290 if (move.path != null) pathLatch = (InterpreterPath)move.path;
292 if (move.dataOut && isInputDock()) dataReadyForShip = true;
293 if (move.dataOut && !isInputDock())
294 new Packet(pathLatch, new BitVector(dataLatch), true).send();
296 new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();