32e39c847b7eb280b198782a1e4793e23d5ec132
[fleet.git] / src / edu / berkeley / fleet / slipway / Generator.java
1 // note: got rid of funnel "fairness" code
2 package edu.berkeley.fleet.slipway;
3 import edu.berkeley.fleet.slipway.*;
4 import edu.berkeley.fleet.doc.*;
5 import edu.berkeley.fleet.api.*;
6 import edu.berkeley.fleet.ies44.*;
7 import edu.berkeley.fleet.*;
8 import java.lang.reflect.*;
9 import edu.berkeley.sbp.chr.*;
10 import edu.berkeley.sbp.misc.*;
11 import edu.berkeley.sbp.meta.*;
12 import edu.berkeley.sbp.util.*;
13 import java.util.*;
14 import java.io.*;
15
16 public class Generator {
17
18     public static class SimpleValue implements Value {
19         private final String s;
20         public SimpleValue(String s) { this.s = s; }
21         public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
22         public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
23         public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
24         public String getVerilogName() { return s; }
25         public String toString() { return s; }
26     }
27
28     public static interface Action {
29         public String getVerilogAction();
30     }
31
32     public static interface Trigger {
33         public String getVerilogTrigger();
34     }
35
36     public static interface Assignable {
37         public String getVerilogName();
38         public Assignable getAssignableBits(int high, int low);
39     }
40
41     public static interface Value extends Assignable {
42         public String getVerilogName();
43         public Value getBits(int high, int low);
44     }
45
46     public static class ConditionalAction implements Action {
47         private String condition;
48         private Action action;
49         public ConditionalAction(String condition, Action action) {
50             this.condition = condition;
51             this.action = action;
52         }
53         public String toString() { return getVerilogAction(); }
54         public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
55     }
56
57     public static class ConditionalTrigger implements Trigger {
58         private String condition;
59         private Trigger trigger;
60         public ConditionalTrigger(String condition, Trigger trigger) {
61             this.condition = condition;
62             this.trigger = trigger;
63             if (trigger instanceof Module.Port)
64                 ((Module.Port)trigger).hasLatch = true;
65         }
66         public String getVerilogTrigger() {
67             return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
68         }
69     }
70
71     public static class SimpleAssignable implements Assignable {
72         private final String s;
73         public SimpleAssignable(String s) { this.s = s; }
74         public String getVerilogName() { return s; }
75         public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
76     }
77
78     public static class AssignAction implements Action {
79         private String left;
80         private String right;
81         public AssignAction(Assignable left, Value right) {
82             this.left = left.getVerilogName();
83             this.right = right.getVerilogName().toString();
84         }
85         public AssignAction(Assignable left, String right) {
86             this.left = left.getVerilogName();
87             this.right = right;
88         }
89         public String getVerilogAction() { return left + "<=" + right + ";"; }
90         public String toString() { return getVerilogAction(); }
91     }
92     
93     public static class SimpleAction implements Action {
94         private final String verilog;
95         public SimpleAction(String verilog) { this.verilog = verilog; }
96         public String getVerilogAction() { return verilog; }
97         public String toString() { return verilog; }
98     }
99
100     public static class Module {
101         private int id = 0;
102         private final String name;
103         public String getName() { return name; }
104         public Port getPort(String name) { return ports.get(name); }
105
106         private HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
107         private final ArrayList<Event> events = new ArrayList<Event>();
108
109         // FIXME: always-alphabetical convention?
110         private final HashMap<String,Port> ports = new HashMap<String,Port>();
111         private final ArrayList<String> portorder = new ArrayList<String>();
112         private final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
113         private final HashMap<String,Latch> latches = new HashMap<String,Latch>();
114         
115         private StringBuffer crap = new StringBuffer();
116         private StringBuffer precrap = new StringBuffer();
117         public void addCrap(String s) { crap.append(s); crap.append('\n'); }
118         public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
119
120         public Module(String name) {
121             this.name = name;
122         }
123
124         public SourcePort createInputPort(String name, int width) {
125             if (ports.get(name)!=null) throw new RuntimeException();
126             return new SourcePort(name, width, true);
127         }
128         public SourcePort getInputPort(String name) {
129             SourcePort ret = (SourcePort)ports.get(name);
130             if (ret==null) throw new RuntimeException();
131             return ret;
132         }
133         public SinkPort createOutputPort(String name, int width, String resetBehavior) {
134             if (ports.get(name)!=null) throw new RuntimeException();
135             return new SinkPort(name, width, true, resetBehavior);
136         }
137         public SinkPort getOutputPort(String name) {
138             SinkPort ret = (SinkPort)ports.get(name);
139             if (ret==null) throw new RuntimeException();
140             return ret;
141         }
142
143         private class StateWire {
144             public final String name;
145             public final boolean initiallyFull;
146             public String getName() { return name; }
147             public Action isFull()  { return new SimpleAction(name+"==1"); }
148             public Action isEmpty() { return new SimpleAction(name+"==0"); }
149             public Action doFill()  { return new SimpleAction(name+"<=1;"); }
150             public Action doDrain() { return new SimpleAction(name+"<=0;"); }
151             public StateWire(String name) { this(name, false); }
152             public StateWire(String name, boolean initiallyFull) {
153                 this.name = name;
154                 this.initiallyFull = initiallyFull;
155                 statewires.put(name, this);
156             }
157             public void dump(PrintWriter pw) {
158                 pw.println("  reg "+name+";");
159                 pw.println("  initial "+name+"="+(initiallyFull?"1":"0")+";");
160             }
161         }
162
163         public class Latch implements Assignable, Value {
164             public final String name;
165             public final int width;
166             public Latch(String name, int width) {
167                 this.width = width;
168                 this.name = name;
169                 latches.put(name, this);
170             }
171             public String getVerilogName() { return name; }
172             public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
173             public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
174             public void dump(PrintWriter pw) {
175                 pw.println("  reg ["+(width-1)+":0] "+name+";");
176                 //pw.println("  initial "+name+"="+(initiallyFull?"1":"0")+";");
177             }
178         }
179
180         private abstract class Port implements Action, Assignable, Trigger {
181             public final String name;
182             public String getName() { return name; }
183             public final int width;
184             public int getWidth() { return width; }
185             public boolean hasLatch = false;
186             public boolean external;
187             public Port(String name, int width, boolean external) {
188                 this.width = width;
189                 this.name = name;
190                 this.external = external;
191                 ports.put(name, this);
192                 if (external)
193                     portorder.add(name);
194             }
195             public String getVerilogName() { return name; }
196             public String getAck() { return name+"_a"; }
197             public String getReq() { return name+"_r"; }
198             public abstract String getInterface();
199             public abstract String getSimpleInterface();
200             public abstract String getDeclaration();
201             public abstract String getAssignments();
202         }
203
204         private class InstantiatedModule {
205             public final Module module;
206             public final int id;
207             private final HashMap<String,Port> ports = new HashMap<String,Port>();
208             public String getName() { return module.getName()+"_"+id; }
209             public InstantiatedModule(Module module) {
210                 this.module = module;
211                 this.id = Module.this.id++;
212                 instantiatedModules.add(this);
213             }
214             public void dump(PrintWriter pw) {
215                 pw.println("  " + module.getName() + " " + getName() + "(clk");
216                 for(String s : module.portorder)
217                     pw.println(", " + getPort(s).getSimpleInterface());
218                 pw.println("   );");
219             }
220             public Port getPort(String name) {
221                 return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
222             }
223             public SinkPort getInputPort(String name) {
224                 int width = module.getPort(name).getWidth();
225                 SinkPort port = (SinkPort)ports.get(name);
226                 if (port == null) {
227                     port = new SinkPort(getName()+"_"+name, width, false, "");
228                     ports.put(name, port);
229                 }
230                 return port;
231             }
232             public SourcePort getOutputPort(String name) {
233                 int width = module.getPort(name).getWidth();
234                 SourcePort port = (SourcePort)ports.get(name);
235                 if (port == null) {
236                     port = new SourcePort(getName()+"_"+name, width, false);
237                     ports.put(name, port);
238                 }
239                 return port;
240             }
241         }
242
243         private class SourcePort extends Port implements Value {
244             private SinkPort driven = null;
245             public SourcePort(String name, int width, boolean external) { 
246                 super(name, width, external); }
247             public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
248             public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
249             public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
250             public String getVerilogAction() { return getAck() + " <= 1;"; }
251             public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
252             public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
253             public String getDeclaration() {
254                 StringBuffer sb = new StringBuffer();
255                 if (external) {
256                     sb.append("input "  +                 name +"_r;\n");
257                     sb.append("output " +                 name +"_a_;\n");
258                     sb.append("input ["+(width-1)+":0]" + name +";\n");
259                 } else {
260                     sb.append("wire "  +                 name +"_r;\n");
261                     sb.append("wire ["+(width-1)+":0]" + name +";\n");
262                 }
263                 if (!hasLatch) {
264                     sb.append("wire "    +                 name +"_a;\n");
265                 } else {
266                     sb.append("reg "    +                 name +"_a;\n");
267                     sb.append("initial " +                name +"_a = 0;\n");
268                 }
269                 return sb.toString();
270             }
271             public String getAssignments() {
272                 StringBuffer sb = new StringBuffer();
273                 if (external)
274                     sb.append("assign " +                 name +"_a_ = " + name + "_a;\n");
275                 if (driven != null) {
276                     sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
277                     sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
278                     sb.append("assign " + driven.name +"   = " + name + ";\n");
279                 }
280                 return sb.toString();
281             }
282             public void connect(SinkPort driven) {
283                 this.driven = driven;
284             }
285         }
286         private class SinkPort extends Port {
287             public final String resetBehavior;
288             public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
289             public String getVerilogAction() { return getReq() + " <= 1;"; }
290             public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
291             public SinkPort(String name, int width, boolean external, String resetBehavior) {
292                 super(name, width, external); this.resetBehavior=resetBehavior; }
293             public String getResetBehavior() { return resetBehavior; }
294             public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
295             public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
296             public String getDeclaration() {
297                 StringBuffer sb = new StringBuffer();
298                 if (external) {
299                     sb.append("output "  +                 name +"_r_;\n");
300                     sb.append("input "   +                 name +"_a;\n");
301                     sb.append("output ["+(width-1)+":0]" + name +"_;\n");
302                 } else {
303                     sb.append("wire "   +                 name +"_a;\n");
304                 }
305                 if (!hasLatch) {
306                     sb.append("wire "    +                 name +"_r;\n");
307                     sb.append("wire   ["+(width-1)+":0]" + name +";\n");
308                 } else {
309                     sb.append("reg "    +                  name +"_r;\n");
310                     sb.append("initial " +                 name +"_r = 0;\n");
311                     sb.append("reg    ["+(width-1)+":0]" + name +";\n");
312                     sb.append("initial " +                 name +" = 0;\n");
313                 }
314                 return sb.toString();
315             }
316             public String getAssignments() {
317                 StringBuffer sb = new StringBuffer();
318                 if (external) {
319                     sb.append("assign " +                  name +"_r_ = " + name + "_r;\n");
320                     sb.append("assign " +                  name +"_ = " + name + ";\n");
321                 }
322                 return sb.toString();
323             }
324         }
325
326         public void dump(PrintWriter pw) {
327             pw.println("`include \"macros.v\"");
328             pw.println("module "+name+"(clk");
329             for(String name : portorder) {
330                 Port p = ports.get(name);
331                 pw.println("    , " + p.getInterface());
332             }
333             pw.println("   );");
334             pw.println();
335             pw.println("    input clk;");
336             for(String name : ports.keySet()) {
337                 Port p = ports.get(name);
338                 pw.println("    " + p.getDeclaration());
339             }
340             for(StateWire sw : statewires.values())
341                 sw.dump(pw);
342             for(Latch l : latches.values())
343                 l.dump(pw);
344             for(String name : ports.keySet()) {
345                 Port p = ports.get(name);
346                 pw.println("    " + p.getAssignments());
347             }
348             for(InstantiatedModule m : instantiatedModules) {
349                 m.dump(pw);
350             }
351             pw.println(precrap);
352             pw.println("always @(posedge clk) begin");
353             for(Port p : ports.values()) {
354                 if (p instanceof SourcePort) {
355                     SourcePort ip = (SourcePort)p;
356                     if (ip.hasLatch)
357                         pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
358                 } else {
359                     SinkPort op = (SinkPort)p;
360                     if (op.hasLatch)
361                         pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
362                                    op.getReq()+"<=0; "+
363                                    op.getResetBehavior()+" end");
364                 }
365             }
366
367             for(Event a : events) a.dump(pw);
368             pw.println(" begin end");
369             pw.println("end");
370
371             pw.println(crap);
372             pw.println("endmodule");
373         }
374
375         private class Event {
376             private Object[]  triggers;
377             private Object[]  actions;
378             public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
379             public Event(Object[] triggers, Object[] actions) {
380                 Module.this.events.add(this);
381                 this.triggers = triggers;
382                 this.actions = actions;
383                 for(int i=0; i<triggers.length; i++)
384                     if (triggers[i] instanceof Port)
385                         ((Port)triggers[i]).hasLatch = true;
386             }
387             public void dump(PrintWriter pw) {
388                 pw.print("if (1");
389                 for(Object o : triggers) {
390                     if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
391                     else                      pw.print(" && " + o);
392                 }
393                 pw.println(") begin ");
394                 for(Object a : actions) pw.println(((Action)a).getVerilogAction());
395                 pw.println("end else ");
396             }
397         }
398     }
399
400     public static final int WORD_WIDTH = 37;
401     public static final int DESTINATION_WIDTH = 11;
402     public static final int COUNT_WIDTH = 7;
403     public static final int PACKET_WIDTH = WORD_WIDTH + DESTINATION_WIDTH;
404     public static final int INSTRUCTION_WIDTH = WORD_WIDTH;
405
406     public static void main(String[] s) throws Exception {
407         String prefix = "src/edu/berkeley/fleet/slipway/";
408         PrintWriter pw;
409
410         mkfunnel("funnel", prefix);
411         mkhorn(    "horn", prefix, PACKET_WIDTH-1, DESTINATION_WIDTH-1, 0, 0);
412         mkhorn(   "ihorn", prefix, PACKET_WIDTH-1, 34, 24, 0);
413
414         Module fifostage = mkfifo("fifostage", 0, null,      prefix);
415         Module fifo4     = mkfifo("fifo4",     4, fifostage, prefix);
416         Module fifoship  = mkfifo("fifo",      4, fifo4,     prefix);
417         mkBox("outbox", false, prefix, fifo4);
418         mkBox("inbox", true, prefix, fifo4);
419     }
420
421     private static Module mkfunnel(String name, String prefix) throws Exception {
422         Module funnel = new Module(name);
423         Module.SinkPort    out = funnel.createOutputPort("out", PACKET_WIDTH, "");
424         Module.SourcePort  in1 = funnel.createInputPort("in1", PACKET_WIDTH);
425         Module.SourcePort  in2 = funnel.createInputPort("in2", PACKET_WIDTH);
426         funnel.new Event(new Object[] { in1, out },
427                          new Action[] { in1, out,
428                                         new AssignAction(out, in1) });
429         funnel.new Event(new Object[] { in2, out },
430                          new Action[] { in2, out,
431                                         new AssignAction(out, in2) });
432         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
433         funnel.dump(pw);
434         pw.flush();
435         return funnel;
436     }
437
438     private static Module mkfifo(String name, int len, Module instance, String prefix) throws Exception {
439         Module fifo = new Module(name);
440         Module.SourcePort  in  = fifo.createInputPort("in", PACKET_WIDTH);
441         Module.SinkPort    out = fifo.createOutputPort("out", PACKET_WIDTH, "");
442         Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
443         if (len==0) {
444             fifo.new Event(new Object[] { in, out },
445                             new Action[] { in, out, new AssignAction(out, in) });
446         } else for(int i=0; i<=len; i++) {
447             if (i<len) stages[i] = fifo.new InstantiatedModule(instance);
448             Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
449             Module.SinkPort   driven = i==len ? out : stages[i].getInputPort("in");
450             driver.connect(driven);
451         }
452         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
453         fifo.dump(pw);
454         pw.flush();
455         return fifo;
456     }
457
458     public static void mkhorn(String name, 
459                               String prefix,
460                               int top,
461                               int top_of_addr_field,
462                               int bot_of_addr_field,
463                               int bot) throws Exception {
464         Module horn = new Module(name);
465         Module.SourcePort in   = horn.createInputPort("in",    PACKET_WIDTH);
466         Module.SinkPort   out0 = horn.createOutputPort("out0", PACKET_WIDTH, "");
467         Module.SinkPort   out1 = horn.createOutputPort("out1", PACKET_WIDTH, "");
468         String shifted_packet = "{ ";
469         if (top_of_addr_field+1 < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
470         shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
471         if (bot_of_addr_field > 0) shifted_packet += ",  in["+(bot_of_addr_field-1)+":0]  ";
472         shifted_packet += " }";
473         // same behavior as FLEET -- wait for both
474         horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
475                        new Action[] { in, out0, new AssignAction(out0, shifted_packet) });
476         horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
477                        new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
478         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
479         horn.dump(pw);
480         pw.flush();
481     }
482
483     private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
484         Module box = new Module(name);
485         Module.SourcePort instr         = box.createInputPort("instr",       INSTRUCTION_WIDTH);
486         Module.SourcePort fabric_in     = box.createInputPort("fabric_in",   PACKET_WIDTH);
487         Module.SinkPort   fabric_out    = box.createOutputPort("fabric_out", PACKET_WIDTH, "");
488         Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
489         fabric_in.connect(dfifo.getInputPort("in"));
490         
491         Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
492         Module.SourcePort   ship_out    = null;
493         if (!inbox) {
494             ship_out = box.createInputPort("ship",        WORD_WIDTH);
495             ship_out.hasLatch = true;
496         }
497
498         Module.SinkPort   ship_in     = null;
499         if (inbox) {
500             ship_in = box.createOutputPort("ship",        PACKET_WIDTH, "");
501             ship_in.hasLatch = true;
502         }
503
504         Module.Latch     ondeck         = box.new Latch("ondeck", INSTRUCTION_WIDTH);
505         Module.Latch     repcount       = box.new Latch("repcount", COUNT_WIDTH);
506         Module.StateWire ondeckFull     = box.new StateWire("ondeck_full");
507         Module.StateWire newMayProceed  = box.new StateWire("newmayproceed", true);
508         Module.StateWire doRepeat       = box.new StateWire("dorepeat", false);
509         Module.StateWire doRepeatKill   = box.new StateWire("dorepeatkill", false);
510         Module.StateWire doKill         = box.new StateWire("dokill", false);
511         Module.StateWire isClogged      = box.new StateWire("clogged", false);
512         
513         Module.SinkPort   token_out     = fabric_out;
514         Module.SourcePort token_in      = dfifo_out;
515         Module.SinkPort   data_out      = inbox ? ship_in   : fabric_out;
516         Module.SourcePort data_in       = inbox ? dfifo_out : ship_out;
517
518         Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
519         Module.SinkPort   ififo_in      = ififo.getInputPort("in");
520         Module.SourcePort ififo_out     = ififo.getOutputPort("out");
521
522         Value instruction_count_ondeck        = ondeck  .getBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
523         Value instruction_count_instr         = instr   .getBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
524         Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
525
526         // Clog (must be first)
527         box.new Event(
528                       new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
529                       new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
530                       );
531
532         // UnClog
533         box.new Event(
534                       new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
535                       new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill()  }
536                       );
537
538         // First Kill
539         box.new Event(
540                       new Object[] { instr, ififo_out,
541                                      "`instruction_is_kill(instr)",
542                                      "!`instruction_is_unclog(instr)",
543                                      newMayProceed.isFull() },
544                       new Action[] { instr, ififo_out,
545                                      new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
546                                      new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
547                                      new ConditionalAction("`instruction_count(instr)!=0", newMayProceed.doDrain()),
548                                      new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
549                       });
550
551         // Kill              
552         box.new Event(
553                       new Object[] { doKill.isFull() },
554                       new Action[] { doKill.doDrain(),
555                                      new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
556                                      new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
557                                      new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
558                       });
559
560         // RepKill
561         box.new Event(
562                       new Object[] { doRepeatKill.isFull(), ififo_out },
563                       new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
564                                      new AssignAction(instruction_count_ondeck, repcount) }
565                       );
566
567         // Enqueue
568         box.new Event(
569                       new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
570                       new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr)  }
571                       );
572
573         // New
574         box.new Event(
575                       new Object[] { ififo_out, ondeckFull.isEmpty(), newMayProceed.isFull() },
576                       new Action[] { ififo_out, ondeckFull.doFill(), newMayProceed.doDrain(),
577                                      new AssignAction(ondeck, ififo_out)  }
578                       );
579
580         // RepeatExecute
581         box.new Event(
582                       new Object[] { doRepeat.isFull() },
583                       new Action[] { doRepeat.doDrain(),
584                                      ondeckFull.doFill(),
585                                      new AssignAction(instruction_count_ondeck, repcount) }
586                       );
587
588         Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
589         String data_latch_input = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
590         box.new Event(
591                       new Object[] { ondeckFull.isFull(),
592                                      data_out,
593                                      token_out,
594                                      ififo_in,
595                                      new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
596                                      new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
597                               },
598                               new Action[] { new SimpleAction("ondeck_full<=0;"),
599                                              new ConditionalAction("`instruction_count(ondeck)==1 || `instruction_bit_recycle(ondeck)", newMayProceed.doFill()),
600                                              new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1",
601                                                                    new AssignAction(ififo_in, ondeck)),
602                                              new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
603                                                                    new AssignAction(instruction_count_ififo_in, "0")),
604                                              new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
605                                                                    new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
606                                              new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
607                                              new ConditionalAction("!`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1", doRepeat.doFill()),
608                                              new ConditionalAction("`instruction_count(ondeck)==0", new AssignAction(repcount, "0")),
609                                              new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
610                                              new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
611                                              new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
612                                              new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
613                                              new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out),
614                                              new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
615                                              new ConditionalAction("`instruction_bit_tokenout(ondeck)",
616                                                                    new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
617                                                                                     "`instruction_bit_dest(ondeck)")),
618                                              new ConditionalAction("`instruction_bit_dataout(ondeck)",
619                                                                    inbox ? new SimpleAction("")
620                                                                    : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
621                                                                                       "`instruction_bit_dest(ondeck)"))
622                               }
623                               );
624
625         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
626         box.dump(pw);
627         pw.flush();
628         return box;
629     }
630
631 }
632
633
634
635