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