make dock counters as wide as the machine word
[fleet.git] / src / edu / berkeley / fleet / fpga / FpgaDock.java
index 259409d..61e8a56 100644 (file)
@@ -1,6 +1,6 @@
 package edu.berkeley.fleet.fpga;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.two.*;
 import edu.berkeley.fleet.*;
 import java.lang.reflect.*;
 import edu.berkeley.sbp.chr.*;
@@ -9,19 +9,24 @@ import edu.berkeley.sbp.meta.*;
 import edu.berkeley.sbp.util.*;
 import java.util.*;
 import java.io.*;
-import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
-import static edu.berkeley.fleet.verilog.Verilog.*;
+import static edu.berkeley.fleet.two.FleetTwoFleet.*;
+import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
 import edu.berkeley.fleet.api.*;
-import static edu.berkeley.fleet.verilog.Verilog.*;
 import edu.berkeley.fleet.api.Dock;
 import edu.berkeley.fleet.two.*;
 import java.util.*;
 
-
-/** the pump itself is a */
 public class FpgaDock extends FleetTwoDock implements FabricElement {
 
-    private static final int INSTRUCTION_FIFO_SIZE = 8;
+    //private static final int INSTRUCTION_FIFO_SIZE = 12;
+
+    // Marina has 12 latches in the ring, 9 of which are wagged (plus
+    // M1, OD, RQ), so max capacity is 11 instructions
+    static final int INSTRUCTION_FIFO_SIZE = 11;
+    static final int INSTRUCTION_WAGGED_STAGES = 8;
+
+    //private static final int DATA_FIFO_SIZE        = 4;
+    static final int DATA_FIFO_SIZE        = 8;
         
     private FpgaDestination dataDestination;
     private FpgaDestination instructionDestination;
@@ -30,12 +35,15 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
 
     public Module.InstantiatedModule getInstance() { return instance; }
 
+    private Fpga fpga;
+
     public Destination getDataDestination() { return dataDestination; }
     public Destination getInstructionDestination() { return instructionDestination; }
     public int         getInstructionFifoSize() { return INSTRUCTION_FIFO_SIZE; }
 
     FpgaDock(FpgaShip ship, DockDescription bbd) {
         super(ship, bbd);
+        this.fpga = (Fpga)ship.getFleet();
         this.instance = new Module.InstantiatedModule(((Fpga)ship.getFleet()).top, new DockModule(isInputDock()));
         this.dataDestination = new FpgaDestination(this, this.instance.getInputPort("fabric_in"), false);
         this.instructionDestination = new FpgaDestination(this, this.instance.getInputPort("instruction"), true);
@@ -51,278 +59,340 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
     // FabricElement methods //////////////////////////////////////////////////////////////////////////////
 
     private FabricElement upstream;
-    public Module.Port getOutputPort() { throw new RuntimeException(); }
+    public Module.SourcePort getOutputPort() { throw new RuntimeException(); }
     public Module.Port getInputPort()  { throw new RuntimeException(); }
-    public FpgaPath getPath(FabricElement dest, BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
-    public FpgaPath getPath(Destination dest,BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
+    public Path getPath(Destination dest,BitVector signal) { return getPath((FpgaDestination)dest, signal); }
+    public FpgaPath getPath(FpgaDestination dest,BitVector signal) { return upstream.getPath(dest, signal); }
+    public int      getPathLength(FpgaDestination dest) { return upstream.getPathLength(dest)-1; }
     public void addInput(FabricElement in, Module.Port inPort) { throw new RuntimeException(); }
     public void addOutput(FabricElement out, Module.Port outPort) {
         this.upstream = out;
         instance.getOutputPort("fabric_out").connect((Module.SinkPort)outPort);
     }
 
-    public static class DockModule extends Module {
+    public class TorpedoBranchModule extends Module {
+        public TorpedoBranchModule() {
+            super("torpedobranch");
+            Module.SourcePort in      = createInputPort ("in",  fpga.WIDTH_PACKET);
+            Module.SinkPort   out     = createOutputPort("out", fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+            Module.SinkPort   torpedo = createOutputPort("torpedo", 0);
+            Module.StateWire  busy    = new StateWire("busy", false);
+
+            new Event(new Object[] { in, busy.isFull(), out },
+                      new Action[] { in, busy.doDrain() });
+            new Event(new Object[] { in, busy.isEmpty(), out, torpedo, in.testMask(fpga.PACKET_IS_TOKEN) },
+                      new Action[] { in,                      torpedo });
+            new Event(new Object[] { in, busy.isEmpty(), out,          in.testMask(fpga.PACKET_IS_TOKEN).invert() },
+                      new Action[] {     busy.doFill(),  out });
+
+            out.connectValue(in.getBits(fpga.PACKET_DATA));
+        }
+    }
+
+    public class RequeueModule extends Module {
+        public RequeueModule() {
+            super("requeue");
+            Module.SourcePort fabric_in     = createInputPort ("fabric_in",  fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+            Module.SourcePort ondeck_in     = createInputPort ("ondeck_in",  fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+            Module.SourcePort abort         = createInputPort ("abort",     1);
+            Module.SinkPort   out           = createOutputPort("out",        fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+
+            Module.StateWire  circulating   = new StateWire("circulating", false);
+            Module.StateWire  doResetFabric = new StateWire("doResetFabric", false);
+            Module.StateWire  doResetOndeck = new StateWire("doResetOndeck", false);
+
+            out.connectValue(new MuxValue(circulating.isEmpty(), fabric_in, ondeck_in));
+
+            // always: discard one-shot instructions
+            new Event(new Object[] { doResetFabric.isFull(),  out },
+                      new Action[] { doResetFabric.doDrain(), fabric_in });
+            new Event(new Object[] { doResetOndeck.isFull(),  out },
+                      new Action[] { doResetOndeck.doDrain(), ondeck_in });
+
+            // Updating->Circulating transition
+            new Event(new Object[] { doResetFabric.isEmpty(),
+                                     doResetOndeck.isEmpty(),
+                                     circulating.isEmpty(),
+                                     fabric_in,
+                                     fpga.TAIL.verilog(fabric_in.getName()),
+                                     ondeck_in,
+                                     fpga.HEAD.verilog(ondeck_in.getName()) },
+                      new Action[] { circulating.doFill(),
+                                     fabric_in,
+                                     ondeck_in });
+
+            // Circulating->Updating transition
+            new Event(new Object[] { doResetFabric.isEmpty(),
+                                     doResetOndeck.isEmpty(),
+                                     circulating.isFull(),
+                                     ondeck_in,
+                                     abort.getVerilog() },
+                      new Action[] { circulating.doDrain(),
+                                     ondeck_in });
+
+            // Updating
+            new Event(new Object[] { doResetFabric.isEmpty(),
+                                     doResetOndeck.isEmpty(),
+                                     circulating.isEmpty(),
+                                     fabric_in,
+                                     "!"+fpga.TAIL.verilog(fabric_in.getName()) },
+                      new Action[] { doResetFabric.doFill(),
+                                     out });
+            new Event(new Object[] { doResetFabric.isEmpty(),
+                                     doResetOndeck.isEmpty(),
+                                     circulating.isEmpty(),
+                                     ondeck_in,
+                                     "!"+fpga.HEAD.verilog(ondeck_in.getName()) },
+                      new Action[] { ondeck_in });
+                                     
+            // Circulating
+            new Event(new Object[] { doResetFabric.isEmpty(),
+                                     doResetOndeck.isEmpty(),
+                                     circulating.isFull(),
+                                     ondeck_in,
+                                     "!"+abort.getVerilog() },
+                      new Action[] { doResetOndeck.doFill(),
+                                     out });
+        }
+    }
+
+    public class DockModule extends Module {
 
         public DockModule(boolean inbox) {
             super(inbox ? "inbox" : "outbox");
-            Module fifo4     = new FifoModule(4);
-            Module fifo8     = new FifoModule(8);
-            Module fifo      = fifo8;
-            Module ififo_m   = new FifoModule(INSTRUCTION_FIFO_SIZE);
-            Module efifo_m   = fifo4;
-            Module.SourcePort instruction   = createInputPort("instruction",       WIDTH_PACKET);
-            instruction.hasLatch = true;
-
-            Module.SourcePort fabric_in     = createInputPort("fabric_in",   WIDTH_PACKET);
-            Module.SinkPort   fabric_out    = createOutputPort("fabric_out", WIDTH_PACKET, "");
-            Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, fifo);
+
+            int dfifo_width = inbox ? fpga.getWordWidth()+1 : 1;
+
+            // FIXME: assumes fpga.DISPATCH_PATH is at top of word!!!
+            Module ififo_m_1   = new FifoModule(INSTRUCTION_FIFO_SIZE, fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+            //Module ififo_m_1   = new FifoModule(INSTRUCTION_FIFO_SIZE-INSTRUCTION_WAGGED_STAGES, fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+            //Module ififo_m_2   = new FifoModule(INSTRUCTION_WAGGED_STAGES, fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth, true);
+
+            Module dfifo_m   = new FifoModule(DATA_FIFO_SIZE,        dfifo_width);
+
+            Module.SourcePort instruction   = createInputPort("instruction", fpga.WIDTH_PACKET);
+            Module.SourcePort fabric_in     = createInputPort("fabric_in",   fpga.WIDTH_PACKET);
+
+            // FIXME: at inboxes, no need for a full set of latches
+            Module.SinkPort   fabric_out    = createOutputPort("fabric_out", fpga.WIDTH_PACKET);
+            
+            Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, dfifo_m);
+
             fabric_in.connect(dfifo.getInputPort("in"));
+            dfifo.getInputPort("in").connectValue(
+                !inbox
+                ? fabric_in.getBits(fpga.PACKET_SIGNAL)
+                : new CatValue(new Value[] {
+                        fabric_in.getBits(fpga.PACKET_SIGNAL),
+                        fabric_in.getBits(fpga.PACKET_DATA)
+                    }));
         
-            Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
-            Module.SourcePort   ship_out    = null;
-            if (!inbox) {
-                ship_out = createInputPort("ship",        WIDTH_WORD);
-                ship_out.hasLatch = true;
-            }
-
-            Module.SinkPort   ship_in     = null;
-            if (inbox) {
-                ship_in = createOutputPort("ship",        WIDTH_PACKET, "");
-                ship_in.hasLatch = true;
-            }
-
-            Module.Latch     ondeck         = new Latch("ondeck", WIDTH_WORD);
-            Module.Latch     repeat_counter = new Latch("repeat_counter", SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
-            Module.Latch     loop_counter   = new Latch("loop_counter", SET_OLC_FROM_IMMEDIATE.valmaskwidth, 1);
-            Module.Latch     tapl           = new Latch("tapl", SET_TAPL_FROM_IMMEDIATE.valmaskwidth);
+            Module.SourcePort dfifo_out     = dfifo.getOutputPort("out");
+            Module.SourcePort ship_out      = !inbox ? createInputPort("ship",  fpga.getWordWidth()+1) : null;
+            Module.SinkPort   ship_in       =  inbox ? createOutputPort("ship", fpga.getWordWidth()+1) : null;
+
+            Module.Latch     ilc            = new Latch("ilc", fpga.SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
+            Module.Latch     olc            = new Latch("olc", fpga.getWordWidth(), 1);
             Module.Latch     flag_a         = new Latch("flag_a", 1);
             Module.Latch     flag_b         = new Latch("flag_b", 1);
             Module.Latch     flag_c         = new Latch("flag_c", 1);
-            Module.StateWire ondeckFull     = new StateWire("ondeck_full");
-            Module.StateWire newMayProceed  = new StateWire("newmayproceed", true);
-            Module.StateWire doRepeat       = new StateWire("dorepeat", false);
+            Module.Latch     flag_d         = new Latch("flag_d", 1);
 
-            Module.StateWire  isHatchOpen   = new StateWire("hatch", true);
-        
             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 = new Module.InstantiatedModule(this, ififo_m);
-            Module.SinkPort   ififo_in      = ififo.getInputPort("in");
-            Module.SourcePort ififo_out     = ififo.getOutputPort("out");
-
-            Module.InstantiatedModule efifo = new Module.InstantiatedModule(this, efifo_m);
-            Module.SinkPort   efifo_in      = efifo.getInputPort("in");
-            Module.SourcePort efifo_out     = efifo.getOutputPort("out");
-            efifo_in.hasLatch = true;
-
-            addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
-            addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_input;");
-            addPreCrap("assign data_latch_output = " +
-                       (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
-            addPreCrap("assign data_latch_input = " +
-                       (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";");
-            Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() :
-                                                            "`packet_data("+data_out.getName()+")");
-            String data_latch_input  = "data_latch_input";
-
-            // Open the Hatch
-            new Event(new Object[] { "loop_counter==0" },
-                      new Action[] { isHatchOpen.doFill() });
-
-            // Torpedo Arrival
-            new Event(new Object[] { instruction,
-                                     PACKET_TOKEN.verilogVal("instruction"),
-                                     ondeckFull.isFull(),
-                                     token_out,
-                                     I.verilog("ondeck"),
-                },
-                new Action[] { instruction,
-                               ondeckFull.doDrain(),
-                               newMayProceed.doFill(),
-                               new AssignAction(loop_counter, "0"),
-                               new AssignAction(repeat_counter, "1"),
-                               new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"), "1"),
-                               new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "tapl"),
-                               token_out,
-                               isHatchOpen.doFill(),
-                });
-            // Non-Torpedo Arrival
-            new Event(new Object[] { instruction,
-                                     efifo_in,
-                                     "!("+PACKET_TOKEN.verilogVal("instruction")+")"
+            Module.InstantiatedModule ififo_1 = new Module.InstantiatedModule(this, ififo_m_1);
+            //Module.InstantiatedModule ififo_2 = new Module.InstantiatedModule(this, ififo_m_2);
+            //ififo_1.getOutputPort("out").connect(ififo_2.getInputPort("in"));
+            Module.SinkPort   ififo_in      = ififo_1.getInputPort("in");
+            //Module.SourcePort ififo_out     = ififo_2.getOutputPort("out");
+            Module.SourcePort ififo_out     = ififo_1.getOutputPort("out");
+
+            Module.InstantiatedModule torpedo_branch = new Module.InstantiatedModule(this, new TorpedoBranchModule());
+            instruction.connect(torpedo_branch.getInputPort("in"));
+            Module.SourcePort efifo_out              = torpedo_branch.getOutputPort("out");
+            Module.SourcePort torpedo_branch_torpedo = torpedo_branch.getOutputPort("torpedo");
+
+            Module.InstantiatedModule fanout_module = new Module.InstantiatedModule(this, new FanoutModule(fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth));
+            Module.SinkPort   fanout_module_in   = fanout_module.getInputPort("in");
+            Module.SourcePort fanout_module_out0 = fanout_module.getOutputPort("out0");
+            Module.SourcePort fanout_module_out1 = fanout_module.getOutputPort("out1");
+
+            Module.InstantiatedModule requeue_module = new Module.InstantiatedModule(this, new RequeueModule());
+            Module.SinkPort   requeue_fabric_in = requeue_module.getInputPort("fabric_in");
+            Module.SinkPort   requeue_ondeck    = requeue_module.getInputPort("ondeck_in");
+            Module.SinkPort   requeue_abort     = requeue_module.getInputPort("abort");
+            Module.SourcePort requeue_out       = requeue_module.getOutputPort("out");
+
+            efifo_out.connect(requeue_fabric_in);
+            requeue_out.connect(ififo_in);
+            ififo_out.connect(fanout_module_in);
+            fanout_module_out0.connect(requeue_ondeck);
+            Module.SourcePort ondeck = fanout_module_out1;
+
+            WireValue decremented = new WireValue("decremented", Math.max(ilc.width,olc.width),
+                                                  new SimpleValue("("+ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE).getVerilogTrigger()+
+                                                                  " ? olc : ilc)-1"));
+            WireValue data_latch_output_p = new WireValue("data_latch_output",
+                                                           inbox ? fpga.getWordWidth()+1 : fpga.getWordWidth(),
+                                                           (inbox
+                                                            ? new SimpleValue(data_out.getName())
+                                                            : new SimpleValue(data_out.getBits(fpga.PACKET_DATA).getVerilog()))
+                                                          );
+
+            Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() : data_out.getBits(fpga.PACKET_DATA).getVerilog());
+            Module.SourcePort  data_latch_input = inbox ? data_in : data_in;
+
+            BitVector bv = new BitVector(fpga.SET_ILC_FROM_IMMEDIATE.valmaskwidth+1);
+            bv.set(fpga.SET_ILC_FROM_IMMEDIATE.valmaskwidth, true);
+            Value magic_standing_value = new ConstantValue(bv);
+
+            Trigger done_executing       = new SimpleTrigger("((ilc==0) || (ilc==1) || !"+fpga.MOVE.verilog(ondeck.getName())+")");
+
+            String predicate_met = 
+                "("+
+                "("+
+                "!"+fpga.MOVE.verilog(ondeck.getName())+" || (ilc!=0)"+
+                ") && ("+
+                "("+
+                fpga.P_ALWAYS.verilog(ondeck.getName())+
+                ") || ("+
+                fpga.P_OLC_ZERO.verilog(ondeck.getName())+"==flag_d"+
+                ")"+
+                ") && ("+
+                " " + fpga.P_A.verilog(ondeck.getName())+" ? flag_a"+
+                ":" + fpga.P_B.verilog(ondeck.getName())+" ? flag_b"+
+                ":" + fpga.P_NOT_A.verilog(ondeck.getName())+" ? !flag_a"+
+                ":" + fpga.P_NOT_B.verilog(ondeck.getName())+" ? !flag_b "+
+                ": 1"+
+                ")"+
+                ")";
+
+            requeue_abort.connectValue(new SimpleValue("("+predicate_met+") && "+fpga.ABORT.verilog(ondeck.getName())));
+
+            // Torpedo strikes
+            new Event(new Object[] {
+                    ondeck,
+                    data_out,
+                    token_out,
+                    predicate_met,
+                    fpga.MOVE.verilog(ondeck.getName()),
+                    "!"+fpga.NOT_INTERRUPTIBLE.verilog(ondeck.getName()),
+                    torpedo_branch_torpedo
                 },
-                new Action[] {
-                    efifo_in,
-                    instruction,
-                    new AssignAction(efifo_in, instruction)
+                new Object[] {
+                    ondeck,
+                    torpedo_branch_torpedo,
+                    new AssignAction(olc,    new ConstantValue(new BitVector(olc.width).set(0))),
+                    new AssignAction(flag_d, new ConstantValue(new BitVector(1).set(1))),
+                    new AssignAction(ilc,    new ConstantValue(new BitVector(ilc.width).set(1)))
                 });
 
-            // Tail
-            new Event(new Object[] { efifo_out, TAIL.verilog("`packet_data("+efifo_out.getName()+")") },
-                      new Action[] { efifo_out, isHatchOpen.doDrain() } );
-            // Enqueue
-            new Event(new Object[] { efifo_out,
-                                     ififo_in,
-                                     "!("+TAIL.verilog("`packet_data("+efifo_out.getName()+")")+")",
-                                     isHatchOpen.isFull() },
-                new Action[] { efifo_out, ififo_in, new AssignAction(ififo_in, "`packet_data("+efifo_out.getName()+")")  } );
-
-            // New
-            new Event(new Object[] { ififo_out,
-                                     ondeckFull.isEmpty(),
-                                     newMayProceed.isFull(),
-                                     },
-                      new Action[] { ififo_out,
-                                     ondeckFull.doFill(),
-                                     newMayProceed.doDrain(),
-                                     new AssignAction(ondeck, ififo_out)
-                      }
-                      );
-
-            // RepeatExecute
-            new Event(new Object[] { doRepeat.isFull() },
-                      new Action[] { doRepeat.doDrain(), ondeckFull.doFill(),
-                                     new AssignAction(repeat_counter,
-                                                      "repeat_counter==`magic_standing_value?`magic_standing_value:(repeat_counter-1)")
+            // Predicate not met
+            new Event(new Object[] { ondeck, "!("+predicate_met+")" },
+                      new Action[] { ondeck,
+                                     new ConditionalAction(ondeck.testMask(fpga.MOVE),
+                                                           new AssignAction(ilc, new ConstantValue(new BitVector(ilc.width).set(1))))
                       });
 
-            // Execute                                     
-            new Event(
-                      new Object[] { ondeckFull.isFull(),
+            new Event(new Object[] { ondeck,
                                      data_out,
                                      token_out,
-                                     ififo_in,
-                                     "(!`predicate_met(ondeck) || "+OS.verilog("ondeck")+" || !hatch)",
-                                     new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_datain(ondeck))", data_in),
-                                     new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck))", token_in)
+                                     predicate_met,
+                                     "(!"+fpga.MOVE.verilog(ondeck.getName())+" || "+fpga.NOT_INTERRUPTIBLE.verilog(ondeck.getName())+" || !"+torpedo_branch_torpedo.isFull()+")",
+                                     new ConditionalTrigger(ondeck.testMask(fpga.DI), data_in),
+                                     new ConditionalTrigger(ondeck.testMask(fpga.TI), token_in)
                       },
-                      new Action[] { ondeckFull.doDrain(),
-                                     new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
-                                     new ConditionalAction("`done_executing(ondeck) && `instruction_is_normal(ondeck)",
-                                                           new AssignAction(repeat_counter, "1")),
-                                     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("!`done_executing(ondeck)", doRepeat.doFill()),
-
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_loop(ondeck)",
-                                                           new AssignAction(loop_counter, "data_latch_output")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_loop(ondeck)",
-                                                           new AssignAction(loop_counter, "`instruction_loop_count_immediate(ondeck)")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_decr_loop(ondeck)",
-                                                           new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")),
-
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_repeat(ondeck)",
-                                                           new AssignAction(repeat_counter, "data_latch_output")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_repeat(ondeck)",
-                                                           new AssignAction(repeat_counter, "`instruction_repeat_count_immediate(ondeck)")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_standing_to_repeat(ondeck)",
-                                                           new AssignAction(repeat_counter, "`magic_standing_value")),
-                                     new ConditionalAction("`predicate_met(ondeck) &&"+SHIFT.verilog("ondeck"),
-                                                           new AssignAction(data_latch,
-                                                                            "({ data_latch_output["+(WIDTH_WORD-1-19)+":0], 19'b0 } | "+
-                                                                            SHIFT.verilogVal("ondeck")+")")),
-                                     new ConditionalAction("`predicate_met(ondeck) && "+SET_IMMEDIATE.verilog("ondeck"),
-                                                           new AssignAction(data_latch,
-                                                                            "{ {"+(WIDTH_WORD-InstructionEncoder.DataLatch_WIDTH)+
-                                                                            "{"+SET_IMMEDIATE_EXTEND.verilogVal("ondeck")+"}}, "+
-                                                                            SET_IMMEDIATE.verilogVal("ondeck")+" }")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
-                                                           new AssignAction(flag_a, "`new_flag_a(ondeck)")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
-                                                           new AssignAction(flag_b, "`new_flag_b(ondeck)")),
-                                     (inbox
-                                      ? new ConditionalAction("`predicate_met(ondeck) && "+
-                                                              "(`instruction_bit_datain(ondeck) || `instruction_bit_tokenin(ondeck))",
-                                                              new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
-                                      : new ConditionalAction("`predicate_met(ondeck) && "+
-                                                              "(!`instruction_bit_datain(ondeck) && `instruction_bit_tokenin(ondeck))",
-                                                              new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
-                                      /* FIXME: C-flag-from-ship */
-                                      ),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)",   data_in),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)",  data_out),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)",  token_in),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)",
-                                                           new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
-                                                                            "1")),
-                                     new ConditionalAction("`predicate_met(ondeck) && !`instruction_bit_tokenout(ondeck)",
-                                                           new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
-                                                                            "0")),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
-                                                           new AssignAction(data_latch, data_latch_input)),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
-                                                           new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
-                                                                            DISPATCH_PATH.verilogVal(data_latch_input))),
-                                     new ConditionalAction("`predicate_met(ondeck) && "+SET_TAPL_FROM_IMMEDIATE.verilog("ondeck"),
-                                                           new AssignAction(tapl, SET_TAPL_FROM_IMMEDIATE.verilogVal("ondeck"))),
-                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_immediate(ondeck)",
-                                                           new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
-                                                                            "`instruction_path_immediate(ondeck)")),
+                      new Action[] { 
+                          new ConditionalAction(new AndTrigger(done_executing, ondeck.testMask(fpga.MOVE)),
+                                                new AssignAction(ilc, new ConstantValue(new BitVector(ilc.width).set(1)))),
+                          new ConditionalAction(done_executing, ondeck),
+                          new ConditionalAction(done_executing.invert(),
+                                                new AssignAction(ilc, new MuxValue(new TestValue(ilc, TestValue.TestType.EQ, magic_standing_value),
+                                                                                   magic_standing_value,
+                                                                                   decremented.getBits(ilc.width-1,0)))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_DATA_LATCH),
+                                                new AssignAction(olc, new SimpleValue("data_latch_output"))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_IMMEDIATE),
+                                                new AssignAction(olc, ondeck.getBits(fpga.SET_OLC_FROM_IMMEDIATE))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE),
+                                                new AssignAction(olc, new SimpleValue("olc==0 ? 0 : decremented"))),
+
+                          new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_DATA_LATCH),
+                                                new AssignAction(flag_d, new SimpleValue("data_latch_output==0"))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_IMMEDIATE),
+                                                new AssignAction(flag_d, new SimpleValue(ondeck.getBits(fpga.SET_OLC_FROM_IMMEDIATE).getVerilog()+"==0"))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE),
+                                                new AssignAction(flag_d, new SimpleValue("(olc==0 || olc==1)"))),
+
+                          new ConditionalAction(ondeck.testMask(fpga.SET_ILC_FROM_DATA_LATCH),
+                                                new AssignAction(ilc, new SimpleValue("data_latch_output"))),
+
+                          new ConditionalAction(ondeck.testMask(fpga.SET_ILC_FROM_IMMEDIATE),
+                                                new AssignAction(ilc, ondeck.getBits(fpga.SET_ILC_FROM_IMMEDIATE))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_ILC_FROM_INFINITY),
+                                                new AssignAction(ilc, magic_standing_value)),
+                          new ConditionalAction(ondeck.testMask(fpga.SHIFT),
+                                                new AssignAction(data_latch,
+                                                                 new SimpleValue("{ data_latch_output["+(fpga.getWordWidth()-1-fpga.SHIFT.valmaskwidth)+":0], "+
+                                                                                 ondeck.getBits(fpga.SHIFT).getVerilog()+"}"))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_IMMEDIATE),
+                                                new AssignAction(data_latch,
+                                                                 new SimpleValue("{ {"+(fpga.getWordWidth()-fpga.DataLatch_WIDTH)+
+                                                                                 "{"+ondeck.getBits(fpga.SET_IMMEDIATE_EXTEND).getVerilog()+"}}, "+
+                                                                                 ondeck.getBits(fpga.SET_IMMEDIATE).getVerilog()+" }"))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_FLAGS),
+                                                new AssignAction(flag_a, new_flag(ondeck.getBits(fpga.SET_FLAGS_A),flag_a,flag_b,flag_c))),
+                          new ConditionalAction(ondeck.testMask(fpga.SET_FLAGS),
+                                                new AssignAction(flag_b, new_flag(ondeck.getBits(fpga.SET_FLAGS_B),flag_a,flag_b,flag_c))),
+                          new ConditionalAction(ondeck.testMask(fpga.MOVE),
+                                                new AssignAction(flag_c,
+                                                                 inbox
+                                                                 ? dfifo_out.getBits(dfifo_width-1, dfifo_width-1)
+                                                                 : new MuxValue(ondeck.testMask(fpga.DC),
+                                                                                ship_out.getBits(fpga.getWordWidth(), fpga.getWordWidth()),
+                                                                                dfifo_out.getBits(dfifo_width-1, dfifo_width-1))
+                                                                 )),
+                          new ConditionalAction(ondeck.testMask(fpga.DI),    data_in),
+                          new ConditionalAction(ondeck.testMask(fpga.DO),    data_out),
+                          new ConditionalAction(ondeck.testMask(fpga.FLUSH), data_out),
+                          inbox
+                          ? new AssignAction(new SimpleAssignable(data_out.getName()+"["+fpga.getWordWidth()+"]"),
+                                             new SimpleValue(fpga.FLUSH.verilog(ondeck.getName())+"?1:0"))
+                          : null,
+                          new ConditionalAction(ondeck.testMask(fpga.TI),    token_in),
+                          new ConditionalAction(ondeck.testMask(fpga.TO),    token_out),
+                          new ConditionalAction(ondeck.testMask(fpga.DC),   new AssignAction(data_latch, data_latch_input)),
+                          new AssignAction(token_out.getBits(fpga.PACKET_TOKEN),
+                                           new SimpleValue("("+fpga.TO.verilog(ondeck.getName())+")?1:0")),
+                          new ConditionalAction(ondeck.testMask(fpga.PATH_DATA),
+                                                new AssignAction(new SimpleAssignable("{ "+token_out.getBits(fpga.PACKET_SIGNAL).getVerilog()+", "+
+                                                                                      token_out.getBits(fpga.PACKET_DEST).getVerilog()+" }"),
+                                                                 data_latch_input.getBits(fpga.DISPATCH_PATH))),
+                          new ConditionalAction(ondeck.testMask(fpga.PATH_IMMEDIATE),
+                                                new AssignAction(new SimpleAssignable("{ "+token_out.getBits(fpga.PACKET_SIGNAL).getVerilog()+", "+
+                                                                                      token_out.getBits(fpga.PACKET_DEST).getVerilog()+" }"),
+                                                                 ondeck.getBits(fpga.PATH_IMMEDIATE)))
                       }
-                      );
+                );
         }
 
-        public void dump(PrintWriter pw, boolean fix) {
-
-            pw.println("`define packet_signal_and_dest(p)                 { "+PACKET_SIGNAL.verilogVal("p")+", "+PACKET_DEST.verilogVal("p")+" }");
-            pw.println("`define instruction_is_load_data_to_repeat(i)     "+SET_ILC_FROM_DATA_LATCH.verilog("i"));
-            pw.println("`define instruction_is_load_data_to_loop(i)       "+SET_OLC_FROM_DATA_LATCH.verilog("i"));
-            pw.println("`define instruction_is_load_immediate_to_repeat(i)  "+SET_ILC_FROM_IMMEDIATE.verilog("i"));
-            pw.println("`define instruction_is_load_immediate_to_loop(i)    "+SET_OLC_FROM_IMMEDIATE.verilog("i"));
-            pw.println("`define instruction_is_load_standing_to_repeat(i) "+SET_ILC_FROM_INFINITY.verilog("i"));
-            pw.println("`define instruction_repeat_count_immediate(i)       "+SET_ILC_FROM_IMMEDIATE.verilogVal("i"));
-            pw.println("`define instruction_loop_count_immediate(i)         "+SET_OLC_FROM_IMMEDIATE.verilogVal("i"));
-
-            pw.println("`define instruction_path_immediate(i)              "+PATH_IMMEDIATE.verilogVal("i"));
-            pw.println("`define instruction_path_from_immediate(i)         "+PATH_IMMEDIATE.verilog("i"));
-            pw.println("`define instruction_path_from_data(i)            "+PATH_DATA.verilog("i"));
-
-            pw.println("`define instruction_is_tail(i)                   "+TAIL.verilog("i"));
-            pw.println("`define instruction_is_normal(i)                 "+MOVE.verilog("i"));
-            pw.println("`define instruction_is_setflags(i)               "+SET_FLAGS.verilog("i"));
-            pw.println("`define instruction_is_set(i)                    "+SET.verilog("i"));
-
-            pw.println("`define instruction_is_decr_loop(i)              "+SET_OLC_FROM_OLC_MINUS_ONE.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 should_requeue(i)               (loop_counter > 0 && !("+OS.verilog("i")+"))");
-            pw.println("`define predicate_met(i)  ("+
-                       "("+
-                       "!`instruction_is_normal(i) || repeat_counter>0"+
-                       ") && ("+
-              " " + P_A.verilog("i")+" ? flag_a "+
-              ":" + P_B.verilog("i")+" ? flag_b "+
-              ":" + P_C.verilog("i")+" ? flag_c "+
-              ":" + P_NOT_A.verilog("i")+" ? !flag_a "+
-              ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
-              ":" + P_NOT_C.verilog("i")+" ? !flag_c "+
-              ":" + P_OLC.verilog("i")+" ? (loop_counter>0) "+
-              ": 1"+
-                       ")"+
-              ")");
-            pw.println("`define new_flag(x)         ("+
-                       "( ((x >> 0) & 1) & !flag_c) |" +
-                       "( ((x >> 1) & 1) &  flag_c) |" +
-                       "( ((x >> 2) & 1) & !flag_b) |" +
-                       "( ((x >> 3) & 1) &  flag_b) |" +
-                       "( ((x >> 4) & 1) & !flag_a) |" +
-                       "( ((x >> 5) & 1) &  flag_a) | 0" +
-                       ")");
-            pw.println("`define new_flag_a(i)                   `new_flag("+SET_FLAGS_A.verilogVal("i")+")");
-            pw.println("`define new_flag_b(i)                   `new_flag("+SET_FLAGS_B.verilogVal("i")+")");
-            pw.println("`define done_executing(i)               (repeat_counter==0 || repeat_counter==1 || !`instruction_is_normal(i))");
-
-            pw.println("`define magic_standing_value            (1<<"+SET_ILC_FROM_IMMEDIATE.valmaskwidth+")");
-
-            super.dump(pw,fix);
+        private Value new_flag(Value v, Value flag_a, Value flag_b, Value flag_c) {
+            Value[] vals = new Value[] {
+                new LogicValue(v.getBits(0,0), LogicValue.LogicType.AND, flag_c.invertBits()),
+                new LogicValue(v.getBits(1,1), LogicValue.LogicType.AND, flag_c),
+                new LogicValue(v.getBits(2,2), LogicValue.LogicType.AND, flag_b.invertBits()),
+                new LogicValue(v.getBits(3,3), LogicValue.LogicType.AND, flag_b),
+                new LogicValue(v.getBits(4,4), LogicValue.LogicType.AND, flag_a.invertBits()),
+                new LogicValue(v.getBits(5,5), LogicValue.LogicType.AND, flag_a),
+            };
+            Value ret = new ConstantValue(new BitVector(1).set(0));
+            for(int i=0; i<vals.length; i++)
+                ret = new LogicValue(ret, LogicValue.LogicType.OR, vals[i]);
+            return ret;
         }
     }
 }
+