updated to AM14, AM15
[fleet.git] / src / edu / berkeley / fleet / interpreter / Interpreter.java
similarity index 52%
rename from src/edu/berkeley/fleet/Fleet.java
rename to src/edu/berkeley/fleet/interpreter/Interpreter.java
index 13e53eb..1126de7 100644 (file)
@@ -1,5 +1,8 @@
-package edu.berkeley.fleet;
+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.*;
@@ -10,7 +13,33 @@ import java.util.*;
 import java.io.*;
 import edu.berkeley.fleet.ships.*;
 
-public class Fleet {
+public class Interpreter extends Fleet implements Iterable<Ship> {
+
+    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;
@@ -18,23 +47,79 @@ public class Fleet {
     public int[] mem = new int[0];
     public ArrayList<String> imports = new ArrayList<String>();
 
-    public ArrayList<Ship> shiplist = new ArrayList<Ship>();
-    public HashMap<String,Ship> ships = new HashMap<String,Ship>();
+    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
+        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<Ship> iterator() {
+        return (Iterator<Ship>)(Object)shiplist.iterator();
+    }
 
     public void go() {
         while(!halt)
-            for(Ship ship : ships.values())
+            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(Ship ship : ships.values())
+            for(InterpreterShip ship : ships.values())
                 for(int j=0; j<10; j++)
                     ship._service();
 
         // check the state of the ships
-        for(Ship ship : ships.values())
+        for(InterpreterShip ship : ships.values())
             ship.shutdown();
 
         Log.println(Log.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
@@ -59,29 +144,31 @@ public class Fleet {
         mem[addr] = data;
     }
 
-    public Ship getShip(String name) {
-        Ship s = ships.get(name);
+    public InterpreterShip getShip(String name) {
+        InterpreterShip s = ships.get(name);
         if (s == null) throw new RuntimeException("unknown ship \""+name+"\"");
         return s;
     }
 
-    boolean tryCreate(String classname, String shipname) {
+    public InterpreterShip tryCreate(String classname, String shipname) {
         try {
             Class c = Class.forName(classname);
-            Constructor con = c.getConstructor(new Class[] { Fleet.class, String.class });
-            con.newInstance(new Object[] { this, shipname });
-            return true;
+            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 false;
+            return null;
         }
     }
 
-    public void sendToken(Port source, Port dest) {
+    public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
         Log.token(source, dest);
         dest.addTokenFromFabric();
     }
 
-    public void sendData(Port source, int data, Port dest) {
+    public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
         Log.data(data+"", source, dest);
         dest.addDataFromFabric(data);
     }
@@ -90,33 +177,33 @@ public class Fleet {
         // 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<Port>();
-        for(Ship ship : shiplist)
-            for(Port port : ship.portlist)
-                if (!port.special())
+        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((Port[])instructionports.toArray(new Port[0]),
+            new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
                            "ihorn",
                            "instruction");
 
-        ArrayList inputports = new ArrayList<Port>();
-        for(Ship ship : shiplist)
-            for(Port port : ship.portlist)
-                if (!port.special())
+        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((Port[])inputports.toArray(new Port[0]),
+            new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
                            "horn",
                            "dest");
 
-        ArrayList outputports = new ArrayList<Port>();
-        for(Ship ship : shiplist)
-            for(Port port : ship.portlist)
-                if (!port.special())
+        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((Port[])outputports.toArray(new Port[0]),
+            new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
                            "funnel",
                            "source");
 
@@ -136,7 +223,6 @@ public class Fleet {
         System.out.println("  input  top_r;");
         System.out.println("  output top_a;");
         System.out.println("  input  [(`PACKET_WIDTH-1):0] top;");
-        //        System.out.println("  wire   [(`PACKET_WIDTH-1):0] dest;");
         System.out.println("  output data_debug_out_r;");
         System.out.println("  input  data_debug_out_a;");
         System.out.println("  output [(`PACKET_WIDTH-1):0] data_debug_out;");
@@ -148,10 +234,10 @@ public class Fleet {
         instructions.dumpChannels(true);
         outputs.dumpChannels(true);
         inputs.dumpChannels(true);
-        for(Ship ship : shiplist)
-            for(Port port : ship.portlist) {
-                if (ship instanceof CommandShip && port instanceof Outbox) continue;
-                System.out.println("  wire [(`PACKET_WIDTH-1):0] data_"+ship.getName()+"_"+port.getName()+";");
+        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()+";");
             }
 
         System.out.println("");
@@ -161,26 +247,26 @@ public class Fleet {
         System.out.println("");
         inputs.dumpChannels(false);
         System.out.println("");
-        for(Ship ship : shiplist) {
-            System.out.print(ship.getBalsaName());
+        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(Port port : ship.portlist) {
+            for(BenkoBox port : ship.getBenkoBoxes()) {
                 if (!first) System.out.print(", ");
                 first = false;
-                System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
-                System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
-                System.out.print("data_"+port.getShip().getName()+"_"+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(");");
 
-            for(Port port : ship.portlist) {
-                if (port.special()) continue;
+            for(BenkoBox port : ship.getBenkoBoxes()) {
+                if (((InterpreterBenkoBox)port).special()) continue;
                 if (port instanceof Inbox) {
-                    if (port.noInbox())
+                    if (((InterpreterBenkoBox)port).noInbox())
                         System.out.print("stupidinbox");
                     else
                         System.out.print("inbox");
@@ -188,18 +274,18 @@ public class Fleet {
                     System.out.print("outbox");
                 }
                 System.out.print(" krunk"+(krunk++)+"(clk, ");
-                System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
-                System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
-                System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName()+", ");
-                System.out.print("dest_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
-                System.out.print("dest_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
-                System.out.print("dest_"+port.getShip().getName()+"_"+port.getName()+", ");
-                System.out.print("source_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
-                System.out.print("source_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
-                System.out.print("source_"+port.getShip().getName()+"_"+port.getName()+", ");
-                System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
-                System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
-                System.out.print("data_"+port.getShip().getName()+"_"+port.getName());
+                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();
             }
@@ -218,14 +304,14 @@ public class Fleet {
         String prefix;
         Node root;
         public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
-        public FabricTree(Port[] ports, String component, String prefix) {
+        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, Port[] ports, int start, int end, int addr, int bits) {
+        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) {
-                Port p = ports[start];
+                InterpreterBenkoBox p = ports[start];
                 if (prefix.equals("instruction")) {
                     p.instr_addr = addr;
                     p.instr_bits = bits;
@@ -245,9 +331,9 @@ public class Fleet {
         }
         private String describe(String prefix, Object o) {
             if (o==null) return null;
-            if (o instanceof Port) {
-                Port p = (Port)o;
-                return prefix+"_"+p.getShip().getName()+"_"+p.getName();
+            if (o instanceof InterpreterBenkoBox) {
+                InterpreterBenkoBox p = (InterpreterBenkoBox)o;
+                return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
             }
             if (o instanceof Node) {
                 return ((Node)o).describe(prefix);