X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Ffpga%2FFpga.java;h=6a6734c3dd04664033a785f050ff9d435ec5b3e5;hb=407cbc5807096c6d512df162a1a3eef5addf08a0;hp=c409eb0b63a53e5999cd53b92ffb2145df89994a;hpb=f793208c02dc38ee6f3b1c548087157b5c3300db;p=fleet.git diff --git a/src/edu/berkeley/fleet/fpga/Fpga.java b/src/edu/berkeley/fleet/fpga/Fpga.java index c409eb0..6a6734c 100644 --- a/src/edu/berkeley/fleet/fpga/Fpga.java +++ b/src/edu/berkeley/fleet/fpga/Fpga.java @@ -1,7 +1,7 @@ package edu.berkeley.fleet.fpga; import edu.berkeley.fleet.fpga.*; import edu.berkeley.fleet.api.*; -import edu.berkeley.fleet.ies44.*; +import edu.berkeley.fleet.two.*; import edu.berkeley.fleet.*; import java.lang.reflect.*; import edu.berkeley.sbp.chr.*; @@ -11,275 +11,335 @@ import edu.berkeley.sbp.util.*; import java.util.*; import java.io.*; import edu.berkeley.fleet.two.*; -import static edu.berkeley.fleet.ies44.InstructionEncoder.*; -import static edu.berkeley.fleet.verilog.Verilog.*; +import static edu.berkeley.fleet.two.FleetTwoFleet.*; +import static edu.berkeley.fleet.fpga.verilog.Verilog.*; +import edu.berkeley.fleet.two.PercolatedPort; + +public class Fpga extends FleetTwoFleet { -public class Fpga extends Fleet { + public Module top; + Ship debugShip; + + public LinkedHashMap ships = new LinkedHashMap(); + public Iterator iterator() { return (Iterator)(Object)ships.values().iterator(); } public Ship getShip(String type, int ordinal) { for(Ship s : this) if (s.getType().equals(type)) - if (ordinal-- < 0) + if (--ordinal < 0) return s; return null; } - public int getWordWidth() { return 37; } - private static final BitVector SIGNAL_ZERO = new BitVector(1); - private static final BitVector SIGNAL_ONE = new BitVector(1); - static { - SIGNAL_ONE.set(0,true); - } - - public Module top; - public FabricElement top_horn; - - public LinkedHashMap ships = new LinkedHashMap(); - public Iterator iterator() { return (Iterator)(Object)ships.values().iterator(); } - public static void main(String[] s) throws Exception { - String prefix = s[0]; - - new FunnelModule().dump(prefix); - new HornModule().dump(prefix); - - new FifoModule(0).dump(prefix); - new FifoModule(4).dump(prefix); - new FifoModule(8).dump(prefix); - new FpgaDock.DockModule(false).dump(prefix); - new FpgaDock.DockModule(true).dump(prefix); - - Module top = new Module("root"); - new Fpga(top).top.dump(prefix); + new Fpga(new Module("main")).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 { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - for(Instruction i : instructions) - writeInstruction(dos, getUniversalSource(), i); - dos.flush(); - return new Client("none", baos.toByteArray()); + 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() throws Exception { this(new Module("main")); } public Fpga(Module top) throws Exception { this.top = top; - debugShip = createShip("Debug", "debug"); - createShip("Memory", "memory"); - createShip("Fifo", "fifo1"); - createShip("Fifo", "fifo2"); - createShip("Alu2", "alu2a"); - createShip("Rotator", "rotator"); - //createShip("Alu1", "alu1"); - createShip("Lut3", "lut3"); - createShip("Alu3", "alu3"); - - Module fifostage = new FifoModule(0); - Module fifo4 = new FifoModule(4); - Module fifo8 = new FifoModule(8); - Module horn = new HornModule(); - Module funnel = new FunnelModule(); - Module outbox = new FpgaDock.DockModule(false); - Module inbox = new FpgaDock.DockModule(true); - - Module.SinkPort debug_in = top.createWirePort("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"); + debugShip = createShip("Debug"); + + //boolean small = true; + boolean small = false; + + if (small) { + 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"); + + } else { + + 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"); + + //createShip("CarrySaveAdder"); + //createShip("Rotator"); + createShip("Random"); + createShip("Button"); + } - Module.SourcePort in = top.createInputPort("in", 8); - Module.SinkPort out = top.createOutputPort("out", 8, ""); - Module.Latch temp_in = top.new Latch("temp", WIDTH_PACKET) { public String doReset() { return name+"=0;"; } }; - Module.Latch count = top.new Latch("count", 8); - Module.Latch count_out = top.new Latch("count_out", 8); - top.new Event(new Object[] { in, debug_in }, - new Object[] { new SimpleAction(temp_in.getVerilogName()+" = ("+temp_in.getVerilogName()+" << 8) | in;"), - new SimpleAction("if (count >= 5) begin"+ - " count <= 0; "+ - " `packet_token("+debug_in.getVerilogName()+") <= 0;"+ - " `packet_data("+debug_in.getVerilogName()+") <= "+temp_in.getVerilogName()+";"+ - " `packet_dest("+debug_in.getVerilogName()+") <= `instruction_dest("+temp_in.getVerilogName()+");"+ - " "+debug_in.getVerilogName()+"_r <= 1; "+ - "end else count <= count+1; "), - 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 }); + createShip("Timer"); + createShip("DDR2"); + createShip("Dvi"); + + // for FifoShip + new Module.InstantiatedModule(top, new FifoModule(8, WIDTH_WORD)); - ArrayList sources = new ArrayList(); 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) { - sources.add(((FpgaDock)port)); - dests.add(port.getInstructionDestination()); - dests.add(port.getDataDestination()); + if (port.isInputDock()) { + sources.add(((FpgaDock)port)); + dests.add(port.getInstructionDestination()); + dests.add(port.getDataDestination()); + } else { + sources.add(((FpgaDock)port)); + dests.add(port.getInstructionDestination()); + dests.add(port.getDataDestination()); + } + } + 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); + } + }); } } - 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, debug_in, source.getOutputPort()); - ((FunnelModule.FunnelInstance)source).out = top_funnel; - //top_horn.addInput(top_funnel, top_funnel.getOutputPort()); - top_funnel.addOutput(top_horn, top_horn.getInputPort()); + 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 auto = !"debug".equals(filename); + 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;"); + } + } - if (auto) { - pw.println("`include \"macros.v\""); - pw.println(); + pw.print("`define reset "); + for(DockDescription bb : sd.ports()) { + String bb_name = bb.getName(); + if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; "); + else pw.print(bb_name+"_r <= 0; "); + } + pw.println(); + + 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.ports()) + if (bb.isInputDock()) + pw.print(" && "+bb.getName()+"_f"); + pw.print(") begin "); + 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("`define reset "); - for(DockDescription bb : sd) { - String bb_name = bb.getName(); - if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; "); - else pw.print(bb_name+"_r <= 0; "); + pw.print(" end"); + + pw.println(); + + pw.println("module " + filename + "( clk, rst "); + for(DockDescription bb : sd.ports()) { + String bb_name = bb.getName(); + pw.print(" "); + if (bb.isInputDock()) { + pw.print(", " + bb_name+"_r_"); + pw.print(", " + bb_name+"_a_"); + pw.print(", " + bb_name+"_d"); + } else { + pw.print(", " + bb_name+"_r_"); + pw.print(", " + bb_name+"_a"); + pw.print(", " + bb_name+"_d_"); } pw.println(); + } + for(PercolatedPort pp : sd.percolatedPorts) { + pw.print(" , "); + pw.println(pp.name); + } + pw.println(" );"); + pw.println(); + pw.println(" input clk;"); + pw.println(" input rst;"); + 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(";"); + } - pw.println("module " + filename + "( clk, rst "); - for(DockDescription bb : sd) { - String bb_name = bb.getName(); - pw.print(" "); - if (bb.isInputDock()) { - pw.print(", " + bb_name+"_r"); - pw.print(", " + bb_name+"_a_"); - pw.print(", " + bb_name+"_d"); - } else { - pw.print(", " + bb_name+"_r_"); - pw.print(", " + bb_name+"_a"); - pw.print(", " + bb_name+"_d_"); - } - pw.println(); + 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+":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+"];"); + pw.println(" output "+bb_name+"_a_;"); + pw.println(" reg "+bb_name+"_a;"); + pw.println(" initial "+bb_name+"_a = 0;"); + 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+":0] "+bb_name+"_d_;"); + pw.println(" input "+bb_name+"_a;"); + pw.println(" output "+bb_name+"_r_;"); + pw.println(" reg "+bb_name+"_r;"); + pw.println(" initial "+bb_name+"_r = 0;"); + pw.println(" assign "+bb_name+"_r_ = "+bb_name+"_r;"); } - pw.println(" );"); pw.println(); - pw.println(" input clk;"); - pw.println(" input rst;"); - for(DockDescription bb : sd) { - String bb_name = bb.getName(); - pw.print(" "); - if (bb.isInputDock()) { - pw.println("`input(" + - bb_name+"_r, "+ - bb_name+"_a, "+ - bb_name+"_a_, "+ - "[("+WIDTH_WORD+"-1):0],"+ - bb_name+"_d)" - ); - } else { - pw.println("`output(" + - bb_name+"_r, "+ - bb_name+"_r_, "+ - bb_name+"_a, "+ - "[("+WIDTH_WORD+"-1):0],"+ - bb_name+"_d_)" - ); - if (!bb_name.equals("out") || !"memory".equals(filename)) - pw.println("`defreg(" + - bb_name+"_d_, "+ - "[("+WIDTH_WORD+"-1):0],"+ - bb_name+"_d)" - ); - } - 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")); + } - if (auto) - pw.println("endmodule"); + pw.println("endmodule"); pw.flush(); pw.close(); } catch (Exception e) { throw new RuntimeException(e); } } - private FpgaInstructionEncoder iie = new FpgaInstructionEncoder(); - public Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException { return iie.readInstruction(dispatchFrom, is); } - public Instruction readInstruction(Dock dispatchFrom, long instr) { return iie.readInstruction(dispatchFrom, instr); } - public long writeInstruction(Dock dispatchFrom, Instruction d) { return iie.writeInstruction(dispatchFrom, d); } - public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException { iie.writeInstruction(os, dispatchFrom, d); } - - private Ship debugShip; - - - public Dock getUniversalSource() { return debugShip.getDock("in"); } - private class FpgaInstructionEncoder extends InstructionEncoder { - public Dock getUniversalSource() { return debugShip.getDock("in"); } - public long getDestAddr(Path path) { - return ((FpgaPath)path).toLong(); - } - public Path getPathByAddr(Dock source, long dest) { - for(Ship ship : Fpga.this) - for(Dock bb : ship) { - for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) { - for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) { - FpgaPath p = (FpgaPath)source.getPath(d, signal); - if (p.toLong() == dest) return p; - } - } - } - return null; - } - 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; - } - } }