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