import edu.berkeley.fleet.assembler.*;
import edu.berkeley.fleet.util.*;
-public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynamicShips {
+public class Interpreter extends FleetTwoFleet {
+
+ /** used to allocate serial numbers; see InterpreterDestination for further detail */
+ int maxAllocatedDestinationSerialNumber = 0;
- private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
private InterpreterShip debugShip = null;
- private HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
+ 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)
+ if (ordinal-- <= 0)
return s;
return null;
}
- void dispatch(Instruction i) {
- Log.dispatch(i);
- ((InterpreterDock)i.dock).addInstruction(i);
+ /** 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 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, ShipDescription.class });
- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
- ShipDescription sd = new ShipDescription(shipType, br);
+ 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)
}
}
- void debug(long d) {
- throw new RuntimeException();
- }
+ void debug(long d) { debug(new BitVector(getWordWidth()).set(d)); }
void debug(BitVector data) {
try {
if (debugStream != null) debugStream.put(data);
// Instruction Encoding /////////////////////////////////////////////////////////////////////////
- public long getDestAddr(Path path) {
- long ret = ((InterpreterDestination)path.getDestination()).addr;
- BitVector bv = path.getSignal();
- if (bv.length() > 1) throw new RuntimeException();
- if (bv.length() > 0 && bv.get(0)) ret |= 1;
- return ret;
+ 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;
}
pw.println("");
pw.println("public class "+filename+" extends InterpreterShip {");
pw.println("");
+ 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(" InterpreterDock box_");
pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));");
}
pw.println("");
- pw.println(" public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {");
- pw.println(" super(fleet, sd);");
- for(DockDescription b : sd)
- pw.println(" addDock(\""+b.getName()+"\", box_"+b.getName()+");");
- pw.println(" }");
- pw.println("");
pw.println(sd.getSection("fleeterpreter"));
pw.println("}");
pw.flush();
// Run //////////////////////////////////////////////////////////////////////////////
public FleetProcess run(final Instruction[] instructions) {
- InterpreterProcess ip = new InterpreterProcess(instructions);
- new Thread(ip).start();
+ InterpreterProcess ip = initialize(instructions);
+ Thread ipt = new Thread(ip);
+ ipt.setDaemon(true);
+ ipt.start();
return ip;
}
- private class InterpreterProcess extends FleetProcess implements Runnable {
+ 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 void dispatchInstruction(Instruction i) { dispatch(i); }
public Dock getDebugInputDock() { return debugShip.getDock("in"); }
- public BitVector readWord() {
+ public BitVector recvWord() {
try {
return debugStream.take();
} catch (Exception e) { throw new RuntimeException(e); }
protected void _terminate() { }
public void run() {
try {
- while(!isTerminated())
- for(InterpreterShip ship : ships.values())
- for(int j=0; j<10; j++)
- ship._service();
+ while(!isTerminated()) {
+ flush();
+ }
for(InterpreterShip ship : ships.values())
ship.reset();
debugStream.clear();
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();
+ }
+
}
-}
\ No newline at end of file
+}