X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Finterpreter%2FInterpreter.java;h=311a0aa5dd0343fd3f490241d2765a3c6e4c1c6c;hb=28e41c98c299d834bb5ec9a749126d858dc81bf0;hp=d4eff59b8147da032003e238acd7b195e4dd9420;hpb=4fc722432236db1c8a8444bad87edef16393d090;p=fleet.git diff --git a/src/edu/berkeley/fleet/interpreter/Interpreter.java b/src/edu/berkeley/fleet/interpreter/Interpreter.java index d4eff59..311a0aa 100644 --- a/src/edu/berkeley/fleet/interpreter/Interpreter.java +++ b/src/edu/berkeley/fleet/interpreter/Interpreter.java @@ -3,264 +3,252 @@ import java.io.*; import java.util.*; import java.util.concurrent.*; import java.lang.reflect.*; -import edu.berkeley.fleet.*; -import edu.berkeley.fleet.doc.*; +import edu.berkeley.sbp.util.ANSI; import edu.berkeley.fleet.api.*; -import edu.berkeley.fleet.ies44.*; -import edu.berkeley.fleet.interpreter.ships.*; +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 class Interpreter extends Fleet { + /** 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); + } - /** some "halt ship" can turn this on to stop the interpreter */ - public boolean halt = false; - public ArrayList shiplist = new ArrayList(); - public HashMap ships = new HashMap(); - private BlockingQueue debugStream = new LinkedBlockingQueue(); - public int[] mem = new int[0]; + 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++; + } + } + 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 }); + 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) { + throw new RuntimeException(e); + } + } - 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(Log.invert(" DEBUG: got a datum: " + data+Log.clreol())); - } + 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 static class DynamicInterpreter extends Interpreter implements Fleet.WithDynamicShips { + // Instruction Encoding ///////////////////////////////////////////////////////////////////////// + + 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) { try { - String filename = (sd.name.charAt(0)+"").toUpperCase() + sd.name.substring(1).toLowerCase(); - File outf = new File("build/java/edu/berkeley/fleet/interpreter/ships/"+filename+".java"); + 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.ships;"); - pw.println("import edu.berkeley.fleet.interpreter.*;"); + 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(ShipDescription.BenkoBox b : sd.benkoBoxes) { - if (b.ports.length != 1) - throw new RuntimeException("multiple ports not supported"); - String name = b.ports[0]; - pw.print(" "); - if (!b.tokenOnly && b.inbox) pw.print("DataInbox"); - if ( b.tokenOnly && b.inbox) pw.print("TokenInbox"); - if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox"); - if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox"); - pw.print(" box_"); + 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 "); - if (!b.tokenOnly && b.inbox) pw.print("DataInbox"); - if ( b.tokenOnly && b.inbox) pw.print("TokenInbox"); - if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox"); - if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox"); - pw.println("(this, \""+name+"\");"); + pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));"); } pw.println(""); - pw.println(" public "+filename+"(Interpreter fleet, String name) { super(fleet, name); }"); - pw.println(""); - //pw.println(" public void service() {"); - pw.println(sd.sections.get("fleeterpreter")); - //pw.println("}"); + pw.println(sd.getSection("fleeterpreter")); pw.println("}"); pw.flush(); pw.close(); } catch (Exception e) { throw new RuntimeException(e); } } - 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() { - shiplist = new ArrayList(); - ships = new HashMap(); - debugStream = new LinkedBlockingQueue(); - mem = new int[0]; - } - }; - new Thread() { - public void run() { - try { - go(fp, instructions); - } catch (Exception e) { - if (fp.isTerminated()) return; - throw new RuntimeException(e); - } - } - }.start(); - return fp; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public void go(FleetProcess fp, byte[] instructions) { - try { - // find the first icache - InterpreterShip iscratch = null; - for(Ship ship : this) - if (ship.getClass().getSimpleName().equals("Iscratch")) { - iscratch = (InterpreterShip)ship; - break; - } - if (iscratch==null) - iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.ships.Iscratch") - .getConstructor(new Class[] { Interpreter.class, String.class }) - .newInstance(new Object[] { this, "iscratch" }); - iscratch - .getClass() - .getMethod("boot", new Class[] { byte[].class }) - .invoke(iscratch, new Object[] { instructions }); - - while(!halt && !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(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======")); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public void dispatch(Instruction i, long address) { - Log.dispatch(i); - if (i instanceof Instruction.Executable) { - InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox); - ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i)); - - } else if (i instanceof Instruction.Literal.CodeBagDescriptor) { - Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i; - InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(cbd.dest); - long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size; - destBenkoBox.addDataFromFabric((int)absolute_cbd); - - } else if (i instanceof Instruction.Literal.Absolute) { - InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(((Instruction.Literal.Absolute)i).dest); - Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox); - destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value); + // Run ////////////////////////////////////////////////////////////////////////////// - } else if (i instanceof Instruction.Kill) { - InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox); - ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count); - - } else { - throw new Error("unsupported: " + i.getClass().getName()); - } + public FleetProcess run(final Instruction[] instructions) { + InterpreterProcess ip = initialize(instructions); + Thread ipt = new Thread(ip); + ipt.setDaemon(true); + ipt.start(); + return ip; } - public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) { - Log.token(source, dest); - dest.addTokenFromFabric(); + public InterpreterProcess initialize(Instruction[] instr) { + return new InterpreterProcess(instr); } - public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) { - Log.data(data+"", source, dest); - dest.addDataFromFabric(data); - } - - - // Implementation of the Fleet class abstract methods ///////////////////////////////////////////////////////// - - public Iterator iterator() { return (Iterator)(Object)shiplist.iterator(); } - - public int computeOffset(int origin, int target) { return (target - origin)/6; } - public int computeTarget(int origin, int offset) { return origin + (offset*6); } - - private 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); } - - private class InterpreterInstructionEncoder extends InstructionEncoder { - public long getBoxAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).addr; } - public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).instr_addr; } - public BenkoBox getBoxByAddr(long dest) { - for(Ship ship : Interpreter.this) - for(BenkoBox bb : ship.getBenkoBoxes()) - if (((InterpreterBenkoBox)bb).addr == dest) - return bb; - return null; + 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 BenkoBox getBoxByInstAddr(long dest) { - for(Ship ship : Interpreter.this) - for(BenkoBox bb : ship.getBenkoBoxes()) - if (((InterpreterBenkoBox)bb).instr_addr == dest) - return bb; - return null; + 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 Ship createShip(String shipType, String shipname) { - try { - Class c = Class.forName("edu.berkeley.fleet.interpreter.ships."+shipType); - Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class }); - InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname }); - ships.put(shipname, ret); - shiplist.add(ret); - return ret; - } catch (Exception e) { - return null; + public InterpreterProcess(Instruction[] instructions) { + this.instructions = instructions; + for(Instruction i : instructions) + sendInstruction(i); } - } - - - // Memory ////////////////////////////////////////////////////////////////////////////// - - public void dumpMem() { - Log.print(Log.cyan(" MEMORY: ")); - 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); + } } - Log.println(); - } - public int readMem(int addr) { - return addr >= mem.length ? 0 : mem[addr]; - } - 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; + 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(); + } } - mem[addr] = data; - } + public synchronized void step(Dock d) { + ((InterpreterDock)d).service(); + } + + public synchronized void step(Ship s) { + ((InterpreterShip)s).service(); + } + } } -