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; }
29 private static final BitVector SIGNAL_ZERO = new BitVector(1);
30 private static final BitVector SIGNAL_ONE = new BitVector(1);
32 SIGNAL_ONE.set(0,true);
36 public FabricElement top_horn;
38 public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
39 public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
41 public static void main(String[] s) throws Exception {
44 new FunnelModule().dump(prefix);
45 new HornModule().dump(prefix);
47 new FifoModule(0).dump(prefix);
48 new FifoModule(4).dump(prefix);
49 new FifoModule(8).dump(prefix);
50 new FpgaDock.DockModule(false).dump(prefix);
51 new FpgaDock.DockModule(true).dump(prefix);
53 Module top = new Module("root");
54 new Fpga(top).top.dump(prefix);
57 public FleetProcess run(Instruction[] instructions) {
59 return new Client(this, "none", instructions);
60 } catch (Exception e) { throw new RuntimeException(e); }
63 // Setup //////////////////////////////////////////////////////////////////////////////
65 public Ship createShip(String type, String name) throws IOException {
66 ShipDescription sd = new ShipDescription(type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
67 FpgaShip ship = new FpgaShip(this, sd);
68 ships.put(name, ship);
72 public Fpga() throws Exception { this(new Module("root")); }
73 public Fpga(Module top) throws Exception {
75 debugShip = createShip("Debug", "debug");
76 createShip("Memory", "memory");
77 createShip("Fifo", "fifo1");
78 createShip("Fifo", "fifo2");
79 createShip("Alu2", "alu2a");
80 createShip("Rotator", "rotator");
81 //createShip("Alu1", "alu1");
82 createShip("Lut3", "lut3");
83 createShip("Alu3", "alu3");
85 Module fifostage = new FifoModule(0);
86 Module fifo4 = new FifoModule(4);
87 Module fifo8 = new FifoModule(8);
88 Module horn = new HornModule();
89 Module funnel = new FunnelModule();
90 Module outbox = new FpgaDock.DockModule(false);
91 Module inbox = new FpgaDock.DockModule(true);
93 Module.SinkPort debug_in = top.createWirePort("debug_in", WIDTH_PACKET);
94 Module.SourcePort debug_out = null;
95 for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
96 if (ship.getType().toLowerCase().equals("debug"))
97 debug_out = ship.getVerilogModule().getOutputPort("debug_out");
100 Module.SourcePort in = top.createInputPort("in", 8);
101 Module.SinkPort out = top.createOutputPort("out", 8, "");
102 Module.Latch temp_in = top.new Latch("temp", WIDTH_PACKET) { public String doReset() { return name+"=0;"; } };
103 Module.Latch count = top.new Latch("count", 8);
104 Module.Latch count_out = top.new Latch("count_out", 8);
105 top.new Event(new Object[] { in, debug_in },
106 new Object[] { new SimpleAction(temp_in.getVerilogName()+" = ("+temp_in.getVerilogName()+" << 8) | in;"),
107 new SimpleAction("if (count >= 5) begin"+
109 " `packet_token("+debug_in.getVerilogName()+") <= 0;"+
110 " `packet_data("+debug_in.getVerilogName()+") <= "+temp_in.getVerilogName()+";"+
111 " `packet_dest("+debug_in.getVerilogName()+") <= `instruction_dest("+temp_in.getVerilogName()+");"+
112 " "+debug_in.getVerilogName()+"_r <= 1; "+
113 "end else count <= count+1; "),
116 top.new Event(new Object[] { out, debug_out },
117 new Object[] { new SimpleAction(out.getVerilogName()+" <= ("+debug_out.getVerilogName()+">> (count_out*8));"),
118 new SimpleAction("if (count_out >= 5) begin "+
119 "count_out <= 0; "+debug_out.getVerilogName()+"_a <= 1; end"+
120 " else count_out <= count_out+1; "),
123 ArrayList sources = new ArrayList<FabricElement>();
124 ArrayList dests = new ArrayList<FabricElement>();
125 for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
126 if (ship.getType().toLowerCase().equals("debug"))
127 debug_out = ship.getVerilogModule().getOutputPort("debug_out");
128 for(Dock port : ship) {
129 sources.add(((FpgaDock)port));
130 dests.add(port.getInstructionDestination());
131 dests.add(port.getDataDestination());
134 top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
135 FabricElement source = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false);
136 FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, debug_in, source.getOutputPort());
137 ((FunnelModule.FunnelInstance)source).out = top_funnel;
138 //top_horn.addInput(top_funnel, top_funnel.getOutputPort());
139 top_funnel.addOutput(top_horn, top_horn.getInputPort());
142 public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); }
143 public FabricElement mkNode(FabricElement[] ports, boolean is_horn, int start, int end) {
146 case 1: return ports[start];
148 FabricElement leftPort = mkNode(ports, is_horn, start, (end+start)/2);
149 FabricElement rightPort = mkNode(ports, is_horn, (end+start)/2, end);
151 ? new HornModule.HornInstance(top, leftPort, rightPort)
152 : new FunnelModule.FunnelInstance(top, leftPort, rightPort);
157 public Module getVerilogModule() { return top; }
160 // Expand //////////////////////////////////////////////////////////////////////////////
162 public void expand(ShipDescription sd) {
164 if (sd.getSection("fpga")==null) return;
165 String filename = sd.getName().toLowerCase();
166 File outf = new File("build/fpga/"+filename+".v");
167 new File(outf.getParent()).mkdirs();
168 System.err.println("writing to " + outf);
169 FileOutputStream out = new FileOutputStream(outf);
170 PrintWriter pw = new PrintWriter(out);
172 boolean auto = !"debug".equals(filename);
175 pw.println("`include \"macros.v\"");
178 pw.print("`define reset ");
179 for(DockDescription bb : sd) {
180 String bb_name = bb.getName();
181 if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; ");
182 else pw.print(bb_name+"_r <= 0; ");
186 pw.println("module " + filename + "( clk, rst ");
187 for(DockDescription bb : sd) {
188 String bb_name = bb.getName();
190 if (bb.isInputDock()) {
191 pw.print(", " + bb_name+"_r");
192 pw.print(", " + bb_name+"_a_");
193 pw.print(", " + bb_name+"_d");
195 pw.print(", " + bb_name+"_r_");
196 pw.print(", " + bb_name+"_a");
197 pw.print(", " + bb_name+"_d_");
203 pw.println(" input clk;");
204 pw.println(" input rst;");
205 for(DockDescription bb : sd) {
206 String bb_name = bb.getName();
208 if (bb.isInputDock()) {
209 pw.println("`input(" +
213 "[("+WIDTH_WORD+"-1):0],"+
217 pw.println("`output(" +
221 "[("+WIDTH_WORD+"-1):0],"+
224 if (!bb_name.equals("out") || !"memory".equals(filename))
225 pw.println("`defreg(" +
227 "[("+WIDTH_WORD+"-1):0],"+
235 pw.println(sd.getSection("fpga"));
238 pw.println("endmodule");
242 } catch (Exception e) { throw new RuntimeException(e); }
246 private Ship debugShip;
249 public Dock getUniversalSource() { return debugShip.getDock("in"); }
250 public long getDestAddr(Path path) {
251 return ((FpgaPath)path).toLong();
253 public Path getPathByAddr(Dock source, long dest) {
254 for(Ship ship : Fpga.this)
255 for(Dock bb : ship) {
256 for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {
257 for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) {
258 FpgaPath p = (FpgaPath)source.getPath(d, signal);
259 if (p.toLong() == dest) return p;
265 public Dock getBoxByInstAddr(long dest) {
266 for(Ship ship : Fpga.this)
268 if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest)