public class Generator {
+ public static class SimpleValue implements Value {
+ private final String s;
+ public SimpleValue(String s) { this.s = s; }
+ public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
+ public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
+ public String getVerilogName() { return s; }
+ public String toString() { return s; }
+ }
+
+ public static interface Action {
+ public String getVerilogAction();
+ }
+
+ public static interface Trigger {
+ public String getVerilogTrigger();
+ }
+
+ public static interface Assignable {
+ public String getVerilogName();
+ public Assignable getAssignableBits(int high, int low);
+ }
+
+ public static interface Value extends Assignable {
+ public String getVerilogName();
+ public Value getBits(int high, int low);
+ }
+
+ public static class ConditionalAction implements Action {
+ private String condition;
+ private Action action;
+ public ConditionalAction(String condition, Action action) {
+ this.condition = condition;
+ this.action = action;
+ }
+ public String toString() { return getVerilogAction(); }
+ public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
+ }
+
+ public static class ConditionalTrigger implements Trigger {
+ private String condition;
+ private Trigger trigger;
+ public ConditionalTrigger(String condition, Trigger trigger) {
+ this.condition = condition;
+ this.trigger = trigger;
+ if (trigger instanceof Module.Port)
+ ((Module.Port)trigger).hasLatch = true;
+ }
+ public String getVerilogTrigger() {
+ return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
+ }
+ }
+
+ public static class SimpleAssignable implements Assignable {
+ private final String s;
+ public SimpleAssignable(String s) { this.s = s; }
+ public String getVerilogName() { return s; }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
+ }
+
+ public static class AssignAction implements Action {
+ private String left;
+ private String right;
+ public AssignAction(Assignable left, Value right) {
+ this.left = left.getVerilogName();
+ this.right = right.getVerilogName().toString();
+ }
+ public AssignAction(Assignable left, String right) {
+ this.left = left.getVerilogName();
+ this.right = right;
+ }
+ public String getVerilogAction() { return left + "<=" + right + ";"; }
+ public String toString() { return getVerilogAction(); }
+ }
+
+ public static class SimpleAction implements Action {
+ private final String verilog;
+ public SimpleAction(String verilog) { this.verilog = verilog; }
+ public String getVerilogAction() { return verilog; }
+ public String toString() { return verilog; }
+ }
public static class Module {
private int id = 0;
private final String name;
public String getName() { return name; }
+ public Port getPort(String name) { return ports.get(name); }
private HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
- private final ArrayList<Action> actions = new ArrayList<Action>();
+ private final ArrayList<Event> events = new ArrayList<Event>();
// FIXME: always-alphabetical convention?
private final HashMap<String,Port> ports = new HashMap<String,Port>();
private final ArrayList<String> portorder = new ArrayList<String>();
+ private final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
+ private final HashMap<String,Latch> latches = new HashMap<String,Latch>();
private StringBuffer crap = new StringBuffer();
private StringBuffer precrap = new StringBuffer();
this.name = name;
}
- public SourcePort getInputPort(String name, int width) {
+ public SourcePort createInputPort(String name, int width) {
+ if (ports.get(name)!=null) throw new RuntimeException();
+ return new SourcePort(name, width, true);
+ }
+ public SourcePort getInputPort(String name) {
SourcePort ret = (SourcePort)ports.get(name);
- if (ret==null) ret = new SourcePort(name, width, true);
+ if (ret==null) throw new RuntimeException();
return ret;
}
- public SinkPort getOutputPort(String name, int width, String resetBehavior) {
+ public SinkPort createOutputPort(String name, int width, String resetBehavior) {
+ if (ports.get(name)!=null) throw new RuntimeException();
+ return new SinkPort(name, width, true, resetBehavior);
+ }
+ public SinkPort getOutputPort(String name) {
SinkPort ret = (SinkPort)ports.get(name);
- if (ret==null) ret = new SinkPort(name, width, true, resetBehavior);
+ if (ret==null) throw new RuntimeException();
return ret;
}
- private abstract class Port {
+
+ private class StateWire {
public final String name;
+ public final boolean initiallyFull;
public String getName() { return name; }
+ public Action isFull() { return new SimpleAction(name+"==1"); }
+ public Action isEmpty() { return new SimpleAction(name+"==0"); }
+ public Action doFill() { return new SimpleAction(name+"<=1;"); }
+ public Action doDrain() { return new SimpleAction(name+"<=0;"); }
+ public StateWire(String name) { this(name, false); }
+ public StateWire(String name, boolean initiallyFull) {
+ this.name = name;
+ this.initiallyFull = initiallyFull;
+ statewires.put(name, this);
+ }
+ public void dump(PrintWriter pw) {
+ pw.println(" reg "+name+";");
+ pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
+ }
+ }
+
+ public class Latch implements Assignable, Value {
+ public final String name;
public final int width;
+ public Latch(String name, int width) {
+ this.width = width;
+ this.name = name;
+ latches.put(name, this);
+ }
+ public String getVerilogName() { return name; }
+ public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public void dump(PrintWriter pw) {
+ pw.println(" reg ["+(width-1)+":0] "+name+";");
+ //pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
+ }
+ }
+
+ private abstract class Port implements Action, Assignable, Trigger {
+ public final String name;
+ public String getName() { return name; }
+ public final int width;
+ public int getWidth() { return width; }
public boolean hasLatch = false;
- public boolean supress = false;
- public boolean noAssignData = false;
public boolean external;
- public boolean pretendDriven = false;
- public boolean noreg = false;
public Port(String name, int width, boolean external) {
this.width = width;
this.name = name;
if (external)
portorder.add(name);
}
+ public String getVerilogName() { return name; }
public String getAck() { return name+"_a"; }
public String getReq() { return name+"_r"; }
public abstract String getInterface();
public void dump(PrintWriter pw) {
pw.println(" " + module.getName() + " " + getName() + "(clk");
for(String s : module.portorder)
- pw.println(", " + getPort(s, module.ports.get(s).width).getSimpleInterface());
+ pw.println(", " + getPort(s).getSimpleInterface());
pw.println(" );");
}
- public Port getPort(String name, int width) {
- if (module.ports.get(name) instanceof SinkPort)
- return getOutputPort(name, width, "");
- return getInputPort(name, width);
+ public Port getPort(String name) {
+ return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
}
- public SinkPort getInputPort(String name, int width) {
+ public SinkPort getInputPort(String name) {
+ int width = module.getPort(name).getWidth();
SinkPort port = (SinkPort)ports.get(name);
if (port == null) {
port = new SinkPort(getName()+"_"+name, width, false, "");
}
return port;
}
- public SourcePort getOutputPort(String name, int width, String resetBehavior) {
+ public SourcePort getOutputPort(String name) {
+ int width = module.getPort(name).getWidth();
SourcePort port = (SourcePort)ports.get(name);
if (port == null) {
port = new SourcePort(getName()+"_"+name, width, false);
}
}
- private class SourcePort extends Port {
+ private class SourcePort extends Port implements Value {
private SinkPort driven = null;
public SourcePort(String name, int width, boolean external) {
super(name, width, external); }
+ public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
+ public String getVerilogAction() { return getAck() + " <= 1;"; }
public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
public String getDeclaration() {
}
public String getAssignments() {
StringBuffer sb = new StringBuffer();
- if (external && !pretendDriven) {
+ if (external)
sb.append("assign " + name +"_a_ = " + name + "_a;\n");
- }
if (driven != null) {
sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
}
private class SinkPort extends Port {
public final String resetBehavior;
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public String getVerilogAction() { return getReq() + " <= 1;"; }
+ public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
public SinkPort(String name, int width, boolean external, String resetBehavior) {
super(name, width, external); this.resetBehavior=resetBehavior; }
public String getResetBehavior() { return resetBehavior; }
} else {
sb.append("reg " + name +"_r;\n");
sb.append("initial " + name +"_r = 0;\n");
- if (!noreg) {
- sb.append("reg ["+(width-1)+":0]" + name +";\n");
- sb.append("initial " + name +" = 0;\n");
- }
+ sb.append("reg ["+(width-1)+":0]" + name +";\n");
+ sb.append("initial " + name +" = 0;\n");
}
return sb.toString();
}
public String getAssignments() {
StringBuffer sb = new StringBuffer();
- if (external && !pretendDriven) {
+ if (external) {
sb.append("assign " + name +"_r_ = " + name + "_r;\n");
- if (!noAssignData) {
- sb.append("assign " + name +"_ = " + name + ";\n");
- }
+ sb.append("assign " + name +"_ = " + name + ";\n");
}
return sb.toString();
}
Port p = ports.get(name);
pw.println(" " + p.getDeclaration());
}
+ for(StateWire sw : statewires.values())
+ sw.dump(pw);
+ for(Latch l : latches.values())
+ l.dump(pw);
for(String name : ports.keySet()) {
Port p = ports.get(name);
pw.println(" " + p.getAssignments());
for(Port p : ports.values()) {
if (p instanceof SourcePort) {
SourcePort ip = (SourcePort)p;
- if (ip.hasLatch && !ip.supress)
+ if (ip.hasLatch)
pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
} else {
SinkPort op = (SinkPort)p;
- if (op.hasLatch && !op.supress)
+ if (op.hasLatch)
pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
op.getReq()+"<=0; "+
op.getResetBehavior()+" end");
}
}
- for(Action a : actions) a.dump(pw);
+ for(Event a : events) a.dump(pw);
pw.println(" begin end");
pw.println("end");
pw.println("endmodule");
}
- private class Action {
- private String[] triggers;
- private SourcePort[] inports;
- private SinkPort[] outports;
+ private class Event {
+ private Object[] triggers;
private Object[] actions;
- public Action(Object[] triggers, String action) { this(triggers, new Object[] { action }); }
- public Action(Object[] triggers, Object[] actions) {
- int numtriggers = 0;
- int numinports = 0;
- int numoutports = 0;
- Module.this.actions.add(this);
+ public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
+ public Event(Object[] triggers, Object[] actions) {
+ Module.this.events.add(this);
+ this.triggers = triggers;
+ this.actions = actions;
for(int i=0; i<triggers.length; i++)
- if (triggers[i] instanceof String) numtriggers++;
- else if (triggers[i] instanceof SourcePort) {
- numinports++;
- ((Port)triggers[i]).hasLatch = true;
- } else if (triggers[i] instanceof SinkPort) {
- numoutports++;
+ if (triggers[i] instanceof Port)
((Port)triggers[i]).hasLatch = true;
- }
- this.triggers = new String[numtriggers];
- this.inports = new SourcePort[numinports];
- this.outports = new SinkPort[numoutports];
- for(int i=0; i<triggers.length; i++)
- if (triggers[i] instanceof String) this.triggers[--numtriggers] = (String)triggers[i];
- else if (triggers[i] instanceof SourcePort) this.inports[--numinports] = (SourcePort)triggers[i];
- else if (triggers[i] instanceof SinkPort) this.outports[--numoutports] = (SinkPort)triggers[i];
- this.actions = actions;
- for(Object o : actions)
- if (o instanceof SourcePort) ((Port)o).hasLatch = true;
- else if (o instanceof SinkPort) ((Port)o).hasLatch = true;
}
public void dump(PrintWriter pw) {
pw.print("if (1");
- for(String s : triggers) pw.print(" && " + s);
- for(SourcePort ip : inports) pw.print(" && " + ip.getReq() + " && !"+ip.getAck());
- for(SinkPort op : outports) pw.print(" && !" + op.getReq() + " && !"+op.getAck());
- pw.println(") begin ");
- for(Object s : this.actions) {
- if (s instanceof String) pw.println(s);
- else if (s instanceof SourcePort) pw.println(((SourcePort)s).getAck() + " <= 1;");
- else if (s instanceof SinkPort) pw.println(((SinkPort)s).getReq() + " <= 1;");
+ for(Object o : triggers) {
+ if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
+ else pw.print(" && " + o);
}
+ pw.println(") begin ");
+ for(Object a : actions) pw.println(((Action)a).getVerilogAction());
pw.println("end else ");
}
}
public static final int WORD_WIDTH = 37;
public static final int DESTINATION_WIDTH = 11;
+ public static final int COUNT_WIDTH = 7;
public static final int PACKET_WIDTH = WORD_WIDTH + DESTINATION_WIDTH;
public static final int INSTRUCTION_WIDTH = WORD_WIDTH;
Module fifostage = mkfifo("fifostage", 0, null, prefix);
Module fifo4 = mkfifo("fifo4", 4, fifostage, prefix);
Module fifoship = mkfifo("fifo", 4, fifo4, prefix);
- mkoutbox("outbox", false, prefix, fifo4);
- mkoutbox("inbox", true, prefix, fifo4);
-
- mkkill("kill", prefix);
- }
-
- private static Module mkkill(String name, String prefix) throws Exception {
- Module killm = new Module(name);
- Module.SourcePort instr = killm.getInputPort("instr", INSTRUCTION_WIDTH);
- Module.SinkPort kill = killm.getOutputPort("kill", INSTRUCTION_WIDTH+1, "");
- Module.SinkPort notkill = killm.getOutputPort("notkill", INSTRUCTION_WIDTH, "");
- killm.addPreCrap(" reg ifull;");
- killm.addPreCrap(" initial ifull = 0;");
- killm.new Action(new Object[] { "!ifull", instr, notkill },
- new Object[] { "notkill = instr;", instr, "ifull = 1;" }
- );
- killm.new Action(new Object[] { kill, "ifull", "`instruction_is_kill(notkill)" },
- new Object[] { kill, "ifull=0;",
- "kill = { `instruction_bit_kill_only_standing(notkill), `instruction_count(notkill) };" }
- );
- killm.new Action(new Object[] { notkill, "ifull", "!`instruction_is_kill(notkill)" },
- new Object[] { notkill, "ifull=0;" }
- );
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- killm.dump(pw);
- pw.flush();
- return killm;
+ mkBox("outbox", false, prefix, fifo4);
+ mkBox("inbox", true, prefix, fifo4);
}
private static Module mkfunnel(String name, String prefix) throws Exception {
Module funnel = new Module(name);
- Module.SinkPort out = funnel.getOutputPort("out", PACKET_WIDTH, "");
- Module.SourcePort in1 = funnel.getInputPort("in1", PACKET_WIDTH);
- Module.SourcePort in2 = funnel.getInputPort("in2", PACKET_WIDTH);
- funnel.new Action(new Object[] { in1, out }, new Object[] { in1, out, "out = in1;" });
- funnel.new Action(new Object[] { in2, out }, new Object[] { in2, out, "out = in2;" });
+ Module.SinkPort out = funnel.createOutputPort("out", PACKET_WIDTH, "");
+ Module.SourcePort in1 = funnel.createInputPort("in1", PACKET_WIDTH);
+ Module.SourcePort in2 = funnel.createInputPort("in2", PACKET_WIDTH);
+ funnel.new Event(new Object[] { in1, out },
+ new Action[] { in1, out,
+ new AssignAction(out, in1) });
+ funnel.new Event(new Object[] { in2, out },
+ new Action[] { in2, out,
+ new AssignAction(out, in2) });
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
funnel.dump(pw);
pw.flush();
return funnel;
}
- private static Module mkoutbox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
- Module box = new Module(name);
- Module.SourcePort instr = box.getInputPort("instr", INSTRUCTION_WIDTH);
- //instr.hasLatch = true;
- //instr.supress = true;
- Module.SourcePort fabric_in = box.getInputPort("fabric_in", PACKET_WIDTH);
- Module.SinkPort fabric_out = box.getOutputPort("fabric_out", PACKET_WIDTH, "");
- fabric_out.hasLatch = true;
- //fabric_out.supress = true;
-
- Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
- fabric_in.connect(dfifo.getInputPort("in", PACKET_WIDTH));
-
- Module.SourcePort dfifo_out = dfifo.getOutputPort("out", PACKET_WIDTH, "");
- String fabric_in_d0 = dfifo_out.name;
- String fabric_in_r0 = fabric_in_d0+"_r";
- String fabric_in_a0 = fabric_in_d0+"_a";
- dfifo_out.hasLatch = true;
-
- Module.SourcePort ship_out = null;
- if (!inbox) {
- ship_out = box.getInputPort("ship", WORD_WIDTH);
- ship_out.hasLatch = true;
- }
-
- Module.SinkPort ship_in = null;
- if (inbox) {
- ship_in = box.getOutputPort("ship", PACKET_WIDTH, "");
- ship_in.hasLatch = true;
- }
-
- box.addPreCrap(" reg[(`INSTRUCTION_WIDTH-1):0] ondeck;");
- box.addPreCrap(" reg[(`COUNT_WIDTH-1):0] repcount;");
- box.addPreCrap(" initial ondeck=0;");
- box.addPreCrap(" reg ondeck_full; initial ondeck_full=0;");
- box.addPreCrap(" reg newmayproceed; initial newmayproceed=1;");
- box.addPreCrap(" reg dorepeat; initial dorepeat=0;");
- box.addPreCrap(" reg dorepeatkill; initial dorepeatkill=0;");
- box.addPreCrap(" reg dokill; initial dokill=0;");
- box.addPreCrap(" reg clogged; initial clogged=0;");
-
- // FIXME: destination
- Module.SinkPort token_out = fabric_out;
- Module.SourcePort token_in = dfifo_out;
- Module.SinkPort data_out = inbox ? ship_in : fabric_out;
- Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
-
- Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
- Module.SinkPort ififo_in = ififo.getInputPort("in", PACKET_WIDTH);
- ififo_in.hasLatch = true;
- Module.SourcePort ififo_out = ififo.getOutputPort("out", PACKET_WIDTH, "");
-
- // Clog (must be first)
- box.new Action(
- new Object[] { ififo_out, "newmayproceed==1", "`instruction_is_clog("+ififo_out.getName()+")" },
- new Object[] { ififo_out, "clogged <= 1;", "newmayproceed<=0;" }
- );
-
- // UnClog
- box.new Action(
- new Object[] { instr, "clogged==1", "`instruction_is_unclog(instr)" },
- new Object[] { instr, "clogged <= 0;", "newmayproceed<=1;" }
- );
-
- // First Kill
- box.new Action(
- new Object[] { instr, ififo_out, "`instruction_is_kill(instr)", "!`instruction_is_unclog(instr)", "newmayproceed==1" },
- new Object[] { instr, ififo_out,
- "if (`instruction_count(instr)!=0)"+
- " begin repcount <= `instruction_count(instr)-1; newmayproceed <= 0; "+
- " dorepeatkill <= 1; end else begin newmayproceed<=1; end" }
- );
-
- // Kill
- box.new Action(
- new Object[] { "dokill==1" },
- new Object[] { "dokill<=0;",
- "if (`instruction_count(ondeck)!=0)"+
- " begin repcount <= `instruction_count(ondeck)-1;"+
- " dorepeatkill <= 1; end else begin newmayproceed<=1; end" }
- );
-
- // RepKill
- box.new Action(
- new Object[] { "dorepeatkill==1", ififo_out },
- new Object[] { "dorepeatkill<=0;", ififo_out, "dokill<=1;", "`instruction_count(ondeck)<=repcount;" }
- );
-
- // Enqueue
- box.new Action(
- new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
- new Object[] { instr, ififo_in, ififo_in.getName()+"<=instr;" }
- );
-
- // New
- box.new Action(
- new Object[] { ififo_out, "ondeck_full==0", "newmayproceed==1" },
- new Object[] { ififo_out, "ondeck_full<=1;", "newmayproceed<=0;",
- "ondeck<="+ififo_out.getName()+";" }
- );
-
- // RepeatExecute
- box.new Action(
- new Object[] { "dorepeat==1", },
- new Object[] { "dorepeat<=0;", "ondeck_full<=1;", "`instruction_count(ondeck)<=repcount;" }
- );
-
- for(int di=0; di<=1; di++)
- for(int dout=0; dout<=1; dout++)
- for(int tout=0; tout<=1; tout++)
- for(int ti=0; ti<=1; ti++) {
- box.new Action(
- new Object[] { "ondeck_full==1",
- data_out,
- token_out,
- ififo_in,
- (di==1 ? "" : "!")+"`instruction_bit_datain(ondeck)",
- (di==1 ? data_in : "1"),
- (ti==1 ? "" : "!")+"`instruction_bit_tokenin(ondeck)",
- (ti==1 ? token_in : "1"),
- (dout==1 ? "" : "!")+"`instruction_bit_dataout(ondeck)",
- (tout==1 ? "" : "!")+"`instruction_bit_tokenout(ondeck)"
- },
- new Object[] { "ondeck_full<=0;",
- "if (`instruction_count(ondeck)==1 || `instruction_bit_recycle(ondeck)) newmayproceed<=1;",
- "if (`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1) "+
- " begin "+ififo_in.getName()+"<=ondeck; "+
- " `instruction_count("+ififo_in.getName()+")<=(`instruction_count(ondeck)==0?0:`instruction_count(ondeck)-1);"+
- " "+ififo_in.getReq()+"<=1; end",
- "if (!`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1) "+
- " dorepeat <= 1;",
- "repcount <= (`instruction_count(ondeck)==0 ? 0 : (`instruction_count(ondeck)-1));",
- (di==1 ? data_in : ""),
- (dout==1 ? data_out : ""),
- (ti==1 ? token_in : ""),
- (tout==1 ? token_out : ""),
- ("if (`instruction_bit_latch(ondeck)) "+
- (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+
- "<="+
- (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";"),
- (tout==1 ? "`packet_dest("+token_out.getName()+")<=`instruction_bit_dest(ondeck);" : ""),
- (dout==1 && !inbox ? "`packet_dest("+data_out.getName()+")<=`instruction_bit_dest(ondeck);" : "")
- }
- );
- }
-
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- box.dump(pw);
- pw.flush();
- return box;
- }
-
private static Module mkfifo(String name, int len, Module instance, String prefix) throws Exception {
- Module fifo4 = new Module(name);
- Module.SourcePort inx = fifo4.getInputPort("in", PACKET_WIDTH);
- Module.SinkPort outx = fifo4.getOutputPort("out", PACKET_WIDTH, "");
+ Module fifo = new Module(name);
+ Module.SourcePort in = fifo.createInputPort("in", PACKET_WIDTH);
+ Module.SinkPort out = fifo.createOutputPort("out", PACKET_WIDTH, "");
Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
if (len==0) {
- fifo4.new Action(new Object[] { inx, outx }, new Object[] { inx, outx, "out = in;" });
+ fifo.new Event(new Object[] { in, out },
+ new Action[] { in, out, new AssignAction(out, in) });
} else for(int i=0; i<=len; i++) {
- if (i<len) stages[i] = fifo4.new InstantiatedModule(instance);
- Module.SourcePort driver = i==0 ? inx : stages[i-1].getOutputPort("out", PACKET_WIDTH, "");
- Module.SinkPort driven = i==len ? outx : stages[i].getInputPort("in", PACKET_WIDTH);
+ if (i<len) stages[i] = fifo.new InstantiatedModule(instance);
+ Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
+ Module.SinkPort driven = i==len ? out : stages[i].getInputPort("in");
driver.connect(driven);
}
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- fifo4.dump(pw);
+ fifo.dump(pw);
pw.flush();
- return fifo4;
+ return fifo;
}
public static void mkhorn(String name,
int bot_of_addr_field,
int bot) throws Exception {
Module horn = new Module(name);
- Module.SourcePort in = horn.getInputPort("in", PACKET_WIDTH);
- Module.SinkPort out0 = horn.getOutputPort("out0", PACKET_WIDTH, "");
- Module.SinkPort out1 = horn.getOutputPort("out1", PACKET_WIDTH, "");
+ Module.SourcePort in = horn.createInputPort("in", PACKET_WIDTH);
+ Module.SinkPort out0 = horn.createOutputPort("out0", PACKET_WIDTH, "");
+ Module.SinkPort out1 = horn.createOutputPort("out1", PACKET_WIDTH, "");
String shifted_packet = "{ ";
if (top_of_addr_field+1 < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
if (bot_of_addr_field > 0) shifted_packet += ", in["+(bot_of_addr_field-1)+":0] ";
shifted_packet += " }";
// same behavior as FLEET -- wait for both
- horn.new Action(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
- new Object[] { in, out0, "out0 = " + shifted_packet + ";" });
- horn.new Action(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
- new Object[] { in, out1, "out1 = " + shifted_packet + ";" });
-
+ horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
+ new Action[] { in, out0, new AssignAction(out0, shifted_packet) });
+ horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
+ new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
horn.dump(pw);
pw.flush();
}
+ private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
+ Module box = new Module(name);
+ Module.SourcePort instr = box.createInputPort("instr", INSTRUCTION_WIDTH);
+ Module.SourcePort fabric_in = box.createInputPort("fabric_in", PACKET_WIDTH);
+ Module.SinkPort fabric_out = box.createOutputPort("fabric_out", PACKET_WIDTH, "");
+ Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
+ fabric_in.connect(dfifo.getInputPort("in"));
+
+ Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
+ Module.SourcePort ship_out = null;
+ if (!inbox) {
+ ship_out = box.createInputPort("ship", WORD_WIDTH);
+ ship_out.hasLatch = true;
+ }
+
+ Module.SinkPort ship_in = null;
+ if (inbox) {
+ ship_in = box.createOutputPort("ship", PACKET_WIDTH, "");
+ ship_in.hasLatch = true;
+ }
+
+ Module.Latch ondeck = box.new Latch("ondeck", INSTRUCTION_WIDTH);
+ Module.Latch repcount = box.new Latch("repcount", COUNT_WIDTH);
+ Module.StateWire ondeckFull = box.new StateWire("ondeck_full");
+ Module.StateWire newMayProceed = box.new StateWire("newmayproceed", true);
+ Module.StateWire doRepeat = box.new StateWire("dorepeat", false);
+ Module.StateWire doRepeatKill = box.new StateWire("dorepeatkill", false);
+ Module.StateWire doKill = box.new StateWire("dokill", false);
+ Module.StateWire isClogged = box.new StateWire("clogged", false);
+
+ Module.SinkPort token_out = fabric_out;
+ Module.SourcePort token_in = dfifo_out;
+ Module.SinkPort data_out = inbox ? ship_in : fabric_out;
+ Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
+
+ Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
+ Module.SinkPort ififo_in = ififo.getInputPort("in");
+ Module.SourcePort ififo_out = ififo.getOutputPort("out");
+
+ Value instruction_count_ondeck = ondeck .getBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
+ Value instruction_count_instr = instr .getBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
+ Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
+
+ // Clog (must be first)
+ box.new Event(
+ new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
+ new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
+ );
+
+ // UnClog
+ box.new Event(
+ new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
+ new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill() }
+ );
+
+ // First Kill
+ box.new Event(
+ new Object[] { instr, ififo_out,
+ "`instruction_is_kill(instr)",
+ "!`instruction_is_unclog(instr)",
+ newMayProceed.isFull() },
+ new Action[] { instr, ififo_out,
+ new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
+ new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
+ new ConditionalAction("`instruction_count(instr)!=0", newMayProceed.doDrain()),
+ new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+ });
+
+ // Kill
+ box.new Event(
+ new Object[] { doKill.isFull() },
+ new Action[] { doKill.doDrain(),
+ new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
+ new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
+ new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+ });
+
+ // RepKill
+ box.new Event(
+ new Object[] { doRepeatKill.isFull(), ififo_out },
+ new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
+ new AssignAction(instruction_count_ondeck, repcount) }
+ );
+
+ // Enqueue
+ box.new Event(
+ new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
+ new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr) }
+ );
+
+ // New
+ box.new Event(
+ new Object[] { ififo_out, ondeckFull.isEmpty(), newMayProceed.isFull() },
+ new Action[] { ififo_out, ondeckFull.doFill(), newMayProceed.doDrain(),
+ new AssignAction(ondeck, ififo_out) }
+ );
+
+ // RepeatExecute
+ box.new Event(
+ new Object[] { doRepeat.isFull() },
+ new Action[] { doRepeat.doDrain(),
+ ondeckFull.doFill(),
+ new AssignAction(instruction_count_ondeck, repcount) }
+ );
+
+ Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
+ String data_latch_input = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
+ box.new Event(
+ new Object[] { ondeckFull.isFull(),
+ data_out,
+ token_out,
+ ififo_in,
+ new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
+ new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
+ },
+ new Action[] { new SimpleAction("ondeck_full<=0;"),
+ new ConditionalAction("`instruction_count(ondeck)==1 || `instruction_bit_recycle(ondeck)", newMayProceed.doFill()),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1",
+ new AssignAction(ififo_in, ondeck)),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
+ new AssignAction(instruction_count_ififo_in, "0")),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
+ new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
+ new ConditionalAction("!`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1", doRepeat.doFill()),
+ new ConditionalAction("`instruction_count(ondeck)==0", new AssignAction(repcount, "0")),
+ new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
+ new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
+ new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
+ new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
+ new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out),
+ new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
+ new ConditionalAction("`instruction_bit_tokenout(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
+ "`instruction_bit_dest(ondeck)")),
+ new ConditionalAction("`instruction_bit_dataout(ondeck)",
+ inbox ? new SimpleAction("")
+ : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
+ "`instruction_bit_dest(ondeck)"))
+ }
+ );
+
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
+ box.dump(pw);
+ pw.flush();
+ return box;
+ }
+
}