X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Finterpreter%2FInterpreter.java;h=311a0aa5dd0343fd3f490241d2765a3c6e4c1c6c;hb=28e41c98c299d834bb5ec9a749126d858dc81bf0;hp=cff67db1d4abc6677e36841c8a33aece94edd5c7;hpb=dedfac6beabb6d57ef4cc9b164cce1ea1b4da1af;p=fleet.git diff --git a/src/edu/berkeley/fleet/interpreter/Interpreter.java b/src/edu/berkeley/fleet/interpreter/Interpreter.java index cff67db..311a0aa 100644 --- a/src/edu/berkeley/fleet/interpreter/Interpreter.java +++ b/src/edu/berkeley/fleet/interpreter/Interpreter.java @@ -1,402 +1,254 @@ 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 { - - public InterpreterBenkoBox resolve(edu.berkeley.fleet.api.BenkoBox bb) { return (InterpreterBenkoBox)bb; } - - public void dispatch(Instruction i) { - - 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.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!"); - } - } - - /** some "halt ship" can turn this on to stop the interpreter */ - public boolean halt = false; - - public int[] mem = new int[0]; - public ArrayList imports = new ArrayList(); - - private static String getUniqueName(Ship ship) { - return ship.getType() + ship.getOrdinal(); - } - - public ArrayList shiplist = new ArrayList(); - public HashMap ships = new HashMap(); - - /** 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 { + + /** used to allocate serial numbers; see InterpreterDestination for further detail */ + int maxAllocatedDestinationSerialNumber = 0; + + private InterpreterShip debugShip = null; + private BlockingQueue debugStream = new LinkedBlockingQueue(); + private LinkedHashMap ships = new LinkedHashMap(); + public Iterator iterator() { return (Iterator)(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 { - if (d instanceof Instruction.Executable) { - Instruction.Executable inst = (Instruction.Executable)d; - - InterpreterBenkoBox dest = resolve(inst.dest); - long instr = dest==null ? 0 : (dest.addr << 1); - - instr |= (((long)inst.count) << (11+1)); - if (inst.tokenIn) instr |= (1L << (11+1+7+0)); - if (inst.dataOut) instr |= (1L << (11+1+7+1)); - if (inst.latch) instr |= (1L << (11+1+7+2)); - if (inst.dataIn) 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); - long out = 0; - out |= ((InterpreterBenkoBox)ships.get("command").getBenkoBox("data")).addr; - out |= instr << 11; - dump(os, (out >> (5*8)) & 0xff); - dump(os, (out >> (4*8)) & 0xff); - dump(os, (out >> (3*8)) & 0xff); - dump(os, (out >> (2*8)) & 0xff); - dump(os, (out >> (1*8)) & 0xff); - dump(os, (out >> (0*8)) & 0xff); - } else if (d instanceof Instruction.Literal.Absolute) { - Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d; - long out = 0; - out |= resolve(ld.dest).addr; - out |= ((long)ld.value) << 11; - dump(os, (out >> (5*8)) & 0xff); - dump(os, (out >> (4*8)) & 0xff); - dump(os, (out >> (3*8)) & 0xff); - dump(os, (out >> (2*8)) & 0xff); - dump(os, (out >> (1*8)) & 0xff); - dump(os, (out >> (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 iterator() { - return (Iterator)(Object)shiplist.iterator(); - } - - public void go() { - 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) { - int[] mem2 = new int[addr*2+1]; - System.arraycopy(mem, 0, mem2, 0, mem2.length); - mem = mem2; + public Interpreter(String[] ships, boolean logging) { + int i=0; + Log.quiet = !logging; + for(String s : ships) { + try { + createShip(ships[i], ships[i]+"_"+i); + } catch (Exception e) { + System.err.println(e); + } + i++; } - 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) { + private 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 }); + 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 }); + 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); - shiplist.add(ret); + if (shipType.equals("Debug") && debugShip == null) + debugShip = ret; return ret; } catch (Exception e) { - return null; + throw new RuntimeException(e); } } - public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) { - Log.token(source, dest); - dest.addTokenFromFabric(); - } - - public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) { - Log.data(data+"", source, dest); - dest.addDataFromFabric(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())); + } 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(); - 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(); - 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"); + 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; + } - ArrayList outputports = new ArrayList(); - 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 added = new HashSet(); - 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, top_r, top_a, top,"); - System.out.println(" data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);"); - System.out.println(" input clk;"); - System.out.println(" input top_r;"); - System.out.println(" output top_a;"); - System.out.println(" input [(`PACKET_WIDTH-1):0] top;"); - 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_Command0_out;"); - System.out.println(); - - System.out.println(); + // ShipDescription ////////////////////////////////////////////////////////////////////////////// - instructions.dumpChannels(true); - outputs.dumpChannels(true); - inputs.dumpChannels(true); - for(InterpreterShip ship : shiplist) - for(BenkoBox port : ship.getBenkoBoxes()) { - if (ship instanceof Command && port instanceof Outbox) continue; - System.out.println(" wire [(`PACKET_WIDTH-1):0] data_"+getUniqueName(ship)+"_"+port.getName()+";"); + 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(""); + 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(name); + pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));"); } + pw.println(""); + pw.println(sd.getSection("fleeterpreter")); + pw.println("}"); + pw.flush(); + pw.close(); + } catch (Exception e) { throw new RuntimeException(e); } + } - 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(");"); + // Run ////////////////////////////////////////////////////////////////////////////// - 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(); - } + public FleetProcess run(final Instruction[] instructions) { + InterpreterProcess ip = initialize(instructions); + Thread ipt = new Thread(ip); + ipt.setDaemon(true); + ipt.start(); + return ip; + } - } - System.out.println("funnel topfun(clk, dest_r, dest_a, dest, source_r, source_a, source, top_r, top_a, top);"); - System.out.println(""); - System.out.println(" assign instruction_r = data_Command0_out_r;"); - System.out.println(" assign data_Command0_out_a = instruction_a;"); - System.out.println(" assign instruction = data_Command0_out;"); - System.out.println("endmodule"); + public InterpreterProcess initialize(Instruction[] instr) { + return new InterpreterProcess(instr); } - 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); + 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(); } - 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; - } - 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); + 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(); } - 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 InterpreterProcess(Instruction[] instructions) { + this.instructions = instructions; + for(Instruction i : instructions) + sendInstruction(i); } - 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 2000 && !Log.quiet && + !"false".equals(System.getProperty("fleet.log.state","false"))) { + System.out.println("== State Dump ==================================================="); + for(InterpreterShip ship : ships.values()) + for(Dock d : ship) + synchronized(this) { + ((InterpreterDock)d).dumpState(); + } + lastStatus = now; } } + for(InterpreterShip ship : ships.values()) + ship.reset(); + debugStream.clear(); + } catch (Exception e) { + if (isTerminated()) return; + throw new RuntimeException(e); } - public String describe(String prefix) { - return prefix+name; - } } + + 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(); + } + } - public static int krunk=0; }