Interpreter.java: add a Button and Dvi to the default fleet
[fleet.git] / src / edu / berkeley / fleet / interpreter / Interpreter.java
index d09b3d0..a12906e 100644 (file)
@@ -9,11 +9,14 @@ import edu.berkeley.fleet.two.*;
 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 InterpreterShip debugShip = null;
     private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
-    private HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
+    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)
@@ -24,7 +27,43 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
     }
 
     /** do not use this; it is going to go away */
-    public Interpreter() {
+    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) {
@@ -36,15 +75,7 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
         }
     }
 
-    void dispatch(Instruction i) {
-        Log.dispatch(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();
-    }
-
-    /** do not use this; it is going to go away */
-    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);
@@ -52,7 +83,7 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
             String src = "/ships/" + shipType + ".ship";
             InputStream is = getClass().getResourceAsStream(src);
             BufferedReader br = new BufferedReader(new InputStreamReader(is));
-            ShipDescription sd = new ShipDescription(shipType, br);
+            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)
@@ -77,7 +108,7 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
     // Instruction Encoding /////////////////////////////////////////////////////////////////////////
 
     public BitVector getDestAddr(Path path) {
-        long ret = ((InterpreterDestination)path.getDestination()).addr;
+        long ret = ((InterpreterDestination)path.getDestination()).getSerialNumber();
         BitVector sig = path.getSignal();
         BitVector bv = new BitVector(DISPATCH_PATH.valmaskwidth+1);
         bv.set(ret);
@@ -111,6 +142,10 @@ 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("    InterpreterDock box_");
@@ -118,12 +153,6 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
                 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();
@@ -135,7 +164,9 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
 
     public FleetProcess run(final Instruction[] instructions) {
         InterpreterProcess ip = initialize(instructions);
-        new Thread(ip).start();
+        Thread ipt = new Thread(ip);
+        ipt.setDaemon(true);
+        ipt.start();
         return ip;
     }
 
@@ -145,18 +176,26 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
 
     public class InterpreterProcess extends FleetProcess implements Runnable {
         private Instruction[] instructions;
-        public void flush() { }
-        public void sendWord(Destination d, BitVector word) {
-            throw new RuntimeException("not implemented");
+        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 void sendToken(Destination d) { throw new RuntimeException("not implemented"); }
         public InterpreterProcess(Instruction[] instructions) {
             this.instructions = instructions;
             for(Instruction i : instructions)
                 sendInstruction(i);
         }
         public Fleet getFleet() { return Interpreter.this; }
-        public void sendInstruction(Instruction i) { dispatch(i); }
+        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 {
@@ -166,10 +205,9 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
         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();
@@ -179,11 +217,21 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
             }
         }
 
-        public void step(Dock d) {
+        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 void step(Ship s) {
+        public synchronized void step(Ship s) {
             ((InterpreterShip)s).service();
         }