1 package edu.berkeley.fleet.interpreter;
3 import edu.berkeley.fleet.two.*;
4 import edu.berkeley.fleet.api.*;
6 /** anything that has a source (instruction horn) address on the switch fabric */
7 class InterpreterDock extends FleetTwoDock {
9 // Dock State //////////////////////////////////////////////////////////////////////////////
11 boolean flag_a = false;
12 boolean flag_b = false;
13 boolean flag_c = false;
14 boolean flag_d = false;
17 final BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth());
18 InterpreterPath pathLatch = null;
19 boolean requeueStageInCirculatingState = false;
20 boolean requeueStageHasTailInstruction = false;
21 boolean torpedoWaiting = false;
22 boolean flushing = false;
24 Queue<Instruction> instructions = new LinkedList<Instruction>();
25 Queue<Packet> dataPackets = new LinkedList<Packet>();
26 boolean dataReadyForShip = false;
27 boolean readyForDataFromShip = true;
29 boolean flagCFromShip;
31 protected void reset() {
40 requeueStageInCirculatingState = false;
41 requeueStageHasTailInstruction = false;
44 dataReadyForShip = false;
45 readyForDataFromShip = true;
46 torpedoWaiting = false;
50 // Destinations //////////////////////////////////////////////////////////////////////////////
52 /** includes the epilogue fifo */
53 public InterpreterDestination instructionDestination = new InterpreterDestination(this) {
54 public String toString() { return getDock()+":i"; }
55 public void addDataFromFabric(Packet p) {
57 if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
58 torpedoWaiting = true;
63 getInterpreter().decodeInstruction(p.getValue(),
64 InterpreterDock.this /* this is wrong, but harmless */);
66 // FIXME: this is a bit too conservative. In theory,
67 // it's okay to dispatch new instructions to the dock
68 // as long as we know that it will reach the updating
69 // state without any further input from the outside
70 // world -- ie that the instructions which remain to
71 // be executed before the requeue stage transitions to
72 // the updating state are all "non-blocking" (no moves
74 if (requeueStageInCirculatingState || requeueStageHasTailInstruction)
75 throw new RuntimeException("An instruction arrived while the requeue stage was circulating -- "+
76 "this means that instructions have backed up into "+
77 "the switch fabric, which nearly always risks deadlock! "+
79 "\n dock: " + InterpreterDock.this +
80 "\n instruction: " + inst
82 if (inst instanceof Instruction.Tail) {
83 requeueStageHasTailInstruction = true;
86 instructions.add(inst);
89 public InterpreterDestination dataDestination = new InterpreterDestination(this) {
90 public String toString() { return getDock()+""; }
91 public void addDataFromFabric(Packet packet) { dataPackets.add(packet); }
94 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
96 ship.docks.put(bbd.getName(), this);
99 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
100 public Destination getInstructionDestination() { return instructionDestination; }
101 public Destination getDataDestination() { return dataDestination; }
102 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
103 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
105 protected final void service() {
107 if (dataReadyForShip || flushing) return;
108 if (instructions.size()==0) return;
110 if (instructions.peek() instanceof Instruction.Head) {
111 if (requeueStageInCirculatingState) { instructions.remove(); return; }
112 if (!requeueStageHasTailInstruction) return;
113 requeueStageHasTailInstruction = false;
114 requeueStageInCirculatingState = true;
115 instructions.remove();
119 // in the while..false idiom block below, use "break" to
120 // consume the instruction at instructions.peek(), or "return"
121 // to leave it and retry on the next call.
123 if (!instructions.peek().predicate.evaluate(flag_a, flag_b, flag_c, flag_d))
126 if (instructions.peek() instanceof Instruction.Move) {
127 Instruction.Move move = (Instruction.Move)instructions.peek();
129 if (ilc==0) { ilc = 1; break; }
131 if (move.interruptible && torpedoWaiting) {
132 torpedoWaiting = false;
138 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
139 if (move.dataIn && isInputDock() && dataPackets.size()==0) return;
140 if (move.tokenIn && dataPackets.size()==0) return;
143 Packet p = dataPackets.remove();
144 flag_c = p.getSignal().get(0);
149 Packet p = dataPackets.remove();
150 bv = new BitVector(p.getValue());
151 flag_c = p.getSignal().get(0);
153 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
154 readyForDataFromShip = true;
155 flag_c = flagCFromShip;
157 if (move.latchData) dataLatch.set(bv);
158 if (move.latchPath) {
159 BitVector bvp = ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv);
160 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, bvp);
164 if (move.path != null) pathLatch = (InterpreterPath)move.path;
166 if (move.dataOut && isInputDock()) dataReadyForShip = true;
167 if (move.dataOut && !isInputDock()) new Packet(pathLatch, new BitVector(dataLatch), false).send();
168 if (move.tokenOut) new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();
174 } else if (instructions.peek() instanceof Instruction.Abort) {
175 requeueStageInCirculatingState = false;
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 for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
187 dataLatch.set(i, shift.immediate.get(i));
190 } else if (instructions.peek() instanceof Instruction.Set) {
191 Instruction.Set set = (Instruction.Set)instructions.peek();
193 case DataLatch: dataLatch.setAndSignExtend(set.immediate);
195 case InnerLoopCounter:
197 case Infinity: ilc = -1; break;
198 case Immediate: ilc = (int)set.immediate; break;
201 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
202 if (dataLatch.get(i))
205 default: throw new RuntimeException("impossible");
208 case OuterLoopCounter:
210 case Decrement: olc = Math.max(0,olc-1); break;
211 case Immediate: olc = (int)set.immediate; break;
214 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
215 if (dataLatch.get(i))
218 default: throw new RuntimeException("impossible");
224 boolean new_flag_a = set.newFlagA.evaluate(flag_a, flag_b, flag_c, flag_d);
225 boolean new_flag_b = set.newFlagB.evaluate(flag_a, flag_b, flag_c, flag_d);
230 default: throw new RuntimeException("FIXME!");
233 throw new RuntimeException("unimplemented instruction: " + instructions.peek());
237 if (requeueStageInCirculatingState)
238 instructions.add(instructions.peek());
239 instructions.remove();
243 // Interface for use by Subclasses ///////////////////////////////////////////////////////////////////////
245 // all the methods below convert 64-bit longs to/from
246 // getWordWidth()-bit BitVectors by truncation and sign-extension.
248 protected boolean dataReadyForShip() { return dataReadyForShip; }
249 protected final boolean readyForDataFromShip() { return readyForDataFromShip; }
250 protected long removeDataForShip() {
251 long val = peekDataForShip();
252 dataReadyForShip = false;
255 protected long peekDataForShip() {
256 if (!dataReadyForShip)
257 throw new RuntimeException("peekDataForShip() invoked when dataReadyForShip()==false");
258 BitVector bv = dataLatch;
260 for(int i=0; i<bv.length(); i++)
265 protected void addDataFromShip(long data) { addDataFromShip(data, false); }
266 protected void addDataFromShip(long data, boolean pending_flag_c) {
267 if (!readyForDataFromShip())
268 throw new RuntimeException("addDataFromShip() invoked when readyForDataFromShip()");
269 readyForDataFromShip = false;
271 flagCFromShip = pending_flag_c;