1 package edu.berkeley.fleet.fpga;
2 import edu.berkeley.fleet.fpga.*;
3 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.two.*;
5 import edu.berkeley.fleet.*;
6 import java.lang.reflect.*;
7 import edu.berkeley.sbp.chr.*;
8 import edu.berkeley.sbp.misc.*;
9 import edu.berkeley.sbp.meta.*;
10 import edu.berkeley.sbp.util.*;
13 import edu.berkeley.fleet.two.*;
14 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
15 import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
16 import edu.berkeley.fleet.two.PercolatedPort;
19 public class Fpga extends FleetTwoFleet {
24 public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
25 public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
27 public Ship getShip(String type, int ordinal) {
29 if (s.getType().equals(type))
35 public static void main(String[] s) throws Exception {
36 new Fpga(new Module("main")).top.dump(s[0]);
39 pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(s[0]+"/timescale.v")));
40 pw.println("`timescale 1ns / 10ps");
43 pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(s[0]+"/vram.v")));
44 pw.println("`define BRAM_ADDR_WIDTH 19");
45 pw.println("`define BRAM_DATA_WIDTH 3");
46 pw.println("`define BRAM_SIZE (640*480)");
47 pw.println("`define BRAM_NAME vram");
48 pw.println("`include \"bram.inc\"");
52 public Module getVerilogModule() { return top; }
54 public FleetProcess run(Instruction[] instructions) {
56 return new Client(this, "none", instructions);
57 } catch (Exception e) { throw new RuntimeException(e); }
60 protected BitVector getDestAddr(Path path) {
61 return ((FpgaPath)path).toBitVector();
64 // Setup //////////////////////////////////////////////////////////////////////////////
66 Ship createShip(String type) throws IOException {
67 ShipDescription sd = new ShipDescription(this, type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
69 for(Ship ship : ships.values()) if (ship.getType().equals(type)) count++;
70 String name = type+count;
71 FpgaShip ship = new FpgaShip(this, sd);
72 ships.put(name, ship);
76 public Fpga() throws Exception { this(new Module("main")); }
77 public Fpga(Module top) throws Exception {
79 debugShip = createShip("Debug");
81 //boolean small = true;
82 boolean small = false;
85 for(int i=0; i<2; i++) createShip("Alu");
86 for(int i=0; i<1; i++) createShip("Memory");
87 for(int i=0; i<2; i++) createShip("Fifo");
88 createShip("Counter");
89 createShip("CarrySaveAdder");
90 createShip("Rotator");
99 for(int i=0; i<3; i++) createShip("Memory");
100 for(int i=0; i<3; i++) createShip("Alu");
101 for(int i=0; i<2; i++) createShip("Fifo");
102 for(int i=0; i<11; i++) createShip("Counter");
105 for(int i=0; i<3; i++) createShip("Memory");
106 for(int i=0; i<3; i++) createShip("Alu");
107 for(int i=0; i<2; i++) createShip("Fifo");
108 for(int i=0; i<14; i++) createShip("Counter");
110 // "really big" configuration: 138 docks
111 for(int i=0; i<4; i++) createShip("Alu");
114 //createShip("CarrySaveAdder");
115 //createShip("Rotator");
116 //createShip("Lut3");
125 new Module.InstantiatedModule(top, new FifoModule(8, WIDTH_WORD));
127 ArrayList dests = new ArrayList<FabricElement>();
128 ArrayList sources = new ArrayList<FabricElement>();
129 for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
130 for(Dock port : ship) {
131 if (port.isInputDock()) {
132 sources.add(((FpgaDock)port));
133 dests.add(port.getInstructionDestination());
134 dests.add(port.getDataDestination());
136 sources.add(((FpgaDock)port));
137 dests.add(port.getInstructionDestination());
138 dests.add(port.getDataDestination());
141 for(Module.SourcePort sp0 : ship.docklessPorts.values()) {
142 final Module.SourcePort sp = sp0;
143 sources.add(new FabricElement.AbstractFabricElement() {
144 private FabricElement upstream;
145 public FpgaPath getPath(FpgaDestination dest, BitVector signal) { return upstream.getPath(dest, signal); }
146 public void addOutput(FabricElement out, Module.Port outPort) {
148 sp.connect((Module.SinkPort)outPort);
153 FabricElement top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
154 mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false)
155 .addOutput(top_horn, top_horn.getInputPort());
158 public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); }
159 public FabricElement mkNode(FabricElement[] ports, boolean is_horn, int start, int end) {
161 case 0: throw new RuntimeException("this should never happen");
162 case 1: return ports[start];
164 FabricElement leftPort = mkNode(ports, is_horn, start, (end+start)/2);
165 FabricElement rightPort = mkNode(ports, is_horn, (end+start)/2, end);
167 ? new HornModule.HornInstance(this, top, leftPort, rightPort)
168 : new FunnelModule.FunnelInstance(this, top, leftPort, rightPort);
174 // Expand //////////////////////////////////////////////////////////////////////////////
176 public void expand(ShipDescription sd) {
178 if (sd.getSection("fpga")==null) return;
179 String filename = sd.getName().toLowerCase();
181 if (sd.getSection("ucf") != null) {
182 File outf = new File("build/fpga/"+filename+".ucf");
183 FileOutputStream out = new FileOutputStream(outf);
184 PrintWriter pw = new PrintWriter(out);
185 pw.println(sd.getSection("ucf"));
190 File outf = new File("build/fpga/"+filename+".v");
191 new File(outf.getParent()).mkdirs();
192 System.err.println("writing to " + outf);
193 FileOutputStream out = new FileOutputStream(outf);
194 PrintWriter pw = new PrintWriter(out);
196 pw.println("`define WORDWIDTH "+WIDTH_WORD);
197 pw.println("`define CODEBAG_SIZE_BITS "+CBD_SIZE.valmaskwidth);
200 for(DockDescription dd : sd.ports()) {
201 String name = dd.getName();
202 pw.println("`define "+name+"_full ("+name+"_r && !"+name+"_a)");
203 pw.println("`define "+name+"_empty (!"+name+"_r && !"+name+"_a)");
204 if (dd.isInputDock()) {
205 // gets stuck on colliding-tokens
206 //pw.println("`define drain_"+name+" if ("+name+"_r && !"+name+"_a) "+name+"_a <= 1;");
208 // gets stuck on colliding-tokens
209 //pw.println("`define drain_"+name+" if ("+name+"_r) "+name+"_a <= 1;");
212 //pw.println("`define drain_"+name+" if (!"+name+"_a) "+name+"_a <= 1;");
213 pw.println("`define drain_"+name+" "+name+"_a <= 1;");
215 pw.println("`define fill_"+name+" "+name+"_r <= 1;");
219 pw.print("`define reset ");
220 for(DockDescription bb : sd.ports()) {
221 String bb_name = bb.getName();
222 if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; ");
223 else pw.print(bb_name+"_r <= 0; ");
227 pw.print("`define cleanup ");
230 for(DockDescription dd : sd.ports())
231 if (!dd.isInputDock())
232 pw.print("if ( "+dd.getName()+"_r && "+dd.getName()+"_a) "+dd.getName()+"_r <= 0; ");
234 // input docks: if all inputs are flushing, drain them all
236 for(DockDescription bb : sd.ports())
237 if (bb.isInputDock())
238 pw.print(" && "+bb.getName()+"_f");
239 pw.print(") begin ");
240 for(DockDescription bb : sd.ports())
241 if (bb.isInputDock())
242 pw.print(bb.getName()+"_a <= 1; ");
244 // input docks: if no inputs are flushing, do normal stuff
245 pw.print("end else if (1");
246 for(DockDescription bb : sd.ports())
247 if (bb.isInputDock())
248 pw.print(" && !"+bb.getName()+"_f");
249 pw.print(") begin ");
251 for(DockDescription bb : sd.ports())
252 if (bb.isInputDock())
253 pw.print("if (!"+bb.getName()+"_r_ && "+bb.getName()+"_a) "+bb.getName()+"_a <= 0; ");
255 // input docks: if some-but-not-all inputs are flushing, drain all non-flushing docks
256 pw.print("end else begin ");
258 for(DockDescription bb : sd.ports())
259 if (bb.isInputDock()) {
260 pw.print("if (!"+bb.getName()+"_r && "+bb.getName()+"_a) "+bb.getName()+"_a <= 0; ");
261 pw.print("if ("+bb.getName()+"_r && !"+bb.getName()+"_a) "+bb.getName()+"_a <= 1; ");
268 pw.println("module " + filename + "( clk, rst ");
269 for(DockDescription bb : sd.ports()) {
270 String bb_name = bb.getName();
272 if (bb.isInputDock()) {
273 pw.print(", " + bb_name+"_r_");
274 pw.print(", " + bb_name+"_a_");
275 pw.print(", " + bb_name+"_d");
277 pw.print(", " + bb_name+"_r_");
278 pw.print(", " + bb_name+"_a");
279 pw.print(", " + bb_name+"_d_");
283 for(PercolatedPort pp : sd.percolatedPorts) {
289 pw.println(" input clk;");
290 pw.println(" input rst;");
291 for(PercolatedPort pp : sd.percolatedPorts) {
293 case UP: pw.print("output"); break;
294 case DOWN: pw.print("input"); break;
295 case INOUT: pw.print("inout"); break;
299 pw.print("["+(pp.width-1)+":0]");
305 for(DockDescription bb : sd.ports()) {
306 String bb_name = bb.getName();
307 int width = bb.isDockless() ? WIDTH_PACKET : WIDTH_WORD;
308 if (bb.isInputDock()) {
309 pw.println(" input ["+width+":0] "+bb_name+"_d;");
310 pw.println(" input "+bb_name+"_r_;");
311 pw.println(" wire "+bb_name+"_r;");
312 pw.println(" assign "+bb_name+"_r = "+bb_name+"_r_ & ~"+bb_name+"_d["+width+"];");
313 pw.println(" output "+bb_name+"_a_;");
314 pw.println(" reg "+bb_name+"_a;");
315 pw.println(" initial "+bb_name+"_a = 0;");
316 pw.println(" wire "+bb_name+"_f;");
317 pw.println(" assign "+bb_name+"_f = "+bb_name+"_r_ & "+bb_name+"_d["+width+"] && ~"+bb_name+"_a;");
318 pw.println(" assign "+bb_name+"_a_ = "+bb_name+"_a;");
320 pw.println(" output ["+width+":0] "+bb_name+"_d_;");
321 pw.println(" input "+bb_name+"_a;");
322 pw.println(" output "+bb_name+"_r_;");
323 pw.println(" reg "+bb_name+"_r;");
324 pw.println(" initial "+bb_name+"_r = 0;");
325 pw.println(" assign "+bb_name+"_r_ = "+bb_name+"_r;");
330 if (filename.equals("fifo")) {
331 pw.println(" wire in_a__;");
332 pw.println(" wire out_r__;");
333 pw.println(" fifo8x37 fifo8x37(clk, rst,");
334 pw.println(" in_r, in_a__, in_d,");
335 pw.println(" out_r__, out_a, out_d_);");
336 pw.println(" always @(posedge clk) begin");
337 pw.println(" if (rst) begin");
338 pw.println(" `reset");
339 pw.println(" end else begin");
340 pw.println(" `cleanup");
341 pw.println(" out_r <= out_r__;");
342 pw.println(" if (in_a__) in_a <= 1;");
346 pw.println(sd.getSection("fpga"));
349 pw.println("endmodule");
353 } catch (Exception e) { throw new RuntimeException(e); }