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>();
28 private Queue<Instruction> instructionsBackedUpIntoSwitchFabric = new LinkedList<Instruction>();
30 boolean dataReadyForShip = false;
31 boolean readyForDataFromShip = true;
33 boolean flagCFromShip;
35 protected void reset() {
44 requeueStageInCirculatingState = false;
45 requeueStageHasTailInstruction = false;
48 instructionsBackedUpIntoSwitchFabric.clear();
49 dataReadyForShip = false;
50 readyForDataFromShip = true;
51 torpedoWaiting = false;
55 // Destinations //////////////////////////////////////////////////////////////////////////////
57 /** includes the epilogue fifo */
58 public InterpreterDestination instructionDestination = new InterpreterDestination(this) {
59 public String toString() { return getDock()+":i"; }
60 public void addDataFromFabric(Packet p) {
62 if (instructionsBackedUpIntoSwitchFabric.size()!=0)
63 throw new RuntimeException("torpedo arrived while instructions were backed up into switch fabric");
64 if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
65 torpedoWaiting = true;
70 getInterpreter().decodeInstruction(p.getValue(),
71 InterpreterDock.this /* this is wrong, but harmless */);
75 public InterpreterDestination dataDestination = new InterpreterDestination(this) {
76 public String toString() { return getDock()+""; }
77 public void addDataFromFabric(Packet packet) { dataPackets.add(packet); }
80 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
82 ship.docks.put(bbd.getName(), this);
85 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
86 public Destination getInstructionDestination() { return instructionDestination; }
87 public Destination getDataDestination() { return dataDestination; }
88 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
89 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
91 boolean trace = false;
93 private void addInstruction(Instruction inst) {
94 if (requeueStageInCirculatingState || requeueStageHasTailInstruction) {
96 instructionsBackedUpIntoSwitchFabric.add(inst);
99 if (inst instanceof Instruction.Tail) {
100 requeueStageHasTailInstruction = true;
103 instructions.add(inst);
106 protected final void service() {
108 if (dataReadyForShip || flushing) return;
109 if (instructions.size()==0) return;
111 if (instructions.peek() instanceof Instruction.Head) {
112 if (requeueStageInCirculatingState) { instructions.remove(); return; }
113 if (!requeueStageHasTailInstruction) return;
114 requeueStageHasTailInstruction = false;
115 requeueStageInCirculatingState = true;
116 instructions.remove();
120 // in the while..false idiom block below, use "break" to
121 // consume the instruction at instructions.peek(), or "return"
122 // to leave it and retry on the next call.
124 if (!instructions.peek().predicate.evaluate(flag_a, flag_b, flag_c, flag_d))
127 if (instructions.peek() instanceof Instruction.Move) {
128 Instruction.Move move = (Instruction.Move)instructions.peek();
130 if (ilc==0) { ilc = 1; break; }
132 if (move.interruptible && torpedoWaiting) {
133 torpedoWaiting = false;
139 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
140 if (move.dataIn && isInputDock() && dataPackets.size()==0) return;
141 if (move.tokenIn && dataPackets.size()==0) return;
144 Packet p = dataPackets.remove();
145 flag_c = p.getSignal().get(0);
150 Packet p = dataPackets.remove();
151 bv = new BitVector(p.getValue());
152 flag_c = p.getSignal().get(0);
154 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
155 readyForDataFromShip = true;
156 if (move.latchData) flag_c = flagCFromShip;
158 if (move.latchData) dataLatch.set(bv);
159 if (move.latchPath) {
160 BitVector bvp = ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv);
161 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, bvp);
165 if (move.path != null) pathLatch = (InterpreterPath)move.path;
167 if (move.dataOut && isInputDock()) dataReadyForShip = true;
168 if (move.dataOut && !isInputDock()) new Packet(pathLatch, new BitVector(dataLatch), false).send();
169 if (move.tokenOut) new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();
175 } else if (instructions.peek() instanceof Instruction.Abort) {
176 requeueStageInCirculatingState = false;
178 while (instructionsBackedUpIntoSwitchFabric.size()!=0) {
179 Instruction i = instructionsBackedUpIntoSwitchFabric.remove();
181 instructionsBackedUpIntoSwitchFabric.clear();
185 } else if (instructions.peek() instanceof Instruction.Flush) {
189 } else if (instructions.peek() instanceof Instruction.Shift) {
190 Instruction.Shift shift = (Instruction.Shift)instructions.peek();
191 for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--)
192 dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth()));
193 BitVector shift_immediate = shift.immediate.getBitVector();
194 for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
195 dataLatch.set(i, shift_immediate.get(i));
198 } else if (instructions.peek() instanceof Instruction.Set) {
199 Instruction.Set set = (Instruction.Set)instructions.peek();
201 case DataLatch: dataLatch.setAndSignExtend(set.immediate);
203 case InnerLoopCounter:
205 case Infinity: ilc = -1; break;
206 case Immediate: ilc = (int)set.immediate; break;
209 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
210 if (dataLatch.get(i))
213 default: throw new RuntimeException("impossible");
216 case OuterLoopCounter:
218 case Decrement: olc = Math.max(0,olc-1); break;
219 case Immediate: olc = (int)set.immediate; break;
222 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
223 if (dataLatch.get(i))
226 default: throw new RuntimeException("impossible");
232 boolean new_flag_a = set.newFlagA.evaluate(flag_a, flag_b, flag_c, flag_d);
233 boolean new_flag_b = set.newFlagB.evaluate(flag_a, flag_b, flag_c, flag_d);
238 default: throw new RuntimeException("FIXME!");
241 throw new RuntimeException("unimplemented instruction: " + instructions.peek());
245 if (requeueStageInCirculatingState)
246 instructions.add(instructions.peek());
247 instructions.remove();
251 // Interface for use by Subclasses ///////////////////////////////////////////////////////////////////////
253 // all the methods below convert 64-bit longs to/from
254 // getWordWidth()-bit BitVectors by truncation and sign-extension.
256 protected boolean dataReadyForShip() { return dataReadyForShip; }
257 protected final boolean readyForDataFromShip() { return readyForDataFromShip; }
258 protected long removeDataForShip() {
259 long val = peekDataForShip();
260 dataReadyForShip = false;
263 protected long peekDataForShip() {
264 if (!dataReadyForShip)
265 throw new RuntimeException("peekDataForShip() invoked when dataReadyForShip()==false");
266 return dataLatch.toLong();
268 protected void addDataFromShip(long data) { addDataFromShip(data, false); }
269 protected void addDataFromShip(long data, boolean pending_flag_c) {
270 if (!readyForDataFromShip())
271 throw new RuntimeException("addDataFromShip() invoked when readyForDataFromShip()");
272 readyForDataFromShip = false;
274 flagCFromShip = pending_flag_c;