package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.*;
-import java.lang.reflect.*;
-import edu.berkeley.sbp.chr.*;
-import edu.berkeley.sbp.misc.*;
-import edu.berkeley.sbp.meta.*;
-import edu.berkeley.sbp.bind.*;
-import edu.berkeley.sbp.util.*;
-import java.util.*;
import java.io.*;
-import edu.berkeley.fleet.ships.*;
-
-public class Interpreter extends Fleet implements Iterable<Ship> {
-
- public InterpreterBenkoBox resolve(edu.berkeley.fleet.api.BenkoBox bb) { return (InterpreterBenkoBox)bb; }
-
- public void dumpCode(Instruction[] instructions) throws IOException {
- DataOutputStream dos = new DataOutputStream(new FileOutputStream("build/fleet.bin"));
- for(int i=1; i<instructions.length; i++) {
- Instruction inst = instructions[i];
- writeInstruction(dos, inst);
- }
- dos.flush();
- dos.close();
- }
-
- public void dispatch(Instruction i, long address) {
-
- if (i instanceof Instruction.Executable) {
- InterpreterBenkoBox sourceBenkoBox = resolve(((Instruction.Executable)i).benkoBox);
- if (!(sourceBenkoBox instanceof InstructionPort))
- throw new RuntimeException(sourceBenkoBox + " is not an InstructionPort!");
- ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
-
- } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
- Log.dispatch(i);
- Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
- dispatchCodeBag(cbd.offset+address, cbd.size);
-
- } else if (i instanceof Instruction.Literal.Absolute) {
- InterpreterBenkoBox destBenkoBox = resolve(((Instruction.Literal.Absolute)i).dest);
- Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
- destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
-
- } else if (i instanceof Instruction.Kill) {
- InterpreterBenkoBox benkoBox = resolve(((Instruction.Kill)i).benkoBox);
- if (!(benkoBox instanceof InstructionPort))
- throw new RuntimeException(benkoBox + " is not an InstructionPort!");
- ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count);
-
- } else {
- throw new Error("unsupported: " + i.getClass().getName());
- }
- }
-
- /** some "halt ship" can turn this on to stop the interpreter */
- public boolean halt = false;
-
- public int[] mem = new int[0];
-
- public Instruction[] instructions = null;
- public ArrayList<String> imports = new ArrayList<String>();
-
- private static String getUniqueName(Ship ship) {
- return ship.getType() + ship.getOrdinal();
- }
-
- public ArrayList<InterpreterShip> shiplist = new ArrayList<InterpreterShip>();
- public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
-
- /** read a machine-formatted instruction from a file (into a Java object) */
- public Instruction readInstruction(DataInputStream is) throws IOException {
- // FIXME
+import java.util.*;
+import java.util.concurrent.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.util.ANSI;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.assembler.*;
+import edu.berkeley.fleet.util.*;
+
+public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynamicShips {
+
+ private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
+ private InterpreterShip debugShip = null;
+ private HashMap<String,InterpreterShip> ships = new HashMap<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 writeInstruction(DataOutputStream os, Instruction d) throws IOException {
- long instr = 0;
-
- // Kill is encoded as Execute with the illegal combination (Latch & ~DataIn)
- if (d instanceof Instruction.Kill) {
- Instruction.Kill k = (Instruction.Kill)d;
- d = new Instruction.Executable(k.benkoBox, null, k.count, false, false, true, false, false, false);
- }
-
- if (d instanceof Instruction.Executable) {
- Instruction.Executable inst = (Instruction.Executable)d;
- InterpreterBenkoBox dest = resolve(inst.dest);
- instr = dest==null ? 0 : (dest.addr << 1);
- instr |= (((long)inst.count) << (11+1));
- if (inst.tokenIn) instr |= (1L << (11+1+7+0));
- if (inst.dataIn) instr |= (1L << (11+1+7+1));
- if (inst.latch) instr |= (1L << (11+1+7+2));
- if (inst.dataOut) instr |= (1L << (11+1+7+3));
- if (inst.tokenOut) instr |= (1L << (11+1+7+4));
- instr |= ((long)resolve(inst.benkoBox).instr_addr) << (11+5+7+1);
-
- } else if (d instanceof Instruction.Literal.Absolute) {
- Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
- instr = (2L << (11+24));
- instr |= (resolve(ld.dest).addr) << 24;
- instr |= ((long)ld.value);
- }
-
- dump(os, (instr >> (5*8)) & 0xff);
- dump(os, (instr >> (4*8)) & 0xff);
- dump(os, (instr >> (3*8)) & 0xff);
- dump(os, (instr >> (2*8)) & 0xff);
- dump(os, (instr >> (1*8)) & 0xff);
- dump(os, (instr >> (0*8)) & 0xff);
- }
- public void dump(OutputStream os, long data_) throws IOException {
- int data = (int)data_;
- os.write((byte)data);
- System.out.println(data);
- }
-
- public Iterator<Ship> iterator() {
- return (Iterator<Ship>)(Object)shiplist.iterator();
- }
-
- public void dispatchCodeBag(long base, long size) {
- for(long i=base; i<base+size; i++)
- dispatch(instructions[(int)i], i);
+ void dispatch(Instruction i) {
+ Log.dispatch(i);
+ ((InterpreterDock)i.dock).addInstruction(i);
}
- public void go() {
- Instruction.Literal.CodeBagDescriptor cbl =
- (Instruction.Literal.CodeBagDescriptor)instructions[0];
- dispatchCodeBag(cbl.offset+0, cbl.size);
-
- while(!halt)
- 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(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
- }
-
- public void dumpMem() {
- Log.print(Log.cyan(" MEMORY: "));
- for(int i=0; i<mem.length; i++) {
- if ((i%10)==0 && i!=0) Log.print(Log.cyan(" "));
- Log.print(Log.cyan(mem[i] + " "));
- if ((i%10)==9 && i!=mem.length-1) Log.println("");
- }
- Log.println();
- }
-
- public void writeMem(int addr, int data) {
- if (addr >= mem.length) {
- int[] mem2 = new int[addr*2+1];
- System.arraycopy(mem, 0, mem2, 0, mem2.length);
- mem = mem2;
- }
- mem[addr] = data;
- }
-
- public InterpreterShip getShip(String name) {
- InterpreterShip s = ships.get(name);
- if (s == null) throw new RuntimeException("unknown ship \""+name+"\"");
- return s;
- }
-
- public InterpreterShip tryCreate(String classname, String shipname) {
+ public Ship createShip(String shipType, String shipname) {
try {
- Class c = Class.forName(classname);
- Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
- InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, 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);
+ InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname, sd });
ships.put(shipname, ret);
- shiplist.add(ret);
+ if (shipType.equals("Debug") && debugShip == null)
+ debugShip = ret;
return ret;
} catch (Exception e) {
+ e.printStackTrace();
return null;
}
}
- public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
- Log.token(source, dest);
- dest.addTokenFromFabric();
+ void debug(long d) {
+ throw new RuntimeException();
}
-
- public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
- Log.data(data+"", source, dest);
- dest.addDataFromFabric(data);
+ void debug(BitVector data) {
+ try {
+ if (debugStream != null) debugStream.put(data);
+ else Log.println(ANSI.invert(" DEBUG: got a datum: " + data+ANSI.clreol()));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
- public void dumpFabric(boolean quiet) {
- // FIXME: this is really ugly: the order of port declarations in
- // the XXXShip.java file must match the order in the .balsa file!
-
- ArrayList instructionports = new ArrayList<InterpreterBenkoBox>();
- for(InterpreterShip ship : shiplist)
- for(BenkoBox port : ship.getBenkoBoxes())
- if (!((InterpreterBenkoBox)port).special())
- instructionports.add(port);
- FabricTree instructions =
- new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
- "ihorn",
- "instruction");
+ // Instruction Encoding /////////////////////////////////////////////////////////////////////////
- ArrayList inputports = new ArrayList<InterpreterBenkoBox>();
- for(InterpreterShip ship : shiplist)
- for(BenkoBox port : ship.getBenkoBoxes())
- if (!((InterpreterBenkoBox)port).special())
- inputports.add(port);
- FabricTree inputs =
- new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
- "horn",
- "dest");
-
- ArrayList outputports = new ArrayList<InterpreterBenkoBox>();
- for(InterpreterShip ship : shiplist)
- for(BenkoBox port : ship.getBenkoBoxes())
- if (!((InterpreterBenkoBox)port).special())
- outputports.add(port);
- FabricTree outputs =
- new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
- "funnel",
- "source");
-
- if (quiet) return;
- System.out.println("`include \"macros.v\"");
- /*
- HashSet<Class> added = new HashSet<Class>();
- for(Ship ship : shiplist)
- if (!added.contains(ship.getClass())) {
- added.add(ship.getClass());
- System.out.println("import ["+ship.getBalsaName()+"]");
- }
- */
- System.out.println("module fabric(clk, data_Execute0_in_r, data_Execute0_in_a, data_Execute0_in,");
- System.out.println(" data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);");
- System.out.println(" input clk;");
- System.out.println(" input data_Execute0_in_r;");
- System.out.println(" output data_Execute0_in_a;");
- System.out.println(" input [(`PACKET_WIDTH-1):0] data_Execute0_in;");
- System.out.println(" output data_Debug0_out_r;");
- System.out.println(" input data_Debug0_out_a;");
- System.out.println(" output [(`PACKET_WIDTH-1):0] data_Debug0_out;");
- System.out.println(" wire [(`INSTRUCTION_WIDTH-1):0] data_Execute0_ihorn;");
- System.out.println(" wire [(`PACKET_WIDTH-1):0] data_Execute0_dhorn;");
- System.out.println();
-
- System.out.println();
-
- instructions.dumpChannels(true);
- outputs.dumpChannels(true);
- inputs.dumpChannels(true);
- for(InterpreterShip ship : shiplist)
- for(BenkoBox port : ship.getBenkoBoxes()) {
- if (ship instanceof Execute && port instanceof Outbox) continue;
- System.out.println(" wire [(`PACKET_WIDTH-1):0] data_"+getUniqueName(ship)+"_"+port.getName()+";");
- }
-
- System.out.println("");
- instructions.dumpChannels(false);
- System.out.println("");
- outputs.dumpChannels(false);
- System.out.println("");
- inputs.dumpChannels(false);
- System.out.println("");
- for(InterpreterShip ship : shiplist) {
- System.out.print(ship.getClass().getSimpleName().toLowerCase());
- System.out.print(" ");
- System.out.print("krunk"+(krunk++));
- System.out.print("(clk, ");
- boolean first = true;
- for(BenkoBox port : ship.getBenkoBoxes()) {
- if (!first) System.out.print(", ");
- first = false;
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
- System.out.print(" ");
- }
- System.out.println(");");
+ 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;
+ }
- for(BenkoBox port : ship.getBenkoBoxes()) {
- if (((InterpreterBenkoBox)port).special()) continue;
- if (port instanceof Inbox) {
- if (((InterpreterBenkoBox)port).noInbox())
- System.out.print("stupidinbox");
- else
- System.out.print("inbox");
- } else {
- System.out.print("outbox");
- }
- System.out.print(" krunk"+(krunk++)+"(clk, ");
- System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
- System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
- System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
- System.out.print(");");
- System.out.println();
- }
- }
- System.out.println("funnel topfun(clk,"+
- " dest_r, dest_a, dest,"+
- " source_r, source_a, source,"+
- " data_Execute0_dhorn_r, data_Execute0_dhorn_a, data_Execute0_dhorn);");
- System.out.println("assign instruction_r = data_Execute0_ihorn_r;");
- System.out.println("assign data_Execute0_ihorn_a = instruction_a;");
- System.out.println("assign instruction = data_Execute0_ihorn;");
- System.out.println("endmodule");
- }
+ // ShipDescription //////////////////////////////////////////////////////////////////////////////
- private static class FabricTree {
- int master_idx = 1;
- String prefix;
- Node root;
- public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
- public FabricTree(InterpreterBenkoBox[] ports, String component, String prefix) {
- this.prefix = prefix;
- root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
- }
- private Object mkNode(String name, String component, InterpreterBenkoBox[] ports,
- int start, int end, int addr, int bits) {
- if (end-start == 0) return null;
- if (end-start == 1) {
- InterpreterBenkoBox p = ports[start];
- if (prefix.equals("instruction")) {
- p.instr_addr = addr;
- p.instr_bits = bits;
- } else {
- p.addr = addr;
- p.bits = bits;
- }
- return p;
+ public void expand(ShipDescription sd) {
+ try {
+ String filename = sd.getName();
+ //String filename = (sd.getName().charAt(0)+"").toUpperCase() + sd.getName().substring(1).toLowerCase();
+ File outf = new File("build/java/edu/berkeley/fleet/interpreter/"+filename+".java");
+ new File(outf.getParent()).mkdirs();
+ System.err.println("writing to " + outf);
+ FileOutputStream out = new FileOutputStream(outf);
+ PrintWriter pw = new PrintWriter(out);
+
+ 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(DockDescription b : sd) {
+ String name = b.getName();
+ pw.print(" InterpreterDock box_");
+ pw.print(name);
+ pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));");
}
- int len = end-start;
- return new Node(name,
- component,
- mkNode(name+"_0", component, ports, start, start+len/2, addr, bits+1),
- mkNode(name+"_1", component, ports, start+len/2, end, addr | (1 << bits), bits+1),
- addr,
- bits);
+ 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();
+ pw.close();
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+
+ // Run //////////////////////////////////////////////////////////////////////////////
+
+ public FleetProcess run(final Instruction[] instructions) {
+ InterpreterProcess ip = new InterpreterProcess(instructions);
+ new Thread(ip).start();
+ return ip;
+ }
+
+ private class InterpreterProcess extends FleetProcess implements Runnable {
+ private Instruction[] instructions;
+ public InterpreterProcess(Instruction[] instructions) {
+ this.instructions = instructions;
}
- private String describe(String prefix, Object o) {
- if (o==null) return null;
- if (o instanceof InterpreterBenkoBox) {
- InterpreterBenkoBox p = (InterpreterBenkoBox)o;
- return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
- }
- if (o instanceof Node) {
- return ((Node)o).describe(prefix);
- }
- return null;
+ public void dispatchInstruction(Instruction i) { dispatch(i); }
+ public Dock getDebugInputDock() { return debugShip.getDock("in"); }
+ public BitVector readWord() {
+ try {
+ return debugStream.take();
+ } catch (Exception e) { throw new RuntimeException(e); }
}
- private class Node {
- Object left;
- Object right;
- String name;
- String component;
- int addr;
- int bits;
- public Node(String name, String component, Object left, Object right, int addr, int bits) {
- this.left = left;
- this.right = right;
- this.name = name;
- this.component = component;
- this.addr = addr;
- this.bits = bits;
- }
- public void dumpChannels(int indentamount, boolean decl) {
- String indent = "";
- for(int i=0; i<indentamount; i++) indent += " ";
- if (decl) {
- String n = describe(prefix).startsWith("instruction")
- ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
- System.out.println(" wire "+n+" "+indent+describe(prefix)+";");
- } else {
- System.out.println(" "+indent+
- component+" "+
- "krunk"+(krunk++)+"(clk, "+
- describe(prefix)+"_r, "+
- describe(prefix)+"_a, "+
- describe(prefix)+", "+
- FabricTree.this.describe(prefix, left)+"_r, "+
- FabricTree.this.describe(prefix, left)+"_a, "+
- FabricTree.this.describe(prefix, left)+", "+
- FabricTree.this.describe(prefix, right)+"_r, "+
- FabricTree.this.describe(prefix, right)+"_a, "+
- FabricTree.this.describe(prefix, right)+
- ");");
- }
- dumpChannels(left, indentamount+1, decl);
- dumpChannels(right, indentamount+1, decl);
- }
- public void dumpChannels(Object o, int indentamount, boolean decl) {
- if (o==null) return;
- if (o instanceof Node) {
- ((Node)o).dumpChannels(indentamount, decl);
- } else {
- String indent = "";
- for(int i=0; i<indentamount; i++) indent += " ";
- if (decl) {
- String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
- ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
- System.out.println(" wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
- }
- }
- }
- public String describe(String prefix) {
- return prefix+name;
+ protected void _terminate() { }
+ public void run() {
+ try {
+ while(!isTerminated())
+ for(InterpreterShip ship : ships.values())
+ for(int j=0; j<10; j++)
+ ship._service();
+ for(InterpreterShip ship : ships.values())
+ ship.reset();
+ debugStream.clear();
+ } catch (Exception e) {
+ if (isTerminated()) return;
+ throw new RuntimeException(e);
}
}
}
- public static int krunk=0;
-
- public int computeOffset(int origin, int target) { return target - origin; }
- public int computeTarget(int origin, int offset) { return origin + offset; }
-}
+}
\ No newline at end of file