update to AM15
[fleet.git] / src / edu / berkeley / fleet / Fleet.java
1 package edu.berkeley.fleet;
2
3 import java.lang.reflect.*;
4 import edu.berkeley.sbp.chr.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.meta.*;
7 import edu.berkeley.sbp.bind.*;
8 import edu.berkeley.sbp.util.*;
9 import java.util.*;
10 import java.io.*;
11 import edu.berkeley.fleet.ships.*;
12
13 public class Fleet {
14
15     /** some "halt ship" can turn this on to stop the interpreter */
16     public boolean halt = false;
17
18     public int[] mem = new int[0];
19     public ArrayList<String> imports = new ArrayList<String>();
20
21     public ArrayList<Ship> shiplist = new ArrayList<Ship>();
22     public HashMap<String,Ship> ships = new HashMap<String,Ship>();
23
24     public void go() {
25         while(!halt)
26             for(Ship ship : ships.values())
27                 for(int j=0; j<10; j++)
28                     ship._service();
29
30         // run the ships a bit longer for good measure
31         for(int i=0; i<100; i++)
32             for(Ship ship : ships.values())
33                 for(int j=0; j<10; j++)
34                     ship._service();
35
36         // check the state of the ships
37         for(Ship ship : ships.values())
38             ship.shutdown();
39
40         Log.println(Log.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
41     }
42
43     public void dumpMem() {
44         Log.print(Log.cyan("  MEMORY: "));
45         for(int i=0; i<mem.length; i++) {
46             if ((i%10)==0 && i!=0) Log.print(Log.cyan("          "));
47             Log.print(Log.cyan(mem[i] + " "));
48             if ((i%10)==9 && i!=mem.length-1) Log.println("");
49         }
50         Log.println();
51     }
52
53     public void writeMem(int addr, int data) {
54         if (addr >= mem.length) {
55             int[] mem2 = new int[addr*2+1];
56             System.arraycopy(mem, 0, mem2, 0, mem2.length);
57             mem = mem2;
58         }
59         mem[addr] = data;
60     }
61
62     public Ship getShip(String name) {
63         Ship s = ships.get(name);
64         if (s == null) throw new RuntimeException("unknown ship \""+name+"\"");
65         return s;
66     }
67
68     boolean tryCreate(String classname, String shipname) {
69         try {
70             Class c = Class.forName(classname);
71             Constructor con = c.getConstructor(new Class[] { Fleet.class, String.class });
72             con.newInstance(new Object[] { this, shipname });
73             return true;
74         } catch (Exception e) {
75             return false;
76         }
77     }
78
79     public void sendToken(Port source, Port dest) {
80         Log.token(source, dest);
81         dest.addTokenFromFabric();
82     }
83
84     public void sendData(Port source, int data, Port dest) {
85         Log.data(data+"", source, dest);
86         dest.addDataFromFabric(data);
87     }
88
89     public void dumpFabric(boolean quiet) {
90         // FIXME: this is really ugly: the order of port declarations in
91         //        the XXXShip.java file must match the order in the .balsa file!
92
93         ArrayList instructionports = new ArrayList<Port>();
94         for(Ship ship : shiplist)
95             for(Port port : ship.portlist)
96                 if (!port.special())
97                     instructionports.add(port);
98         FabricTree instructions =
99             new FabricTree((Port[])instructionports.toArray(new Port[0]),
100                            "ihorn",
101                            "instruction");
102
103         ArrayList inputports = new ArrayList<Port>();
104         for(Ship ship : shiplist)
105             for(Port port : ship.portlist)
106                 if (!port.special())
107                     inputports.add(port);
108         FabricTree inputs =
109             new FabricTree((Port[])inputports.toArray(new Port[0]),
110                            "horn",
111                            "dest");
112
113         ArrayList outputports = new ArrayList<Port>();
114         for(Ship ship : shiplist)
115             for(Port port : ship.portlist)
116                 if (!port.special())
117                     outputports.add(port);
118         FabricTree outputs =
119             new FabricTree((Port[])outputports.toArray(new Port[0]),
120                            "funnel",
121                            "source");
122
123         if (quiet) return;
124         System.out.println("`include \"macros.v\"");
125         /*
126         HashSet<Class> added = new HashSet<Class>();
127         for(Ship ship : shiplist)
128             if (!added.contains(ship.getClass())) {
129                 added.add(ship.getClass());
130                 System.out.println("import ["+ship.getBalsaName()+"]");
131             }
132         */
133         System.out.println("module fabric(clk, top_r, top_a, top,");
134         System.out.println("                   data_debug_out_r, data_debug_out_a, data_debug_out);");
135         System.out.println("  input  clk;");
136         System.out.println("  input  top_r;");
137         System.out.println("  output top_a;");
138         System.out.println("  input  [(`PACKET_WIDTH-1):0] top;");
139         //        System.out.println("  wire   [(`PACKET_WIDTH-1):0] dest;");
140         System.out.println("  output data_debug_out_r;");
141         System.out.println("  input  data_debug_out_a;");
142         System.out.println("  output [(`PACKET_WIDTH-1):0] data_debug_out;");
143         System.out.println("  wire   [(`INSTRUCTION_WIDTH-1):0] data_command_out;");
144         System.out.println();
145         
146         System.out.println();
147
148         instructions.dumpChannels(true);
149         outputs.dumpChannels(true);
150         inputs.dumpChannels(true);
151         for(Ship ship : shiplist)
152             for(Port port : ship.portlist) {
153                 if (ship instanceof CommandShip && port instanceof Outbox) continue;
154                 System.out.println("  wire [(`PACKET_WIDTH-1):0] data_"+ship.getName()+"_"+port.getName()+";");
155             }
156
157         System.out.println("");
158         instructions.dumpChannels(false);
159         System.out.println("");
160         outputs.dumpChannels(false);
161         System.out.println("");
162         inputs.dumpChannels(false);
163         System.out.println("");
164         for(Ship ship : shiplist) {
165             System.out.print(ship.getBalsaName());
166             System.out.print(" ");
167             System.out.print("krunk"+(krunk++));
168             System.out.print("(clk, ");
169             boolean first = true;
170             for(Port port : ship.portlist) {
171                 if (!first) System.out.print(", ");
172                 first = false;
173                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
174                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
175                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName());
176                 System.out.print(" ");
177             }
178             System.out.println(");");
179
180             for(Port port : ship.portlist) {
181                 if (port.special()) continue;
182                 if (port instanceof Inbox) {
183                     if (port.noInbox())
184                         System.out.print("stupidinbox");
185                     else
186                         System.out.print("inbox");
187                 } else {
188                     System.out.print("outbox");
189                 }
190                 System.out.print(" krunk"+(krunk++)+"(clk, ");
191                 System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
192                 System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
193                 System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName()+", ");
194                 System.out.print("dest_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
195                 System.out.print("dest_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
196                 System.out.print("dest_"+port.getShip().getName()+"_"+port.getName()+", ");
197                 System.out.print("source_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
198                 System.out.print("source_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
199                 System.out.print("source_"+port.getShip().getName()+"_"+port.getName()+", ");
200                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_r, ");
201                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName()+"_a, ");
202                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName());
203                 System.out.print(");");
204                 System.out.println();
205             }
206
207         }
208         System.out.println("funnel topfun(clk, dest_r, dest_a, dest, source_r, source_a, source, top_r, top_a, top);");
209         System.out.println("");
210         System.out.println("  assign instruction_r      = data_command_out_r;");
211         System.out.println("  assign data_command_out_a = instruction_a;");
212         System.out.println("  assign instruction        = data_command_out;");
213         System.out.println("endmodule");
214     }
215
216     private static class FabricTree {
217         int master_idx = 1;
218         String prefix;
219         Node root;
220         public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
221         public FabricTree(Port[] ports, String component, String prefix) {
222             this.prefix = prefix;
223             root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
224         }
225         private Object mkNode(String name, String component, Port[] ports, int start, int end, int addr, int bits) {
226             if (end-start == 0) return null;
227             if (end-start == 1) {
228                 Port p = ports[start];
229                 if (prefix.equals("instruction")) {
230                     p.instr_addr = addr;
231                     p.instr_bits = bits;
232                 } else {
233                     p.addr = addr;
234                     p.bits = bits;
235                 }
236                 return p;
237             }
238             int len = end-start;
239             return new Node(name,
240                             component,
241                             mkNode(name+"_0", component, ports, start, start+len/2, addr, bits+1),
242                             mkNode(name+"_1", component, ports, start+len/2, end,   addr | (1 << bits), bits+1),
243                             addr,
244                             bits);
245         }
246         private String describe(String prefix, Object o) {
247             if (o==null) return null;
248             if (o instanceof Port) {
249                 Port p = (Port)o;
250                 return prefix+"_"+p.getShip().getName()+"_"+p.getName();
251             }
252             if (o instanceof Node) {
253                 return ((Node)o).describe(prefix);
254             }
255             return null;
256         }
257         private class Node {
258             Object left;
259             Object right;
260             String name;
261             String component;
262         int addr;
263         int bits;
264             public Node(String name, String component, Object left, Object right, int addr, int bits) {
265                 this.left = left;
266                 this.right = right;
267                 this.name = name;
268                 this.component = component;
269                 this.addr = addr;
270                 this.bits = bits;
271             }
272             public void dumpChannels(int indentamount, boolean decl) {
273                 String indent = "";
274                 for(int i=0; i<indentamount; i++) indent += "  ";
275                 if (decl) {
276                     String n = describe(prefix).startsWith("instruction") ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
277                     System.out.println("  wire "+n+" "+indent+describe(prefix)+";");
278                 } else {
279                     System.out.println("     "+indent+
280                                        component+" "+
281                                        "krunk"+(krunk++)+"(clk, "+
282                                        describe(prefix)+"_r, "+
283                                        describe(prefix)+"_a, "+
284                                        describe(prefix)+", "+
285                                        FabricTree.this.describe(prefix, left)+"_r, "+
286                                        FabricTree.this.describe(prefix, left)+"_a, "+
287                                        FabricTree.this.describe(prefix, left)+", "+
288                                        FabricTree.this.describe(prefix, right)+"_r, "+
289                                        FabricTree.this.describe(prefix, right)+"_a, "+
290                                        FabricTree.this.describe(prefix, right)+
291                                        ");");
292                 }
293                 dumpChannels(left, indentamount+1, decl);
294                 dumpChannels(right, indentamount+1, decl);
295             }
296             public void dumpChannels(Object o, int indentamount, boolean decl) {
297                 if (o==null) return;
298                 if (o instanceof Node) {
299                     ((Node)o).dumpChannels(indentamount, decl);
300                 } else {
301                     String indent = "";
302                     for(int i=0; i<indentamount; i++) indent += "  ";
303                     if (decl) {
304                         String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
305                             ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
306                         System.out.println("  wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
307                     }
308                 }
309             }
310             public String describe(String prefix) {
311                 return prefix+name;
312             }
313         }
314     }
315     public static int krunk=0;
316 }