add support for a "standing" count value
authoradam <adam@megacz.com>
Tue, 12 Feb 2008 06:58:54 +0000 (07:58 +0100)
committeradam <adam@megacz.com>
Tue, 12 Feb 2008 06:58:54 +0000 (07:58 +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

index 321795a..3521374 100644 (file)
@@ -105,6 +105,7 @@ public abstract class Instruction {
         public static final int DATA_LATCH = -1;
         public static final int REPEAT_COUNTER = -2;
         public static final int LOOP_COUNTER = -3;
+        public static final int STANDING = -3;
         public final int source;
         public final int dest;
         public Counter(Pump pump, int source, int dest) { this(pump, P_ALWAYS, source, dest); }
@@ -123,7 +124,9 @@ public abstract class Instruction {
                 default: throw new RuntimeException("invalid");
             }
             ret.append(" counter");
-            if (source >= 0) {
+            if (source == STANDING)
+                ret.append(" with *");
+            else if (source >= 0) {
                 ret.append(" with " + source);
             } else if (source!=DATA_LATCH) {
                 throw new RuntimeException("invalid");
index ec0b4c6..574633e 100644 (file)
@@ -302,6 +302,9 @@ public class Parser {
                 } else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
                     cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER));
                     continue;
+                } else if ("*".equals(tt.head()))    {
+                    cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER));
+                    continue;
                 } else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
                     cb.add(new Instruction.Counter(pump, predicate, (int)number(tt.child(1)), Instruction.Counter.LOOP_COUNTER));
                     continue;
index b674b3a..de5e101 100644 (file)
@@ -22,6 +22,7 @@ InstructionX    = ^"unclog"                          ";" /ws
                 |  "take" ^"loop" "counter"                            ";" /ws
                 | ^"load" (^"loop"|^"repeat") ws "counter"             ";" /ws
                 |  "load" (^"loop"|^"repeat") ws "counter" ^"with" int ";" /ws
+                |  "load" (^"loop"|^"repeat") ws "counter" "with" ^"*" ";" /ws
                 | ^"decrement" "loop" "counter"                        ";" /ws
                 | ^"setflags" "a" "=" Flags "," "b" "=" Flags          ";" /ws
                 | ^"kill"     int                    ";" /ws
index 461ddaf..3132491 100644 (file)
@@ -579,11 +579,11 @@ public class Generator {
         }
 
         Module.Latch     ondeck         = box.new Latch("ondeck", WIDTH_WORD);
-        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNTER_LITERAL);
-        Module.Latch     repcount2      = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL);
+        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.Latch     repeat_counter = box.new Latch("repeat_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);
@@ -782,6 +782,19 @@ public class Generator {
                            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(
@@ -800,9 +813,12 @@ public class Generator {
                                              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", doRepeat.doFill()),
+                                             new ConditionalAction("repcount2>1 || repcount2==`magic_standing_value", doRepeat.doFill()),
                                              new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
-                                             new ConditionalAction("!`is_standing(ondeck)", new AssignAction(repcount, "repcount2-1")),
+                                             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)",
@@ -825,13 +841,14 @@ public class Generator {
 
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
 
-        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_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_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"));
@@ -858,6 +875,8 @@ public class Generator {
         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]) }");
 
index 8dc44b7..2efe2a6 100644 (file)
@@ -14,18 +14,19 @@ public abstract class InstructionEncoder {
     public static final int WIDTH_CODEBAG_SIZE     = 6;
     public static final int WIDTH_COUNTER_LITERAL  = 6;
 
-    public static final Mask FLAGS               = new Mask("...............000000................");
-    public static final Mask FLAGS_A             = new Mask("...............000000vvvvvvvv........");
-    public static final Mask FLAGS_B             = new Mask("...............000000........vvvvvvvv");
-    public static final Mask REPEAT_FROM_DATA    = new Mask("...............000001.........0......");
-    public static final Mask REPEAT_FROM_LITERAL = new Mask("...............000001.........1vvvvvv");
-    public static final Mask LOOP_FROM_DATA      = new Mask("...............000010.........0......");
-    public static final Mask LOOP_FROM_LITERAL   = new Mask("...............000010.........1vvvvvv");
-    public static final Mask TAKE_LOOP           = new Mask("...............000011................");
-    public static final Mask KILL                = new Mask("...............000100..........vvvvvv");
-    public static final Mask MASSACRE            = new Mask("...............000101................");
-    public static final Mask CLOG                = new Mask("...............000110................");
-    public static final Mask UNCLOG              = new Mask("...............000111................");
+    public static final Mask FLAGS                = new Mask("...............000000................");
+    public static final Mask FLAGS_A              = new Mask("...............000000vvvvvvvv........");
+    public static final Mask FLAGS_B              = new Mask("...............000000........vvvvvvvv");
+    public static final Mask REPEAT_FROM_DATA     = new Mask("...............000001........00......");
+    public static final Mask REPEAT_FROM_LITERAL  = new Mask("...............000001........10vvvvvv");
+    public static final Mask REPEAT_FROM_STANDING = new Mask("...............000001........11......");
+    public static final Mask LOOP_FROM_DATA       = new Mask("...............000010.........0......");
+    public static final Mask LOOP_FROM_LITERAL    = new Mask("...............000010.........1vvvvvv");
+    public static final Mask TAKE_LOOP            = new Mask("...............000011................");
+    public static final Mask KILL                 = new Mask("...............000100..........vvvvvv");
+    public static final Mask MASSACRE             = new Mask("...............000101................");
+    public static final Mask CLOG                 = new Mask("...............000110................");
+    public static final Mask UNCLOG               = new Mask("...............000111................");
 
     public static final Mask SK                  = new Mask("...........1.........................");
     public static final Mask DL                  = new Mask("............1........................");
@@ -94,11 +95,12 @@ public abstract class InstructionEncoder {
         if (P_B.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_B;
         if (P_Z.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_Z;
 
-        if (LOOP_FROM_LITERAL.get(inst))   return new Counter(name, predicate, (int)LOOP_FROM_LITERAL.getval(inst),   LOOP_COUNTER);
-        if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
-        if (LOOP_FROM_DATA.get(inst))      return new Counter(name, predicate, DATA_LATCH, LOOP_COUNTER);
-        if (REPEAT_FROM_DATA.get(inst))    return new Counter(name, predicate, DATA_LATCH, REPEAT_COUNTER);
-        if (TAKE_LOOP.get(inst))           return new Counter(name, predicate, LOOP_COUNTER, DATA_LATCH);
+        if (LOOP_FROM_LITERAL.get(inst))    return new Counter(name, predicate, (int)LOOP_FROM_LITERAL.getval(inst),   LOOP_COUNTER);
+        if (REPEAT_FROM_LITERAL.get(inst))  return new Counter(name, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
+        if (LOOP_FROM_DATA.get(inst))       return new Counter(name, predicate, DATA_LATCH, LOOP_COUNTER);
+        if (REPEAT_FROM_DATA.get(inst))     return new Counter(name, predicate, DATA_LATCH, REPEAT_COUNTER);
+        if (REPEAT_FROM_STANDING.get(inst)) return new Counter(name, predicate, STANDING, REPEAT_COUNTER);
+        if (TAKE_LOOP.get(inst))            return new Counter(name, predicate, LOOP_COUNTER, DATA_LATCH);
 
         if (DL.get(inst))                  return new Instruction.DecrLoop(name, predicate);
 
@@ -193,8 +195,9 @@ public abstract class InstructionEncoder {
         } else if (d instanceof Instruction.Counter) {
             Instruction.Counter ic = (Instruction.Counter)d;
             if      (ic.dest == DATA_LATCH && ic.source == LOOP_COUNTER)   instr = TAKE_LOOP.set(instr);
-            else if (ic.dest == REPEAT_COUNTER && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
             else if (ic.dest == LOOP_COUNTER && ic.source == DATA_LATCH)   instr = LOOP_FROM_DATA.set(instr);
+            else if (ic.dest == REPEAT_COUNTER && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
+            else if (ic.dest == REPEAT_COUNTER && ic.source == STANDING)   instr = REPEAT_FROM_STANDING.set(instr);
             else if (ic.dest == REPEAT_COUNTER)                            instr = REPEAT_FROM_LITERAL.setval(REPEAT_FROM_LITERAL.set(instr), ic.source);
             else if (ic.dest == LOOP_COUNTER)                              instr = LOOP_FROM_LITERAL.setval(LOOP_FROM_LITERAL.set(instr), ic.source);
             else throw new RuntimeException();
index 8e7fd82..3c06ccf 100644 (file)
@@ -24,7 +24,7 @@ abstract class InstructionPump extends InterpreterPump {
     private int killNextStandingInstruction = 0;
 
     public int loopCounter = 0;
-    public int repeatCounter = 1;
+    private int repeatCounter = 1;
 
     InstructionPump(InterpreterShip ship, String name, String[] ports) {
         super(ship, name, ports);
@@ -108,9 +108,12 @@ abstract class InstructionPump extends InterpreterPump {
                 } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
                     loopCounter = (int)peekDataLatch();
                 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
+                    // FIXME: is there any way to load the "standing" value?
                     repeatCounter = (int)peekDataLatch();
                 } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
                     loopCounter = ic.source;
+                } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source==Instruction.Counter.STANDING) {
+                    repeatCounter = -1;
                 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
                     repeatCounter = ic.source;
                 }
@@ -148,6 +151,8 @@ abstract class InstructionPump extends InterpreterPump {
         if (executing==null) return;
         if (executing.isRepeating() && repeatCounter > 1) {
             repeatCounter--;
+        } else if (executing.isRepeating() && repeatCounter == -1) {
+            // repeat
         } else if (executing.isLooping() && oldLoopCounter > 0) {
             addInstruction(executing);
             executing = null;