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.*;
18 public class Fpga extends FleetTwoFleet {
20 public Ship getShip(String type, int ordinal) {
22 if (s.getType().equals(type))
28 public int getWordWidth() { return 37; }
31 public FabricElement top_horn;
33 public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
34 public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
36 public static void main(String[] s) throws Exception {
39 new FunnelModule().dump(prefix);
40 new HornModule().dump(prefix);
42 new FifoModule(0).dump(prefix);
43 new FifoModule(4).dump(prefix);
44 new FifoModule(8).dump(prefix);
45 new FpgaDock.DockModule(false).dump(prefix);
46 new FpgaDock.DockModule(true).dump(prefix);
48 Module top = new Module("root");
49 new Fpga(top).top.dump(prefix);
52 public FleetProcess run(Instruction[] instructions) {
54 return new Client(this, "none", instructions);
55 } catch (Exception e) { throw new RuntimeException(e); }
58 // Setup //////////////////////////////////////////////////////////////////////////////
60 public Ship createShip(String type, String name) throws IOException {
61 ShipDescription sd = new ShipDescription(type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
62 FpgaShip ship = new FpgaShip(this, sd);
63 ships.put(name, ship);
67 public Fpga() throws Exception { this(new Module("root")); }
68 public Fpga(Module top) throws Exception {
70 debugShip = createShip("Debug", "debug");
71 createShip("Memory", "memory");
72 createShip("Fifo", "fifo1");
73 createShip("Fifo", "fifo2");
74 createShip("Alu2", "alu2a");
75 createShip("Rotator", "rotator");
76 //createShip("Alu1", "alu1");
77 createShip("Lut3", "lut3");
78 createShip("Alu3", "alu3");
80 Module fifostage = new FifoModule(0);
81 Module fifo4 = new FifoModule(4);
82 Module fifo8 = new FifoModule(8);
83 Module horn = new HornModule();
84 Module funnel = new FunnelModule();
85 Module outbox = new FpgaDock.DockModule(false);
86 Module inbox = new FpgaDock.DockModule(true);
88 Module.SinkPort debug_in = top.createWirePort("debug_in", WIDTH_PACKET);
89 Module.SourcePort debug_out = null;
90 for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
91 if (ship.getType().toLowerCase().equals("debug"))
92 debug_out = ship.getVerilogModule().getOutputPort("debug_out");
95 Module.SourcePort in = top.createInputPort("in", 8);
96 Module.SinkPort out = top.createOutputPort("out", 8, "");
97 Module.Latch temp_in = top.new Latch("temp", WIDTH_PACKET) { public String doReset() { return name+"=0;"; } };
98 Module.Latch count = top.new Latch("count", 8);
99 Module.Latch count_out = top.new Latch("count_out", 8);
100 top.new Event(new Object[] { in, debug_in },
101 new Object[] { new SimpleAction(temp_in.getVerilogName()+" = ("+temp_in.getVerilogName()+" << 8) | in;"),
102 new SimpleAction("if (count >= 5) begin"+
104 " `packet_token("+debug_in.getVerilogName()+") <= 0;"+
105 " `packet_data("+debug_in.getVerilogName()+") <= "+temp_in.getVerilogName()+";"+
106 " `packet_dest("+debug_in.getVerilogName()+") <= `instruction_dest("+temp_in.getVerilogName()+");"+
107 " "+debug_in.getVerilogName()+"_r <= 1; "+
108 "end else count <= count+1; "),
111 top.new Event(new Object[] { out, debug_out },
112 new Object[] { new SimpleAction(out.getVerilogName()+" <= ("+debug_out.getVerilogName()+">> (count_out*8));"),
113 new SimpleAction("if (count_out >= 5) begin "+
114 "count_out <= 0; "+debug_out.getVerilogName()+"_a <= 1; end"+
115 " else count_out <= count_out+1; "),
118 ArrayList sources = new ArrayList<FabricElement>();
119 ArrayList dests = new ArrayList<FabricElement>();
120 for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
121 if (ship.getType().toLowerCase().equals("debug"))
122 debug_out = ship.getVerilogModule().getOutputPort("debug_out");
123 for(Dock port : ship) {
124 sources.add(((FpgaDock)port));
125 dests.add(port.getInstructionDestination());
126 dests.add(port.getDataDestination());
129 top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
130 FabricElement source = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false);
131 FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, debug_in, source.getOutputPort());
132 ((FunnelModule.FunnelInstance)source).out = top_funnel;
133 //top_horn.addInput(top_funnel, top_funnel.getOutputPort());
134 top_funnel.addOutput(top_horn, top_horn.getInputPort());
137 public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); }
138 public FabricElement mkNode(FabricElement[] ports, boolean is_horn, int start, int end) {
141 case 1: return ports[start];
143 FabricElement leftPort = mkNode(ports, is_horn, start, (end+start)/2);
144 FabricElement rightPort = mkNode(ports, is_horn, (end+start)/2, end);
146 ? new HornModule.HornInstance(top, leftPort, rightPort)
147 : new FunnelModule.FunnelInstance(top, leftPort, rightPort);
152 public Module getVerilogModule() { return top; }
155 // Expand //////////////////////////////////////////////////////////////////////////////
157 public void expand(ShipDescription sd) {
159 if (sd.getSection("fpga")==null) return;
160 String filename = sd.getName().toLowerCase();
161 File outf = new File("build/fpga/"+filename+".v");
162 new File(outf.getParent()).mkdirs();
163 System.err.println("writing to " + outf);
164 FileOutputStream out = new FileOutputStream(outf);
165 PrintWriter pw = new PrintWriter(out);
167 boolean auto = !"debug".equals(filename);
170 pw.println("`include \"macros.v\"");
173 pw.print("`define reset ");
174 for(DockDescription bb : sd) {
175 String bb_name = bb.getName();
176 if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; ");
177 else pw.print(bb_name+"_r <= 0; ");
181 pw.println("module " + filename + "( clk, rst ");
182 for(DockDescription bb : sd) {
183 String bb_name = bb.getName();
185 if (bb.isInputDock()) {
186 pw.print(", " + bb_name+"_r");
187 pw.print(", " + bb_name+"_a_");
188 pw.print(", " + bb_name+"_d");
190 pw.print(", " + bb_name+"_r_");
191 pw.print(", " + bb_name+"_a");
192 pw.print(", " + bb_name+"_d_");
198 pw.println(" input clk;");
199 pw.println(" input rst;");
200 for(DockDescription bb : sd) {
201 String bb_name = bb.getName();
203 if (bb.isInputDock()) {
204 pw.println("`input(" +
208 "[("+WIDTH_WORD+"-1):0],"+
212 pw.println("`output(" +
216 "[("+WIDTH_WORD+"-1):0],"+
219 if (!bb_name.equals("out") || !"memory".equals(filename))
220 pw.println("`defreg(" +
222 "[("+WIDTH_WORD+"-1):0],"+
230 pw.println(sd.getSection("fpga"));
233 pw.println("endmodule");
237 } catch (Exception e) { throw new RuntimeException(e); }
244 public long getDestAddr(Path path) {
245 return ((FpgaPath)path).toLong();
247 public Dock getBoxByInstAddr(long dest) {
248 for(Ship ship : Fpga.this)
250 if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest)