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;
24 Instruction executing = null;
25 Queue<Instruction> instructions = new LinkedList<Instruction>();
26 Queue<Instruction> epilogue = new LinkedList<Instruction>();
27 Queue<Packet> dataPackets = new LinkedList<Packet>();
28 boolean dataReadyForShip = false;
29 boolean readyForDataFromShip = true;
31 boolean torpedoWaiting = false;
33 protected void reset() {
39 dataLatch = new BitVector(getShip().getFleet().getWordWidth());
45 dataReadyForShip = false;
46 readyForDataFromShip = true;
48 torpedoWaiting = false;
51 // Destinations //////////////////////////////////////////////////////////////////////////////
53 /** includes the epilogue fifo */
54 public InterpreterDestination instructionDestination = new InterpreterDestination(this, true) {
55 public String toString() { return getDock()+":i"; }
56 public void addDataFromFabric(Packet p) {
58 if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
59 torpedoWaiting = true;
61 BitVector bv = p.getValue();
63 for(int i=0; i<bv.length(); i++)
66 epilogue.add(getInterpreter().readInstruction(val, InterpreterDock.this));
70 public InterpreterDestination dataDestination = new InterpreterDestination(this, false) {
71 public String toString() { return getDock()+""; }
72 public void addDataFromFabric(Packet packet) { dataPackets.add(packet); }
75 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
77 ship.docks.put(bbd.getName(), this);
80 public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
81 public Destination getInstructionDestination() { return instructionDestination; }
82 public Destination getDataDestination() { return dataDestination; }
83 public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
84 public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
86 // interface to subclass ///////////////////////////////////////////////////////////////////////
88 /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
90 public boolean dataReadyForShip() { return dataReadyForShip; }
91 public final boolean readyForDataFromShip() { return readyForDataFromShip; }
93 public long removeDataForShip() {
94 long val = peekDataForShip();
95 dataReadyForShip = false;
98 public long peekDataForShip() {
99 if (!dataReadyForShip) throw new RuntimeException();
100 BitVector bv = dataLatch;
102 for(int i=0; i<bv.length(); i++)
107 public void addDataFromShip(long data) {
108 if (!readyForDataFromShip()) throw new RuntimeException();
109 readyForDataFromShip = false;
113 protected final void service() {
115 if (hatchIsOpen && epilogue.size() > 0) {
116 Instruction inst = epilogue.remove();
117 if (inst instanceof Instruction.Head) {
121 if (inst instanceof Instruction.Tail)
124 instructions.add(inst);
127 if (dataReadyForShip) return;
129 if (executing==null && instructions.size() > 0) {
130 executing = instructions.remove();
134 if (executing==null) return;
136 if (executing.looping && hatchIsOpen && olc>0) return;
138 boolean enabled = true;
139 switch(executing.predicate) {
140 case IgnoreFlagD: enabled = true; break;
141 case Default: enabled = olc>0; break;
142 case FlagA: enabled = flag_a; break;
143 case FlagB: enabled = flag_b; break;
144 case FlagC: enabled = flag_c; break;
145 case NotFlagA: enabled = !flag_a; break;
146 case NotFlagB: enabled = !flag_b; break;
147 case NotFlagC: enabled = !flag_c; break;
148 default: throw new RuntimeException();
151 if (executing.looping && olc>0)
152 instructions.add(executing);
157 if (executing instanceof Instruction.Move) {
158 Instruction.Move move = (Instruction.Move)executing;
160 if (move.interruptible && torpedoWaiting) {
161 torpedoWaiting = false;
166 new Packet(tapl, new BitVector(getInterpreter().getWordWidth()), true).send();
171 if (move.dataIn && !isInputDock() && readyForDataFromShip) return;
172 if (move.dataIn && isInputDock() && dataPackets.size()==0) return;
173 if (move.tokenIn && dataPackets.size()==0) return;
176 if (executing.looping && olc>0)
177 instructions.add(executing);
179 if (executing instanceof Instruction.Shift) {
181 Instruction.Shift shift = (Instruction.Shift)executing;
182 for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--)
183 dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth()));
184 for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
185 dataLatch.set(i, shift.immediate.get(i));
189 throw new RuntimeException("FIXME");
192 if (executing instanceof Instruction.Set) {
193 Instruction.Set set = (Instruction.Set)executing;
196 dataLatch = new BitVector(getInterpreter().getWordWidth()).setAndSignExtend(set.immediate);
198 case InnerLoopCounter:
205 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
206 if (dataLatch.get(i))
210 ilc = (int)set.immediate;
213 throw new RuntimeException("FIXME!");
216 case OuterLoopCounter:
219 olc = Math.max(0,olc-1);
220 if (olc==0) hatchIsOpen = true;
224 for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
225 if (dataLatch.get(i))
227 if (olc==0) hatchIsOpen = true;
230 olc = (int)set.immediate;
231 if (olc==0) hatchIsOpen = true;
234 throw new RuntimeException("FIXME!");
239 boolean new_flag_a = false;
240 boolean new_flag_b = false;
241 for(Predicate p : set.newFlagA)
243 case FlagA: new_flag_a |= flag_a; break;
244 case FlagB: new_flag_a |= flag_b; break;
245 case FlagC: new_flag_a |= flag_c; break;
246 case NotFlagA: new_flag_a |= !flag_a; break;
247 case NotFlagB: new_flag_a |= !flag_b; break;
248 case NotFlagC: new_flag_a |= !flag_c; break;
250 for(Predicate p : set.newFlagB)
252 case FlagA: new_flag_b |= flag_a; break;
253 case FlagB: new_flag_b |= flag_b; break;
254 case FlagC: new_flag_b |= flag_c; break;
255 case NotFlagA: new_flag_b |= !flag_a; break;
256 case NotFlagB: new_flag_b |= !flag_b; break;
257 case NotFlagC: new_flag_b |= !flag_c; break;
264 throw new RuntimeException("FIXME!");
270 Instruction.Move move = (Instruction.Move)executing;
272 // if ILC==0, don't even bother
273 if (ilc==0) { ilc = 1; executing = null; return; }
276 else if (ilc==1) executing = null;
281 p = dataPackets.remove();
282 if (p.getSignal() != null) flag_c = p.getSignal().get(0);
287 p = dataPackets.remove();
288 bv = new BitVector(p.getValue());
289 if (p.getSignal() != null) flag_c = p.getSignal().get(0);
291 bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
292 readyForDataFromShip = true;
294 if (move.latchData) dataLatch = bv;
296 pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv.toLong()));
297 // FIXME: c-flag at output docks
300 if (move.path != null) pathLatch = (InterpreterPath)move.path;
302 if (move.dataOut && isInputDock()) dataReadyForShip = true;
303 if (move.dataOut && !isInputDock())
304 new Packet(pathLatch, new BitVector(dataLatch), true).send();
306 new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();