1 package edu.berkeley.fleet.interpreter;
3 import edu.berkeley.fleet.two.*;
4 import edu.berkeley.fleet.api.*;
5 import edu.berkeley.sbp.util.ANSI;
7 /** anything that has a source (instruction horn) address on the switch fabric */
8 class InterpreterDock extends FleetTwoDock {
10 // Dock State //////////////////////////////////////////////////////////////////////////////
12 boolean flag_a = false;
13 boolean flag_b = false;
14 boolean flag_c = false;
15 boolean flag_d = false;
18 final BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth());
19 InterpreterPath pathLatch = null;
20 boolean requeueStageInCirculatingState = false;
21 boolean requeueStageHasTailInstruction = false;
22 boolean torpedoWaiting = false;
23 boolean flushing = false;
25 LinkedList<Instruction> instructions = new LinkedList<Instruction>();
26 LinkedList<Packet> dataPackets = new LinkedList<Packet>();
29 private LinkedList<Instruction> instructionsBackedUpIntoSwitchFabric = new LinkedList<Instruction>();
31 boolean dataReadyForShip = false;
32 boolean readyForDataFromShip = true;
34 // FIXME: should be a BitVector
36 boolean flagCFromShip;
38 protected void reset() {
47 requeueStageInCirculatingState = false;
48 requeueStageHasTailInstruction = false;
51 instructionsBackedUpIntoSwitchFabric.clear();
52 dataReadyForShip = false;
53 readyForDataFromShip = true;
54 torpedoWaiting = false;
58 // Destinations //////////////////////////////////////////////////////////////////////////////
60 /** includes the epilogue fifo */
61 public InterpreterDestination instructionDestination = new InterpreterDestination(this) {
62 public String toString() { return getDock()+":i"; }
63 public void addDataFromFabric(Packet p) {
65 if (instructionsBackedUpIntoSwitchFabric.size()!=0)
66 throw new RuntimeException("torpedo arrived while instructions were backed up into switch fabric");
67 if (torpedoWaiting) throw new RuntimeException("two torpedoes collided at dock "+this);
68 torpedoWaiting = true;
73 getInterpreter().decodeInstruction(p.getValue(),
74 InterpreterDock.this /* this is wrong, but harmless */);
78 public InterpreterDestination dataDestination = new InterpreterDestination(this) {
79 public String toString() { return getDock()+""; }
80 public void addDataFromFabric(Packet packet) { dataPackets.add(packet); }
83 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
85 ship.docks.put(bbd.getName(), this);
88 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
89 public Destination getInstructionDestination() { return instructionDestination; }
90 public Destination getDataDestination() { return dataDestination; }
91 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
92 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
94 boolean trace = false;
96 private void addInstruction(Instruction inst) {
97 if (requeueStageInCirculatingState || requeueStageHasTailInstruction) {
99 instructionsBackedUpIntoSwitchFabric.add(inst);
102 if (inst instanceof Instruction.Tail) {
103 requeueStageHasTailInstruction = true;
106 instructions.add(inst);
109 protected final void service() {
111 if (dataReadyForShip || flushing) return;
112 if (instructions.size()==0) return;
114 if (instructions.peek() instanceof Instruction.Head) {
115 if (requeueStageInCirculatingState) { instructions.remove(); return; }
116 if (!requeueStageHasTailInstruction) return;
117 requeueStageHasTailInstruction = false;
118 requeueStageInCirculatingState = true;
119 instructions.remove();
123 // in the while..false idiom block below, use "break" to
124 // consume the instruction at instructions.peek(), or "return"
125 // to leave it and retry on the next call.
127 if (!instructions.peek().predicate.evaluate(flag_a, flag_b, flag_c, flag_d))
130 if (instructions.peek() instanceof Instruction.Move) {
131 Instruction.Move move = (Instruction.Move)instructions.peek();
133 if (ilc==0) { ilc = 1; break; }
135 if (move.interruptible && torpedoWaiting) {
136 torpedoWaiting = false;
142 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
143 if (move.dataIn && isInputDock() && dataPackets.size()==0) return;
144 if (move.tokenIn && dataPackets.size()==0) return;
147 Packet p = dataPackets.remove();
148 flag_c = p.getSignal().get(0);
153 Packet p = dataPackets.remove();
154 bv = new BitVector(p.getValue());
155 flag_c = p.getSignal().get(0);
157 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
158 readyForDataFromShip = true;
159 if (move.latchData) flag_c = flagCFromShip;
161 if (move.latchData) dataLatch.set(bv);
162 if (move.latchPath) {
163 BitVector bvp = ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv);
164 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, bvp);
168 if (move.path != null) pathLatch = (InterpreterPath)move.path;
170 if (move.dataOut && isInputDock()) dataReadyForShip = true;
171 if (move.dataOut && !isInputDock()) new Packet(pathLatch, new BitVector(dataLatch), false).send();
172 if (move.tokenOut) new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();
178 } else if (instructions.peek() instanceof Instruction.Abort) {
179 requeueStageInCirculatingState = false;
180 while (instructionsBackedUpIntoSwitchFabric.size()!=0)
181 addInstruction(instructionsBackedUpIntoSwitchFabric.remove());
184 } else if (instructions.peek() instanceof Instruction.Flush) {
188 } else if (instructions.peek() instanceof Instruction.Shift) {
189 Instruction.Shift shift = (Instruction.Shift)instructions.peek();
190 for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--)
191 dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth()));
192 BitVector shift_immediate = shift.immediate.getBitVector();
193 for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
194 dataLatch.set(i, shift_immediate.get(i));
197 } else if (instructions.peek() instanceof Instruction.Set) {
198 Instruction.Set set = (Instruction.Set)instructions.peek();
200 case DataLatch: dataLatch.setAndSignExtend(set.immediate);
202 case InnerLoopCounter:
204 case Infinity: ilc = -1; break;
205 case Immediate: ilc = (int)set.immediate; break;
208 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
209 if (dataLatch.get(i))
212 default: throw new RuntimeException("impossible");
215 case OuterLoopCounter:
217 case Decrement: olc = Math.max(0,olc-1); break;
218 case Immediate: olc = (int)set.immediate; break;
221 for(int i=0; i<getShip().getFleet().getWordWidth(); i++)
222 if (dataLatch.get(i))
225 default: throw new RuntimeException("impossible");
231 boolean new_flag_a = set.newFlagA.evaluate(flag_a, flag_b, flag_c, flag_d);
232 boolean new_flag_b = set.newFlagB.evaluate(flag_a, flag_b, flag_c, flag_d);
237 default: throw new RuntimeException("FIXME!");
240 throw new RuntimeException("unimplemented instruction: " + instructions.peek());
244 if (requeueStageInCirculatingState)
245 instructions.add(instructions.peek());
246 instructions.remove();
250 // Interface for use by Subclasses ///////////////////////////////////////////////////////////////////////
252 // all the methods below convert 64-bit longs to/from
253 // getWordWidth()-bit BitVectors by truncation and sign-extension.
255 protected boolean dataReadyForShip() { return dataReadyForShip; }
256 protected final boolean readyForDataFromShip() { return readyForDataFromShip; }
257 protected long removeDataForShip() {
258 long val = peekDataForShip();
259 dataReadyForShip = false;
262 protected long peekDataForShip() {
263 if (!dataReadyForShip)
264 throw new RuntimeException("peekDataForShip() invoked when dataReadyForShip()==false");
265 return dataLatch.toLong();
267 protected void addDataFromShip(long data) { addDataFromShip(data, false); }
268 protected void addDataFromShip(long data, boolean pending_flag_c) {
269 if (!readyForDataFromShip())
270 throw new RuntimeException("addDataFromShip() invoked when readyForDataFromShip()");
271 readyForDataFromShip = false;
273 flagCFromShip = pending_flag_c;
277 // Debugging //////////////////////////////////////////////////////////////////////////////
279 public void dumpState() {
280 if (instructions.size()==0 &&
281 dataPackets.size()==0 &&
282 instructionsBackedUpIntoSwitchFabric.size()==0 &&
283 !requeueStageHasTailInstruction &&
284 !requeueStageInCirculatingState &&
288 readyForDataFromShip)
290 System.out.println("state of "+ANSI.green(this)+": "+
291 (ilc==1?"":("[ilc="+(ilc==-1 ? "*" : (ilc+""))+"] "))+
292 (olc==1?"":("[olc="+olc+"] "))+
297 (requeueStageInCirculatingState?"[recirculating] ":"")+
298 (requeueStageHasTailInstruction?"[tail waiting] ":"")+
299 (torpedoWaiting?"[torpedo waiting] ":"")+
300 (flushing?"[flushing] ":"")
302 if (!readyForDataFromShip)
303 System.out.println(ANSI.cyan(" ship has proffered: " + dataFromShip));
304 if (dataReadyForShip)
305 System.out.println(ANSI.cyan(" waiting for ship to accept: " + dataLatch.toLong()));
306 for(Instruction i : instructions)
307 System.out.println(ANSI.red(" "+i));
308 for(Instruction i : instructionsBackedUpIntoSwitchFabric)
309 System.out.println(ANSI.red(ANSI.bold(" "+i+" BACKED UP")));
310 for(Packet p : dataPackets)
311 System.out.println(ANSI.cyan(" "+p));