add support for a "standing" count value
[fleet.git] / src / edu / berkeley / fleet / fpga / Generator.java
index 9e9d047..3132491 100644 (file)
@@ -15,7 +15,7 @@ import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
 
 public class Generator {
 
-    public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_DEST_ADDR;
+    public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_ADDR;
 
     public static class SimpleValue implements Value {
         private final String s;
@@ -150,6 +150,7 @@ public class Generator {
             public Action isEmpty() { return new SimpleAction(name+"==0"); }
             public Action doFill()  { return new SimpleAction(name+"<=1;"); }
             public Action doDrain() { return new SimpleAction(name+"<=0;"); }
+            public String doReset() { return name+"<="+(initiallyFull?"1":"0")+";"; }
             public StateWire(String name) { this(name, false); }
             public StateWire(String name, boolean initiallyFull) {
                 this.name = name;
@@ -173,9 +174,10 @@ public class Generator {
             public String getVerilogName() { return name; }
             public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
             public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+            public String doReset() { return name+"<=0;"; }
             public void dump(PrintWriter pw) {
                 pw.println("  reg ["+(width-1)+":0] "+name+";");
-                //pw.println("  initial "+name+"="+(initiallyFull?"1":"0")+";");
+                pw.println("  initial "+name+"=0;");
             }
         }
 
@@ -214,7 +216,7 @@ public class Generator {
                 instantiatedModules.add(this);
             }
             public void dump(PrintWriter pw) {
-                pw.println("  " + module.getName() + " " + getName() + "(clk");
+                pw.println("  " + module.getName() + " " + getName() + "(clk, rst ");
                 for(String s : module.portorder)
                     pw.println(", " + getPort(s).getSimpleInterface());
                 pw.println("   );");
@@ -325,9 +327,9 @@ public class Generator {
             }
         }
 
-        public void dump(PrintWriter pw) {
+        public void dump(PrintWriter pw, boolean fix) {
             pw.println("`include \"macros.v\"");
-            pw.println("module "+name+"(clk");
+            pw.println("module "+name+"(clk, rst ");
             for(String name : portorder) {
                 Port p = ports.get(name);
                 pw.println("    , " + p.getInterface());
@@ -335,6 +337,7 @@ public class Generator {
             pw.println("   );");
             pw.println();
             pw.println("    input clk;");
+            pw.println("    input rst;");
             for(String name : ports.keySet()) {
                 Port p = ports.get(name);
                 pw.println("    " + p.getDeclaration());
@@ -352,6 +355,23 @@ public class Generator {
             }
             pw.println(precrap);
             pw.println("always @(posedge clk) begin");
+            pw.println("  if (!rst) begin");
+            for(Latch l : latches.values())
+                pw.println(l.doReset());
+            for(StateWire sw : statewires.values())
+                pw.println(sw.doReset());
+            for(Port p : ports.values()) {
+                if (p instanceof SourcePort) {
+                    SourcePort ip = (SourcePort)p;
+                    if (ip.hasLatch)
+                        pw.println(ip.getAck()+" <=1;");
+                } else {
+                    SinkPort op = (SinkPort)p;
+                    if (op.hasLatch)
+                        pw.println(op.getReq()+" <=0;");
+                }
+            }
+            pw.println("  end else begin");
             for(Port p : ports.values()) {
                 if (p instanceof SourcePort) {
                     SourcePort ip = (SourcePort)p;
@@ -365,10 +385,10 @@ public class Generator {
                                    op.getResetBehavior()+" end");
                 }
             }
-
-            for(Event a : events) a.dump(pw);
-            pw.println(" begin end");
-            pw.println("end");
+            for(Event a : events) a.dump(pw, fix);
+            pw.println("    begin end");
+            pw.println("    end");
+            pw.println("  end");
 
             pw.println(crap);
             pw.println("endmodule");
@@ -386,7 +406,7 @@ public class Generator {
                     if (triggers[i] instanceof Port)
                         ((Port)triggers[i]).hasLatch = true;
             }
-            public void dump(PrintWriter pw) {
+            public void dump(PrintWriter pw, boolean fix) {
                 pw.print("if (1");
                 for(Object o : triggers) {
                     if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
@@ -394,7 +414,8 @@ public class Generator {
                 }
                 pw.println(") begin ");
                 for(Object a : actions) pw.println(((Action)a).getVerilogAction());
-                pw.println("end else ");
+                if (fix) pw.println("end /*else*/ ");
+                else     pw.println("end else ");
             }
         }
     }
@@ -406,28 +427,31 @@ public class Generator {
         pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
         pw.println("`define DATAWIDTH                "+WIDTH_WORD);
         pw.println("`define CODEBAG_SIZE_BITS        "+WIDTH_CODEBAG_SIZE);
-        pw.println("`define PUMP_ADDRESS_BITS    "+WIDTH_PUMP_ADDR);
-        pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_DEST_ADDR);
+        pw.println("`define PUMP_ADDRESS_BITS    "+WIDTH_ADDR);
+        pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_ADDR);
+        /*
         pw.println("`define COUNT_BITS               "+WIDTH_COUNT);
         pw.println("`define COUNT_WIDTH              "+WIDTH_COUNT);
+        */
         pw.println("`define PACKET_WIDTH             (`DATAWIDTH + `DESTINATION_ADDRESS_BITS)");
         pw.println("`define INSTRUCTION_WIDTH        "+WIDTH_WORD);
         pw.println("`define packet_data(p)              p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
         pw.println("`define packet_dest(p)              p[(`DESTINATION_ADDRESS_BITS-1):0]");
         pw.println("`define instruction_data(p)         p[(`DATAWIDTH-1):0]");
-        pw.println("`define instruction_dest(p)         p["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]");
+        pw.println("`define instruction_dest(p)         "+PUMP_NAME.verilogVal("p"));
         pw.flush();
         pw.close();
 
         mkfunnel("funnel", prefix);
-        mkhorn(    "horn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
-        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
+        mkhorn(    "horn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
+        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
 
         Module fifostage = mkfifo("fifostage", 0, null,      prefix);
         Module fifo4     = mkfifo("fifo4",     4, fifostage, prefix);
+        Module fifo8     = mkfifo("fifo8",     8, fifostage, prefix);
         Module fifoship  = mkfifo("fifo",      4, fifo4,     prefix);
-        mkBox("outbox", false, prefix, fifo4);
-        mkBox("inbox", true, prefix, fifo4);
+        mkBox("outbox", false, prefix, fifo4, fifo8);
+        mkBox("inbox", true, prefix, fifo4, fifo8);
 
         Module fabric = new Module("fabric");
         fabric.createInputPort("horn_in",     WIDTH_PACKET);
@@ -444,8 +468,6 @@ public class Generator {
         Module.SourcePort  fabric_out  = fabric.getOutputPort("funnel_out");
         Module.Latch       count       = root.new Latch("count", 8);
         Module.Latch       count_out   = root.new Latch("count_out", 8);
-        root.addPreCrap("initial count = 0;");
-        root.addPreCrap("initial count_out = 0;");
         root.new Event(new Object[] { in, fabric_in },
                        new Object[] { new SimpleAction(fabric_in.getName()+" <= ("+fabric_in.getName()+" << 8) | in;"),
                                       new SimpleAction("if (count >= 5) begin count <= 0; "+fabric_in.getName()+"_r <= 1; end else count <= count+1; "),
@@ -456,7 +478,7 @@ public class Generator {
                                       new SimpleAction("if (count_out >= 5) begin count_out <= 0; "+fabric_out.getName()+"_a <= 1; end else count_out <= count_out+1; "),
                                       out });
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        root.dump(pw);
+        root.dump(pw, true);
         pw.flush();
         return root;
     }
@@ -473,7 +495,7 @@ public class Generator {
                          new Action[] { in2, out,
                                         new AssignAction(out, in2) });
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        funnel.dump(pw);
+        funnel.dump(pw, true);
         pw.flush();
         return funnel;
     }
@@ -493,7 +515,19 @@ public class Generator {
             driver.connect(driven);
         }
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        fifo.dump(pw);
+        fifo.dump(pw, true);
+        /*
+          pw.println("`define FIFO_LENGTH " + len);
+          //pw.println("`define NAME " + name);
+          pw.println("`include \"macros.v\"");
+          pw.println("module "+name+"(clk, rst ");
+          pw.println("              , in_r, in_a_, in");
+          pw.println("              , out_r_, out_a, out_);");
+          BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("src/edu/berkeley/fleet/fpga/fifo.inc")));
+          String s;
+          while((s = br.readLine())!=null)
+          pw.println(s);
+        */
         pw.flush();
         return fifo;
     }
@@ -519,11 +553,11 @@ public class Generator {
         horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
                        new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        horn.dump(pw);
+        horn.dump(pw, true);
         pw.flush();
     }
 
-    private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
+    private static Module mkBox(String name, boolean inbox, String prefix, Module fifo, Module ififo_m) throws Exception {
         Module box = new Module(name);
         Module.SourcePort instr         = box.createInputPort("instr",       WIDTH_WORD);
         Module.SourcePort fabric_in     = box.createInputPort("fabric_in",   WIDTH_PACKET);
@@ -545,36 +579,52 @@ public class Generator {
         }
 
         Module.Latch     ondeck         = box.new Latch("ondeck", WIDTH_WORD);
-        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNT);
+        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNTER_LITERAL+1);
+        Module.Latch     repcount2      = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL+1);
+        Module.Latch     repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL+1);
+        Module.Latch     killcount      = box.new Latch("killcount", WIDTH_COUNTER_LITERAL);
+        Module.Latch     loop_counter   = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL);
         Module.StateWire ondeckFull     = box.new StateWire("ondeck_full");
         Module.StateWire newMayProceed  = box.new StateWire("newmayproceed", true);
         Module.StateWire doRepeat       = box.new StateWire("dorepeat", false);
         Module.StateWire doRepeatKill   = box.new StateWire("dorepeatkill", false);
         Module.StateWire doKill         = box.new StateWire("dokill", false);
         Module.StateWire isClogged      = box.new StateWire("clogged", false);
+        Module.StateWire isMassacreing  = box.new StateWire("massacreing", false);
         
         Module.SinkPort   token_out     = fabric_out;
         Module.SourcePort token_in      = dfifo_out;
         Module.SinkPort   data_out      = inbox ? ship_in   : fabric_out;
         Module.SourcePort data_in       = inbox ? dfifo_out : ship_out;
 
-        Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
+        Module.InstantiatedModule ififo = box.new InstantiatedModule(ififo_m);
         Module.SinkPort   ififo_in      = ififo.getInputPort("in");
         Module.SourcePort ififo_out     = ififo.getOutputPort("out");
 
-        Value instruction_count_ondeck        = ondeck  .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
-        Value instruction_count_instr         = instr   .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
-        Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
+
+        // Massacre (when enqueued)
+        box.new Event(
+                      new Object[] { ififo_out, "!`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
+                      new Action[] { ififo_out }
+                      );
+        box.new Event(
+                      new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
+                      new Action[] { ififo_out, isMassacreing.doDrain(), newMayProceed.doFill() }
+                      );
+        box.new Event(
+                      new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)", isMassacreing.isEmpty() },
+                      new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr), isMassacreing.doFill(), ondeckFull.doDrain(), newMayProceed.doDrain() }
+                      );
 
         // Clog (must be first)
         box.new Event(
-                      new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
+                      new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")", isMassacreing.isEmpty() },
                       new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
                       );
 
         // UnClog
         box.new Event(
-                      new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
+                      new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)", isMassacreing.isEmpty() },
                       new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill()  }
                       );
 
@@ -583,43 +633,60 @@ public class Generator {
                       new Object[] { instr,
                                      "`instruction_is_kill(instr)",
                                      "!`instruction_is_unclog(instr)",
-                                     ondeckFull.isFull()
+                                     ondeckFull.isFull(),
+                                     isMassacreing.isEmpty()
                       },
                       new Action[] { instr,
                                      ondeckFull.doDrain(),
-                                     new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
-                                     new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
-                                     new ConditionalAction("`instruction_count(instr)!=0", newMayProceed.doDrain()),
-                                     new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+                                     new ConditionalAction("`instruction_kill_count(instr)!=0", new AssignAction(repcount, "`instruction_kill_count(instr)")),
+                                     new ConditionalAction("`instruction_kill_count(instr)!=0", doRepeatKill.doFill()),
+                                     new ConditionalAction("`instruction_kill_count(instr)!=0", newMayProceed.doDrain()),
+                                     new ConditionalAction("`instruction_kill_count(instr)==0", newMayProceed.doFill())
                       });
 
         // Kill              
         box.new Event(
                       new Object[] { doKill.isFull() },
                       new Action[] { doKill.doDrain(),
-                                     new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
-                                     new ConditionalAction("`instruction_count(ondeck)!=0", doRepeatKill.doFill()),
-                                     new ConditionalAction("`instruction_count(ondeck)==0", newMayProceed.doFill())
+                                     new ConditionalAction("killcount!=0", new AssignAction(repcount, "killcount-1")),
+                                     new ConditionalAction("killcount!=0", doRepeatKill.doFill()),
+                                     new ConditionalAction("killcount==0", newMayProceed.doFill())
                       });
 
         // RepKill
         box.new Event(
                       new Object[] { doRepeatKill.isFull(), ififo_out },
                       new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
-                                     new AssignAction(instruction_count_ondeck, repcount) }
+                                     new AssignAction(killcount, repcount) }
                       );
 
         // Enqueue
         box.new Event(
-                      new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
+                      new Object[] { instr,
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr) && !`instruction_is_unclog(instr) && !`instruction_is_massacre(instr)",
+                                     isMassacreing.isEmpty()
+                      },
                       new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr)  }
                       );
 
         // New
         box.new Event(
-                      new Object[] { ififo_out, ondeckFull.isEmpty(), newMayProceed.isFull() },
-                      new Action[] { ififo_out, ondeckFull.doFill(), newMayProceed.doDrain(),
-                                     new AssignAction(ondeck, ififo_out)  }
+                      new Object[] { ififo_out,
+                                     ondeckFull.isEmpty(),
+                                     newMayProceed.isFull(),
+                                     "!`instruction_is_clog("+ififo_out.getName()+")",
+                                     "!`instruction_is_kill(instr)",
+                                     isMassacreing.isEmpty() },
+                      new Action[] { ififo_out,
+                                     ondeckFull.doFill(),
+                                     newMayProceed.doDrain(),
+                                     new AssignAction(ondeck, ififo_out),
+                                     new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+") && !`is_standing("+ififo_out.getName()+")",
+                                                           new AssignAction(repcount2, "(repeat_counter==0?1:repeat_counter)")),
+                                     new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
+                                                           new AssignAction(repeat_counter, "1")),
+                      }
                       );
 
         // RepeatExecute
@@ -627,79 +694,204 @@ public class Generator {
                       new Object[] { doRepeat.isFull() },
                       new Action[] { doRepeat.doDrain(),
                                      ondeckFull.doFill(),
-                                     new AssignAction(instruction_count_ondeck, repcount) }
+                                     new AssignAction(repcount2, repcount)
+                      }
                       );
 
-        Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
-        String data_latch_input = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
+        box.addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
+        box.addPreCrap("assign data_latch_output = " + (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
 
+        Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
+        String data_latch_input  = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
+
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_loop_to_data(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(data_latch, loop_counter),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_data_to_loop(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(loop_counter, "data_latch_output"),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_literal_to_loop(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(loop_counter, "`instruction_loop_count_literal(ondeck)"),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_decr_loop(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)"),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_data_to_repeat(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(repeat_counter, "data_latch_output"),
+                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_literal_to_repeat(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(repeat_counter, "`instruction_repeat_count_literal(ondeck)"),
+                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_standing_to_repeat(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(repeat_counter, "`magic_standing_value"),
+                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+                           
+                                     
         box.new Event(
                       new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
                                      data_out,
                                      token_out,
                                      ififo_in,
-                                     "(`instruction_is_normal(ondeck) || `instruction_is_literal(ondeck))",
+                                     "!`instruction_is_kill(instr)",
+                                     "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) ||"+
+                                     " `instruction_is_literal_lo(ondeck) || `instruction_is_literal(ondeck))",
                                      new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
                                      new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
                               },
-                              new Action[] { new SimpleAction("ondeck_full<=0;"),
-                                             new ConditionalAction("`instruction_count(ondeck)==1 || `instruction_bit_requeue(ondeck)", newMayProceed.doFill()),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1",
-                                                                   new AssignAction(ififo_in, ondeck)),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
-                                                                   new AssignAction(instruction_count_ififo_in, "0")),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
-                                                                   new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
-                                             new ConditionalAction("!`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", doRepeat.doFill()),
-                                             new ConditionalAction("`instruction_count(ondeck)==0", new AssignAction(repcount, "0")),
-                                             new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
-                                             new ConditionalAction("`instruction_is_literal(ondeck)", new AssignAction(data_latch, "`instruction_literal(ondeck)")),
-                                             new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
-                                             new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
-                                             new ConditionalAction("`instruction_bit_tokenout(ondeck) && (!`instruction_bit_tokenoutlast(ondeck) || `instruction_count(ondeck)==1)",
-                                                                   token_out),
+                              new Action[] { ondeckFull.doDrain(),
+                                             new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
+                                             new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
+                                             new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
+                                             new ConditionalAction("repcount2>1 || repcount2==`magic_standing_value", doRepeat.doFill()),
+                                             new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
+                                             new ConditionalAction("!`is_standing(ondeck) && repcount2!=`magic_standing_value",
+                                                                   new AssignAction(repcount, "repcount2-1")),
+                                             new ConditionalAction("!`is_standing(ondeck) && repcount2==`magic_standing_value",
+                                                                   new AssignAction(repcount, "`magic_standing_value")),
+                                             new ConditionalAction("`instruction_is_literal(ondeck)",
+                                                                   new AssignAction(data_latch, "`instruction_literal(ondeck)")),
+                                             new ConditionalAction("`instruction_is_literal_hi(ondeck)",
+                                                                   new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")),
+                                             new ConditionalAction("`instruction_is_literal_lo(ondeck)",
+                                                                   new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")),
+                                             new ConditionalAction("`instruction_bit_datain(ondeck)",   data_in),
+                                             new ConditionalAction("`instruction_bit_dataout(ondeck)",  data_out),
+                                             new ConditionalAction("`instruction_bit_tokenin(ondeck)",  token_in),
+                                             new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out),
                                              new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
-                                             new ConditionalAction("`instruction_bit_tokenout(ondeck)",
+                                             new ConditionalAction("`instruction_path_from_data(ondeck)",
                                                                    new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
-                                                                                    "`instruction_bit_dest(ondeck)")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && !`instruction_bit_tokenout(ondeck)",
-                                                                   inbox ? new SimpleAction("")
-                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      "`instruction_bit_dest(ondeck)")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && !`instruction_bit_datain(ondeck)",
-                                                                   inbox ? new SimpleAction("")
-                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      data_out.getName()+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && `instruction_bit_datain(ondeck)",
-                                                                   inbox ? new SimpleAction("")
-                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      data_latch_input+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]"))
+                                                                                    PUMP_NAME.verilogVal(data_latch_input))),
+                                             new ConditionalAction("`instruction_path_from_literal(ondeck)",
+                                                                   new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
+                                                                                    "`instruction_path_literal(ondeck)")),
                               }
                       );
 
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        pw.println("`define instruction_bit_dest(instruction)     instruction["+(OFFSET_DEST+WIDTH_DEST_ADDR-1)+":"+OFFSET_DEST+"]");
-        pw.println("`define instruction_is_literal(i)             (i["+(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1)+":"+OFFSET_MASK_LITERAL+"]=="+MASK_LITERAL+")");
-        pw.println("`define instruction_count(i)                  (`instruction_is_literal(i)?1:i["+(OFFSET_COUNT+WIDTH_COUNT-1)+":"+OFFSET_COUNT+"])");
-        pw.println("`define instruction_is_kill(i)                (i["+(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1)+":"+OFFSET_MASK_KILL+"]=="+MASK_KILL+")");
-        pw.println("`define instruction_is_unclog(i)              (i["+(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1)+":"+OFFSET_MASK_UNCLOG+"]=="+MASK_UNCLOG+")");
-        pw.println("`define instruction_is_clog(i)                (i["+(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1)+":"+OFFSET_MASK_CLOG+"]=="+MASK_CLOG+")");
-        pw.println("`define instruction_is_normal(i)              (i["+(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1)+":"+OFFSET_MASK_NORMAL+"]=="+MASK_NORMAL+")");
-        pw.println("`define instruction_bit_requeue(instruction)  (instruction["+OFFSET_RQ+"] && !`instruction_is_literal(instruction))");
-
-        pw.println("`define instruction_bit_tokenout(i)     (!`instruction_is_literal(i) && i["+OFFSET_TO+"])");
-        pw.println("`define instruction_bit_tokenoutlast(i) (!`instruction_is_literal(i) && i["+OFFSET_IG+"])");
-        pw.println("`define instruction_bit_dataout(i)      (!`instruction_is_literal(i) && i["+OFFSET_DO+"])");
-        pw.println("`define instruction_bit_latch(i)        (!`instruction_is_literal(i) && i["+OFFSET_DL+"])");
-        pw.println("`define instruction_bit_datain(i)       (!`instruction_is_literal(i) && i["+OFFSET_DI+"])");
-        pw.println("`define instruction_bit_tokenin(i)      (!`instruction_is_literal(i) && i["+OFFSET_TI+"])");
-
-        int signextbits = WIDTH_WORD - WIDTH_LITERAL;
-        pw.println("`define instruction_literal(i)                {{ "+signextbits+"{i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+"]}},"+
-                   " i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+":"+OFFSET_LITERAL+"]}");
-        box.dump(pw);
+
+        pw.println("`define instruction_is_load_loop_to_data(i)       "+TAKE_LOOP.verilog("i"));
+        pw.println("`define instruction_is_load_data_to_repeat(i)     "+REPEAT_FROM_DATA.verilog("i"));
+        pw.println("`define instruction_is_load_data_to_loop(i)       "+LOOP_FROM_DATA.verilog("i"));
+        pw.println("`define instruction_is_load_literal_to_repeat(i)  "+REPEAT_FROM_LITERAL.verilog("i"));
+        pw.println("`define instruction_is_load_literal_to_loop(i)    "+LOOP_FROM_LITERAL.verilog("i"));
+        pw.println("`define instruction_is_load_standing_to_repeat(i) "+REPEAT_FROM_STANDING.verilog("i"));
+        pw.println("`define instruction_repeat_count_literal(i)       "+REPEAT_FROM_LITERAL.verilogVal("i"));
+        pw.println("`define instruction_loop_count_literal(i)         "+LOOP_FROM_LITERAL.verilogVal("i"));
+
+        pw.println("`define instruction_path_literal(i)              "+PATH_LITERAL.verilogVal("i"));
+        pw.println("`define instruction_path_from_literal(i)         "+PATH_LITERAL.verilog("i"));
+        pw.println("`define instruction_path_from_data(i)            "+PATH_DATA.verilog("i"));
+
+        pw.println("`define instruction_is_literal_hi(i)             "+LITERAL_HI.verilog("i"));
+        pw.println("`define instruction_is_literal_lo(i)             "+LITERAL_LO.verilog("i"));
+        pw.println("`define instruction_is_literal(i)                "+LITERAL.verilog("i"));
+        pw.println("`define instruction_kill_count(i)                "+KILL.verilogVal("i"));
+        pw.println("`define instruction_is_kill(i)                   "+KILL.verilog("i"));
+        pw.println("`define instruction_is_unclog(i)                 "+UNCLOG.verilog("i"));
+        pw.println("`define instruction_is_clog(i)                   "+CLOG.verilog("i"));
+        pw.println("`define instruction_is_massacre(i)               "+MASSACRE.verilog("i"));
+        pw.println("`define instruction_is_normal(i)                 "+MOVE.verilog("i"));
+
+        pw.println("`define instruction_is_decr_loop(i)              "+DL.verilog("i"));
+
+        pw.println("`define instruction_bit_tokenout(i)     (`instruction_is_normal(i) && "+TO.verilog("i")+")");
+        pw.println("`define instruction_bit_dataout(i)      (`instruction_is_normal(i) && "+DO.verilog("i")+")");
+        pw.println("`define instruction_bit_latch(i)        (`instruction_is_normal(i) && "+DC.verilog("i")+")");
+        pw.println("`define instruction_bit_datain(i)       (`instruction_is_normal(i) && "+DI.verilog("i")+")");
+        pw.println("`define instruction_bit_tokenin(i)      (`instruction_is_normal(i) && "+TI.verilog("i")+")");
+        pw.println("`define is_standing(i)                  (`instruction_is_normal(i) && "+STAND.verilog("i")+")");
+        pw.println("`define should_requeue(i)               (loop_counter > 0)");
+        pw.println("`define done_executing(i)               (!`is_standing(i) && (repcount2==0 || repcount2==1))");
+
+        pw.println("`define magic_standing_value            (1<<"+WIDTH_COUNTER_LITERAL+")");
+
+        pw.println("`define instruction_literal_hi(i,d) { (i[17:0]),  (d[18:0]) }");
+        pw.println("`define instruction_literal_lo(i,d) { (d[36:19]), (i[18:0]) }");
+
+        pw.println("`define instruction_literal_sel(i) " + LITERAL_SEL.verilogVal("i"));
+        pw.println("`define instruction_literal(i) " +
+                   "("+
+                   "  `instruction_literal_sel(i) == 0 ? { (i[17:0]),  {19{1'b0}} } "+
+                   ": `instruction_literal_sel(i) == 1 ? { (i[17:0]),  {19{1'b1}} } "+
+                   ": `instruction_literal_sel(i) == 2 ? { {18{1'b0}}, (i[18:0]) } "+
+                   ":                                    { {18{1'b1}}, (i[18:0]) } "+
+                   ")"
+                   );
+
+
+        box.dump(pw, true);
         pw.flush();
         return box;
     }