update to 03-Jan-2009 am33: head, abort, and d-flag
authormegacz <adam@megacz.com>
Sun, 4 Jan 2009 05:41:24 +0000 (21:41 -0800)
committermegacz <adam@megacz.com>
Sun, 4 Jan 2009 05:41:24 +0000 (21:41 -0800)
21 files changed:
ships/Lut3.ship
ships/Rotator.ship
src/edu/berkeley/fleet/api/Instruction.java
src/edu/berkeley/fleet/api/Predicate.java
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/assembler/fleet.g
src/edu/berkeley/fleet/fpga/Client.java
src/edu/berkeley/fleet/fpga/FpgaDock.java
src/edu/berkeley/fleet/interpreter/InterpreterDock.java
src/edu/berkeley/fleet/ir/Context.java
src/edu/berkeley/fleet/two/FleetTwoFleet.java
tests/dock/one-instruction-loop.fleet
tests/dock/predicate-olc-equals-zero.fleet
tests/dock/test-use-loop-counter.fleet
tests/requeue/requeueing-literal.fleet
tests/requeue/test-for-common-requeue-timing-error.fleet
tests/requeue/test-requeue.fleet
tests/torpedo/basic-torpedo-inbox.test
tests/torpedo/basic-torpedo-outbox.test
tests/torpedo/epilogue-fifo.test
tests/torpedo/epilogue-fifo2.test

index 4c8401e..3993ed7 100644 (file)
@@ -376,6 +376,7 @@ alu.in1:
    set ilc=*;  recv, deliver;
 alu.out:
   set olc=2;
+  head;
   [Rq] recv token, collect, send to lut.inLut;
   [Rq] send to alu.in1;
   tail;
index 5c8226a..c5bbf64 100644 (file)
@@ -104,6 +104,7 @@ rotator.inAmount:
    deliver;
 rotator.out:
    set olc=3;
+   head;
    [Rq] collect, send to debug.in;
    [Rq] set flags a=c, b=b;
    [Rq] [!a] set word=0;
index 03f676d..13a266b 100644 (file)
@@ -331,9 +331,21 @@ public abstract class Instruction {
         }
     }
 
+    /** a flush instruction */
+    public static class Abort extends Instruction {
+        public Abort(Dock dock, Predicate predicate) { super(dock, false, predicate); }
+        public String toString() { return super.toString()+"abort"; }
+    }
+
+    /** marks the start of a loop; closes the hatch */
+    public static class Head extends Instruction {
+        public Head(Dock dock) { super(dock, false, Predicate.IgnoreFlagD); }
+        public String toString() { return dock+": head;"; }
+    }
+
     /** marks the end of a loop; closes the hatch */
     public static class Tail extends Instruction {
-        public Tail(Dock dock) { super(dock, false, Predicate.IgnoreOLC); }
+        public Tail(Dock dock) { super(dock, false, Predicate.IgnoreFlagD); }
         public String toString() { return dock+": tail;"; }
     }
 
index 4c42033..2556e47 100644 (file)
@@ -2,7 +2,7 @@ package edu.berkeley.fleet.api;
 
 /** possible predicate field values */
 public enum Predicate {
-    Default, FlagA, NotFlagA, FlagB, NotFlagB, FlagC, NotFlagC, IgnoreOLC, OLCZero;
+    Default, FlagA, NotFlagA, FlagB, NotFlagB, FlagC, NotFlagC, IgnoreFlagD, FlagD;
     public String toString() {
         switch(this) {
             case Default:    return "";
@@ -12,24 +12,24 @@ public enum Predicate {
             case NotFlagA:   return "!a";
             case NotFlagB:   return "!b";
             case NotFlagC:   return "!c";
-            case IgnoreOLC:  return "*";
-            case OLCZero:    return "olc=0";
+            case IgnoreFlagD:return "*";
+            case FlagD:      return "d";
             default:         throw new Error("unknown predicate " + this);
         }
     }
 
     /** evaluates this predicate for a given set of flags and olc */
-    public boolean evaluate(boolean flag_a, boolean flag_b, boolean flag_c, boolean olc_zero) {
+    public boolean evaluate(boolean flag_a, boolean flag_b, boolean flag_c, boolean flag_d) {
         switch(this) {
-            case Default:    return !olc_zero;
-            case FlagA:      return !olc_zero && flag_a;
-            case FlagB:      return !olc_zero && flag_b;
-            case FlagC:      return !olc_zero && flag_c;
-            case NotFlagA:   return !olc_zero && !flag_a;
-            case NotFlagB:   return !olc_zero && !flag_b;
-            case NotFlagC:   return !olc_zero && !flag_c;
-            case IgnoreOLC:  return true;
-            case OLCZero:    return olc_zero;
+            case Default:    return !flag_d;
+            case FlagA:      return !flag_d && flag_a;
+            case FlagB:      return !flag_d && flag_b;
+            case FlagC:      return !flag_d && flag_c;
+            case NotFlagA:   return !flag_d && !flag_a;
+            case NotFlagB:   return !flag_d && !flag_b;
+            case NotFlagC:   return !flag_d && !flag_c;
+            case IgnoreFlagD:return true;
+            case FlagD:      return flag_d;
             default:         throw new Error("unknown predicate " + this);
         }
     }
index 3a1fdbd..6adb24c 100644 (file)
@@ -106,7 +106,7 @@ public class Parser {
                     long lit = 0;
                     lit = ((FleetTwoFleet)fleet).CBD_SIZE.setval(lit, codeBags.get((int)old.immediate).size());
                     lit = ((FleetTwoFleet)fleet).CBD_OFFSET.setval(lit, codeBagMap[(int)old.immediate]);
-                    inst = new Set(old.dock, false, IgnoreOLC, SetDest.DataLatch, lit);
+                    inst = new Set(old.dock, false, IgnoreFlagD, SetDest.DataLatch, lit);
                 }
                 ret.add(inst);
                 count++;
@@ -154,15 +154,15 @@ public class Parser {
         for(int i=0; i<instructions.length; i++) {
             long lit = ((FleetTwoFleet)fpga).writeInstruction(instructions[i], out);
             ret.add(discard(out));
-            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, lit))));
-            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, lit))));
+            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, lit))));
+            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, lit))));
             ret.add(deliver(inDataWrite));
-            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, i))));
-            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, i))));
+            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, i))));
+            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, i))));
             ret.add(deliver(inAddrWrite));
         }
-        ret.add(new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, startcbd))));
-        ret.add(new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, startcbd))));
+        ret.add(new Instruction.Shift(inCBD, false, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, startcbd))));
+        ret.add(new Instruction.Shift(inCBD, false, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, startcbd))));
         ret.add(wait(inCBD));
         ret.add(deliver(inCBD));
         ret.add(sendto(out, out.getPath(inCBD.getDataDestination(),null)));
@@ -175,8 +175,8 @@ public class Parser {
             int num = Math.min(count, MAX_ILC);
             num_instrs+=2;
             count -= num;
-            ret.add(new Instruction.Set(ihorn, false, IgnoreOLC, SetDest.InnerLoopCounter, num));
-            ret.add(new Instruction.Move(ihorn, false, IgnoreOLC, false, null,false,true,true,true,true,false));
+            ret.add(new Instruction.Set(ihorn, false, IgnoreFlagD, SetDest.InnerLoopCounter, num));
+            ret.add(new Instruction.Move(ihorn, false, IgnoreFlagD, false, null,false,true,true,true,true,false));
         }
         if (num_instrs > ihorn.getInstructionFifoSize()) throw new RuntimeException();
 
@@ -363,6 +363,9 @@ public class Parser {
                 if ("tail".equals(tt.head()))    {
                     cb.add(new Tail(dock));
                     continue;
+                } else if ("head".equals(tt.head()))    {
+                    cb.add(new Head(dock));
+                    continue;
                 }
 
                 int count = 1;
@@ -377,15 +380,12 @@ public class Parser {
                     if ("[!a]".equals(ttt.head())) predicate = NotFlagA;
                     if ("[!b]".equals(ttt.head())) predicate = NotFlagB;
                     if ("[!c]".equals(ttt.head())) predicate = NotFlagC;
-                    if ("[*]".equals(ttt.head()))  predicate = IgnoreOLC;
-                    if ("[olc=0]".equals(ttt.head()))  predicate = OLCZero;
+                    if ("[*]".equals(ttt.head()))  predicate = IgnoreFlagD;
+                    if ("[d]".equals(ttt.head()))  predicate = FlagD;
                     if ("[Rq]".equals(ttt.head()))  looping = true;
                 }
                 tt = tt.child(1);
-                if ("tail".equals(tt.head()))    {
-                    cb.add(new Tail(dock));
-                    continue;
-                } else if ("flags".equals(tt.head()))    {
+                if ("flags".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
                     continue;
                 } else if ("olc=word".equals(tt.head()))    {
@@ -416,6 +416,9 @@ public class Parser {
                 } else if ("flush".equals(tt.head())) {
                     cb.add(new Flush(dock, looping, predicate));
                     continue;
+                } else if ("abort".equals(tt.head())) {
+                    cb.add(new Abort(dock, predicate));
+                    continue;
                 } else if ("word".equals(tt.head())) {
                     long literal = 0;
                     if (tt.child(0).head().equals("CodeBagBody")) {
@@ -582,8 +585,8 @@ public class Parser {
         public Ship createShip(String shiptype, String shipname);
     }
 
-    private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, true,  false, false, false, false); }
-    private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, false, false, false, true,  false); }
-    private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreOLC, false, null, true,  false, false, false, false, false); }
-    private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreOLC, false, path, false, false, false, false, true,  false); }
+    private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
+    private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
+    private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
+    private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
 }
index 1a7a87a..90f601d 100644 (file)
@@ -13,10 +13,11 @@ Fiber::         = Dock        ":" Instructions        /ws
 
 Instructions::  = Instruction +/ ws
 Instruction     = Instruction:: (Tags:: Tag*) InstructionX
+                | ^"head" ";" /ws
                 | ^"tail" ";" /ws
 Tag             = ^"[a]"  ws |  ^"[b]" ws
                 | ^"[!a]" ws | ^"[!b]" ws
-                | ^"[olc=0]" ws
+                | ^"[d]" ws
                 | ^"[*]" ws
                 | ^"[Rq]" ws
 InstructionX    = (() | ^"[T]" ws) ^"nop"                                            ";" /ws
@@ -31,6 +32,7 @@ InstructionX    = (() | ^"[T]" ws) ^"nop"
                 |                   "set" ^"word"      "=" Literal                   ";" /ws
                 |              ^"shift" Literal                                      ";" /ws
                 |              ^"flush"                                              ";" /ws
+                |              ^"abort"                                              ";" /ws
 
 Flags:: = (^"0") |  (^"1") | (^"a" |  ^"b" |  ^"c" | ^"!a" | ^"!b" | ^"!c") +/ (ws "|" ws)
 
index 6b71a76..859e062 100644 (file)
@@ -121,8 +121,8 @@ public class Client extends FleetProcess {
                  new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
     }
 
-    private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, true,  false, false, false, false); }
-    private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, false, false, false, true,  false); }
-    private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreOLC, false, null, true,  false, false, false, false, false); }
-    private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreOLC, false, path, false, false, false, false, true,  false); }
+    private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
+    private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
+    private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
+    private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
 }
index f0ea9fd..71df5ec 100644 (file)
@@ -85,12 +85,11 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
     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 flag_z    = createInputPort ("flag_z",     1);
-            Module.SinkPort   out       = createOutputPort("out",        fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+            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  using         = new StateWire("using", false);
             Module.StateWire  circulating   = new StateWire("circulating", false);
             Module.StateWire  doResetFabric = new StateWire("doResetFabric", false);
             Module.StateWire  doResetOndeck = new StateWire("doResetOndeck", false);
@@ -98,27 +97,55 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             out.connectValue(new MuxValue(circulating.isEmpty(), fabric_in, ondeck_in));
 
             // always: discard one-shot instructions
-            new Event(new Object[] { ondeck_in, fpga.OS.verilog(ondeck_in.getName()) },
-                      new Action[] { ondeck_in, });
-
             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 });
 
-            new Event(new Object[] { circulating.isEmpty(),                  fabric_in, fpga.TAIL.verilog(fabric_in.getName()) },
-                      new Action[] { circulating.doFill(),                   fabric_in });
-            new Event(new Object[] { circulating.isEmpty(),                  fabric_in, "!("+fpga.TAIL.verilog(fabric_in.getName())+")", doResetFabric.isEmpty() },
-                      new Action[] {                                         out, doResetFabric.doFill() });
-            new Event(new Object[] { using.isEmpty(),                        ondeck_in, "!("+fpga.OS.verilog(ondeck_in.getName())+")", "flag_z" },
-                      new Action[] {                                         ondeck_in, });
-            new Event(new Object[] { using.isEmpty(),                        ondeck_in, "!("+fpga.OS.verilog(ondeck_in.getName())+")", "!flag_z" },
-                      new Action[] { using.doFill() });
-            new Event(new Object[] { circulating.isFull(),  using.isFull(),  ondeck_in, "!("+fpga.OS.verilog(ondeck_in.getName())+")", "flag_z" },
-                      new Action[] { circulating.doDrain(), using.doDrain(), ondeck_in, });
-            new Event(new Object[] { circulating.isFull(),  using.isFull(),  ondeck_in, "!("+fpga.OS.verilog(ondeck_in.getName())+")", "!flag_z", doResetOndeck.isEmpty() },
-                      new Action[] {                                         out, doResetOndeck.doFill() });
-
+            // 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 });
         }
     }
 
@@ -159,6 +186,7 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             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.Latch     flag_d         = new Latch("flag_d", 1);
             Module.Latch     flag_z         = new Latch("flag_z", 1);
 
             Module.SinkPort   token_out     = fabric_out;
@@ -183,7 +211,7 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             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_flag_z    = requeue_module.getInputPort("flag_z");
+            Module.SinkPort   requeue_abort     = requeue_module.getInputPort("abort");
             Module.SourcePort requeue_out       = requeue_module.getOutputPort("out");
 
             efifo_out.connect(requeue_fabric_in);
@@ -201,7 +229,6 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                                                             ? new SimpleValue(data_out.getName())
                                                             : new SimpleValue(data_out.getBits(fpga.PACKET_DATA).getVerilog()))
                                                           );
-            requeue_flag_z.connectValue(new SimpleValue("(olc==0)"));
 
             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;
@@ -220,7 +247,7 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                 "("+
                 fpga.P_ALWAYS.verilog(ondeck.getName())+
                 ") || ("+
-                fpga.P_OLC_ZERO.verilog(ondeck.getName())+"==flag_z"+
+                fpga.P_OLC_ZERO.verilog(ondeck.getName())+"==flag_d"+
                 ")"+
                 ") && ("+
                 " " + fpga.P_A.verilog(ondeck.getName())+" ? flag_a"+
@@ -231,6 +258,8 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                 ")"+
                 ")";
 
+            requeue_abort.connectValue(new SimpleValue("("+predicate_met+") && "+fpga.ABORT.verilog(ondeck.getName())));
+
             // Torpedo strikes
             new Event(new Object[] {
                     ondeck,
@@ -246,6 +275,7 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                     torpedo_branch_torpedo,
                     new AssignAction(olc,    new ConstantValue(new BitVector(olc.width).set(0))),
                     new AssignAction(flag_z, new ConstantValue(new BitVector(1).set(0))),
+                    new AssignAction(flag_d, new ConstantValue(new BitVector(1).set(0))),
                     new AssignAction(ilc,    new ConstantValue(new BitVector(ilc.width).set(1)))
                 });
 
@@ -286,6 +316,13 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                           new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE),
                                                 new AssignAction(flag_z, new SimpleValue("(olc==0 || olc==1)"))),
 
+                          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"))),
 
index c9f9282..296be98 100644 (file)
@@ -109,6 +109,10 @@ class InterpreterDock extends FleetTwoDock {
 
         if (hatchIsOpen && epilogue.size() > 0) {
             Instruction inst = epilogue.remove();
+            if (inst instanceof Instruction.Head) {
+                // FIXME
+                return;
+            }
             if (inst instanceof Instruction.Tail)
                 hatchIsOpen = false;
             else
@@ -128,7 +132,7 @@ class InterpreterDock extends FleetTwoDock {
 
         boolean enabled = true;
         switch(executing.predicate) {
-            case IgnoreOLC:  enabled =  true;   break;
+            case IgnoreFlagD:  enabled =  true;   break;
             case Default:    enabled =  olc>0;  break;
             case FlagA:      enabled =  flag_a; break;
             case FlagB:      enabled =  flag_b; break;
index 170c2a5..a196660 100644 (file)
@@ -350,7 +350,7 @@ public class Context {
             boolean blockingInstructionEncountered = false;
 
             // Set the OLC (it might previously have been zero)
-            ic.add(new Set(dock, false, Predicate.IgnoreOLC, SetDest.OuterLoopCounter, count==0 ? 1 : count));
+            ic.add(new Set(dock, false, Predicate.IgnoreFlagD, SetDest.OuterLoopCounter, count==0 ? 1 : count));
 
             for(Instruction i : instructions) {
                 if (i instanceof Move && (((Move)i).tokenIn || ((Move)i).dataIn))
@@ -366,6 +366,7 @@ public class Context {
                     numInstructionsNotIncludingNonblockingPrefix > dock.getInstructionFifoSize())
                     throw new RuntimeException("instruction sequence is too long for instruction fifo at " + dock);
             } else {
+                ic.add(new Instruction.Head(dock));
                 if (count != 0) {
                     ic.add(new Instruction.Set(dock, true, Predicate.Default, SetDest.OuterLoopCounter, SetSource.Decrement));
                     if (blockingInstructionEncountered)
@@ -375,7 +376,7 @@ public class Context {
             }
             if (autoflush && !"Debug".equals(dock.getShip().getType()) && next==null) {
                 if (dock.isInputDock())
-                    ic.add(new Instruction.Flush(dock, true, Predicate.OLCZero));
+                    ic.add(new Instruction.Flush(dock, true, Predicate.FlagD));
             }
             if (count!=1) {
                 ic.add(new Instruction.Tail(dock));
index 27bf3df..311a007 100644 (file)
@@ -39,6 +39,8 @@ public abstract class FleetTwoFleet extends Fleet {
     public final Mask SHIFT;
 
     public final Mask TAIL;
+    public final Mask HEAD;
+    public final Mask ABORT;
 
     public final Mask MOVE;
     public final Mask TI;
@@ -110,7 +112,9 @@ public abstract class FleetTwoFleet extends Fleet {
 
             SHIFT                      = new Mask("..........101111.1vvvvvvvvvvvvvvvvvvv");
 
-            TAIL                       = new Mask("................1....................");
+            TAIL                       = new Mask("................1...................0");
+            HEAD                       = null;
+            ABORT                      = null;
 
             MOVE                       = new Mask("..........110111.....................");
             TI                         = new Mask("..........110111..1..................");
@@ -162,7 +166,10 @@ public abstract class FleetTwoFleet extends Fleet {
 
             SHIFT                      = new Mask("................00vvvvvvvvvvvvvvvvvvv");
 
-            TAIL                       = new Mask("................11...................");
+            ABORT                      = new Mask("................1100.................");  // note: has a predicate!
+
+            HEAD                       = new Mask("................1110.................");
+            TAIL                       = new Mask("................1111.................");
 
             MOVE                       = new Mask("................01...................");
             TI                         = new Mask("................011..................");
@@ -252,11 +259,12 @@ public abstract class FleetTwoFleet extends Fleet {
         Dock dock = getPathByAddr(dispatchFrom, DISPATCH_PATH.getvalAsBitVector(inst)).getDestination().getDock();
 
         if (TAIL.get(inst))   return new Tail(dock);
+        if (HEAD.get(inst))   return new Head(dock);
 
         Predicate predicate = Default;
-        if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
+        if (P_ALWAYS.get(inst)) predicate = IgnoreFlagD;
         if (P_OLC_NONZERO.get(inst))    predicate = Default;
-        if (P_OLC_ZERO.get(inst))    predicate = OLCZero;
+        if (P_OLC_ZERO.get(inst))    predicate = FlagD;
         if (P_A.get(inst))      predicate = FlagA;
         if (P_B.get(inst))      predicate = FlagB;
         if (P_NOT_A.get(inst))  predicate = NotFlagA;
@@ -265,6 +273,8 @@ public abstract class FleetTwoFleet extends Fleet {
         boolean looping = !OS.get(inst);
         if (FLUSH.get(inst))
             return new Flush(dock, looping, predicate);
+        if (ABORT.get(inst))
+            return new Abort(dock, predicate);
         if (SHIFT.get(inst))                return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
         if (SET_IMMEDIATE.get(inst)) {
             boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
@@ -336,8 +346,8 @@ public abstract class FleetTwoFleet extends Fleet {
         Instruction pi = d;
         if (!pi.looping) instr = OS.set(instr);
         switch(pi.predicate) {
-            case IgnoreOLC:         instr = P_ALWAYS.set(instr); break;
-            case OLCZero:         instr = P_OLC_ZERO.set(instr); break;
+            case IgnoreFlagD:         instr = P_ALWAYS.set(instr); break;
+            case FlagD:         instr = P_OLC_ZERO.set(instr); break;
             case Default: instr = P_OLC_NONZERO.set(instr); break;
             case FlagA:      instr = P_A.set(instr);      break;
             case FlagB:      instr = P_B.set(instr);      break;
@@ -349,6 +359,9 @@ public abstract class FleetTwoFleet extends Fleet {
         if (d instanceof Tail) {
             instr = TAIL.set(instr);
 
+        } else if (d instanceof Head) {
+            instr = HEAD.set(instr);
+
         } else if (d instanceof Shift) {
             Shift shift = (Shift)d;
             instr = SHIFT.set(instr);
@@ -357,6 +370,9 @@ public abstract class FleetTwoFleet extends Fleet {
         } else if (d instanceof Flush) {
             instr = FLUSH.set(instr);
 
+        } else if (d instanceof Abort) {
+            instr = ABORT.set(instr);
+
         } else if (d instanceof Set) {
             Set s = (Set)d;
             switch(s.dest) {
index e0da7ce..b75874f 100644 (file)
 debug.in:
   set word=5;
   deliver;
-  set olc=1;
+  set olc=4;
+  head;
   [Rq] set olc--;
+  [d] abort;
   tail;
   [*] set word=4;
   [*] deliver;
index 9753aca..759ad67 100644 (file)
@@ -9,9 +9,11 @@ debug.in:
   set word=5;
   set flags a=0, b=0;
   set olc=3;
-  [Rq] [olc=0] set word=4;
-  [Rq] [olc=0] deliver;
+  head;
+  [Rq] [d] set word=4;
+  [Rq] [d] deliver;
   [Rq] deliver;
   [Rq] set olc--;
+  [d] abort;
   tail;
 
index 0154d63..dc518c1 100644 (file)
@@ -20,11 +20,13 @@ fifo.out:
 
 fifo.in:
   set olc=3;
+  head;
   [Rq] set word=5;
   [Rq] deliver;
   [Rq] send token to memory.inCBD;
   [Rq] recv, deliver;
   [Rq] set olc--;
+  [d] abort;
   tail;
 
 memory.out:
index 5fbbc3d..75fd4cc 100644 (file)
@@ -18,10 +18,12 @@ debug.in:
 
 fifo.out:
   set olc=3;
+  head;
   [Rq] set word= 5;
   [Rq] send to debug.in;
   [Rq] collect;
   [Rq] send to debug.in;
+  [d] abort;
   tail;
 
 
index c32e9f1..64891eb 100644 (file)
@@ -29,6 +29,7 @@ alu21.inOp: deliver;
 alu21.in1: set ilc=*;
 alu21.in1: recv, deliver, send token to fifo0.out;
 
+fifo0.out: head;
 fifo0.out: [Rq] send to alu21.in1;
 fifo0.out: [Rq] recv token;
 
@@ -40,6 +41,7 @@ fifo0.out: tail;
 
 alu21.out: send token to alu21.out;
 alu21.out: set olc=1;
+alu21.out: head;
 alu21.out: [Rq] collect;
 //alu21.out: [Rq] set flags a=a, b=b;   // uncommenting this line will mask the bug
 alu21.out: [Rq] send to debug0.in;
index 92f90da..5d0c12a 100644 (file)
@@ -52,6 +52,7 @@ alu.in2:   set word= 4;
            set ilc=*;  deliver;
 
 alu.out:   set olc=40;
+           head;
            [Rq] collect, send to alu.in1;
            [Rq] send to debug.in;
            [Rq] recv token;
@@ -61,6 +62,7 @@ alu.in1:   set word= 2;
            set ilc=4;
            deliver;
            set olc=2;
+           head;
            [Rq] recv, deliver;
            [Rq] recv nothing, deliver;
            tail;
index 007be78..db47e8e 100644 (file)
@@ -3,6 +3,7 @@
 #ship fifo  : Fifo
 
 debug.in:
+  head;
   [Rq] nop;
   send token to fifo.out;
   set ilc=*;
index 73907a2..0614428 100644 (file)
@@ -7,6 +7,7 @@ debug.in:
   recv, deliver;
 
 fifo.out:
+  head;
   [Rq] nop;
   send token to fifo.in;
   set ilc=*;
index a3ea4b1..52d73e7 100644 (file)
@@ -8,6 +8,7 @@ fifo.out:
   send token to debug.in:i;
 
 debug.in:
+  head;
   [Rq] nop;
   send token to fifo.out;
   set ilc=*;
index cb05d53..4cadf30 100644 (file)
@@ -5,9 +5,11 @@
 
 debug.in:
   set word= 0;
+  head;
   [Rq] nop;
   deliver;
   set olc=0;
+  [d] abort;
   tail;
   [*] deliver;