checkpoint
[fleet.git] / src / edu / berkeley / fleet / Fleet.java
index 2c570be..cd41c9f 100644 (file)
@@ -8,6 +8,7 @@ import edu.berkeley.sbp.bind.*;
 import edu.berkeley.sbp.util.*;
 import java.util.*;
 import java.io.*;
+import edu.berkeley.fleet.ships.*;
 
 public class Fleet {
 
@@ -17,6 +18,7 @@ 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>();
 
     public void go() {
@@ -83,4 +85,178 @@ public class Fleet {
         Log.data(data+"", source, dest);
         dest.addDataFromFabric(data);
     }
+
+    public void dumpFabric(boolean quiet) {
+        // 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)
+                instructionports.add(port);
+        FabricTree instructions =
+            new FabricTree((Port[])instructionports.toArray(new Port[0]),
+                           "horn",
+                           "instruction");
+
+        ArrayList inputports = new ArrayList<Port>();
+        for(Ship ship : shiplist)
+            for(Port port : ship.portlist)
+                if (port instanceof Inbox)
+                    inputports.add(port);
+        FabricTree inputs =
+            new FabricTree((Port[])inputports.toArray(new Port[0]),
+                           "horn",
+                           "dest");
+
+        ArrayList outputports = new ArrayList<Port>();
+        for(Ship ship : shiplist)
+            for(Port port : ship.portlist)
+                if (port instanceof Outbox && !(port.getShip() instanceof DebugShip))
+                    outputports.add(port);
+        FabricTree outputs =
+            new FabricTree((Port[])outputports.toArray(new Port[0]),
+                           "funnel",
+                           "source");
+
+        if (quiet) return;
+        System.out.println("import [balsa.sim.portio]");
+        System.out.println("import [xbit]");
+        System.out.println("import [funnel]");
+        System.out.println("import [horn]");
+        System.out.println("import [par2ser]");
+        System.out.println("import [ser2par]");
+
+        HashSet<Class> added = new HashSet<Class>();
+        for(Ship ship : shiplist)
+            if (!added.contains(ship.getClass())) {
+                added.add(ship.getClass());
+                System.out.println("import ["+ship.getBalsaName()+"]");
+            }
+
+        System.out.println("procedure fabric(input top_in:XBit; output top_out:XBit)");
+        System.out.println("is");
+        System.out.println("  channel source_debug_out : XBit");
+        instructions.dumpChannels(true);
+        outputs.dumpChannels(true);
+        inputs.dumpChannels(true);
+        System.out.println("begin");
+        System.out.println("     loop source -> dest end");
+        System.out.println("  || loop top_in -> instruction end");
+        System.out.println("  || loop source_debug_out -> top_out end");
+        System.out.println("");
+        instructions.dumpChannels(false);
+        System.out.println("");
+        outputs.dumpChannels(false);
+        System.out.println("");
+        inputs.dumpChannels(false);
+        System.out.println("");
+        for(Ship ship : shiplist) {
+            System.out.print("  || ");
+            System.out.print(ship.getBalsaName());
+            System.out.print("(");
+            boolean first = true;
+            for(Port port : ship.portlist) {
+                if (!first) System.out.print(", ");
+                first = false;
+                System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName());
+                System.out.print(",");
+                if (port instanceof Inbox)
+                    System.out.print("dest_"+port.getShip().getName()+"_"+port.getName());
+                else
+                    System.out.print("source_"+port.getShip().getName()+"_"+port.getName());
+                System.out.print(" ");
+            }
+            System.out.println(")");
+        }
+        System.out.println("end");
+    }
+
+    private static class FabricTree {
+        int master_idx = 1;
+        String prefix;
+        Node root;
+        public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
+        public FabricTree(Port[] 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) {
+            if (end-start == 0) return null;
+            if (end-start == 1) {
+                Port p = ports[start];
+                if (prefix.equals("instruction")) {
+                    p.instr_addr = addr;
+                    p.instr_bits = bits;
+                } else {
+                    p.addr = addr;
+                    p.bits = bits;
+                }
+                return p;
+            }
+            int len = end-start;
+            return new Node(name,
+                            component,
+                            mkNode(name+"_0", component, ports, start, start+len/2, (addr<<1)|0, bits+1),
+                            mkNode(name+"_1", component, ports, start+len/2, end, (addr<<1)|1, bits+1),
+                            addr,
+                            bits);
+        }
+        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 Node) {
+                return ((Node)o).describe(prefix);
+            }
+            return null;
+        }
+        private class Node {
+            Object left;
+            Object right;
+            String name;
+            String component;
+        int addr;
+        int bits;
+            public Node(String name, String component, Object left, Object right, int addr, int bits) {
+                this.left = left;
+                this.right = right;
+                this.name = name;
+                this.component = component;
+                this.addr = addr;
+                this.bits = bits;
+            }
+            public void dumpChannels(int indentamount, boolean decl) {
+                String indent = "";
+                for(int i=0; i<indentamount; i++) indent += "  ";
+                if (decl) {
+                    System.out.println("  channel "+indent+describe(prefix)+" : XBit");
+                } else {
+                    System.out.println("  || "+indent+
+                                       component+"("+describe(prefix)+
+                                       ", "+FabricTree.this.describe(prefix, left)+
+                                       ", "+FabricTree.this.describe(prefix, right)+")");
+                }
+                dumpChannels(left, indentamount+1, decl);
+                dumpChannels(right, indentamount+1, decl);
+            }
+            public void dumpChannels(Object o, int indentamount, boolean decl) {
+                if (o==null) return;
+                if (o instanceof Node) {
+                    ((Node)o).dumpChannels(indentamount, decl);
+                } else {
+                    String indent = "";
+                    for(int i=0; i<indentamount; i++) indent += "  ";
+                    if (decl)
+                        System.out.println("  channel "+indent+FabricTree.this.describe(prefix,o)+" :XBit");
+                }
+            }
+            public String describe(String prefix) {
+                return prefix+name;
+            }
+        }
+    }
+
 }