implement support (fpga+interp+test) for massacre instruction
authoradam <adam@megacz.com>
Wed, 2 Jan 2008 08:05:28 +0000 (09:05 +0100)
committeradam <adam@megacz.com>
Wed, 2 Jan 2008 08:05:28 +0000 (09:05 +0100)
src/edu/berkeley/fleet/api/Instruction.java
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/assembler/fleet.g
src/edu/berkeley/fleet/fpga/Generator.java
src/edu/berkeley/fleet/ies44/InstructionEncoder.java
src/edu/berkeley/fleet/interpreter/InstructionPump.java
src/edu/berkeley/fleet/interpreter/Interpreter.java
tests/pump/test-massacre.fleet [new file with mode: 0644]

index 177a0ff..f021242 100644 (file)
@@ -22,6 +22,10 @@ public abstract class Instruction {
         public String toString() { return super.toString() + "unclog;"; }
     }
 
+    public static class Massacre extends Instruction {
+        public Massacre(Pump pump) { super(pump); }
+    }
+
     public static class Clog extends Executable {
         public Clog(Pump pump) { super(pump, 1); }
         public String toString() { return super.toString() + "clog;"; }
index 5df6efd..e4b7105 100644 (file)
@@ -265,6 +265,9 @@ public class Parser {
                     count = tt.size()==0 ? 1 : (int)number(tt.child(0));
                     cb.add(new Instruction.Kill(pump, count));
                     continue;
+                } else if ("massacre".equals(tt.head()))    {
+                    cb.add(new Instruction.Massacre(pump));
+                    continue;
                 } else if ("literal".equals(tt.head()))  {
                     long literal = 0;
                     if (tt.child(0).head().equals("CodeBagBody")) {
index dfee550..463a1ba 100644 (file)
@@ -14,6 +14,7 @@ Fiber::         = Pump        ":" Instructions        /ws
 Instructions::  = Instruction +/ ws
 Instruction     = ^"unclog"                          ";" /ws
                 | ^"clog"                            ";" /ws
+                | ^"massacre"                        ";" /ws
                 | ^"kill"                            ";" /ws
                 | ^"kill"     int                    ";" /ws
                 | ^"literal"  Literal  RequeueCount  ";" /ws
index 9e9d047..5d5667f 100644 (file)
@@ -552,6 +552,7 @@ public class Generator {
         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;
@@ -578,6 +579,16 @@ public class Generator {
                       new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill()  }
                       );
 
+        // Massacre (when enqueued)
+        box.new Event(
+                      new Object[] { instr, "`instruction_is_massacre(instr)" },
+                      new Action[] { instr, isMassacreing.doFill(), newMayProceed.doFill() }
+                      );
+        box.new Event(
+                      new Object[] { ondeckFull.isFull(), "`instruction_is_massacre(ondeck)" },
+                      new Action[] { ondeckFull.doDrain(), isMassacreing.doDrain() }
+                      );
+
         // First Kill
         box.new Event(
                       new Object[] { instr,
@@ -635,6 +646,7 @@ public class Generator {
 
         box.new Event(
                       new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
                                      data_out,
                                      token_out,
                                      ififo_in,
@@ -685,6 +697,7 @@ public class Generator {
         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_massacre(i)        (i["+(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1)+":"+OFFSET_MASK_MASSACRE+"]=="+MASK_MASSACRE+")");
         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))");
index 2705b35..7a3d3cd 100644 (file)
@@ -100,6 +100,8 @@ public abstract class InstructionEncoder {
             return new Instruction.UnClog(name);
         if (getIntField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,inst)==MASK_CLOG)
             return new Instruction.Clog(name);
+        if (getIntField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE,inst)==MASK_MASSACRE)
+            return new Instruction.Massacre(name);
         int count           = getIntField(                 OFFSET_COUNT+WIDTH_COUNT-1,         OFFSET_COUNT,     inst);
         if (getIntField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,inst)==MASK_KILL)
             return new Instruction.Kill(name, count);
@@ -151,12 +153,16 @@ public abstract class InstructionEncoder {
         } else if (d instanceof Instruction.Clog) {
             instr |= putField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,       MASK_CLOG);
 
+        } else if (d instanceof Instruction.Massacre) {
+            instr |= putField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE,       MASK_MASSACRE);
+
         } else if (d instanceof Instruction.LocalLiteral) {
             Instruction.LocalLiteral inst = (Instruction.LocalLiteral)d;
             if (inst.pump != null) {
                 instr |= putField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL,    MASK_LITERAL);
                 instr |= putSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1,           OFFSET_LITERAL,         inst.literal);
-                instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,               OFFSET_COUNT,           inst.count);
+                // FIXME remove soon
+                //instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,               OFFSET_COUNT,           inst.count);
             } else {
                 instr = inst.literal;
             }
index 640f12c..cb4c0c2 100644 (file)
@@ -24,6 +24,12 @@ abstract class InstructionPump extends InterpreterPump {
         super(ship, name, ports);
     }
 
+    public void massacre() {
+        executing = null;
+        while(instructions.size() > 0)
+            instructions.remove();
+    }
+
     public void kill(int count, boolean killOnlyStandingInstructions) {
         if (count==0) return;
         if (!killOnlyStandingInstructions) {
index fc2737b..507090d 100644 (file)
@@ -99,6 +99,10 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
             InterpreterPump pump = (InterpreterPump)(((Instruction.Kill)i).pump);
             ((InstructionPump)pump).kill(((Instruction.Kill)i).count+1, false);
 
+        } else if (i instanceof Instruction.Massacre) {
+            InterpreterPump pump = (InterpreterPump)(((Instruction.Massacre)i).pump);
+            ((InstructionPump)pump).massacre();
+
         } else {
             throw new Error("unsupported: " + i.getClass().getName());
         }
diff --git a/tests/pump/test-massacre.fleet b/tests/pump/test-massacre.fleet
new file mode 100644 (file)
index 0000000..2b32557
--- /dev/null
@@ -0,0 +1,37 @@
+#expect 7
+#expect 7
+#expect 7
+#expect 7
+#expect 9
+
+#ship debug        : Debug
+#ship memory       : Memory
+#ship fifo         : Fifo
+
+debug.in: [*] take, deliver, notify fifo.in;
+
+fifo.out:
+  notify fifo.in;
+  [4] take, sendto debug.in;
+  notify memory.inCBD;
+  [*] take, sendto debug.in;
+
+fifo.in:
+  clog;
+  take,        requeue forever;
+  literal 7,   requeue forever;
+  deliver,     requeue forever;
+  unclog;
+
+memory.inCBD:
+  take;
+  literal {
+    fifo.in:
+      take;
+      massacre;
+      literal 9;
+      deliver;
+  }; deliver;
+
+
+