*/
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);
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 {
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;
public Port getPort(String name) { return ports.get(name); }
// order matters here
- public LinkedList<InstantiatedModule> instantiatedModules = new LinkedList<InstantiatedModule>();
+ public LinkedHashMap<String,InstantiatedModule> instantiatedModules = new LinkedHashMap<String,InstantiatedModule>();
// order matters here
public LinkedList<PercolatedPort> percolatedPorts = new LinkedList<PercolatedPort>();
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();
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) {
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) {
public final Module thisModule;
public final int id;
public final HashMap<String,Port> ports = new HashMap<String,Port>();
- 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);
}
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);
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");
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());