1 // note: got rid of funnel "fairness" code
2 package edu.berkeley.fleet.fpga;
3 import edu.berkeley.fleet.doc.*;
4 import edu.berkeley.fleet.api.*;
5 import edu.berkeley.fleet.ies44.*;
6 import edu.berkeley.fleet.*;
7 import java.lang.reflect.*;
8 import edu.berkeley.sbp.chr.*;
9 import edu.berkeley.sbp.misc.*;
10 import edu.berkeley.sbp.meta.*;
11 import edu.berkeley.sbp.util.*;
14 import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
16 public class Generator {
18 public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_ADDR;
20 public static class SimpleValue implements Value {
21 private final String s;
22 public SimpleValue(String s) { this.s = s; }
23 public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
24 public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
25 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
26 public String getVerilogName() { return s; }
27 public String toString() { return s; }
30 public static interface Action {
31 public String getVerilogAction();
34 public static interface Trigger {
35 public String getVerilogTrigger();
38 public static interface Assignable {
39 public String getVerilogName();
40 public Assignable getAssignableBits(int high, int low);
43 public static interface Value extends Assignable {
44 public String getVerilogName();
45 public Value getBits(int high, int low);
48 public static class ConditionalAction implements Action {
49 private String condition;
50 private Action action;
51 public ConditionalAction(String condition, Action action) {
52 this.condition = condition;
55 public String toString() { return getVerilogAction(); }
56 public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
59 public static class ConditionalTrigger implements Trigger {
60 private String condition;
61 private Trigger trigger;
62 public ConditionalTrigger(String condition, Trigger trigger) {
63 this.condition = condition;
64 this.trigger = trigger;
65 if (trigger instanceof Module.Port)
66 ((Module.Port)trigger).hasLatch = true;
68 public String getVerilogTrigger() {
69 return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
73 public static class SimpleAssignable implements Assignable {
74 private final String s;
75 public SimpleAssignable(String s) { this.s = s; }
76 public String getVerilogName() { return s; }
77 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
80 public static class AssignAction implements Action {
83 public AssignAction(Assignable left, Value right) {
84 this.left = left.getVerilogName();
85 this.right = right.getVerilogName().toString();
87 public AssignAction(Assignable left, String right) {
88 this.left = left.getVerilogName();
91 public String getVerilogAction() { return left + "<=" + right + ";"; }
92 public String toString() { return getVerilogAction(); }
95 public static class SimpleAction implements Action {
96 private final String verilog;
97 public SimpleAction(String verilog) { this.verilog = verilog; }
98 public String getVerilogAction() { return verilog; }
99 public String toString() { return verilog; }
102 public static class Module {
104 private final String name;
105 public String getName() { return name; }
106 public Port getPort(String name) { return ports.get(name); }
108 private HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
109 private final ArrayList<Event> events = new ArrayList<Event>();
111 // FIXME: always-alphabetical convention?
112 private final HashMap<String,Port> ports = new HashMap<String,Port>();
113 private final ArrayList<String> portorder = new ArrayList<String>();
114 private final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
115 private final HashMap<String,Latch> latches = new HashMap<String,Latch>();
117 private StringBuffer crap = new StringBuffer();
118 private StringBuffer precrap = new StringBuffer();
119 public void addCrap(String s) { crap.append(s); crap.append('\n'); }
120 public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
122 public Module(String name) {
126 public SourcePort createInputPort(String name, int width) {
127 if (ports.get(name)!=null) throw new RuntimeException();
128 return new SourcePort(name, width, true);
130 public SourcePort getInputPort(String name) {
131 SourcePort ret = (SourcePort)ports.get(name);
132 if (ret==null) throw new RuntimeException();
135 public SinkPort createOutputPort(String name, int width, String resetBehavior) {
136 if (ports.get(name)!=null) throw new RuntimeException();
137 return new SinkPort(name, width, true, resetBehavior);
139 public SinkPort getOutputPort(String name) {
140 SinkPort ret = (SinkPort)ports.get(name);
141 if (ret==null) throw new RuntimeException();
145 private class StateWire {
146 public final String name;
147 public final boolean initiallyFull;
148 public String getName() { return name; }
149 public Action isFull() { return new SimpleAction(name+"==1"); }
150 public Action isEmpty() { return new SimpleAction(name+"==0"); }
151 public Action doFill() { return new SimpleAction(name+"<=1;"); }
152 public Action doDrain() { return new SimpleAction(name+"<=0;"); }
153 public String doReset() { return name+"<="+(initiallyFull?"1":"0")+";"; }
154 public StateWire(String name) { this(name, false); }
155 public StateWire(String name, boolean initiallyFull) {
157 this.initiallyFull = initiallyFull;
158 statewires.put(name, this);
160 public void dump(PrintWriter pw) {
161 pw.println(" reg "+name+";");
162 pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
166 public class Latch implements Assignable, Value {
167 public final String name;
168 public final int width;
169 public Latch(String name, int width) {
172 latches.put(name, this);
174 public String getVerilogName() { return name; }
175 public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
176 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
177 public String doReset() { return name+"<=0;"; }
178 public void dump(PrintWriter pw) {
179 pw.println(" reg ["+(width-1)+":0] "+name+";");
180 pw.println(" initial "+name+"=0;");
184 private abstract class Port implements Action, Assignable, Trigger {
185 public final String name;
186 public String getName() { return name; }
187 public final int width;
188 public int getWidth() { return width; }
189 public boolean hasLatch = false;
190 public boolean external;
191 public Port(String name, int width, boolean external) {
194 this.external = external;
195 ports.put(name, this);
199 public String getVerilogName() { return name; }
200 public String getAck() { return name+"_a"; }
201 public String getReq() { return name+"_r"; }
202 public abstract String getInterface();
203 public abstract String getSimpleInterface();
204 public abstract String getDeclaration();
205 public abstract String getAssignments();
208 private class InstantiatedModule {
209 public final Module module;
211 private final HashMap<String,Port> ports = new HashMap<String,Port>();
212 public String getName() { return module.getName()+"_"+id; }
213 public InstantiatedModule(Module module) {
214 this.module = module;
215 this.id = Module.this.id++;
216 instantiatedModules.add(this);
218 public void dump(PrintWriter pw) {
219 pw.println(" " + module.getName() + " " + getName() + "(clk, rst ");
220 for(String s : module.portorder)
221 pw.println(", " + getPort(s).getSimpleInterface());
224 public Port getPort(String name) {
225 return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
227 public SinkPort getInputPort(String name) {
228 int width = module.getPort(name).getWidth();
229 SinkPort port = (SinkPort)ports.get(name);
231 port = new SinkPort(getName()+"_"+name, width, false, "");
232 ports.put(name, port);
236 public SourcePort getOutputPort(String name) {
237 int width = module.getPort(name).getWidth();
238 SourcePort port = (SourcePort)ports.get(name);
240 port = new SourcePort(getName()+"_"+name, width, false);
241 ports.put(name, port);
247 private class SourcePort extends Port implements Value {
248 private SinkPort driven = null;
249 public SourcePort(String name, int width, boolean external) {
250 super(name, width, external); }
251 public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
252 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
253 public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
254 public String getVerilogAction() { return getAck() + " <= 1;"; }
255 public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
256 public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
257 public String getDeclaration() {
258 StringBuffer sb = new StringBuffer();
260 sb.append("input " + name +"_r;\n");
261 sb.append("output " + name +"_a_;\n");
262 sb.append("input ["+(width-1)+":0]" + name +";\n");
264 sb.append("wire " + name +"_r;\n");
265 sb.append("wire ["+(width-1)+":0]" + name +";\n");
268 sb.append("wire " + name +"_a;\n");
270 sb.append("reg " + name +"_a;\n");
271 sb.append("initial " + name +"_a = 0;\n");
273 return sb.toString();
275 public String getAssignments() {
276 StringBuffer sb = new StringBuffer();
278 sb.append("assign " + name +"_a_ = " + name + "_a;\n");
279 if (driven != null) {
280 sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
281 sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
282 sb.append("assign " + driven.name +" = " + name + ";\n");
284 return sb.toString();
286 public void connect(SinkPort driven) {
287 this.driven = driven;
290 private class SinkPort extends Port {
291 public final String resetBehavior;
292 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
293 public String getVerilogAction() { return getReq() + " <= 1;"; }
294 public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
295 public SinkPort(String name, int width, boolean external, String resetBehavior) {
296 super(name, width, external); this.resetBehavior=resetBehavior; }
297 public String getResetBehavior() { return resetBehavior; }
298 public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
299 public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
300 public String getDeclaration() {
301 StringBuffer sb = new StringBuffer();
303 sb.append("output " + name +"_r_;\n");
304 sb.append("input " + name +"_a;\n");
305 sb.append("output ["+(width-1)+":0]" + name +"_;\n");
307 sb.append("wire " + name +"_a;\n");
310 sb.append("wire " + name +"_r;\n");
311 sb.append("wire ["+(width-1)+":0]" + name +";\n");
313 sb.append("reg " + name +"_r;\n");
314 sb.append("initial " + name +"_r = 0;\n");
315 sb.append("reg ["+(width-1)+":0]" + name +";\n");
316 sb.append("initial " + name +" = 0;\n");
318 return sb.toString();
320 public String getAssignments() {
321 StringBuffer sb = new StringBuffer();
323 sb.append("assign " + name +"_r_ = " + name + "_r;\n");
324 sb.append("assign " + name +"_ = " + name + ";\n");
326 return sb.toString();
330 public void dump(PrintWriter pw, boolean fix) {
331 pw.println("`include \"macros.v\"");
332 pw.println("module "+name+"(clk, rst ");
333 for(String name : portorder) {
334 Port p = ports.get(name);
335 pw.println(" , " + p.getInterface());
339 pw.println(" input clk;");
340 pw.println(" input rst;");
341 for(String name : ports.keySet()) {
342 Port p = ports.get(name);
343 pw.println(" " + p.getDeclaration());
345 for(StateWire sw : statewires.values())
347 for(Latch l : latches.values())
349 for(String name : ports.keySet()) {
350 Port p = ports.get(name);
351 pw.println(" " + p.getAssignments());
353 for(InstantiatedModule m : instantiatedModules) {
357 pw.println("always @(posedge clk) begin");
358 pw.println(" if (!rst) begin");
359 for(Latch l : latches.values())
360 pw.println(l.doReset());
361 for(StateWire sw : statewires.values())
362 pw.println(sw.doReset());
363 for(Port p : ports.values()) {
364 if (p instanceof SourcePort) {
365 SourcePort ip = (SourcePort)p;
367 pw.println(ip.getAck()+" <=1;");
369 SinkPort op = (SinkPort)p;
371 pw.println(op.getReq()+" <=0;");
374 pw.println(" end else begin");
375 for(Port p : ports.values()) {
376 if (p instanceof SourcePort) {
377 SourcePort ip = (SourcePort)p;
379 pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
381 SinkPort op = (SinkPort)p;
383 pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
385 op.getResetBehavior()+" end");
388 for(Event a : events) a.dump(pw, fix);
389 pw.println(" begin end");
394 pw.println("endmodule");
397 private class Event {
398 private Object[] triggers;
399 private Object[] actions;
400 public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
401 public Event(Object[] triggers, Object[] actions) {
402 Module.this.events.add(this);
403 this.triggers = triggers;
404 this.actions = actions;
405 for(int i=0; i<triggers.length; i++)
406 if (triggers[i] instanceof Port)
407 ((Port)triggers[i]).hasLatch = true;
409 public void dump(PrintWriter pw, boolean fix) {
411 for(Object o : triggers) {
412 if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
413 else pw.print(" && " + o);
415 pw.println(") begin ");
416 for(Object a : actions) pw.println(((Action)a).getVerilogAction());
417 if (fix) pw.println("end /*else*/ ");
418 else pw.println("end else ");
423 public static void main(String[] s) throws Exception {
424 String prefix = s[0];
427 pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
428 pw.println("`define DATAWIDTH "+WIDTH_WORD);
429 pw.println("`define CODEBAG_SIZE_BITS "+WIDTH_CODEBAG_SIZE);
430 pw.println("`define PUMP_ADDRESS_BITS "+WIDTH_ADDR);
431 pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_ADDR);
433 pw.println("`define COUNT_BITS "+WIDTH_COUNT);
434 pw.println("`define COUNT_WIDTH "+WIDTH_COUNT);
436 pw.println("`define PACKET_WIDTH (`DATAWIDTH + `DESTINATION_ADDRESS_BITS)");
437 pw.println("`define INSTRUCTION_WIDTH "+WIDTH_WORD);
438 pw.println("`define packet_data(p) p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
439 pw.println("`define packet_dest(p) p[(`DESTINATION_ADDRESS_BITS-1):0]");
440 pw.println("`define instruction_data(p) p[(`DATAWIDTH-1):0]");
441 pw.println("`define instruction_dest(p) "+PUMP_NAME.verilogVal("p"));
445 mkfunnel("funnel", prefix);
446 mkhorn( "horn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
447 mkhorn( "ihorn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
449 Module fifostage = mkfifo("fifostage", 0, null, prefix);
450 Module fifo4 = mkfifo("fifo4", 4, fifostage, prefix);
451 Module fifo8 = mkfifo("fifo8", 8, fifostage, prefix);
452 Module fifoship = mkfifo("fifo", 4, fifo4, prefix);
453 mkBox("outbox", false, prefix, fifo4, fifo8);
454 mkBox("inbox", true, prefix, fifo4, fifo8);
456 Module fabric = new Module("fabric");
457 fabric.createInputPort("horn_in", WIDTH_PACKET);
458 fabric.createOutputPort("funnel_out", WIDTH_PACKET, "");
459 mkRoot("root", prefix, fabric);
462 private static Module mkRoot(String name, String prefix, Module fabricm) throws Exception {
463 Module root = new Module(name);
464 Module.SourcePort in = root.createInputPort("in", 8);
465 Module.SinkPort out = root.createOutputPort("out", 8, "");
466 Module.InstantiatedModule fabric = root.new InstantiatedModule(fabricm);
467 Module.SinkPort fabric_in = fabric.getInputPort("horn_in");
468 Module.SourcePort fabric_out = fabric.getOutputPort("funnel_out");
469 Module.Latch count = root.new Latch("count", 8);
470 Module.Latch count_out = root.new Latch("count_out", 8);
471 root.addPreCrap("initial count = 0;");
472 root.addPreCrap("initial count_out = 0;");
473 root.new Event(new Object[] { in, fabric_in },
474 new Object[] { new SimpleAction(fabric_in.getName()+" <= ("+fabric_in.getName()+" << 8) | in;"),
475 new SimpleAction("if (count >= 5) begin count <= 0; "+fabric_in.getName()+"_r <= 1; end else count <= count+1; "),
478 root.new Event(new Object[] { out, fabric_out },
479 new Object[] { new SimpleAction(out.getName()+" <= ("+fabric_out.getName()+">> (count_out*8));"),
480 new SimpleAction("if (count_out >= 5) begin count_out <= 0; "+fabric_out.getName()+"_a <= 1; end else count_out <= count_out+1; "),
482 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
488 private static Module mkfunnel(String name, String prefix) throws Exception {
489 Module funnel = new Module(name);
490 Module.SinkPort out = funnel.createOutputPort("out", WIDTH_PACKET, "");
491 Module.SourcePort in1 = funnel.createInputPort("in1", WIDTH_PACKET);
492 Module.SourcePort in2 = funnel.createInputPort("in2", WIDTH_PACKET);
493 funnel.new Event(new Object[] { in1, out },
494 new Action[] { in1, out,
495 new AssignAction(out, in1) });
496 funnel.new Event(new Object[] { in2, out },
497 new Action[] { in2, out,
498 new AssignAction(out, in2) });
499 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
500 funnel.dump(pw, true);
505 private static Module mkfifo(String name, int len, Module instance, String prefix) throws Exception {
506 Module fifo = new Module(name);
507 Module.SourcePort in = fifo.createInputPort("in", WIDTH_PACKET);
508 Module.SinkPort out = fifo.createOutputPort("out", WIDTH_PACKET, "");
509 Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
511 fifo.new Event(new Object[] { in, out },
512 new Action[] { in, out, new AssignAction(out, in) });
513 } else for(int i=0; i<=len; i++) {
514 if (i<len) stages[i] = fifo.new InstantiatedModule(instance);
515 Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
516 Module.SinkPort driven = i==len ? out : stages[i].getInputPort("in");
517 driver.connect(driven);
519 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
525 public static void mkhorn(String name,
528 int top_of_addr_field,
529 int bot_of_addr_field,
530 int bot) throws Exception {
531 Module horn = new Module(name);
532 Module.SourcePort in = horn.createInputPort("in", WIDTH_PACKET);
533 Module.SinkPort out0 = horn.createOutputPort("out0", WIDTH_PACKET, "");
534 Module.SinkPort out1 = horn.createOutputPort("out1", WIDTH_PACKET, "");
535 String shifted_packet = "{ ";
536 if (top_of_addr_field+1 < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
537 shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
538 if (bot_of_addr_field > 0) shifted_packet += ", in["+(bot_of_addr_field-1)+":0] ";
539 shifted_packet += " }";
540 // same behavior as FLEET -- wait for both
541 horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
542 new Action[] { in, out0, new AssignAction(out0, shifted_packet) });
543 horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
544 new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
545 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
550 private static Module mkBox(String name, boolean inbox, String prefix, Module fifo, Module ififo_m) throws Exception {
551 Module box = new Module(name);
552 Module.SourcePort instr = box.createInputPort("instr", WIDTH_WORD);
553 Module.SourcePort fabric_in = box.createInputPort("fabric_in", WIDTH_PACKET);
554 Module.SinkPort fabric_out = box.createOutputPort("fabric_out", WIDTH_PACKET, "");
555 Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
556 fabric_in.connect(dfifo.getInputPort("in"));
558 Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
559 Module.SourcePort ship_out = null;
561 ship_out = box.createInputPort("ship", WIDTH_WORD);
562 ship_out.hasLatch = true;
565 Module.SinkPort ship_in = null;
567 ship_in = box.createOutputPort("ship", WIDTH_PACKET, "");
568 ship_in.hasLatch = true;
571 Module.Latch ondeck = box.new Latch("ondeck", WIDTH_WORD);
572 Module.Latch repcount = box.new Latch("repcount", WIDTH_COUNTER_LITERAL);
573 Module.Latch repcount2 = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL);
574 Module.Latch killcount = box.new Latch("killcount", WIDTH_COUNTER_LITERAL);
575 Module.Latch loop_counter = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL);
576 Module.Latch repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL);
577 Module.StateWire ondeckFull = box.new StateWire("ondeck_full");
578 Module.StateWire newMayProceed = box.new StateWire("newmayproceed", true);
579 Module.StateWire doRepeat = box.new StateWire("dorepeat", false);
580 Module.StateWire doRepeatKill = box.new StateWire("dorepeatkill", false);
581 Module.StateWire doKill = box.new StateWire("dokill", false);
582 Module.StateWire isClogged = box.new StateWire("clogged", false);
583 Module.StateWire isMassacreing = box.new StateWire("massacreing", false);
585 Module.SinkPort token_out = fabric_out;
586 Module.SourcePort token_in = dfifo_out;
587 Module.SinkPort data_out = inbox ? ship_in : fabric_out;
588 Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
590 Module.InstantiatedModule ififo = box.new InstantiatedModule(ififo_m);
591 Module.SinkPort ififo_in = ififo.getInputPort("in");
592 Module.SourcePort ififo_out = ififo.getOutputPort("out");
595 // Massacre (when enqueued)
597 new Object[] { ififo_out, "!`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
598 new Action[] { ififo_out }
601 new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
602 new Action[] { ififo_out, isMassacreing.doDrain(), newMayProceed.doFill() }
605 new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)", isMassacreing.isEmpty() },
606 new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr), isMassacreing.doFill(), ondeckFull.doDrain(), newMayProceed.doDrain() }
609 // Clog (must be first)
611 new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")", isMassacreing.isEmpty() },
612 new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
617 new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)", isMassacreing.isEmpty() },
618 new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill() }
623 new Object[] { instr,
624 "`instruction_is_kill(instr)",
625 "!`instruction_is_unclog(instr)",
627 isMassacreing.isEmpty()
629 new Action[] { instr,
630 ondeckFull.doDrain(),
631 new ConditionalAction("`instruction_kill_count(instr)!=0", new AssignAction(repcount, "`instruction_kill_count(instr)")),
632 new ConditionalAction("`instruction_kill_count(instr)!=0", doRepeatKill.doFill()),
633 new ConditionalAction("`instruction_kill_count(instr)!=0", newMayProceed.doDrain()),
634 new ConditionalAction("`instruction_kill_count(instr)==0", newMayProceed.doFill())
639 new Object[] { doKill.isFull() },
640 new Action[] { doKill.doDrain(),
641 new ConditionalAction("killcount!=0", new AssignAction(repcount, "killcount-1")),
642 new ConditionalAction("killcount!=0", doRepeatKill.doFill()),
643 new ConditionalAction("killcount==0", newMayProceed.doFill())
648 new Object[] { doRepeatKill.isFull(), ififo_out },
649 new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
650 new AssignAction(killcount, repcount) }
655 new Object[] { instr,
657 "!`instruction_is_kill(instr) && !`instruction_is_unclog(instr) && !`instruction_is_massacre(instr)",
658 isMassacreing.isEmpty()
660 new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr) }
665 new Object[] { ififo_out,
666 ondeckFull.isEmpty(),
667 newMayProceed.isFull(),
668 "!`instruction_is_clog("+ififo_out.getName()+")",
669 "!`instruction_is_kill(instr)",
670 isMassacreing.isEmpty() },
671 new Action[] { ififo_out,
673 newMayProceed.doDrain(),
674 new AssignAction(ondeck, ififo_out),
675 new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+") && !`is_standing("+ififo_out.getName()+")",
676 new AssignAction(repcount2, "(repeat_counter==0?1:repeat_counter)")),
677 new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
678 new AssignAction(repeat_counter, "1")),
684 new Object[] { doRepeat.isFull() },
685 new Action[] { doRepeat.doDrain(),
687 new AssignAction(repcount2, repcount)
691 box.addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
692 box.addPreCrap("assign data_latch_output = " + (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
694 Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
695 String data_latch_input = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
697 box.new Event(new Object[] { ondeckFull.isFull(),
698 isMassacreing.isEmpty(),
700 "!`instruction_is_kill(instr)",
701 "`instruction_is_load_loop_to_data(ondeck)"
703 new Action[] { ondeckFull.doDrain(),
704 newMayProceed.doFill(),
705 new AssignAction(data_latch, loop_counter),
706 new AssignAction(ififo_in, ondeck),
707 new ConditionalAction("`should_requeue(ondeck)", ififo_in)
710 box.new Event(new Object[] { ondeckFull.isFull(),
711 isMassacreing.isEmpty(),
713 "!`instruction_is_kill(instr)",
714 "`instruction_is_load_data_to_loop(ondeck)"
716 new Action[] { ondeckFull.doDrain(),
717 newMayProceed.doFill(),
718 new AssignAction(loop_counter, "data_latch_output"),
719 new AssignAction(ififo_in, ondeck),
720 new ConditionalAction("`should_requeue(ondeck)", ififo_in)
723 box.new Event(new Object[] { ondeckFull.isFull(),
724 isMassacreing.isEmpty(),
726 "!`instruction_is_kill(instr)",
727 "`instruction_is_load_literal_to_loop(ondeck)"
729 new Action[] { ondeckFull.doDrain(),
730 newMayProceed.doFill(),
731 new AssignAction(loop_counter, "`instruction_loop_count_literal(ondeck)"),
732 new AssignAction(ififo_in, ondeck),
733 new ConditionalAction("`should_requeue(ondeck)", ififo_in)
736 box.new Event(new Object[] { ondeckFull.isFull(),
737 isMassacreing.isEmpty(),
739 "!`instruction_is_kill(instr)",
740 "`instruction_is_decr_loop(ondeck)"
742 new Action[] { ondeckFull.doDrain(),
743 newMayProceed.doFill(),
744 new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)"),
745 new AssignAction(ififo_in, ondeck),
746 new ConditionalAction("`should_requeue(ondeck)", ififo_in)
749 box.new Event(new Object[] { ondeckFull.isFull(),
750 isMassacreing.isEmpty(),
752 "!`instruction_is_kill(instr)",
753 "`instruction_is_load_data_to_repeat(ondeck)"
755 new Action[] { ondeckFull.doDrain(),
756 newMayProceed.doFill(),
757 new AssignAction(repeat_counter, "data_latch_output"),
758 new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
759 new ConditionalAction("`should_requeue(ondeck)", ififo_in)
762 box.new Event(new Object[] { ondeckFull.isFull(),
763 isMassacreing.isEmpty(),
765 "!`instruction_is_kill(instr)",
766 "`instruction_is_load_literal_to_repeat(ondeck)"
768 new Action[] { ondeckFull.doDrain(),
769 newMayProceed.doFill(),
770 new AssignAction(repeat_counter, "`instruction_repeat_count_literal(ondeck)"),
771 new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
772 new ConditionalAction("`should_requeue(ondeck)", ififo_in)
778 new Object[] { ondeckFull.isFull(),
779 isMassacreing.isEmpty(),
783 "!`instruction_is_kill(instr)",
784 "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) ||"+
785 " `instruction_is_literal_lo(ondeck) || `instruction_is_literal(ondeck))",
786 new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
787 new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
789 new Action[] { ondeckFull.doDrain(),
790 new ConditionalAction("`done_executing(ondeck)", newMayProceed.doFill()),
791 new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
792 new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
793 new ConditionalAction("repcount2>1", doRepeat.doFill()),
794 new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
795 new ConditionalAction("!`is_standing(ondeck)", new AssignAction(repcount, "repcount2-1")),
796 new ConditionalAction("`instruction_is_literal(ondeck)",
797 new AssignAction(data_latch, "`instruction_literal(ondeck)")),
798 new ConditionalAction("`instruction_is_literal_hi(ondeck)",
799 new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")),
800 new ConditionalAction("`instruction_is_literal_lo(ondeck)",
801 new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")),
802 new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
803 new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
804 new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
805 new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out),
806 new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
807 new ConditionalAction("`instruction_path_from_data(ondeck)",
808 new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
809 PUMP_NAME.verilogVal(data_latch_input))),
810 new ConditionalAction("`instruction_path_from_literal(ondeck)",
811 new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
812 "`instruction_path_literal(ondeck)")),
816 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
818 pw.println("`define instruction_is_load_loop_to_data(i) "+TAKE_LOOP.verilog("i"));
819 pw.println("`define instruction_is_load_data_to_repeat(i) "+REPEAT_FROM_DATA.verilog("i"));
820 pw.println("`define instruction_is_load_data_to_loop(i) "+LOOP_FROM_DATA.verilog("i"));
821 pw.println("`define instruction_is_load_literal_to_repeat(i) "+REPEAT_FROM_LITERAL.verilog("i"));
822 pw.println("`define instruction_is_load_literal_to_loop(i) "+LOOP_FROM_LITERAL.verilog("i"));
823 pw.println("`define instruction_repeat_count_literal(i) "+REPEAT_FROM_LITERAL.verilogVal("i"));
824 pw.println("`define instruction_loop_count_literal(i) "+LOOP_FROM_LITERAL.verilogVal("i"));
826 pw.println("`define instruction_path_literal(i) "+PATH_LITERAL.verilogVal("i"));
827 pw.println("`define instruction_path_from_literal(i) "+PATH_LITERAL.verilog("i"));
828 pw.println("`define instruction_path_from_data(i) "+PATH_DATA.verilog("i"));
830 pw.println("`define instruction_is_literal_hi(i) "+LITERAL_HI.verilog("i"));
831 pw.println("`define instruction_is_literal_lo(i) "+LITERAL_LO.verilog("i"));
832 pw.println("`define instruction_is_literal(i) "+LITERAL.verilog("i"));
833 pw.println("`define instruction_kill_count(i) "+KILL.verilogVal("i"));
834 pw.println("`define instruction_is_kill(i) "+KILL.verilog("i"));
835 pw.println("`define instruction_is_unclog(i) "+UNCLOG.verilog("i"));
836 pw.println("`define instruction_is_clog(i) "+CLOG.verilog("i"));
837 pw.println("`define instruction_is_massacre(i) "+MASSACRE.verilog("i"));
838 pw.println("`define instruction_is_normal(i) "+MOVE.verilog("i"));
840 pw.println("`define instruction_is_decr_loop(i) "+DL.verilog("i"));
842 pw.println("`define instruction_bit_tokenout(i) (`instruction_is_normal(i) && "+TO.verilog("i")+")");
843 pw.println("`define instruction_bit_dataout(i) (`instruction_is_normal(i) && "+DO.verilog("i")+")");
844 pw.println("`define instruction_bit_latch(i) (`instruction_is_normal(i) && "+DC.verilog("i")+")");
845 pw.println("`define instruction_bit_datain(i) (`instruction_is_normal(i) && "+DI.verilog("i")+")");
846 pw.println("`define instruction_bit_tokenin(i) (`instruction_is_normal(i) && "+TI.verilog("i")+")");
847 pw.println("`define is_standing(i) (`instruction_is_normal(i) && "+STAND.verilog("i")+")");
848 pw.println("`define should_requeue(i) (loop_counter > 0)");
849 pw.println("`define done_executing(i) (!`is_standing(i) && (repcount2==0 || repcount2==1))");
851 pw.println("`define instruction_literal_hi(i,d) { (i[17:0]), (d[18:0]) }");
852 pw.println("`define instruction_literal_lo(i,d) { (d[36:19]), (i[18:0]) }");
854 pw.println("`define instruction_literal_sel(i) " + LITERAL_SEL.verilogVal("i"));
855 pw.println("`define instruction_literal(i) " +
857 " `instruction_literal_sel(i) == 0 ? { (i[17:0]), {19{1'b0}} } "+
858 ": `instruction_literal_sel(i) == 1 ? { (i[17:0]), {19{1'b1}} } "+
859 ": `instruction_literal_sel(i) == 2 ? { {18{1'b0}}, (i[18:0]) } "+
860 ": { {18{1'b1}}, (i[18:0]) } "+