make bitfile= option work
[fleet.git] / src / edu / berkeley / fleet / slipway / Slipway.java
1 package edu.berkeley.fleet.slipway;
2 import edu.berkeley.fleet.interpreter.*;
3 import edu.berkeley.fleet.doc.*;
4 import edu.berkeley.fleet.api.*;
5 import edu.berkeley.fleet.ies44.*;
6 import edu.berkeley.fleet.*;
7 import java.lang.reflect.*;
8 import edu.berkeley.sbp.chr.*;
9 import edu.berkeley.sbp.misc.*;
10 import edu.berkeley.sbp.meta.*;
11 import edu.berkeley.sbp.bind.*;
12 import edu.berkeley.sbp.util.*;
13 import java.util.*;
14 import java.io.*;
15 import edu.berkeley.fleet.interpreter.ships.*;
16
17 public class Slipway extends Interpreter {
18
19     private String bitfile;
20
21     public Slipway() { this("superbowl.bit"); }
22     public Slipway(String bitfile) {
23         this.bitfile = bitfile;
24         createShip("Debug",   "debug");
25         createShip("Fifo",    "fifo1");
26         createShip("Alu2",    "alu2a");
27         createShip("Alu2",    "alu2b");
28         createShip("Alu2",    "alu2c");
29         createShip("Alu2",    "alu2d");
30         createShip("Debug",   "debug");
31         //createShip("Execute", "execute");
32         createShip("Fifo",    "fifo1");
33         createShip("Fifo",    "fifo2");
34         createShip("Fifo",    "fifo3");
35         createShip("Fifo",    "fifo4");
36         createShip("Iscratch",  "iscratch1");
37         createShip("Iscratch",  "iscratch2");
38         createShip("Dscratch",  "dscratch1");
39         createShip("Dscratch",  "dscratch2");
40         dumpFabric(true);
41     }
42
43     public Ship createShip(String type, String name) {
44         InterpreterShip ship = (InterpreterShip)super.createShip(type, name);
45         if        (ship.getClass().getSimpleName().equals("Debug")) {
46             new DataOutbox(ship, "out", true);
47             
48         } else if (ship.getClass().getSimpleName().equals("Execute")) {
49             new DataOutbox(ship, "ihorn", true, true, false);
50             new DataOutbox(ship, "dhorn", true, false, true);
51             
52         } else if (ship.getClass().getSimpleName().equals("Iscratch")) {
53             new DataInbox(ship,  "command", true);
54             new DataOutbox(ship, "ihorn",   true, true, false);
55             new DataOutbox(ship, "dhorn",   true, false, true);
56         }
57         return ship;
58     }
59
60     public FleetProcess run(final byte[] instructions) {
61         try {
62             return new Client(bitfile, instructions);
63         } catch (IOException e) { throw new RuntimeException(e); }
64     }
65
66     public void dumpFabric(boolean quiet) {
67         // FIXME: this is really ugly: the order of port declarations in
68         //        the XXXShip.java file must match the order in the .balsa file!
69
70         ArrayList instructionports = new ArrayList<InterpreterBenkoBox>();
71         for(InterpreterShip ship : shiplist)
72             for(BenkoBox port : ship.getBenkoBoxes())
73                 if (!((InterpreterBenkoBox)port).special())
74                     instructionports.add(port);
75         FabricTree instructions =
76             new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
77                            "ihorn",
78                            "instruction");
79
80         ArrayList inputports = new ArrayList<InterpreterBenkoBox>();
81         for(InterpreterShip ship : shiplist)
82             for(BenkoBox port : ship.getBenkoBoxes())
83                 if (!((InterpreterBenkoBox)port).special())
84                     inputports.add(port);
85         FabricTree inputs =
86             new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
87                            "horn",
88                            "dest");
89
90         ArrayList outputports = new ArrayList<InterpreterBenkoBox>();
91         for(InterpreterShip ship : shiplist)
92             for(BenkoBox port : ship.getBenkoBoxes())
93                 if (!((InterpreterBenkoBox)port).special() || ((InterpreterBenkoBox)port).dhorn())
94                     outputports.add(port);
95         FabricTree outputs =
96             new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
97                            "funnel",
98                            "source");
99
100         ArrayList ihornports = new ArrayList<InterpreterBenkoBox>();
101         for(InterpreterShip ship : shiplist)
102             for(BenkoBox port : ship.getBenkoBoxes())
103                 if (((InterpreterBenkoBox)port).ihorn())
104                     ihornports.add(port);
105         FabricTree ihorns =
106             new FabricTree((InterpreterBenkoBox[])ihornports.toArray(new InterpreterBenkoBox[0]),
107                            "funnel",
108                            "ihorn");
109         
110         if (quiet) return;
111         System.out.println("`include \"macros.v\"");
112         System.out.println("module fabric(clk, data_Iscratch0_command_r, data_Iscratch0_command_a, data_Iscratch0_command,");
113         System.out.println("                   data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);");
114         System.out.println("  input  clk;");
115         System.out.println("  input  data_Iscratch0_command_r;");
116         System.out.println("  output data_Iscratch0_command_a;");
117         System.out.println("  output data_Debug0_out_r;");
118         System.out.println("  input  data_Debug0_out_a;");
119         System.out.println("  output [(`PACKET_WIDTH-1):0]      data_Debug0_out;");
120         System.out.println("  input  [(`PACKET_WIDTH-1):0]      data_Iscratch0_command;");
121         //System.out.println("  wire   [(`INSTRUCTION_WIDTH-1):0] data_Iscratch0_ihorn;");
122         //System.out.println("  wire   [(`PACKET_WIDTH-1):0]      data_Iscratch0_dhorn;");
123         System.out.println();
124         
125         System.out.println();
126
127         instructions.dumpChannels(true);
128         outputs.dumpChannels(true);
129         inputs.dumpChannels(true);
130         ihorns.dumpChannels(true);
131         for(InterpreterShip ship : shiplist)
132             for(BenkoBox port : ship.getBenkoBoxes())
133                 if (!((InterpreterBenkoBox)port).special() || ((InterpreterBenkoBox)port).dhorn())
134                     System.out.println("  wire [(`PACKET_WIDTH-1):0] data_"
135                                        +getUniqueName(ship)+"_"+port.getName()+";");
136
137         System.out.println("");
138         instructions.dumpChannels(false);
139         System.out.println("");
140         outputs.dumpChannels(false);
141         System.out.println("");
142         inputs.dumpChannels(false);
143         System.out.println("");
144         ihorns.dumpChannels(false);
145         System.out.println("");
146         for(InterpreterShip ship : shiplist) {
147             System.out.print(ship.getClass().getSimpleName().toLowerCase());
148             System.out.print(" ");
149             System.out.print("krunk"+(krunk++));
150             System.out.print("(clk, ");
151             boolean first = true;
152             for(BenkoBox port : ship.getBenkoBoxes()) {
153                 if (!first) System.out.print(", ");
154                 first = false;
155                 String prefix = "data_";
156                 if (((InterpreterBenkoBox)port).ihorn()) prefix = "ihorn_";
157                 if (((InterpreterBenkoBox)port).dhorn()) prefix = "source_";
158                 System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
159                 System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
160                 System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName());
161                 System.out.print(" ");
162             }
163             System.out.println(");");
164
165             for(BenkoBox port : ship.getBenkoBoxes()) {
166                 if (((InterpreterBenkoBox)port).special()) continue;
167                 if (port instanceof Inbox) {
168                     System.out.print("inbox");
169                 } else {
170                     System.out.print("outbox");
171                 }
172                 System.out.print(" krunk"+(krunk++)+"(clk, ");
173                 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
174                 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
175                 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
176                 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
177                 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
178                 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
179                 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
180                 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
181                 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
182                 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
183                 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
184                 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
185                 System.out.print(");");
186                 System.out.println();
187             }
188
189         }
190         /*
191         System.out.println("funnel topfun(clk,"+
192                            "              dest_r, dest_a, dest,"+
193                            "              source_r, source_a, source,"+
194                            "              data_Iscratch0_dhorn_r, data_Iscratch0_dhorn_a, data_Iscratch0_dhorn);");
195         */
196         System.out.println("assign instruction_r = ihorn_r;");
197         System.out.println("assign ihorn_a = instruction_a;");
198         System.out.println("assign instruction = ihorn;");
199         System.out.println("assign dest_r = source_r;");
200         System.out.println("assign source_a = dest_a;");
201         System.out.println("assign dest = source;");
202         System.out.println("endmodule");
203     }
204
205     private static class FabricTree {
206         int master_idx = 1;
207         String prefix;
208         Node root;
209         public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
210         public FabricTree(InterpreterBenkoBox[] ports, String component, String prefix) {
211             this.prefix = prefix;
212             root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
213         }
214         private Object mkNode(String name, String component, InterpreterBenkoBox[] ports,
215                               int start, int end, int addr, int bits) {
216             if (end-start == 0) return null;
217             if (end-start == 1) {
218                 InterpreterBenkoBox p = ports[start];
219                 if (prefix.equals("instruction")) {
220                     p.instr_addr = addr;
221                     p.instr_bits = bits;
222                 } else if (prefix.equals("dest")) {
223                     p.addr = addr;
224                     p.bits = bits;
225                 }
226                 return p;
227             }
228             int len = end-start;
229             return new Node(name,
230                             component,
231                             mkNode(name+"_0", component, ports, start, start+len/2, addr, bits+1),
232                             mkNode(name+"_1", component, ports, start+len/2, end,   addr | (1 << bits), bits+1),
233                             addr,
234                             bits);
235         }
236         private String describe(String prefix, Object o) {
237             if (o==null) return null;
238             if (o instanceof InterpreterBenkoBox) {
239                 InterpreterBenkoBox p = (InterpreterBenkoBox)o;
240                 return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
241             }
242             if (o instanceof Node) {
243                 return ((Node)o).describe(prefix);
244             }
245             return null;
246         }
247         private class Node {
248             Object left;
249             Object right;
250             String name;
251             String component;
252             int addr;
253             int bits;
254             public Node(String name, String component, Object left, Object right, int addr, int bits) {
255                 this.left = left;
256                 this.right = right;
257                 this.name = name;
258                 this.component = component;
259                 this.addr = addr;
260                 this.bits = bits;
261             }
262             public void dumpChannels(int indentamount, boolean decl) {
263                 String indent = "";
264                 for(int i=0; i<indentamount; i++) indent += "  ";
265                 if (decl) {
266                     String n = describe(prefix).startsWith("instruction")
267                         ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
268                     System.out.println("  wire "+n+" "+indent+describe(prefix)+";");
269                 } else {
270                     System.out.println("     "+indent+
271                                        component+" "+
272                                        "krunk"+(krunk++)+"(clk, "+
273                                        describe(prefix)+"_r, "+
274                                        describe(prefix)+"_a, "+
275                                        describe(prefix)+", "+
276                                        FabricTree.this.describe(prefix, left)+"_r, "+
277                                        FabricTree.this.describe(prefix, left)+"_a, "+
278                                        FabricTree.this.describe(prefix, left)+", "+
279                                        FabricTree.this.describe(prefix, right)+"_r, "+
280                                        FabricTree.this.describe(prefix, right)+"_a, "+
281                                        FabricTree.this.describe(prefix, right)+
282                                        ");");
283                 }
284                 dumpChannels(left, indentamount+1, decl);
285                 dumpChannels(right, indentamount+1, decl);
286             }
287             public void dumpChannels(Object o, int indentamount, boolean decl) {
288                 if (o==null) return;
289                 if (o instanceof Node) {
290                     ((Node)o).dumpChannels(indentamount, decl);
291                 } else {
292                     String indent = "";
293                     for(int i=0; i<indentamount; i++) indent += "  ";
294                     if (decl) {
295                         String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
296                             ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
297                         System.out.println("  wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
298                     }
299                 }
300             }
301             public String describe(String prefix) {
302                 return prefix+name;
303             }
304         }
305     }
306     public static int krunk=0;
307
308     private static String getUniqueName(Ship ship) {
309         return ship.getType() + ship.getOrdinal();
310     }
311
312     public void expand(ShipDescription sd) {
313         try {
314             String filename = sd.name.toLowerCase();
315             File outf = new File("src/edu/berkeley/fleet/slipway/"+filename+".v");
316             new File(outf.getParent()).mkdirs();
317             System.err.println("writing to " + outf);
318             FileOutputStream out = new FileOutputStream(outf);
319             PrintWriter pw = new PrintWriter(out);
320
321             if (filename.equals("alu2")) {
322                 pw.println("`include \"macros.v\"");
323                 pw.println();
324                 pw.println("module " + filename + "( clk");
325                 for(ShipDescription.BenkoBox bb : sd.benkoBoxes) {
326                     if (bb.ports.length > 1) throw new RuntimeException("gah");
327                     String bb_name = bb.ports[0];
328                     pw.print("        ");
329                     if (bb.inbox) {
330                         pw.print(", " + bb_name+"_r");
331                         pw.print(", " + bb_name+"_a_");
332                         pw.print(", " + bb_name+"_d");
333                     } else {
334                         pw.print(", " + bb_name+"_r_");
335                         pw.print(", " + bb_name+"_a");
336                         pw.print(", " + bb_name+"_d_");
337                     }
338                     pw.println();
339                 }
340                 pw.println("        );");
341             }
342
343             pw.println(sd.sections.get("fpga"));
344             pw.flush();
345             pw.close();
346         } catch (Exception e) { throw new RuntimeException(e); }
347     }
348
349 }