X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Ffpga%2Fverilog%2FVerilog.java;h=de2bfbaf359b1c36bab654fc086fc952eb5ad34a;hb=80b2284a15cd0e0595d02e49d1ceb9c608e62ad9;hp=cd0deea43c2243add6e83117e2316b6b178b6a2d;hpb=4399620e3d04288ef9b067cdd589faf82e1612d2;p=fleet.git diff --git a/src/edu/berkeley/fleet/fpga/verilog/Verilog.java b/src/edu/berkeley/fleet/fpga/verilog/Verilog.java index cd0deea..de2bfba 100644 --- a/src/edu/berkeley/fleet/fpga/verilog/Verilog.java +++ b/src/edu/berkeley/fleet/fpga/verilog/Verilog.java @@ -42,6 +42,9 @@ import static edu.berkeley.fleet.two.FleetTwoFleet.*; */ public class Verilog { + public static final int FORWARD_LATENCY = 6; // must be >=1 + public static final int REVERSE_LATENCY = 4; // must be >=3 + public static interface Value { public String getVerilog(); public Value getBits(int high, int low); @@ -319,25 +322,6 @@ public class Verilog { public String getVerilog() { return s; } } - // Percolated Ports ////////////////////////////////////////////////////////////////////////////// - - /** - * A PercolatedPort is a connection to a top-level pin; it is - * propagated up or down the hierarchy - */ - public static class PercolatedPort { - public static enum PortType { UP, DOWN, INOUT }; - public final String name; - public final int width; - public final PortType type; - public PercolatedPort(String name, int width, PortType type) { - this.name = name; - this.width = width; - this.type = type; - } - } - - // Module Internals ////////////////////////////////////////////////////////////////////////////// public static class Module { @@ -345,7 +329,7 @@ public class Verilog { PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v"))); dump(pw, true); pw.flush(); - for(InstantiatedModule m : instantiatedModules) + for(InstantiatedModule m : instantiatedModules.values()) m.module.dump(prefix); } public int id = 0; @@ -354,7 +338,7 @@ public class Verilog { public Port getPort(String name) { return ports.get(name); } // order matters here - public LinkedList instantiatedModules = new LinkedList(); + public LinkedHashMap instantiatedModules = new LinkedHashMap(); // order matters here public LinkedList percolatedPorts = new LinkedList(); @@ -460,7 +444,7 @@ public class Verilog { public String getVerilog() { return name; } String getAck() { return name+"_a"; } String getReq() { return name+"_r"; } - public String isFull() { return "("+name+"_r"+" && !"+name+"_a)"; } + public String isFull() { return "("+getReq()+" && !"+getAck()+")"; } public abstract String getResetCode(); public abstract String getInterface(); public abstract String getSimpleInterface(); @@ -504,8 +488,25 @@ public class Verilog { public String getResetCode() { return driven==null ? name+"_a<=1;" : ""; } public String getAssignments() { StringBuffer sb = new StringBuffer(); - if (external) - sb.append("assign " + name +"_a_ = " + name + "_a;\n"); + if (external) { + int a = REVERSE_LATENCY - 3; + if (a<0 || a>16) { + throw new RuntimeException("cannot offer latency of " + REVERSE_LATENCY +"-3"); + } else if (a==0) { + sb.append("assign " + name +"_a_ = " + name + "_a;\n"); + } else { + a = a-1; // CLK-to-Q gives us one cycle of latency anyways + sb.append("SRL16E srl16_"+name+"_a\n"); + sb.append(" (.Q ("+name+"_a_),\n"); + sb.append(" .A0 ("+((a & (1<<0)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .A1 ("+((a & (1<<1)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .A2 ("+((a & (1<<2)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .A3 ("+((a & (1<<3)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .CE (1),\n"); + sb.append(" .CLK (clk),\n"); + sb.append(" .D ("+name+"_a));\n"); + } + } return sb.toString(); } public void connect(SinkPort driven) { @@ -566,7 +567,23 @@ public class Verilog { public String getAssignments() { StringBuffer sb = new StringBuffer(); if (external) { - sb.append("assign " + name +"_r_ = " + name + "_r;\n"); + int a = FORWARD_LATENCY - 1; + if (a<0 || a>16) { + throw new RuntimeException("cannot offer latency of " + FORWARD_LATENCY +"-1"); + } else if (a==0) { + sb.append("assign " + name +"_r_ = " + name + "_r;\n"); + } else { + a = a-1; // CLK-to-Q gives us one cycle of latency anyways + sb.append("SRL16E srl16_"+name+"_r\n"); + sb.append(" (.Q ("+name+"_r_),\n"); + sb.append(" .A0 ("+((a & (1<<0)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .A1 ("+((a & (1<<1)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .A2 ("+((a & (1<<2)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .A3 ("+((a & (1<<3)) == 0 ? 0 : 1)+"),\n"); + sb.append(" .CE (1),\n"); + sb.append(" .CLK (clk),\n"); + sb.append(" .D ("+name+"_r));\n"); + } sb.append("assign " + name +"_ = " + name + ";\n"); } if (controlDriver != null) { @@ -588,12 +605,17 @@ public class Verilog { public final Module thisModule; public final int id; public final HashMap ports = new HashMap(); - public String getName() { return module.getName()+"_"+id; } + private final String name; + public String getName() { return name; } public InstantiatedModule(Module thisModule, Module module) { this.thisModule = thisModule; this.module = module; - this.id = thisModule.id++; - thisModule.instantiatedModules.add(this); + // CRUDE + int id = 0; + while(thisModule.instantiatedModules.get(module.getName()+"_"+id)!=null) id++; + this.id = id; + this.name = module.getName()+"_"+id; + thisModule.instantiatedModules.put(this.name, this); for(String s : module.portorder) getPort(s); } @@ -634,7 +656,7 @@ public class Verilog { pw.print("module "+name); pw.println(isRoot ? "(clk_pin, rst_pin " : "(clk, rst "); for(String name : portorder) pw.println(" , " + ports.get(name).getInterface()); - for (InstantiatedModule im : this.instantiatedModules) + for (InstantiatedModule im : this.instantiatedModules.values()) for(PercolatedPort pp : im.module.percolatedPorts) if (!isRoot || (!pp.name.startsWith("root_in_") && !pp.name.startsWith("rst_"))) pw.println(" , "+pp.name); @@ -670,7 +692,7 @@ public class Verilog { pw.println(" input rst;"); } - for (InstantiatedModule im : this.instantiatedModules) + for (InstantiatedModule im : this.instantiatedModules.values()) for(PercolatedPort pp : im.module.percolatedPorts) { if (isRoot && (pp.name.startsWith("root_in_") || pp.name.startsWith("rst_"))) pw.print("wire"); @@ -698,7 +720,7 @@ public class Verilog { for(WireValue wv : wires.values()) wv.dump(pw); for(String name : ports.keySet()) pw.println(" " + ports.get(name).getAssignments()); for(WireValue wv : wires.values()) pw.println(" " + wv.getAssignments()); - for(InstantiatedModule m : instantiatedModules) m.dump(pw); + for(InstantiatedModule m : instantiatedModules.values()) m.dump(pw); pw.println("always @(posedge clk) begin"); pw.println(" if (rst) begin"); for(Latch l : latches.values()) pw.println(l.getResetCode());