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