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_DEST_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 StateWire(String name) { this(name, false); }
154 public StateWire(String name, boolean initiallyFull) {
156 this.initiallyFull = initiallyFull;
157 statewires.put(name, this);
159 public void dump(PrintWriter pw) {
160 pw.println(" reg "+name+";");
161 pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
165 public class Latch implements Assignable, Value {
166 public final String name;
167 public final int width;
168 public Latch(String name, int width) {
171 latches.put(name, this);
173 public String getVerilogName() { return name; }
174 public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
175 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
176 public void dump(PrintWriter pw) {
177 pw.println(" reg ["+(width-1)+":0] "+name+";");
178 //pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
182 private abstract class Port implements Action, Assignable, Trigger {
183 public final String name;
184 public String getName() { return name; }
185 public final int width;
186 public int getWidth() { return width; }
187 public boolean hasLatch = false;
188 public boolean external;
189 public Port(String name, int width, boolean external) {
192 this.external = external;
193 ports.put(name, this);
197 public String getVerilogName() { return name; }
198 public String getAck() { return name+"_a"; }
199 public String getReq() { return name+"_r"; }
200 public abstract String getInterface();
201 public abstract String getSimpleInterface();
202 public abstract String getDeclaration();
203 public abstract String getAssignments();
206 private class InstantiatedModule {
207 public final Module module;
209 private final HashMap<String,Port> ports = new HashMap<String,Port>();
210 public String getName() { return module.getName()+"_"+id; }
211 public InstantiatedModule(Module module) {
212 this.module = module;
213 this.id = Module.this.id++;
214 instantiatedModules.add(this);
216 public void dump(PrintWriter pw) {
217 pw.println(" " + module.getName() + " " + getName() + "(clk");
218 for(String s : module.portorder)
219 pw.println(", " + getPort(s).getSimpleInterface());
222 public Port getPort(String name) {
223 return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
225 public SinkPort getInputPort(String name) {
226 int width = module.getPort(name).getWidth();
227 SinkPort port = (SinkPort)ports.get(name);
229 port = new SinkPort(getName()+"_"+name, width, false, "");
230 ports.put(name, port);
234 public SourcePort getOutputPort(String name) {
235 int width = module.getPort(name).getWidth();
236 SourcePort port = (SourcePort)ports.get(name);
238 port = new SourcePort(getName()+"_"+name, width, false);
239 ports.put(name, port);
245 private class SourcePort extends Port implements Value {
246 private SinkPort driven = null;
247 public SourcePort(String name, int width, boolean external) {
248 super(name, width, external); }
249 public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
250 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
251 public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
252 public String getVerilogAction() { return getAck() + " <= 1;"; }
253 public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
254 public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
255 public String getDeclaration() {
256 StringBuffer sb = new StringBuffer();
258 sb.append("input " + name +"_r;\n");
259 sb.append("output " + name +"_a_;\n");
260 sb.append("input ["+(width-1)+":0]" + name +";\n");
262 sb.append("wire " + name +"_r;\n");
263 sb.append("wire ["+(width-1)+":0]" + name +";\n");
266 sb.append("wire " + name +"_a;\n");
268 sb.append("reg " + name +"_a;\n");
269 sb.append("initial " + name +"_a = 0;\n");
271 return sb.toString();
273 public String getAssignments() {
274 StringBuffer sb = new StringBuffer();
276 sb.append("assign " + name +"_a_ = " + name + "_a;\n");
277 if (driven != null) {
278 sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
279 sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
280 sb.append("assign " + driven.name +" = " + name + ";\n");
282 return sb.toString();
284 public void connect(SinkPort driven) {
285 this.driven = driven;
288 private class SinkPort extends Port {
289 public final String resetBehavior;
290 public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
291 public String getVerilogAction() { return getReq() + " <= 1;"; }
292 public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
293 public SinkPort(String name, int width, boolean external, String resetBehavior) {
294 super(name, width, external); this.resetBehavior=resetBehavior; }
295 public String getResetBehavior() { return resetBehavior; }
296 public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
297 public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
298 public String getDeclaration() {
299 StringBuffer sb = new StringBuffer();
301 sb.append("output " + name +"_r_;\n");
302 sb.append("input " + name +"_a;\n");
303 sb.append("output ["+(width-1)+":0]" + name +"_;\n");
305 sb.append("wire " + name +"_a;\n");
308 sb.append("wire " + name +"_r;\n");
309 sb.append("wire ["+(width-1)+":0]" + name +";\n");
311 sb.append("reg " + name +"_r;\n");
312 sb.append("initial " + name +"_r = 0;\n");
313 sb.append("reg ["+(width-1)+":0]" + name +";\n");
314 sb.append("initial " + name +" = 0;\n");
316 return sb.toString();
318 public String getAssignments() {
319 StringBuffer sb = new StringBuffer();
321 sb.append("assign " + name +"_r_ = " + name + "_r;\n");
322 sb.append("assign " + name +"_ = " + name + ";\n");
324 return sb.toString();
328 public void dump(PrintWriter pw) {
329 pw.println("`include \"macros.v\"");
330 pw.println("module "+name+"(clk");
331 for(String name : portorder) {
332 Port p = ports.get(name);
333 pw.println(" , " + p.getInterface());
337 pw.println(" input clk;");
338 for(String name : ports.keySet()) {
339 Port p = ports.get(name);
340 pw.println(" " + p.getDeclaration());
342 for(StateWire sw : statewires.values())
344 for(Latch l : latches.values())
346 for(String name : ports.keySet()) {
347 Port p = ports.get(name);
348 pw.println(" " + p.getAssignments());
350 for(InstantiatedModule m : instantiatedModules) {
354 pw.println("always @(posedge clk) begin");
355 for(Port p : ports.values()) {
356 if (p instanceof SourcePort) {
357 SourcePort ip = (SourcePort)p;
359 pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
361 SinkPort op = (SinkPort)p;
363 pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
365 op.getResetBehavior()+" end");
369 for(Event a : events) a.dump(pw);
370 pw.println(" begin end");
374 pw.println("endmodule");
377 private class Event {
378 private Object[] triggers;
379 private Object[] actions;
380 public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
381 public Event(Object[] triggers, Object[] actions) {
382 Module.this.events.add(this);
383 this.triggers = triggers;
384 this.actions = actions;
385 for(int i=0; i<triggers.length; i++)
386 if (triggers[i] instanceof Port)
387 ((Port)triggers[i]).hasLatch = true;
389 public void dump(PrintWriter pw) {
391 for(Object o : triggers) {
392 if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
393 else pw.print(" && " + o);
395 pw.println(") begin ");
396 for(Object a : actions) pw.println(((Action)a).getVerilogAction());
397 pw.println("end else ");
402 public static void main(String[] s) throws Exception {
403 String prefix = s[0];
406 pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
407 pw.println("`define DATAWIDTH "+WIDTH_WORD);
408 pw.println("`define CODEBAG_SIZE_BITS "+WIDTH_CODEBAG_SIZE);
409 pw.println("`define PUMP_ADDRESS_BITS "+WIDTH_PUMP_ADDR);
410 pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_DEST_ADDR);
411 pw.println("`define COUNT_BITS "+WIDTH_COUNT);
412 pw.println("`define COUNT_WIDTH "+WIDTH_COUNT);
413 pw.println("`define PACKET_WIDTH (`DATAWIDTH + `DESTINATION_ADDRESS_BITS)");
414 pw.println("`define INSTRUCTION_WIDTH "+WIDTH_WORD);
415 pw.println("`define packet_data(p) p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
416 pw.println("`define packet_dest(p) p[(`DESTINATION_ADDRESS_BITS-1):0]");
417 pw.println("`define instruction_data(p) p[(`DATAWIDTH-1):0]");
418 pw.println("`define instruction_dest(p) p["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]");
422 mkfunnel("funnel", prefix);
423 mkhorn( "horn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
424 mkhorn( "ihorn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
426 Module fifostage = mkfifo("fifostage", 0, null, prefix);
427 Module fifo4 = mkfifo("fifo4", 4, fifostage, prefix);
428 Module fifoship = mkfifo("fifo", 4, fifo4, prefix);
429 mkBox("outbox", false, prefix, fifo4);
430 mkBox("inbox", true, prefix, fifo4);
432 Module fabric = new Module("fabric");
433 fabric.createInputPort("horn_in", WIDTH_PACKET);
434 fabric.createOutputPort("funnel_out", WIDTH_PACKET, "");
435 mkRoot("root", prefix, fabric);
438 private static Module mkRoot(String name, String prefix, Module fabricm) throws Exception {
439 Module root = new Module(name);
440 Module.SourcePort in = root.createInputPort("in", 8);
441 Module.SinkPort out = root.createOutputPort("out", 8, "");
442 Module.InstantiatedModule fabric = root.new InstantiatedModule(fabricm);
443 Module.SinkPort fabric_in = fabric.getInputPort("horn_in");
444 Module.SourcePort fabric_out = fabric.getOutputPort("funnel_out");
445 Module.Latch count = root.new Latch("count", 8);
446 Module.Latch count_out = root.new Latch("count_out", 8);
447 root.addPreCrap("initial count = 0;");
448 root.addPreCrap("initial count_out = 0;");
449 root.new Event(new Object[] { in, fabric_in },
450 new Object[] { new SimpleAction(fabric_in.getName()+" <= ("+fabric_in.getName()+" << 8) | in;"),
451 new SimpleAction("if (count >= 5) begin count <= 0; "+fabric_in.getName()+"_r <= 1; end else count <= count+1; "),
454 root.new Event(new Object[] { out, fabric_out },
455 new Object[] { new SimpleAction(out.getName()+" <= ("+fabric_out.getName()+">> (count_out*8));"),
456 new SimpleAction("if (count_out >= 5) begin count_out <= 0; "+fabric_out.getName()+"_a <= 1; end else count_out <= count_out+1; "),
458 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
464 private static Module mkfunnel(String name, String prefix) throws Exception {
465 Module funnel = new Module(name);
466 Module.SinkPort out = funnel.createOutputPort("out", WIDTH_PACKET, "");
467 Module.SourcePort in1 = funnel.createInputPort("in1", WIDTH_PACKET);
468 Module.SourcePort in2 = funnel.createInputPort("in2", WIDTH_PACKET);
469 funnel.new Event(new Object[] { in1, out },
470 new Action[] { in1, out,
471 new AssignAction(out, in1) });
472 funnel.new Event(new Object[] { in2, out },
473 new Action[] { in2, out,
474 new AssignAction(out, in2) });
475 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
481 private static Module mkfifo(String name, int len, Module instance, String prefix) throws Exception {
482 Module fifo = new Module(name);
483 Module.SourcePort in = fifo.createInputPort("in", WIDTH_PACKET);
484 Module.SinkPort out = fifo.createOutputPort("out", WIDTH_PACKET, "");
485 Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
487 fifo.new Event(new Object[] { in, out },
488 new Action[] { in, out, new AssignAction(out, in) });
489 } else for(int i=0; i<=len; i++) {
490 if (i<len) stages[i] = fifo.new InstantiatedModule(instance);
491 Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
492 Module.SinkPort driven = i==len ? out : stages[i].getInputPort("in");
493 driver.connect(driven);
495 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
501 public static void mkhorn(String name,
504 int top_of_addr_field,
505 int bot_of_addr_field,
506 int bot) throws Exception {
507 Module horn = new Module(name);
508 Module.SourcePort in = horn.createInputPort("in", WIDTH_PACKET);
509 Module.SinkPort out0 = horn.createOutputPort("out0", WIDTH_PACKET, "");
510 Module.SinkPort out1 = horn.createOutputPort("out1", WIDTH_PACKET, "");
511 String shifted_packet = "{ ";
512 if (top_of_addr_field+1 < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
513 shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
514 if (bot_of_addr_field > 0) shifted_packet += ", in["+(bot_of_addr_field-1)+":0] ";
515 shifted_packet += " }";
516 // same behavior as FLEET -- wait for both
517 horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
518 new Action[] { in, out0, new AssignAction(out0, shifted_packet) });
519 horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
520 new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
521 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
526 private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
527 Module box = new Module(name);
528 Module.SourcePort instr = box.createInputPort("instr", WIDTH_WORD);
529 Module.SourcePort fabric_in = box.createInputPort("fabric_in", WIDTH_PACKET);
530 Module.SinkPort fabric_out = box.createOutputPort("fabric_out", WIDTH_PACKET, "");
531 Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
532 fabric_in.connect(dfifo.getInputPort("in"));
534 Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
535 Module.SourcePort ship_out = null;
537 ship_out = box.createInputPort("ship", WIDTH_WORD);
538 ship_out.hasLatch = true;
541 Module.SinkPort ship_in = null;
543 ship_in = box.createOutputPort("ship", WIDTH_PACKET, "");
544 ship_in.hasLatch = true;
547 Module.Latch ondeck = box.new Latch("ondeck", WIDTH_WORD);
548 Module.Latch repcount = box.new Latch("repcount", WIDTH_COUNT);
549 Module.StateWire ondeckFull = box.new StateWire("ondeck_full");
550 Module.StateWire newMayProceed = box.new StateWire("newmayproceed", true);
551 Module.StateWire doRepeat = box.new StateWire("dorepeat", false);
552 Module.StateWire doRepeatKill = box.new StateWire("dorepeatkill", false);
553 Module.StateWire doKill = box.new StateWire("dokill", false);
554 Module.StateWire isClogged = box.new StateWire("clogged", false);
556 Module.SinkPort token_out = fabric_out;
557 Module.SourcePort token_in = dfifo_out;
558 Module.SinkPort data_out = inbox ? ship_in : fabric_out;
559 Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
561 Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
562 Module.SinkPort ififo_in = ififo.getInputPort("in");
563 Module.SourcePort ififo_out = ififo.getOutputPort("out");
565 Value instruction_count_ondeck = ondeck .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
566 Value instruction_count_instr = instr .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
567 Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
569 // Clog (must be first)
571 new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
572 new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
577 new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
578 new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill() }
583 new Object[] { instr,
584 "`instruction_is_kill(instr)",
585 "!`instruction_is_unclog(instr)",
588 new Action[] { instr,
589 ondeckFull.doDrain(),
590 new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
591 new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
592 new ConditionalAction("`instruction_count(instr)!=0", newMayProceed.doDrain()),
593 new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
598 new Object[] { doKill.isFull() },
599 new Action[] { doKill.doDrain(),
600 new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
601 new ConditionalAction("`instruction_count(ondeck)!=0", doRepeatKill.doFill()),
602 new ConditionalAction("`instruction_count(ondeck)==0", newMayProceed.doFill())
607 new Object[] { doRepeatKill.isFull(), ififo_out },
608 new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
609 new AssignAction(instruction_count_ondeck, repcount) }
614 new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
615 new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr) }
620 new Object[] { ififo_out, ondeckFull.isEmpty(), newMayProceed.isFull() },
621 new Action[] { ififo_out, ondeckFull.doFill(), newMayProceed.doDrain(),
622 new AssignAction(ondeck, ififo_out) }
627 new Object[] { doRepeat.isFull() },
628 new Action[] { doRepeat.doDrain(),
630 new AssignAction(instruction_count_ondeck, repcount) }
633 Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
634 String data_latch_input = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
637 new Object[] { ondeckFull.isFull(),
641 "(`instruction_is_normal(ondeck) || `instruction_is_literal(ondeck))",
642 new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
643 new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
645 new Action[] { new SimpleAction("ondeck_full<=0;"),
646 new ConditionalAction("`instruction_count(ondeck)==1 || `instruction_bit_requeue(ondeck)", newMayProceed.doFill()),
647 new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1",
648 new AssignAction(ififo_in, ondeck)),
649 new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
650 new AssignAction(instruction_count_ififo_in, "0")),
651 new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
652 new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
653 new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
654 new ConditionalAction("!`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", doRepeat.doFill()),
655 new ConditionalAction("`instruction_count(ondeck)==0", new AssignAction(repcount, "0")),
656 new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
657 new ConditionalAction("`instruction_is_literal(ondeck)", new AssignAction(data_latch, "`instruction_literal(ondeck)")),
658 new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
659 new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
660 new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
661 new ConditionalAction("`instruction_bit_tokenout(ondeck) && (!`instruction_bit_tokenoutlast(ondeck) || `instruction_count(ondeck)==1)",
663 new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
664 new ConditionalAction("`instruction_bit_tokenout(ondeck)",
665 new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
666 "`instruction_bit_dest(ondeck)")),
667 new ConditionalAction("`instruction_bit_dataout(ondeck) && !`instruction_bit_tokenout(ondeck)",
668 inbox ? new SimpleAction("")
669 : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
670 "`instruction_bit_dest(ondeck)")),
671 new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && !`instruction_bit_datain(ondeck)",
672 inbox ? new SimpleAction("")
673 : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
674 data_out.getName()+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]")),
675 new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && `instruction_bit_datain(ondeck)",
676 inbox ? new SimpleAction("")
677 : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
678 data_latch_input+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]"))
682 PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
683 pw.println("`define instruction_bit_dest(instruction) instruction["+(OFFSET_DEST+WIDTH_DEST_ADDR-1)+":"+OFFSET_DEST+"]");
684 pw.println("`define instruction_is_literal(i) (i["+(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1)+":"+OFFSET_MASK_LITERAL+"]=="+MASK_LITERAL+")");
685 pw.println("`define instruction_count(i) (`instruction_is_literal(i)?1:i["+(OFFSET_COUNT+WIDTH_COUNT-1)+":"+OFFSET_COUNT+"])");
686 pw.println("`define instruction_is_kill(i) (i["+(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1)+":"+OFFSET_MASK_KILL+"]=="+MASK_KILL+")");
687 pw.println("`define instruction_is_unclog(i) (i["+(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1)+":"+OFFSET_MASK_UNCLOG+"]=="+MASK_UNCLOG+")");
688 pw.println("`define instruction_is_clog(i) (i["+(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1)+":"+OFFSET_MASK_CLOG+"]=="+MASK_CLOG+")");
689 pw.println("`define instruction_is_normal(i) (i["+(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1)+":"+OFFSET_MASK_NORMAL+"]=="+MASK_NORMAL+")");
690 pw.println("`define instruction_bit_requeue(instruction) (instruction["+OFFSET_RQ+"] && !`instruction_is_literal(instruction))");
692 pw.println("`define instruction_bit_tokenout(i) (!`instruction_is_literal(i) && i["+OFFSET_TO+"])");
693 pw.println("`define instruction_bit_tokenoutlast(i) (!`instruction_is_literal(i) && i["+OFFSET_IG+"])");
694 pw.println("`define instruction_bit_dataout(i) (!`instruction_is_literal(i) && i["+OFFSET_DO+"])");
695 pw.println("`define instruction_bit_latch(i) (!`instruction_is_literal(i) && i["+OFFSET_DL+"])");
696 pw.println("`define instruction_bit_datain(i) (!`instruction_is_literal(i) && i["+OFFSET_DI+"])");
697 pw.println("`define instruction_bit_tokenin(i) (!`instruction_is_literal(i) && i["+OFFSET_TI+"])");
699 int signextbits = WIDTH_WORD - WIDTH_LITERAL;
700 pw.println("`define instruction_literal(i) {{ "+signextbits+"{i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+"]}},"+
701 " i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+":"+OFFSET_LITERAL+"]}");