X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Ffpga%2FFpga.java;h=ef5a24647110b4f4f35e671a2891d2a4f43b113f;hb=76517b7a2ce1461349c1888b15f75502745f0568;hp=e0cbab028eeef25145e20524a2db70ce43f1b016;hpb=2b139619ed94fd3d45d48882ba5a64e5731e2529;p=fleet.git diff --git a/src/edu/berkeley/fleet/fpga/Fpga.java b/src/edu/berkeley/fleet/fpga/Fpga.java index e0cbab0..ef5a246 100644 --- a/src/edu/berkeley/fleet/fpga/Fpga.java +++ b/src/edu/berkeley/fleet/fpga/Fpga.java @@ -13,13 +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 static edu.berkeley.fleet.fpga.verilog.Verilog.PercolatedPort; +import edu.berkeley.fleet.two.PercolatedPort; public class Fpga extends FleetTwoFleet { public Module top; - public FabricElement top_horn; Ship debugShip; public LinkedHashMap ships = new LinkedHashMap(); @@ -41,14 +40,6 @@ public class Fpga extends FleetTwoFleet { pw.println("`timescale 1ns / 10ps"); pw.close(); - pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(s[0]+"/bram14.v"))); - pw.println("`define BRAM_ADDR_WIDTH 14"); - pw.println("`define BRAM_DATA_WIDTH `WORDWIDTH"); - pw.println("`define BRAM_SIZE (1<<(`BRAM_ADDR_WIDTH))"); - pw.println("`define BRAM_NAME bram14"); - pw.println("`include \"bram.inc\""); - 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"); @@ -66,14 +57,17 @@ public class Fpga extends FleetTwoFleet { } catch (Exception e) { throw new RuntimeException(e); } } - public BitVector getDestAddr(Path path) { + 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; @@ -82,105 +76,77 @@ public class Fpga extends FleetTwoFleet { public Fpga() throws Exception { this(new Module("main")); } public Fpga(Module top) throws Exception { this.top = top; - debugShip = createShip("Debug", "debug"); + debugShip = createShip("Debug"); - //boolean small = false; - boolean small = true; - - createShip("Memory", "memory1"); + //boolean small = true; + boolean small = false; if (small) { - for(int i=0; i<2; i++) - createShip("Fifo", "fifo"+i); - for(int i=0; i<2; i++) - createShip("Alu", "alu"+i); - createShip("Counter", "counter"); - createShip("CarrySaveAdder", "csa1"); - createShip("Rotator", "rotator"); - createShip("Lut3", "lut"); - } else { - createShip("Memory", "memory2"); - createShip("Memory", "memory3"); + for(int i=0; i<2; i++) createShip("Alu"); + for(int i=0; i<1; i++) createShip("Memory"); + for(int i=0; i<2; i++) createShip("Fifo"); + createShip("Counter"); + createShip("CarrySaveAdder"); + createShip("Rotator"); + createShip("Lut3"); - for(int i=0; i<3; i++) - createShip("Alu", "alu"+i); + } else { - for(int i=0; i<1; i++) - createShip("Fifo", "fifo"+i); + for(int i=0; i<2; i++) createShip("Memory"); + for(int i=0; i<8; i++) createShip("Alu"); + for(int i=0; i<1; i++) createShip("Fifo"); + for(int i=0; i<12; i++) createShip("Counter"); - for(int i=0; i<14; i++) - createShip("Counter", "counter"+i); + //createShip("CarrySaveAdder"); + //createShip("Rotator"); + createShip("Random"); + createShip("Button"); - /* - createShip("CarrySaveAdder", "csa1"); - createShip("Rotator", "rotator"); - createShip("Lut3", "lut"); - */ - //createShip("DDR2", "ddr2"); } - createShip("DRAM", "dram"); - createShip("Video", "video"); + + createShip("Timer"); + createShip("DDR2"); + createShip("Dvi"); // for FifoShip new Module.InstantiatedModule(top, new FifoModule(8, WIDTH_WORD)); - Module.Latch temp_in = top.new Latch("temp", WIDTH_PACKET); - Module.Latch count = top.new Latch("count", 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) { 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); + } + }); } } - 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(this, top, null, source.getOutputPort()); - ((FunnelModule.FunnelInstance)source).out = top_funnel; - top_funnel.addOutput(top_horn, top_horn.getInputPort()); - Module.SinkPort debug_in = top_funnel.getInputPort("in1"); - - top.addPreCrap("reg root_in_a_;"); - top.addPreCrap("assign root_in_a = root_in_a_;"); - top.new Event(new Object[] { "(root_in_r && root_in_a)" }, - new Object[] { new SimpleAction("root_in_a_<=0;") }); - top.new Event(new Object[] { "(root_in_r && !root_in_a)", "count<=7" }, - new Object[] { new SimpleAction(temp_in.getVerilogName()+" <= {" + temp_in.getVerilogName() + "["+(WIDTH_PACKET-(1+8))+":0], root_in_d[7:0] };"), - new AssignAction(count, count.getVerilogName()+"+1"), - new SimpleAction("root_in_a_<=1;") - }); - top.new Event(new Object[] { debug_in, "count>7" }, - new Object[] { new AssignAction(count, "0"), - new AssignAction(debug_in, temp_in), - debug_in - }); + 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); @@ -199,6 +165,16 @@ public class Fpga extends FleetTwoFleet { try { if (sd.getSection("fpga")==null) return; 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); @@ -209,80 +185,76 @@ public class Fpga extends FleetTwoFleet { pw.println("`define CODEBAG_SIZE_BITS "+CBD_SIZE.valmaskwidth); pw.println(); - for(DockDescription dd : sd) { + 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.println("`define "+name+"_draining ("+name+"_r && "+name+"_a)"); } } 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 cleanup "); - for(DockDescription bb : sd) { - String bb_name = bb.getName(); - if (bb.isInputDock()) pw.print("if (!"+bb_name+"_r && "+bb_name+"_a) "+bb_name+"_a <= 0; "); - else pw.print("if ( "+bb_name+"_r && "+bb_name+"_a) "+bb_name+"_r <= 0; "); - } - pw.println(); - // FIXME: this corresponds to something - /* - pw.print("`define flush_happening (1"); - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(" && "+bb.getName()+"_r_ && !"+bb.getName()+"_a && "+bb.getName()+"_d["+WIDTH_WORD+"]"); - pw.println(")"); - */ + // output docks + for(DockDescription dd : sd.ports()) + if (!dd.isInputDock()) + pw.print("if ( "+dd.getName()+"_r && "+dd.getName()+"_a) "+dd.getName()+"_r <= 0; "); - pw.print("`define flush "); - for(DockDescription bb : sd) - if (bb.isInputDock()) - pw.print(" if (!"+bb.getName()+"_r_) "+bb.getName()+"_f <= 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()) { @@ -318,21 +290,22 @@ public class Fpga extends FleetTwoFleet { 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;"); @@ -349,12 +322,12 @@ public class Fpga extends FleetTwoFleet { 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(" if (rst) begin"); pw.println(" `reset"); pw.println(" end else begin"); - pw.println(" `flush"); + pw.println(" `cleanup"); pw.println(" out_r <= out_r__;"); - pw.println(" in_a <= in_a__;"); + pw.println(" if (in_a__) in_a <= 1;"); pw.println(" end"); pw.println(" end"); } else {