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 flushing = false;
23 LinkedList<Instruction> instructions = new LinkedList<Instruction>();
24 LinkedList<Packet> dataPackets = new LinkedList<Packet>();
27 private LinkedList<Packet> instructionsBackedUpIntoSwitchFabric = new LinkedList<Packet>();
29 boolean dataReadyForShip = false;
30 boolean readyForDataFromShip = true;
32 // FIXME: should be a BitVector
34 boolean flagCFromShip;
36 protected void reset() {
45 requeueStageInCirculatingState = false;
48 instructionsBackedUpIntoSwitchFabric.clear();
49 dataReadyForShip = false;
50 readyForDataFromShip = true;
54 // Destinations //////////////////////////////////////////////////////////////////////////////
56 /** includes the epilogue fifo */
57 public InterpreterDestination instructionDestination = new InterpreterDestination(this) {
58 public String toString() { return getDock()+":i"; }
59 public void addDataFromFabric(Packet p) { addInstruction(p); }
61 public InterpreterDestination dataDestination = new InterpreterDestination(this) {
62 public String toString() { return getDock()+""; }
63 public void addDataFromFabric(Packet packet) { dataPackets.add(packet); }
66 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
68 ship.docks.put(bbd.getName(), this);
71 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
72 public Destination getInstructionDestination() { return instructionDestination; }
73 public Destination getDataDestination() { return dataDestination; }
74 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
75 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
77 boolean trace = false;
79 private void addInstruction(Packet p) {
81 instructionsBackedUpIntoSwitchFabric.size()!=0 ||
82 requeueStageInCirculatingState ||
83 (p2i(p) instanceof Instruction.Tail)) {
84 instructionsBackedUpIntoSwitchFabric.add(p);
86 instructions.add(p2i(p));
90 private Instruction p2i(Packet p) {
91 if (p.isToken()) throw new RuntimeException();
92 return getInterpreter().decodeInstruction(p.getValue(), InterpreterDock.this /* this is wrong, but harmless */);
95 protected final void service() {
97 if (dataReadyForShip || flushing) return;
98 if (instructions.size()==0) return;
100 if (instructions.peek() instanceof Instruction.Head) {
101 if (requeueStageInCirculatingState) { instructions.remove(); return; }
102 Packet p = instructionsBackedUpIntoSwitchFabric.peek();
103 if (p!=null && !p.isToken() && p2i(p) instanceof Instruction.Tail) {
104 instructionsBackedUpIntoSwitchFabric.remove();
105 requeueStageInCirculatingState = true;
106 instructions.remove();
111 // in the while..false idiom block below, use "break" to
112 // consume the instruction at instructions.peek(), or "return"
113 // to leave it and retry on the next call.
115 if (!instructions.peek().predicate.evaluate(flag_a, flag_b, flag_c, flag_d))
118 if (instructions.peek() instanceof Instruction.Move) {
119 Instruction.Move move = (Instruction.Move)instructions.peek();
121 if (ilc==0) { ilc = 1; break; }
123 if (move.interruptible) {
124 Packet p = instructionsBackedUpIntoSwitchFabric.peek();
125 if (p!=null && p.isToken()) {
126 instructionsBackedUpIntoSwitchFabric.remove();
133 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
134 if (move.dataIn && isInputDock() && dataPackets.size()==0) return;
135 if (move.tokenIn && dataPackets.size()==0) return;
138 Packet p = dataPackets.remove();
139 flag_c = p.getSignal().get(0);
144 Packet p = dataPackets.remove();
145 bv = new BitVector(p.getValue());
146 flag_c = p.getSignal().get(0);
148 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
149 readyForDataFromShip = true;
150 if (move.latchData) flag_c = flagCFromShip;
152 if (move.latchData) dataLatch.set(bv);
153 if (move.latchPath) {
154 BitVector bvp = ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv);
155 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, bvp);
159 if (move.path != null) pathLatch = (InterpreterPath)move.path;
161 if (move.dataOut && isInputDock()) dataReadyForShip = true;
162 if (move.dataOut && !isInputDock()) new Packet(pathLatch, new BitVector(dataLatch), false).send();
163 if (move.tokenOut) new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();
169 } else if (instructions.peek() instanceof Instruction.Abort) {
170 requeueStageInCirculatingState = false;
171 LinkedList<Packet> temp = new LinkedList<Packet>();
172 while (instructionsBackedUpIntoSwitchFabric.size()!=0)
173 temp.add(instructionsBackedUpIntoSwitchFabric.remove());
174 while (temp.size()!=0)
175 addInstruction(temp.remove());
178 } else if (instructions.peek() instanceof Instruction.Flush) {
182 } else if (instructions.peek() instanceof Instruction.Shift) {
183 Instruction.Shift shift = (Instruction.Shift)instructions.peek();
184 for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--)
185 dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth()));
186 BitVector shift_immediate = shift.immediate.getBitVector();
187 for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
188 dataLatch.set(i, shift_immediate.get(i));
191 } else if (instructions.peek() instanceof Instruction.Set) {
192 Instruction.Set set = (Instruction.Set)instructions.peek();
194 case DataLatch: dataLatch.setAndSignExtend(set.immediate);
196 case InnerLoopCounter:
198 case Infinity: ilc = -1; break;
199 case Immediate: ilc = (int)set.immediate; break;
202 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
203 if (dataLatch.get(i))
206 default: throw new RuntimeException("impossible");
209 case OuterLoopCounter:
211 case Decrement: olc = Math.max(0,olc-1); break;
212 case Immediate: olc = (int)set.immediate; break;
215 for(int i=0; i<getShip().getFleet().getWordWidth(); i++)
216 if (dataLatch.get(i))
219 default: throw new RuntimeException("impossible");
225 boolean new_flag_a = set.newFlagA.evaluate(flag_a, flag_b, flag_c, flag_d);
226 boolean new_flag_b = set.newFlagB.evaluate(flag_a, flag_b, flag_c, flag_d);
231 default: throw new RuntimeException("FIXME!");
234 throw new RuntimeException("unimplemented instruction: " + instructions.peek());
238 if (requeueStageInCirculatingState)
239 instructions.add(instructions.peek());
240 instructions.remove();
244 // Interface for use by Subclasses ///////////////////////////////////////////////////////////////////////
246 // all the methods below convert 64-bit longs to/from
247 // getWordWidth()-bit BitVectors by truncation and sign-extension.
249 protected boolean dataReadyForShip() { return dataReadyForShip; }
250 protected final boolean readyForDataFromShip() { return readyForDataFromShip; }
251 protected long removeDataForShip() {
252 long val = peekDataForShip();
253 dataReadyForShip = false;
256 protected long peekDataForShip() {
257 if (!dataReadyForShip)
258 throw new RuntimeException("peekDataForShip() invoked when dataReadyForShip()==false");
259 return dataLatch.toLong();
261 protected void addDataFromShip(long data) { addDataFromShip(data, false); }
262 protected void addDataFromShip(long data, boolean pending_flag_c) {
263 if (!readyForDataFromShip())
264 throw new RuntimeException("addDataFromShip() invoked when readyForDataFromShip()");
265 readyForDataFromShip = false;
267 flagCFromShip = pending_flag_c;
271 // Debugging //////////////////////////////////////////////////////////////////////////////
273 public void dumpState() {
274 if (instructions.size()==0 &&
275 dataPackets.size()==0 &&
276 instructionsBackedUpIntoSwitchFabric.size()==0 &&
277 !requeueStageInCirculatingState &&
280 readyForDataFromShip)
282 System.out.println("state of "+ANSI.green(this)+": "+
283 (ilc==1?"":("[ilc="+(ilc==-1 ? "*" : (ilc+""))+"] "))+
284 (olc==1?"":("[olc="+olc+"] "))+
289 (requeueStageInCirculatingState?"[recirculating] ":"")+
290 (flushing?"[flushing] ":"")
292 if (!readyForDataFromShip)
293 System.out.println(ANSI.cyan(" ship has proffered: " + dataFromShip));
294 if (dataReadyForShip)
295 System.out.println(ANSI.cyan(" waiting for ship to accept: " + dataLatch.toLong()));
296 for(Instruction i : instructions)
297 System.out.println(ANSI.red(" "+i));
298 for(Packet i : instructionsBackedUpIntoSwitchFabric)
299 System.out.println(ANSI.red(ANSI.bold(" "+i+" BACKED UP")));
300 for(Packet p : dataPackets)
301 System.out.println(ANSI.cyan(" "+p));