X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Ffpga%2FFpga.java;h=26bbc8f8f172841f64ff5b2e01a46047b991cfa3;hb=28e41c98c299d834bb5ec9a749126d858dc81bf0;hp=9db10b3da88d81c5c47fdaef7abdd07579c20f02;hpb=3954a9875a2575e3729a54da9beffc3f7b719504;p=fleet.git diff --git a/src/edu/berkeley/fleet/fpga/Fpga.java b/src/edu/berkeley/fleet/fpga/Fpga.java index 9db10b3..26bbc8f 100644 --- a/src/edu/berkeley/fleet/fpga/Fpga.java +++ b/src/edu/berkeley/fleet/fpga/Fpga.java @@ -13,21 +13,12 @@ import java.io.*; import edu.berkeley.fleet.two.*; import static edu.berkeley.fleet.two.FleetTwoFleet.*; import static edu.berkeley.fleet.fpga.verilog.Verilog.*; +import edu.berkeley.fleet.two.PercolatedPort; -/* -=> get rid of getInputPort(String) and instead use members -=> clean up fabricelement methods -=> get rid of addcrap -=> automatic width-setting on ports -=> nuke DATAWIDTH? - => serdes and fastclock/slowclock? -*/ - -public class Fpga extends FleetTwoFleet { +public abstract class Fpga extends FleetTwoFleet { public Module top; - public FabricElement top_horn; Ship debugShip; public LinkedHashMap ships = new LinkedHashMap(); @@ -42,214 +33,200 @@ public class Fpga extends FleetTwoFleet { } public static void main(String[] s) throws Exception { - new Fpga(new Module("root")).top.dump(s[0]); + ((Fpga)Fleet.getDefaultImpl()).top.dump(s[0]); + PrintWriter pw; + + pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(s[0]+"/timescale.v"))); + pw.println("`timescale 1ns / 10ps"); + pw.close(); + + pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(s[0]+"/vram.v"))); + pw.println("`define BRAM_ADDR_WIDTH 19"); + pw.println("`define BRAM_DATA_WIDTH 3"); + pw.println("`define BRAM_SIZE (640*480)"); + pw.println("`define BRAM_NAME vram"); + pw.println("`include \"bram.inc\""); + pw.close(); } + public Module getVerilogModule() { return top; } + public FleetProcess run(Instruction[] instructions) { try { return new Client(this, "none", instructions); } catch (Exception e) { throw new RuntimeException(e); } } + protected BitVector getDestAddr(Path path) { + return ((FpgaPath)path).toBitVector(); + } + // Setup ////////////////////////////////////////////////////////////////////////////// - public Ship createShip(String type, String name) throws IOException { - ShipDescription sd = new ShipDescription(type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship")))); + Ship createShip(String type) throws IOException { + ShipDescription sd = new ShipDescription(this, type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship")))); + int count = 0; + for(Ship ship : ships.values()) if (ship.getType().equals(type)) count++; + String name = type+count; FpgaShip ship = new FpgaShip(this, sd); ships.put(name, ship); return ship; } - public Fpga() throws Exception { this(new Module("root")); } - public Fpga(Module top) throws Exception { - this.top = top; - debugShip = createShip("Debug", "debug"); - - boolean small = false; - - createShip("Memory", "memory1"); - - if (small) { - createShip("Fifo", "fifo"); - createShip("Alu", "alu"); - } else { - //createShip("Memory", "memory2"); - //createShip("Memory", "memory3"); - - for(int i=0; i<5; i++) - createShip("Alu", "alu"+i); - - for(int i=0; i<2; i++) - createShip("Fifo", "fifo"+i); - - for(int i=0; i<13; i++) - createShip("Counter", "counter"+i); - - createShip("CarrySaveAdder", "csa1"); - createShip("Rotator", "rotator"); - createShip("Lut3", "lut"); - - //createShip("DDR2", "ddr2"); - } - createShip("DRAM", "dram"); - createShip("Video", "video"); - - //Module.SourcePort debug_in = top.createWireSourcePort("debug_in", WIDTH_PACKET); - Module.SourcePort debug_out = null; - for(FpgaShip ship : (Iterable)(Object)this) { - if (ship.getType().toLowerCase().equals("debug")) - debug_out = ship.getVerilogModule().getOutputPort("debug_out"); - } + protected Fpga() throws IOException { + this.top = new Module("main"); + this.debugShip = createShip("Debug"); + } + protected void init() throws IOException { // for FifoShip new Module.InstantiatedModule(top, new FifoModule(8, WIDTH_WORD)); - Module.SourcePort in = top.createInputPort("in", 8); - Module.SinkPort out = top.createOutputPort("out", 8, ""); - Module.Latch temp_in = top.new Latch("temp", WIDTH_PACKET); - Module.Latch count = top.new Latch("count", 8); - Module.Latch count_out = top.new Latch("count_out", 8); - - ArrayList inbox_sources = new ArrayList(); - ArrayList inbox_dests = new ArrayList(); - ArrayList outbox_sources = new ArrayList(); - ArrayList outbox_dests = new ArrayList(); - ArrayList instruction_dests = new ArrayList(); - int numdocks = 0; + ArrayList dests = new ArrayList(); + ArrayList sources = new ArrayList(); for(FpgaShip ship : (Iterable)(Object)this) { - if (ship.getType().toLowerCase().equals("debug")) - debug_out = ship.getVerilogModule().getOutputPort("debug_out"); for(Dock port : ship) { if (port.isInputDock()) { - inbox_sources.add(((FpgaDock)port)); - instruction_dests.add(port.getInstructionDestination()); - inbox_dests.add(port.getDataDestination()); + sources.add(((FpgaDock)port)); + dests.add(port.getInstructionDestination()); + dests.add(port.getDataDestination()); } else { - outbox_sources.add(((FpgaDock)port)); - instruction_dests.add(port.getInstructionDestination()); - outbox_dests.add(port.getDataDestination()); + sources.add(((FpgaDock)port)); + dests.add(port.getInstructionDestination()); + dests.add(port.getDataDestination()); } - numdocks++; + } + for(Module.SourcePort sp0 : ship.docklessPorts.values()) { + final Module.SourcePort sp = sp0; + sources.add(new FabricElement.AbstractFabricElement() { + private FabricElement upstream; + public int getPathLength(FpgaDestination dest) { return upstream.getPathLength(dest); } + public FpgaPath getPath(FpgaDestination dest, BitVector signal) { return upstream.getPath(dest, signal); } + public void addOutput(FabricElement out, Module.Port outPort) { + this.upstream = out; + sp.connect((Module.SinkPort)outPort); + } + }); } } - //System.err.println("dock count = " + numdocks); - ArrayList dests = new ArrayList(); - ArrayList sources = new ArrayList(); - sources.addAll(inbox_sources); - sources.addAll(outbox_sources); - dests.addAll(inbox_dests); - dests.addAll(instruction_dests); - dests.addAll(outbox_dests); - top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true); - FabricElement source = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false); - FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, null, source.getOutputPort()); - ((FunnelModule.FunnelInstance)source).out = top_funnel; - //top_horn.addInput(top_funnel, top_funnel.getOutputPort()); - top_funnel.addOutput(top_horn, top_horn.getInputPort()); - - //Module.SourcePort debug_in = top.createWireSourcePort("debug_in", WIDTH_PACKET); - Module.SinkPort debug_in = top_funnel.getInputPort("in1"); - - top.new Event(new Object[] { in, "count<=7" }, - new Object[] { new SimpleAction(temp_in.getVerilogName()+" <= {" + temp_in.getVerilogName() + "["+(WIDTH_PACKET-(1+8))+":0], in[7:0] };"), - new SimpleAction("count <= count+1;"), - in - }); - top.new Event(new Object[] { debug_in, "count>7" }, - new Object[] { new SimpleAction(" count <= 0; "), - new AssignAction(debug_in, temp_in), - debug_in - }); - top.new Event(new Object[] { out, debug_out }, - new Object[] { new SimpleAction(out.getVerilogName()+" <= ("+debug_out.getVerilogName()+">> (count_out*8));"), - new SimpleAction("if (count_out >= 5) begin "+ - "count_out <= 0; "+debug_out.getVerilogName()+"_a <= 1; end"+ - " else count_out <= count_out+1; "), - out }); - + FabricElement top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true); + mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false) + .addOutput(top_horn, top_horn.getInputPort()); } public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); } public FabricElement mkNode(FabricElement[] ports, boolean is_horn, int start, int end) { switch(end-start) { - case 0: return null; + case 0: throw new RuntimeException("this should never happen"); case 1: return ports[start]; default: { FabricElement leftPort = mkNode(ports, is_horn, start, (end+start)/2); FabricElement rightPort = mkNode(ports, is_horn, (end+start)/2, end); return is_horn - ? new HornModule.HornInstance(top, leftPort, rightPort) - : new FunnelModule.FunnelInstance(top, leftPort, rightPort); + ? new HornModule.HornInstance(this, top, leftPort, rightPort) + : new FunnelModule.FunnelInstance(this, top, leftPort, rightPort); } } } - public Module getVerilogModule() { return top; } - // Expand ////////////////////////////////////////////////////////////////////////////// public void expand(ShipDescription sd) { try { if (sd.getSection("fpga")==null) return; + if (getShip(sd.getName(),0)==null) return; // no ships of this type String filename = sd.getName().toLowerCase(); + + if (sd.getSection("ucf") != null) { + File outf = new File("build/fpga/"+filename+".ucf"); + FileOutputStream out = new FileOutputStream(outf); + PrintWriter pw = new PrintWriter(out); + pw.println(sd.getSection("ucf")); + pw.flush(); + pw.close(); + } + File outf = new File("build/fpga/"+filename+".v"); new File(outf.getParent()).mkdirs(); System.err.println("writing to " + outf); FileOutputStream out = new FileOutputStream(outf); PrintWriter pw = new PrintWriter(out); - boolean debug = "debug".equals(filename); - - pw.println("`define DATAWIDTH "+WIDTH_WORD); + pw.println("`define WORDWIDTH "+WIDTH_WORD); pw.println("`define CODEBAG_SIZE_BITS "+CBD_SIZE.valmaskwidth); pw.println(); + for(DockDescription dd : sd.ports()) { + String name = dd.getName(); + pw.println("`define "+name+"_full ("+name+"_r && !"+name+"_a)"); + pw.println("`define "+name+"_empty (!"+name+"_r && !"+name+"_a)"); + if (dd.isInputDock()) { + // gets stuck on colliding-tokens + //pw.println("`define drain_"+name+" if ("+name+"_r && !"+name+"_a) "+name+"_a <= 1;"); + + // gets stuck on colliding-tokens + //pw.println("`define drain_"+name+" if ("+name+"_r) "+name+"_a <= 1;"); + + // also gets stuck + //pw.println("`define drain_"+name+" if (!"+name+"_a) "+name+"_a <= 1;"); + pw.println("`define drain_"+name+" "+name+"_a <= 1;"); + } else { + pw.println("`define fill_"+name+" "+name+"_r <= 1;"); + } + } + pw.print("`define reset "); - for(DockDescription bb : sd) { + for(DockDescription bb : sd.ports()) { String bb_name = bb.getName(); - if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; "+bb_name+"_f <= 0; "); + if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; "); else pw.print(bb_name+"_r <= 0; "); } pw.println(); - pw.print("`define flush "); - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(" if (!"+bb.getName()+"_r_) "+bb.getName()+"_f <= 0; "); + pw.print("`define cleanup "); + + // output docks + for(DockDescription dd : sd.ports()) + if (!dd.isInputDock()) + pw.print("if ( "+dd.getName()+"_r && "+dd.getName()+"_a) "+dd.getName()+"_r <= 0; "); + + // input docks: if all inputs are flushing, drain them all pw.print("if (1"); - for(DockDescription bb : sd) + for(DockDescription bb : sd.ports()) if (bb.isInputDock()) - pw.print(" && "+bb.getName()+"_r_ && !"+bb.getName()+"_a"); + pw.print(" && "+bb.getName()+"_f"); pw.print(") begin "); - if (true) { - pw.print("if (1"); - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(" && "+bb.getName()+"_d["+WIDTH_WORD+"] "); - pw.print(") begin "); - if (true) { - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(bb.getName()+"_f <= 1; "); - } - pw.print(" end else if (0"); - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(" || "+bb.getName()+"_d["+WIDTH_WORD+"] "); - pw.print(") begin "); - if (true) { - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(" if (!"+bb.getName()+"_d["+WIDTH_WORD+"]) "+bb.getName()+"_f <= 1; "); + for(DockDescription bb : sd.ports()) + if (bb.isInputDock()) + pw.print(bb.getName()+"_a <= 1; "); + + // input docks: if no inputs are flushing, do normal stuff + pw.print("end else if (1"); + for(DockDescription bb : sd.ports()) + if (bb.isInputDock()) + pw.print(" && !"+bb.getName()+"_f"); + pw.print(") begin "); + + for(DockDescription bb : sd.ports()) + if (bb.isInputDock()) + pw.print("if (!"+bb.getName()+"_r_ && "+bb.getName()+"_a) "+bb.getName()+"_a <= 0; "); + + // input docks: if some-but-not-all inputs are flushing, drain all non-flushing docks + pw.print("end else begin "); + + for(DockDescription bb : sd.ports()) + if (bb.isInputDock()) { + pw.print("if (!"+bb.getName()+"_r && "+bb.getName()+"_a) "+bb.getName()+"_a <= 0; "); + pw.print("if ("+bb.getName()+"_r && !"+bb.getName()+"_a) "+bb.getName()+"_a <= 1; "); } - pw.print(" end "); - } - pw.print(" end "); + + pw.print(" end"); + pw.println(); pw.println("module " + filename + "( clk, rst "); - for(DockDescription bb : sd) { + for(DockDescription bb : sd.ports()) { String bb_name = bb.getName(); pw.print(" "); if (bb.isInputDock()) { @@ -263,112 +240,44 @@ public class Fpga extends FleetTwoFleet { } pw.println(); } - if (filename.equals("debug")) { - pw.println(" , out_r_"); - pw.println(" , out_a"); - pw.println(" , out_d_"); - } - if (filename.equals("dram")) { - pw.println(" , dram_addr_"); - pw.println(" , dram_addr_r_"); - pw.println(" , dram_addr_a"); - pw.println(" , dram_isread_"); - pw.println(" , dram_write_data_"); - pw.println(" , dram_write_data_push_"); - pw.println(" , dram_write_data_full"); - pw.println(" , dram_read_data"); - pw.println(" , dram_read_data_pop_"); - pw.println(" , dram_read_data_empty"); - pw.println(" , dram_read_data_latency"); - } - if (filename.equals("ddr2")) { - pw.println(" , ddr2_addr_"); - pw.println(" , ddr2_addr_r_"); - pw.println(" , ddr2_addr_a"); - pw.println(" , ddr2_isread_"); - pw.println(" , ddr2_write_data_"); - pw.println(" , ddr2_write_data_push_"); - pw.println(" , ddr2_write_data_full"); - pw.println(" , ddr2_read_data"); - pw.println(" , ddr2_read_data_pop_"); - pw.println(" , ddr2_read_data_empty"); - pw.println(" , ddr2_read_data_latency"); - } - if (filename.equals("video")) { - pw.println(" , vga_clk"); - pw.println(" , vga_psave"); - pw.println(" , vga_hsync"); - pw.println(" , vga_vsync"); - pw.println(" , vga_sync"); - pw.println(" , vga_blank"); - pw.println(" , vga_r"); - pw.println(" , vga_g"); - pw.println(" , vga_b"); - pw.println(" , vga_clkout"); + for(PercolatedPort pp : sd.percolatedPorts) { + pw.print(" , "); + pw.println(pp.name); } pw.println(" );"); pw.println(); pw.println(" input clk;"); pw.println(" input rst;"); - if (filename.equals("debug")) { - pw.println(" output ["+WIDTH_WORD+":0] out_d_;"); - pw.println(" input out_a;"); - pw.println(" output out_r_;"); - } - if (filename.equals("dram")) { - pw.println("output [31:0] dram_addr_;"); - pw.println("output dram_addr_r_;"); - pw.println("input dram_addr_a;"); - pw.println("output dram_isread_;"); - pw.println("output [63:0] dram_write_data_;"); - pw.println("output dram_write_data_push_;"); - pw.println("input dram_write_data_full;"); - pw.println("input [63:0] dram_read_data;"); - pw.println("output dram_read_data_pop_;"); - pw.println("input dram_read_data_empty;"); - pw.println("input [1:0] dram_read_data_latency;"); - } - if (filename.equals("ddr2")) { - pw.println("output [31:0] ddr2_addr_;"); - pw.println("output ddr2_addr_r_;"); - pw.println("input ddr2_addr_a;"); - pw.println("output ddr2_isread_;"); - pw.println("output [63:0] ddr2_write_data_;"); - pw.println("output ddr2_write_data_push_;"); - pw.println("input ddr2_write_data_full;"); - pw.println("input [63:0] ddr2_read_data;"); - pw.println("output ddr2_read_data_pop_;"); - pw.println("input ddr2_read_data_empty;"); - pw.println("input [1:0] ddr2_read_data_latency;"); - } - if (filename.equals("video")) { - pw.println("input vga_clk;"); - pw.println("output vga_psave;"); - pw.println("output vga_hsync;"); - pw.println("output vga_vsync;"); - pw.println("output vga_sync;"); - pw.println("output vga_blank;"); - pw.println("output [7:0] vga_r;"); - pw.println("output [7:0] vga_g;"); - pw.println("output [7:0] vga_b;"); - pw.println("output vga_clkout;"); + for(PercolatedPort pp : sd.percolatedPorts) { + switch(pp.type) { + case UP: pw.print("output"); break; + case DOWN: pw.print("input"); break; + case INOUT: pw.print("inout"); break; + } + pw.print(" "); + if (pp.width > 1) + pw.print("["+(pp.width-1)+":0]"); + pw.print(" "); + pw.print(pp.name); + pw.println(";"); } - for(DockDescription bb : sd) { + for(DockDescription bb : sd.ports()) { String bb_name = bb.getName(); + int width = bb.isDockless() ? WIDTH_PACKET : WIDTH_WORD; if (bb.isInputDock()) { - pw.println(" input ["+WIDTH_WORD+":0] "+bb_name+"_d;"); + pw.println(" input ["+width+":0] "+bb_name+"_d;"); pw.println(" input "+bb_name+"_r_;"); pw.println(" wire "+bb_name+"_r;"); - pw.println(" assign "+bb_name+"_r = "+bb_name+"_r_ & ~"+bb_name+"_d["+WIDTH_WORD+"];"); + pw.println(" assign "+bb_name+"_r = "+bb_name+"_r_ & ~"+bb_name+"_d["+width+"];"); pw.println(" output "+bb_name+"_a_;"); pw.println(" reg "+bb_name+"_a;"); pw.println(" initial "+bb_name+"_a = 0;"); - pw.println(" reg "+bb_name+"_f;"); - pw.println(" initial "+bb_name+"_f = 0;"); - pw.println(" assign "+bb_name+"_a_ = "+bb_name+"_a || "+bb_name+"_f;"); + pw.println(" wire "+bb_name+"_f;"); + pw.println(" assign "+bb_name+"_f = "+bb_name+"_r_ & "+bb_name+"_d["+width+"] && ~"+bb_name+"_a;"); + pw.println(" assign "+bb_name+"_a_ = "+bb_name+"_a;"); } else { - pw.println(" output ["+WIDTH_WORD+":0] "+bb_name+"_d_;"); + pw.println(" output ["+width+":0] "+bb_name+"_d_;"); pw.println(" input "+bb_name+"_a;"); pw.println(" output "+bb_name+"_r_;"); pw.println(" reg "+bb_name+"_r;"); @@ -378,7 +287,24 @@ public class Fpga extends FleetTwoFleet { pw.println(); } - pw.println(sd.getSection("fpga")); + if (filename.equals("fifo")) { + pw.println(" wire in_a__;"); + pw.println(" wire out_r__;"); + pw.println(" fifo8x37 fifo8x37(clk, rst,"); + pw.println(" in_r, in_a__, in_d,"); + pw.println(" out_r__, out_a, out_d_);"); + pw.println(" always @(posedge clk) begin"); + pw.println(" if (rst) begin"); + pw.println(" `reset"); + pw.println(" end else begin"); + pw.println(" `cleanup"); + pw.println(" out_r <= out_r__;"); + pw.println(" if (in_a__) in_a <= 1;"); + pw.println(" end"); + pw.println(" end"); + } else { + pw.println(sd.getSection("fpga")); + } pw.println("endmodule"); @@ -387,15 +313,4 @@ public class Fpga extends FleetTwoFleet { } catch (Exception e) { throw new RuntimeException(e); } } - public long getDestAddr(Path path) { - return ((FpgaPath)path).toLong(); - } - public Dock getBoxByInstAddr(long dest) { - for(Ship ship : Fpga.this) - for(Dock bb : ship) - if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest) - return bb; - return null; - } - }