import java.util.*;
import java.util.concurrent.*;
import java.lang.reflect.*;
-import edu.berkeley.fleet.*;
import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.assembler.*;
+import edu.berkeley.fleet.util.*;
-public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
+public class Interpreter extends FleetTwoFleet {
- /** some "halt ship" can turn this on to stop the interpreter */
- private HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
- private BlockingQueue<Long> debugStream = new LinkedBlockingQueue<Long>();
+ /** used to allocate serial numbers; see InterpreterDestination for further detail */
+ int maxAllocatedDestinationSerialNumber = 0;
- public FleetProcess run(final byte[] instructions) {
- try {
- final FleetProcess fp = new FleetProcess() {
- public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
- public long readWord() {
- try {
- return debugStream.take();
- } catch (Exception e) {
- throw new RuntimeException(e);
- } }
- protected void _terminate() {
- // FIXME: hack
- ships = new HashMap<String,InterpreterShip>();
- debugStream = new LinkedBlockingQueue<Long>();
- }
- };
- new Thread() {
- public void run() {
- try {
- // find the first icache
- InterpreterShip iscratch = null;
- for(Ship ship : Interpreter.this)
- if (ship.getClass().getSimpleName().equals("Memory")) {
- iscratch = (InterpreterShip)ship;
- break;
- }
- if (iscratch==null)
- iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
- .getConstructor(new Class[] { Interpreter.class, String.class })
- .newInstance(new Object[] { Interpreter.this, "memory" });
- iscratch
- .getClass()
- .getMethod("boot", new Class[] { byte[].class })
- .invoke(iscratch, new Object[] { instructions });
-
- while(!fp.isTerminated())
- for(InterpreterShip ship : ships.values())
- for(int j=0; j<10; j++)
- ship._service();
-
- // run the ships a bit longer for good measure
- for(int i=0; i<100; i++)
- for(InterpreterShip ship : ships.values())
- for(int j=0; j<10; j++)
- ship._service();
-
- // check the state of the ships
- for(InterpreterShip ship : ships.values())
- ship.shutdown();
-
- Log.println(ANSI.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
-
- } catch (Exception e) {
- if (fp.isTerminated()) return;
- throw new RuntimeException(e);
- }
- }
- }.start();
- return fp;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ private InterpreterShip debugShip = null;
+ private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
+ private LinkedHashMap<String,InterpreterShip> ships = new LinkedHashMap<String,InterpreterShip>();
+ public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
+ public Ship getShip(String type, int ordinal) {
+ for(Ship s : this)
+ if (s.getType().equals(type))
+ if (ordinal-- <= 0)
+ return s;
+ return null;
}
- public void dispatch(Instruction i, long address) {
- Log.dispatch(i);
- if (i instanceof Instruction.Executable) {
- InterpreterPump sourcePump = (InterpreterPump)(((Instruction.Executable)i).pump);
- ((InstructionPump)sourcePump).addInstruction(((Instruction.Executable)i));
-
- } else if (i instanceof Instruction.CodeBagDescriptor) {
- Instruction.CodeBagDescriptor cbd = (Instruction.CodeBagDescriptor)i;
- long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
- throw new RuntimeException();
- //new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.pump).send();
-
- } else if (i instanceof Instruction.UnClog) {
- Instruction.UnClog ic = (Instruction.UnClog)i;
- ((InstructionPump)(ic.pump)).clogged--;
-
- } else if (i instanceof Instruction.Kill) {
- InterpreterPump pump = (InterpreterPump)(((Instruction.Kill)i).pump);
- ((InstructionPump)pump).kill(((Instruction.Kill)i).count, false);
-
- } else {
- throw new Error("unsupported: " + i.getClass().getName());
- }
+ /** do not use this; it is going to go away */
+ public Interpreter() { this(true); }
+ public Interpreter(boolean logging) {
+ this(new String[] {
+ "Debug",
+ "Memory",
+ "Memory",
+ "Memory",
+ "Alu",
+ "Alu",
+ "Alu",
+ "Alu",
+ "Alu",
+ "Alu",
+ "Alu",
+ "Fifo",
+ "Fifo",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Counter",
+ "Lut3",
+ "CarrySaveAdder",
+ "Rotator",
+ "Dvi",
+ "Button",
+ "Timer",
+ }, logging);
}
- public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
+ public Interpreter(String[] ships, boolean logging) {
+ int i=0;
+ Log.quiet = !logging;
+ for(String s : ships) {
+ createShip(ships[i], ships[i]+"_"+i);
+ i++;
+ }
+ }
- public Ship createShip(String shipType, String shipname) {
+ private Ship createShip(String shipType, String shipname) {
try {
+ if (ships.get(shipname)!=null) return ships.get(shipname);
Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
- Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
- InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
- ShipDescription sd = new ShipDescription(shipname, br);
- ret.setShipDescription(sd);
+ Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class });
+ String src = "/ships/" + shipType + ".ship";
+ InputStream is = getClass().getResourceAsStream(src);
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ ShipDescription sd = new ShipDescription(this, shipType, br);
+ InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname, sd });
ships.put(shipname, ret);
+ if (shipType.equals("Debug") && debugShip == null)
+ debugShip = ret;
return ret;
} catch (Exception e) {
+ e.printStackTrace();
return null;
}
}
- public void debug(long data) {
+ void debug(long d) { debug(new BitVector(getWordWidth()).set(d)); }
+ void debug(BitVector data) {
try {
if (debugStream != null) debugStream.put(data);
else Log.println(ANSI.invert(" DEBUG: got a datum: " + data+ANSI.clreol()));
// Instruction Encoding /////////////////////////////////////////////////////////////////////////
- public final InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
- public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
- public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
- public long writeInstruction(Instruction d) { return writeInstruction(d); }
- public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
- public class InterpreterInstructionEncoder extends InstructionEncoder {
- public long getDestAddr(Destination box) { return ((InterpreterDestination)box).getDestAddr(); }
- public long getBoxInstAddr(Pump box) { return ((InterpreterPump)box).getDestAddr(); }
- public Destination getDestByAddr(long dest) {
- for(Ship ship : Interpreter.this)
- for(Pump bb : ship.getPumps())
- for(Destination d : bb.getDestinations())
- if (getDestAddr(d)==dest)
- return d;
- return null;
- }
- public Pump getBoxByInstAddr(long dest) {
- for(Ship ship : Interpreter.this)
- for(Pump bb : ship.getPumps())
- if (getBoxInstAddr(bb) == dest)
- return bb;
- return null;
+ public BitVector getDestAddr(Path path) {
+ long ret = ((InterpreterDestination)path.getDestination()).getSerialNumber();
+ BitVector sig = path.getSignal();
+ BitVector bv = new BitVector(DISPATCH_PATH.valmaskwidth+1);
+ bv.set(ret);
+ if (sig != null) {
+ if (sig.length() > 1) throw new RuntimeException("signal was " + sig.length() + " bits long!");
+ if (sig.length() > 0 && sig.get(0)) bv.set(bv.length()-1,true);
}
+ return bv;
}
+
// ShipDescription //////////////////////////////////////////////////////////////////////////////
public void expand(ShipDescription sd) {
pw.println("package edu.berkeley.fleet.interpreter;");
pw.println("import edu.berkeley.sbp.util.ANSI;");
pw.println("import edu.berkeley.fleet.api.*;");
+ pw.println("import edu.berkeley.fleet.two.*;");
pw.println("import edu.berkeley.fleet.*;");
pw.println("import java.util.*;");
pw.println("import java.io.*;");
pw.println("");
pw.println("public class "+filename+" extends InterpreterShip {");
pw.println("");
- for(PumpDescription b : sd) {
+ pw.println(" public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {");
+ pw.println(" super(fleet, sd);");
+ pw.println(" }");
+ pw.println("");
+ for(DockDescription b : sd) {
String name = b.getName();
- pw.print(" ");
- if ( b.isInbox()) pw.print("Inbox");
- if (!b.isInbox()) pw.print("Outbox");
- pw.print(" box_");
+ pw.print(" InterpreterDock box_");
pw.print(name);
- pw.print(" = new ");
- if ( b.isInbox()) pw.print("Inbox");
- if (!b.isInbox()) pw.print("Outbox");
- pw.print("(this, \""+name+"\", new String[] { ");
- boolean first = true;
- for(String destination : b) {
- if (!first) pw.print(", ");
- first = false;
- pw.print("\""+destination+"\"");
- }
- pw.println("});");
+ pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));");
}
pw.println("");
- pw.println(" public "+filename+"(Interpreter fleet, String name) {");
- pw.println(" super(fleet, name, \""+filename+"\");");
- for(PumpDescription b : sd)
- pw.println(" addPump(\""+b.getName()+"\", box_"+b.getName()+");");
- pw.println(" }");
- pw.println("");
pw.println(sd.getSection("fleeterpreter"));
pw.println("}");
pw.flush();
} catch (Exception e) { throw new RuntimeException(e); }
}
-}
+ // Run //////////////////////////////////////////////////////////////////////////////
+ public FleetProcess run(final Instruction[] instructions) {
+ InterpreterProcess ip = initialize(instructions);
+ Thread ipt = new Thread(ip);
+ ipt.setDaemon(true);
+ ipt.start();
+ return ip;
+ }
+
+ public InterpreterProcess initialize(Instruction[] instr) {
+ return new InterpreterProcess(instr);
+ }
+
+ public class InterpreterProcess extends FleetProcess implements Runnable {
+ private Instruction[] instructions;
+ public synchronized void sendWord(Destination d, BitVector word) { sendWord(d, word, null); }
+ public synchronized void sendWord(Destination d, BitVector word, BitVector signal) {
+ InterpreterPath path = (InterpreterPath)debugShip.getDock("in").getPath(d, signal==null?new BitVector(1):signal);
+ new Packet(path, word, false).send();
+ }
+ public synchronized void sendToken(Destination d) {
+ InterpreterPath path = (InterpreterPath)debugShip.getDock("in").getPath(d, new BitVector(1));
+ new Packet(path, new BitVector(getWordWidth()), true).send();
+ }
+ public InterpreterProcess(Instruction[] instructions) {
+ this.instructions = instructions;
+ for(Instruction i : instructions)
+ sendInstruction(i);
+ }
+ public Fleet getFleet() { return Interpreter.this; }
+ public synchronized void sendInstruction(Instruction i) {
+ long il = writeInstruction(i, debugShip.getDock("in"));
+ Path path = debugShip.getDock("in").getPath(i.dock.getInstructionDestination(), null);
+ new Packet((InterpreterPath)path, new BitVector(getWordWidth()).set(il), false).send();
+ }
+ public Dock getDebugInputDock() { return debugShip.getDock("in"); }
+ public BitVector recvWord() {
+ try {
+ return debugStream.take();
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+ protected void _terminate() { }
+ public void run() {
+ try {
+ while(!isTerminated()) {
+ flush();
+ }
+ for(InterpreterShip ship : ships.values())
+ ship.reset();
+ debugStream.clear();
+ } catch (Exception e) {
+ if (isTerminated()) return;
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void flush() {
+ // FIXME: should this run until we detect some sort of "quiescence"? OTOH that might never happen.
+ for(InterpreterShip ship : ships.values())
+ for(int j=0; j<10; j++)
+ if (!isTerminated())
+ synchronized(this) {
+ ship._service();
+ }
+ }
+
+ public synchronized void step(Dock d) {
+ ((InterpreterDock)d).service();
+ }
+
+ public synchronized void step(Ship s) {
+ ((InterpreterShip)s).service();
+ }
+
+ }
+}