update bitfile and list of tests that work
[fleet.git] / src / edu / berkeley / fleet / slipway / Slipway.java
index a97d404..35b0fe5 100644 (file)
@@ -1,5 +1,5 @@
 package edu.berkeley.fleet.slipway;
-import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.slipway.*;
 import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
@@ -8,53 +8,61 @@ 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.interpreter.ships.*;
 
-public class Slipway extends Interpreter {
+public class Slipway extends Fleet {
 
-    public Slipway() { this("superbowl.bit"); }
+    public ArrayList<SlipwayShip> shiplist   = new ArrayList<SlipwayShip>();
+    public HashMap<String,SlipwayShip> ships = new HashMap<String,SlipwayShip>();
+    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
+
+    private String bitfile;
+
+    public static void main(String[] s) throws Exception {
+        new Slipway().dumpFabric(false);
+    }
+
+    public Slipway() { this("summer1.bit"); }
     public Slipway(String bitfile) {
+        this.bitfile = bitfile;
+        createShip("Debug",   "debug");
         createShip("Alu2",    "alu2a");
         createShip("Alu2",    "alu2b");
         createShip("Alu2",    "alu2c");
         createShip("Alu2",    "alu2d");
-        createShip("Debug",   "debug");
-        //createShip("Execute", "execute");
         createShip("Fifo",    "fifo1");
         createShip("Fifo",    "fifo2");
         createShip("Fifo",    "fifo3");
         createShip("Fifo",    "fifo4");
-        createShip("Iscratch",  "iscratch1");
-        createShip("Iscratch",  "iscratch2");
-        createShip("Dscratch",  "dscratch1");
-        createShip("Dscratch",  "dscratch2");
+        createShip("Execute", "execute");
+        createShip("Memory",    "Memory");
+        createShip("Memory",    "Memory");
+        createShip("Lut3",      "lut3");
+        createShip("Alu1",      "alu1");
+        createShip("Alu3",      "alu3");
+        createShip("Choice",    "Choice");
+        createShip("Choice",    "Choice");
+        createShip("Choice",    "Choice");
+        createShip("Choice",    "Choice");
+        createShip("Stack",     "Stack");
         dumpFabric(true);
     }
 
     public Ship createShip(String type, String name) {
-        InterpreterShip ship = (InterpreterShip)super.createShip(type, name);
-        if        (ship.getClass().getSimpleName().equals("Debug")) {
-            new DataOutbox(ship, "out", true);
-            
-        } else if (ship.getClass().getSimpleName().equals("Execute")) {
-            new DataOutbox(ship, "ihorn", true, true, false);
-            new DataOutbox(ship, "dhorn", true, false, true);
-            
-        } else if (ship.getClass().getSimpleName().equals("Iscratch")) {
-            new DataInbox(ship,  "command", true);
-            new DataOutbox(ship, "ihorn",   true, true, false);
-            new DataOutbox(ship, "dhorn",   true, false, true);
-        }
-        return ship;
+        try {
+            ShipDescription sd = new ShipDescription(new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
+            SlipwayShip ship = new SlipwayShip(this, name, type, sd);
+            ships.put(name, ship);
+            shiplist.add(ship);
+            return ship;
+        } catch (IOException e) { throw new RuntimeException(e); }
     }
 
     public FleetProcess run(final byte[] instructions) {
         try {
-            return new Client(instructions);
+            return new Client(bitfile, instructions);
         } catch (IOException e) { throw new RuntimeException(e); }
     }
 
@@ -62,59 +70,59 @@ public class Slipway extends Interpreter {
         // 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<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList instructionports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special())
+                if (!((SlipwayBenkoBox)port).special())
                     instructionports.add(port);
         FabricTree instructions =
-            new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])instructionports.toArray(new SlipwayBenkoBox[0]),
                            "ihorn",
                            "instruction");
 
-        ArrayList inputports = new ArrayList<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList inputports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special())
+                if (!((SlipwayBenkoBox)port).special())
                     inputports.add(port);
         FabricTree inputs =
-            new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])inputports.toArray(new SlipwayBenkoBox[0]),
                            "horn",
                            "dest");
 
-        ArrayList outputports = new ArrayList<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList outputports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special() || ((InterpreterBenkoBox)port).dhorn())
+                if (!((SlipwayBenkoBox)port).special() || ((SlipwayBenkoBox)port).dhorn())
                     outputports.add(port);
         FabricTree outputs =
-            new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])outputports.toArray(new SlipwayBenkoBox[0]),
                            "funnel",
                            "source");
 
-        ArrayList ihornports = new ArrayList<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList ihornports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (((InterpreterBenkoBox)port).ihorn())
+                if (((SlipwayBenkoBox)port).ihorn())
                     ihornports.add(port);
         FabricTree ihorns =
-            new FabricTree((InterpreterBenkoBox[])ihornports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])ihornports.toArray(new SlipwayBenkoBox[0]),
                            "funnel",
                            "ihorn");
         
         if (quiet) return;
         System.out.println("`include \"macros.v\"");
-        System.out.println("module fabric(clk, data_Iscratch0_command_r, data_Iscratch0_command_a, data_Iscratch0_command,");
+        System.out.println("module fabric(clk, data_Memory0_command_r, data_Memory0_command_a, data_Memory0_command,");
         System.out.println("                   data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);");
         System.out.println("  input  clk;");
-        System.out.println("  input  data_Iscratch0_command_r;");
-        System.out.println("  output data_Iscratch0_command_a;");
+        System.out.println("  input  data_Memory0_command_r;");
+        System.out.println("  output data_Memory0_command_a;");
         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("  input  [(`PACKET_WIDTH-1):0]      data_Iscratch0_command;");
-        //System.out.println("  wire   [(`INSTRUCTION_WIDTH-1):0] data_Iscratch0_ihorn;");
-        //System.out.println("  wire   [(`PACKET_WIDTH-1):0]      data_Iscratch0_dhorn;");
+        System.out.println("  input  [(`PACKET_WIDTH-1):0]      data_Memory0_command;");
+        //System.out.println("  wire   [(`INSTRUCTION_WIDTH-1):0] data_Memory0_ihorn;");
+        //System.out.println("  wire   [(`PACKET_WIDTH-1):0]      data_Memory0_dhorn;");
         System.out.println();
         
         System.out.println();
@@ -123,9 +131,9 @@ public class Slipway extends Interpreter {
         outputs.dumpChannels(true);
         inputs.dumpChannels(true);
         ihorns.dumpChannels(true);
-        for(InterpreterShip ship : shiplist)
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special() || ((InterpreterBenkoBox)port).dhorn())
+                if (!((SlipwayBenkoBox)port).special() || ((SlipwayBenkoBox)port).dhorn())
                     System.out.println("  wire [(`PACKET_WIDTH-1):0] data_"
                                        +getUniqueName(ship)+"_"+port.getName()+";");
 
@@ -138,8 +146,8 @@ public class Slipway extends Interpreter {
         System.out.println("");
         ihorns.dumpChannels(false);
         System.out.println("");
-        for(InterpreterShip ship : shiplist) {
-            System.out.print(ship.getClass().getSimpleName().toLowerCase());
+        for(SlipwayShip ship : shiplist) {
+            System.out.print(ship.getType().toLowerCase());
             System.out.print(" ");
             System.out.print("krunk"+(krunk++));
             System.out.print("(clk, ");
@@ -148,8 +156,8 @@ public class Slipway extends Interpreter {
                 if (!first) System.out.print(", ");
                 first = false;
                 String prefix = "data_";
-                if (((InterpreterBenkoBox)port).ihorn()) prefix = "ihorn_";
-                if (((InterpreterBenkoBox)port).dhorn()) prefix = "source_";
+                if (((SlipwayBenkoBox)port).ihorn()) prefix = "ihorn_";
+                if (((SlipwayBenkoBox)port).dhorn()) prefix = "source_";
                 System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
                 System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
                 System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName());
@@ -158,8 +166,8 @@ public class Slipway extends Interpreter {
             System.out.println(");");
 
             for(BenkoBox port : ship.getBenkoBoxes()) {
-                if (((InterpreterBenkoBox)port).special()) continue;
-                if (port instanceof Inbox) {
+                if (((SlipwayBenkoBox)port).special()) continue;
+                if (((SlipwayBenkoBox)port).inbox) {
                     System.out.print("inbox");
                 } else {
                     System.out.print("outbox");
@@ -186,7 +194,7 @@ public class Slipway extends Interpreter {
         System.out.println("funnel topfun(clk,"+
                            "              dest_r, dest_a, dest,"+
                            "              source_r, source_a, source,"+
-                           "              data_Iscratch0_dhorn_r, data_Iscratch0_dhorn_a, data_Iscratch0_dhorn);");
+                           "              data_Memory0_dhorn_r, data_Memory0_dhorn_a, data_Memory0_dhorn);");
         */
         System.out.println("assign instruction_r = ihorn_r;");
         System.out.println("assign ihorn_a = instruction_a;");
@@ -202,36 +210,59 @@ public class Slipway extends Interpreter {
         String prefix;
         Node root;
         public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
-        public FabricTree(InterpreterBenkoBox[] ports, String component, String prefix) {
+        public FabricTree(SlipwayBenkoBox[] 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, InterpreterBenkoBox[] ports,
+        private Object mkNode(String name, String component, SlipwayBenkoBox[] ports,
                               int start, int end, int addr, int bits) {
             if (end-start == 0) return null;
             if (end-start == 1) {
-                InterpreterBenkoBox p = ports[start];
+                SlipwayBenkoBox p = ports[start];
                 if (prefix.equals("instruction")) {
                     p.instr_addr = addr;
                     p.instr_bits = bits;
                 } else if (prefix.equals("dest")) {
                     p.addr = addr;
                     p.bits = bits;
+                    if (bits >= 11)
+                        throw new RuntimeException("too many benkoboxen!");
+                    int count = 0;
+                    for(Destination d : p.getDestinations()) {
+                        if (!(d instanceof SlipwayBenkoBox.VirtualPort)) continue;
+                        SlipwayBenkoBox.VirtualPort vp = (SlipwayBenkoBox.VirtualPort)d;
+                        vp.addr = p.addr | (count << bits);
+                        count++;
+                    }
                 }
                 return p;
             }
             int len = end-start;
+            int count   = 0;
+            int count2  = 0;
+            int breakpt = 0;
+            if (end-start <= 2) {
+                breakpt = (start+end)/2;
+            } else {
+                for(int i=start; i<end; i++)
+                    count += count(ports[i].getDestinations());
+                for(int i=start; i<end-1; i++) {
+                    count2 += count(ports[i].getDestinations());
+                    breakpt = i;
+                    if (i>start && count2 >= count/2) break;
+                }
+            }
             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),
+                            mkNode(name+"_0", component, ports, start, breakpt, addr,               bits+1),
+                            mkNode(name+"_1", component, ports, breakpt, end,   addr | (1 << bits), bits+1),
                             addr,
                             bits);
         }
         private String describe(String prefix, Object o) {
             if (o==null) return null;
-            if (o instanceof InterpreterBenkoBox) {
-                InterpreterBenkoBox p = (InterpreterBenkoBox)o;
+            if (o instanceof SlipwayBenkoBox) {
+                SlipwayBenkoBox p = (SlipwayBenkoBox)o;
                 return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
             }
             if (o instanceof Node) {
@@ -304,24 +335,31 @@ public class Slipway extends Interpreter {
         return ship.getType() + ship.getOrdinal();
     }
 
+    private static int count(Iterable<Destination> it) {
+        int ret = 0;
+        for(Destination d : it)
+            ret++;
+        return ret;
+    }
+
     public void expand(ShipDescription sd) {
         try {
-            String filename = sd.name.toLowerCase();
+            String filename = sd.getName().toLowerCase();
             File outf = new File("src/edu/berkeley/fleet/slipway/"+filename+".v");
             new File(outf.getParent()).mkdirs();
             System.err.println("writing to " + outf);
             FileOutputStream out = new FileOutputStream(outf);
             PrintWriter pw = new PrintWriter(out);
 
-            if (filename.equals("alu2")) {
+            boolean auto = filename.equals("alu2") || filename.equals("alu1") || filename.equals("alu2b") || filename.equals("lut3") || filename.equals("choice") || filename.equals("alu3") || filename.equals("stack") || filename.equals("mul");
+            if (auto) {
                 pw.println("`include \"macros.v\"");
                 pw.println();
                 pw.println("module " + filename + "( clk");
-                for(ShipDescription.BenkoBox bb : sd.benkoBoxes) {
-                    if (bb.ports.length > 1) throw new RuntimeException("gah");
-                    String bb_name = bb.ports[0];
+                for(BenkoBoxDescription bb : sd) {
+                    String bb_name = bb.getName();
                     pw.print("        ");
-                    if (bb.inbox) {
+                    if (bb.isInbox()) {
                         pw.print(", " + bb_name+"_r");
                         pw.print(", " + bb_name+"_a_");
                         pw.print(", " + bb_name+"_d");
@@ -333,12 +371,74 @@ public class Slipway extends Interpreter {
                     pw.println();
                 }
                 pw.println("        );");
+                pw.println();
+                pw.println("    input clk;");
+                for(BenkoBoxDescription bb : sd) {
+                    String bb_name = bb.getName();
+                    pw.print("        ");
+                    if (bb.isInbox()) {
+                        pw.println("`input(" +
+                                   bb_name+"_r,  "+
+                                   bb_name+"_a,  "+
+                                   bb_name+"_a_, "+
+                                   "[(`PACKET_WIDTH-1):0],"+
+                                   bb_name+"_d)"
+                                   );
+                    } else {
+                        pw.println("`output(" +
+                                   bb_name+"_r,  "+
+                                   bb_name+"_r_, "+
+                                   bb_name+"_a,  "+
+                                   "[(`PACKET_WIDTH-1):0],"+
+                                   bb_name+"_d_)"
+                                   );
+                        pw.println("`defreg(" +
+                                   bb_name+"_d_,  "+
+                                   "[(`PACKET_WIDTH-1):0],"+
+                                   bb_name+"_d)"
+                                   );
+                    }
+                    pw.println();
+                }
             }
 
-            pw.println(sd.sections.get("fpga"));
+            pw.println(sd.getSection("fpga"));
+
+            if (auto)
+                pw.println("endmodule");
+
             pw.flush();
             pw.close();
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
+    public int computeOffset(int origin, int target) { return (target - origin)/6; }
+    public int computeTarget(int origin, int offset) { return origin + (offset*6); }
+
+    private SlipwayInstructionEncoder iie = new SlipwayInstructionEncoder();
+    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 SlipwayInstructionEncoder extends InstructionEncoder {
+        public long getDestAddr(Destination box) { return ((SlipwayBenkoBox.VirtualPort)box).addr; }
+        public long getBoxInstAddr(BenkoBox box) { return ((SlipwayBenkoBox)box).instr_addr; }
+        public Destination getDestByAddr(long dest) {
+            for(Ship ship : Slipway.this)
+                for(BenkoBox bb : ship.getBenkoBoxes())
+                    for(Destination d : bb.getDestinations())
+                        if (getDestAddr(d)==dest)
+                            return d;
+            return null;
+        }
+        public BenkoBox getBoxByInstAddr(long dest) {
+            for(Ship ship : Slipway.this)
+                for(BenkoBox bb : ship.getBenkoBoxes())
+                    if (((SlipwayBenkoBox)bb).instr_addr == dest)
+                        return bb;
+            return null;
+        }
+    }
+
 }
\ No newline at end of file