X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Finterpreter%2FInterpreter.java;h=a12906ebcef159554568e0a0cb5c09205a04e3f7;hb=c14349bf7c3fa5701a5960b028c51f78b0e8f5db;hp=c3ec5824a1a3929fdb9c05c34275437453731751;hpb=ca1a64970cc2c85b56fb08392f0a554465c87d88;p=fleet.git diff --git a/src/edu/berkeley/fleet/interpreter/Interpreter.java b/src/edu/berkeley/fleet/interpreter/Interpreter.java index c3ec582..a12906e 100644 --- a/src/edu/berkeley/fleet/interpreter/Interpreter.java +++ b/src/edu/berkeley/fleet/interpreter/Interpreter.java @@ -3,127 +3,91 @@ import java.io.*; 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.api.*; import edu.berkeley.fleet.two.*; import edu.berkeley.fleet.assembler.*; -import edu.berkeley.fleet.two.*; 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 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) + if (ordinal-- <= 0) return s; return null; } - public int getWordWidth() { return 37; } - /** some "halt ship" can turn this on to stop the interpreter */ - private HashMap ships = new HashMap(); - private BlockingQueue debugStream = new LinkedBlockingQueue(); - - public int getWordSize() { return 37; } - - public FleetProcess run(final byte[] instructions) { - try { - final FleetProcess fp = new FleetProcess() { - public void dispatchInstruction(Instruction i) { throw new RuntimeException(); } - public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); } - public Dock getDebugInputDock() { return null; } - public BitVector readWord() { - /* - try { - return debugStream.take(); - } catch (Exception e) { - throw new RuntimeException(e); - }*/ - throw new RuntimeException(); - } - protected void _terminate() { - // FIXME: hack - ships = new HashMap(); - debugStream = new LinkedBlockingQueue(); - } - }; - 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) { - BufferedReader br = - new BufferedReader(new InputStreamReader(new FileInputStream("ships/Memory.ship"))); - ShipDescription sd = new ShipDescription("Memory", br); - iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory") - .getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class }) - .newInstance(new Object[] { Interpreter.this, "memory", sd }); - } - 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); - } + /** 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 void dispatch(Instruction i, long address) { - Log.dispatch(i); - - if (i instanceof Instruction.Tail) { - Instruction.Tail ic = (Instruction.Tail)i; - ((InstructionDock)(ic.dock)).tailged--; - - } else { - InterpreterDock sourceDock = (InterpreterDock)(((Instruction)i).dock); - ((InstructionDock)sourceDock).addInstruction(((Instruction)i)); + public Interpreter(String[] ships, boolean logging) { + int i=0; + Log.quiet = !logging; + for(String s : ships) { + createShip(ships[i], ships[i]+"_"+i); + i++; } } - public Iterator iterator() { return (Iterator)(Object)ships.values().iterator(); } - - 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) + debugShip = ret; return ret; } catch (Exception e) { e.printStackTrace(); @@ -131,7 +95,8 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami } } - 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())); @@ -142,27 +107,17 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami // Instruction Encoding ///////////////////////////////////////////////////////////////////////// - public Dock getUniversalSource() { return null; } - - public long getDestAddr(Path path) { throw new RuntimeException(); } - public long getBoxInstAddr(Dock box) { return ((InterpreterDock)box).getDestAddr(); } - public Path getPathByAddr(Dock source, long dest) { throw new RuntimeException(); } - public Destination getDestByAddr(long dest) { - /* - for(Ship ship : Interpreter.this) - for(Dock bb : ship) - if (getDestAddr(bb.getDataDestination())==dest) - return bb.getDataDestination(); - */ - return null; - } - public Dock getBoxByInstAddr(long dest) { - for(Ship ship : Interpreter.this) - for(Dock bb : ship) - 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 ////////////////////////////////////////////////////////////////////////////// @@ -187,28 +142,17 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami 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(" "); - if ( b.isInputDock()) pw.print("Inbox"); - if (!b.isInputDock()) pw.print("Outbox"); - pw.print(" box_"); + pw.print(" InterpreterDock box_"); pw.print(name); - pw.print(" = new "); - if ( b.isInputDock()) pw.print("Inbox"); - if (!b.isInputDock()) pw.print("Outbox"); - pw.print("(this, new String[] { "); - boolean first = true; - pw.print("\"\""); - pw.println("}, shipDescription.getDockDescription(\""+name+"\"));"); + pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));"); } pw.println(""); - pw.println(" public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {"); - pw.println(" super(fleet, name, 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(); @@ -216,5 +160,80 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami } 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(); + } + + } +}