major overhaul: update dock to am33
authoradam <adam@megacz.com>
Fri, 25 Jan 2008 02:57:55 +0000 (03:57 +0100)
committeradam <adam@megacz.com>
Fri, 25 Jan 2008 02:57:55 +0000 (03:57 +0100)
src/edu/berkeley/fleet/api/Instruction.java
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/fpga/Fpga.java
src/edu/berkeley/fleet/fpga/Generator.java
src/edu/berkeley/fleet/ies44/InstructionEncoder.java
src/edu/berkeley/fleet/interpreter/Inbox.java
src/edu/berkeley/fleet/interpreter/InstructionPump.java
src/edu/berkeley/fleet/interpreter/Interpreter.java
src/edu/berkeley/fleet/interpreter/Outbox.java
src/edu/berkeley/fleet/util/Mask.java [new file with mode: 0644]

index 851718d..4cfe0b2 100644 (file)
@@ -6,15 +6,15 @@ public abstract class Instruction {
     public Instruction(Pump pump) { this.pump = pump; }
     public String toString() { return pump+": "; }
 
-    public static abstract class CountingInstruction extends Instruction {
-        public final int count;
-        public CountingInstruction(Pump pump, int count) {
-            super(pump);
-            this.count = count;
-        }
-        public boolean isStanding() { return count==0; }
-        public abstract boolean isRequeueing();
-        public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
+    public boolean isLooping() { return false; }
+    public boolean isRepeating() { return false; }
+    public boolean isStanding() { return false; }
+    public boolean isSK() { return false; }
+    public boolean isDL() { return false; }
+
+    public static class Clog extends Instruction {
+        public Clog(Pump pump) { super(pump); }
+        public String toString() { return super.toString() + "clog;"; }
     }
 
     public static class UnClog extends Instruction {
@@ -26,40 +26,25 @@ public abstract class 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;"; }
-        public Instruction.Executable decrementCount() { return null; }
-        public boolean isRequeueing() { return false; }
-    }
-
-    public static class Kill extends CountingInstruction {
-        public Kill(Pump pump, int count) { super(pump, count); }
-        public boolean isRequeueing() { return false; }
-        public String toString() { return super.toString() + "kill;"; }
-    }
-
-    public static abstract class Executable extends CountingInstruction {
-        public Executable(Pump pump, int count) { super(pump, count); }
-        public abstract Instruction.Executable decrementCount();
+    public static class Kill extends Instruction {
+        public final int count;
+        public Kill(Pump pump, int count) { super(pump); this.count = count; }
+        public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; }
     }
 
-    public static class DecrLoop extends Executable {
-        public DecrLoop(Pump pump) { super(pump, 1); }
-        public Instruction.Executable decrementCount() { return null; }
-        public boolean isRequeueing() { return false; }
+    public static class DecrLoop extends Instruction {
+        public DecrLoop(Pump pump) { super(pump); }
+        public boolean isDL() { return true; }
     }
 
-    public static class Counter extends Executable {
+    public static class Counter extends Instruction {
         public static final int DATA_LATCH = -1;
         public static final int REPEAT_COUNTER = -2;
         public static final int LOOP_COUNTER = -3;
         public final int source;
         public final int dest;
-        public Instruction.Executable decrementCount() { return null; }
-        public boolean isRequeueing() { return false; }
         public Counter(Pump pump, int source, int dest) {
-            super(pump, 1);
+            super(pump);
             this.source = source;
             this.dest = dest;
         }
@@ -81,9 +66,10 @@ public abstract class Instruction {
             ret.append(";");
             return ret.toString();
         }
+        public boolean isLooping() { return true; }
     }
 
-    public static class Move extends Executable {
+    public static class Move extends Instruction {
         public final Destination dest;
 
         public final boolean     tokenIn;
@@ -94,8 +80,7 @@ public abstract class Instruction {
         public final boolean     tokenOut;
         public final boolean     requeue;
         public final boolean     ignoreUntilLast;
-
-        public boolean isRequeueing() { return requeue; }
+        public final boolean     standing;
 
         /** count=0 denotes a standing move */
         public Move(Pump        pump,
@@ -109,7 +94,7 @@ public abstract class Instruction {
                           boolean     tokenOut,
                           boolean     requeue,
                           boolean     ignoreUntilLast) {
-            super(pump, count);
+            super(pump);
             this.dest = dest;
             this.tokenIn = tokenIn;
             this.dataIn = dataIn;
@@ -119,8 +104,7 @@ public abstract class Instruction {
             this.tokenOut = tokenOut;
             this.requeue = requeue;
             this.ignoreUntilLast = ignoreUntilLast;
-            if (count < 0)
-                throw new RuntimeException("count field of an instruction must be >=0");
+            this.standing = count==0;
             if (pump.isInbox() && tokenIn && dataIn)
                 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
             if (pump.isOutbox() && tokenOut && dataOut)
@@ -129,12 +113,6 @@ public abstract class Instruction {
                 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
         }
 
-        public Instruction.Executable decrementCount() {
-            if (count==1) return null;
-            return new Move(pump, dest, count==0 ? 0 : count-1,
-                            tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
-        }
-
         public String toString() {
             // FIXME
             String ret = super.toString();
@@ -159,21 +137,36 @@ public abstract class Instruction {
             return ret;
         }
 
+        public boolean isLooping() { return true; }
+        public boolean isRepeating() { return true; }
+        public boolean isStanding() { return standing; }
     }
 
-    public static class LocalLiteral extends Executable {
+    /*
+    public static class FullLiteral extends Executable {
         public final long literal;
-        public final boolean high;
         public boolean isRequeueing() { return true; }
-        public LocalLiteral(Pump pump, long literal, int count, boolean high) {
-            super(pump, count);
+        public HalfLiteral(Pump pump, long literal) {
+            super(pump, 1);
             this.literal = literal;
-            this.high = high;
         }
         public Instruction.Executable decrementCount() {
             if (count==1) return null;
-            return new LocalLiteral(pump, literal, count-1, high);
+            return new FullLiteral(pump, literal, count-1, high);
+        }
+    }
+    */
+
+    public static class HalfLiteral extends Instruction {
+        public final long literal;
+        public final boolean high;
+        public boolean isRequeueing() { return true; }
+        public HalfLiteral(Pump pump, long literal, int count, boolean high) {
+            super(pump);
+            this.literal = literal;
+            this.high = high;
         }
+        public boolean isLooping() { return true; }
     }
 
     public static class CodeBagDescriptor extends Instruction {
index 0e58b3f..dcd5289 100644 (file)
@@ -312,8 +312,8 @@ public class Parser {
                     } else if ("forever".equals(tt.child(1).head())) {
                         count = 0;
                     }
-                    cb.add(new Instruction.LocalLiteral(pump, getField(36, 19, literal), count, true));
-                    cb.add(new Instruction.LocalLiteral(pump, getField(18,  0, literal), count, false));
+                    cb.add(new Instruction.HalfLiteral(pump, getField(36, 19, literal), count, true));
+                    cb.add(new Instruction.HalfLiteral(pump, getField(18,  0, literal), count, false));
                     continue;
                 }
                 Tree ttx = null;
@@ -355,7 +355,7 @@ public class Parser {
                     else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
                     else if ("take".equals(ttt.head()))    { dataIn = true; latch = true; }
                     else if ("recieve".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("send".equals(ttt.head()))  { dataOutDest = true; }
+                    else if ("send".equals(ttt.head()))  { dataOutDest = true; dataOut = true; }
                     else if ("sendto".equals(ttt.head()))  { dataOut = true; dest = portReference(ttt.child(0)); }
                     else if ("deliver".equals(ttt.head())) { dataOut = true;  }
                     else if ("notify".equals(ttt.head()))     { tokenOut = true; dest = portReference(ttt.child(0)); }
index 72a7597..f5815a8 100644 (file)
@@ -32,17 +32,20 @@ public class Fpga extends Fleet {
         createShip("Memory",    "memory2");  // need this to avoid a bug
         createShip("Fifo",    "fifo1");
         createShip("Fifo",    "fifo2");
+        createShip("Alu2",    "alu2a");
+        createShip("BitFifo",   "bitfifo");
+        // above is the minimal ship set needed to run the regression suite, excluding "ships" tests
+        /*
         createShip("Fifo",    "fifo3");
         createShip("Alu1",    "alu1");
-        createShip("Alu2",    "alu2a");
         createShip("Lut3",      "lut3");
         createShip("Choice",    "Choice");
         createShip("Stack",     "Stack");
         createShip("Alu3",      "alu3");
-        createShip("BitFifo",   "bitfifo");
+        */
+        // above is the minimal ship set needed to run the regression suite, including "ships" tests
 
-        // above is the minimal ship set needed to run the regression suite
-        // below are extra bonush ships
+        // below are extra bonus ships
         /*
         createShip("Alu2",    "alu2b");
         createShip("Alu2",    "alu2c");
index 13d8a4c..e0882f7 100644 (file)
@@ -15,7 +15,7 @@ import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
 
 public class Generator {
 
-    public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_DEST_ADDR;
+    public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_ADDR;
 
     public static class SimpleValue implements Value {
         private final String s;
@@ -175,7 +175,7 @@ public class Generator {
             public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
             public void dump(PrintWriter pw) {
                 pw.println("  reg ["+(width-1)+":0] "+name+";");
-                //pw.println("  initial "+name+"="+(initiallyFull?"1":"0")+";");
+                pw.println("  initial "+name+"=0;");
             }
         }
 
@@ -325,7 +325,7 @@ public class Generator {
             }
         }
 
-        public void dump(PrintWriter pw) {
+        public void dump(PrintWriter pw, boolean fix) {
             pw.println("`include \"macros.v\"");
             pw.println("module "+name+"(clk");
             for(String name : portorder) {
@@ -366,7 +366,7 @@ public class Generator {
                 }
             }
 
-            for(Event a : events) a.dump(pw);
+            for(Event a : events) a.dump(pw, fix);
             pw.println(" begin end");
             pw.println("end");
 
@@ -386,7 +386,7 @@ public class Generator {
                     if (triggers[i] instanceof Port)
                         ((Port)triggers[i]).hasLatch = true;
             }
-            public void dump(PrintWriter pw) {
+            public void dump(PrintWriter pw, boolean fix) {
                 pw.print("if (1");
                 for(Object o : triggers) {
                     if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
@@ -394,7 +394,8 @@ public class Generator {
                 }
                 pw.println(") begin ");
                 for(Object a : actions) pw.println(((Action)a).getVerilogAction());
-                pw.println("end else ");
+                if (fix) pw.println("end /*else*/ ");
+                else     pw.println("end else ");
             }
         }
     }
@@ -406,28 +407,31 @@ public class Generator {
         pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
         pw.println("`define DATAWIDTH                "+WIDTH_WORD);
         pw.println("`define CODEBAG_SIZE_BITS        "+WIDTH_CODEBAG_SIZE);
-        pw.println("`define PUMP_ADDRESS_BITS    "+WIDTH_PUMP_ADDR);
-        pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_DEST_ADDR);
+        pw.println("`define PUMP_ADDRESS_BITS    "+WIDTH_ADDR);
+        pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_ADDR);
+        /*
         pw.println("`define COUNT_BITS               "+WIDTH_COUNT);
         pw.println("`define COUNT_WIDTH              "+WIDTH_COUNT);
+        */
         pw.println("`define PACKET_WIDTH             (`DATAWIDTH + `DESTINATION_ADDRESS_BITS)");
         pw.println("`define INSTRUCTION_WIDTH        "+WIDTH_WORD);
         pw.println("`define packet_data(p)              p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
         pw.println("`define packet_dest(p)              p[(`DESTINATION_ADDRESS_BITS-1):0]");
         pw.println("`define instruction_data(p)         p[(`DATAWIDTH-1):0]");
-        pw.println("`define instruction_dest(p)         p["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]");
+        pw.println("`define instruction_dest(p)         "+PUMP_NAME.verilogVal("p"));
         pw.flush();
         pw.close();
 
         mkfunnel("funnel", prefix);
-        mkhorn(    "horn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
-        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
+        mkhorn(    "horn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
+        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
 
         Module fifostage = mkfifo("fifostage", 0, null,      prefix);
         Module fifo4     = mkfifo("fifo4",     4, fifostage, prefix);
+        Module fifo8     = mkfifo("fifo8",     8, fifostage, prefix);
         Module fifoship  = mkfifo("fifo",      4, fifo4,     prefix);
-        mkBox("outbox", false, prefix, fifo4);
-        mkBox("inbox", true, prefix, fifo4);
+        mkBox("outbox", false, prefix, fifo4, fifo8);
+        mkBox("inbox", true, prefix, fifo4, fifo8);
 
         Module fabric = new Module("fabric");
         fabric.createInputPort("horn_in",     WIDTH_PACKET);
@@ -456,7 +460,7 @@ public class Generator {
                                       new SimpleAction("if (count_out >= 5) begin count_out <= 0; "+fabric_out.getName()+"_a <= 1; end else count_out <= count_out+1; "),
                                       out });
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        root.dump(pw);
+        root.dump(pw, true);
         pw.flush();
         return root;
     }
@@ -473,7 +477,7 @@ public class Generator {
                          new Action[] { in2, out,
                                         new AssignAction(out, in2) });
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        funnel.dump(pw);
+        funnel.dump(pw, true);
         pw.flush();
         return funnel;
     }
@@ -493,7 +497,7 @@ public class Generator {
             driver.connect(driven);
         }
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        fifo.dump(pw);
+        fifo.dump(pw, true);
         pw.flush();
         return fifo;
     }
@@ -519,11 +523,11 @@ public class Generator {
         horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
                        new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        horn.dump(pw);
+        horn.dump(pw, true);
         pw.flush();
     }
 
-    private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
+    private static Module mkBox(String name, boolean inbox, String prefix, Module fifo, Module ififo_m) throws Exception {
         Module box = new Module(name);
         Module.SourcePort instr         = box.createInputPort("instr",       WIDTH_WORD);
         Module.SourcePort fabric_in     = box.createInputPort("fabric_in",   WIDTH_PACKET);
@@ -545,7 +549,11 @@ public class Generator {
         }
 
         Module.Latch     ondeck         = box.new Latch("ondeck", WIDTH_WORD);
-        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNT);
+        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNTER_LITERAL);
+        Module.Latch     repcount2      = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL);
+        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);
@@ -559,13 +567,10 @@ public class Generator {
         Module.SinkPort   data_out      = inbox ? ship_in   : fabric_out;
         Module.SourcePort data_in       = inbox ? dfifo_out : ship_out;
 
-        Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
+        Module.InstantiatedModule ififo = box.new InstantiatedModule(ififo_m);
         Module.SinkPort   ififo_in      = ififo.getInputPort("in");
         Module.SourcePort ififo_out     = ififo.getOutputPort("out");
 
-        Value instruction_count_ondeck        = ondeck  .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
-        Value instruction_count_instr         = instr   .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
-        Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
 
         // Massacre (when enqueued)
         box.new Event(
@@ -573,23 +578,23 @@ public class Generator {
                       new Action[] { ififo_out }
                       );
         box.new Event(
-                      new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")" },
+                      new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
                       new Action[] { ififo_out, isMassacreing.doDrain(), newMayProceed.doFill() }
                       );
         box.new Event(
-                      new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)" },
+                      new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)", isMassacreing.isEmpty() },
                       new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr), isMassacreing.doFill(), ondeckFull.doDrain(), newMayProceed.doDrain() }
                       );
 
         // Clog (must be first)
         box.new Event(
-                      new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
+                      new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")", isMassacreing.isEmpty() },
                       new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
                       );
 
         // UnClog
         box.new Event(
-                      new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
+                      new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)", isMassacreing.isEmpty() },
                       new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill()  }
                       );
 
@@ -598,43 +603,60 @@ public class Generator {
                       new Object[] { instr,
                                      "`instruction_is_kill(instr)",
                                      "!`instruction_is_unclog(instr)",
-                                     ondeckFull.isFull()
+                                     ondeckFull.isFull(),
+                                     isMassacreing.isEmpty()
                       },
                       new Action[] { instr,
                                      ondeckFull.doDrain(),
-                                     new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
-                                     new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
-                                     new ConditionalAction("`instruction_count(instr)!=0", newMayProceed.doDrain()),
-                                     new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+                                     new ConditionalAction("`instruction_kill_count(instr)!=0", new AssignAction(repcount, "`instruction_kill_count(instr)")),
+                                     new ConditionalAction("`instruction_kill_count(instr)!=0", doRepeatKill.doFill()),
+                                     new ConditionalAction("`instruction_kill_count(instr)!=0", newMayProceed.doDrain()),
+                                     new ConditionalAction("`instruction_kill_count(instr)==0", newMayProceed.doFill())
                       });
 
         // Kill              
         box.new Event(
                       new Object[] { doKill.isFull() },
                       new Action[] { doKill.doDrain(),
-                                     new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
-                                     new ConditionalAction("`instruction_count(ondeck)!=0", doRepeatKill.doFill()),
-                                     new ConditionalAction("`instruction_count(ondeck)==0", newMayProceed.doFill())
+                                     new ConditionalAction("killcount!=0", new AssignAction(repcount, "killcount-1")),
+                                     new ConditionalAction("killcount!=0", doRepeatKill.doFill()),
+                                     new ConditionalAction("killcount==0", newMayProceed.doFill())
                       });
 
         // RepKill
         box.new Event(
                       new Object[] { doRepeatKill.isFull(), ififo_out },
                       new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
-                                     new AssignAction(instruction_count_ondeck, repcount) }
+                                     new AssignAction(killcount, repcount) }
                       );
 
         // Enqueue
         box.new Event(
-                      new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
+                      new Object[] { instr,
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr) && !`instruction_is_unclog(instr) && !`instruction_is_massacre(instr)",
+                                     isMassacreing.isEmpty()
+                      },
                       new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr)  }
                       );
 
         // New
         box.new Event(
-                      new Object[] { ififo_out, ondeckFull.isEmpty(), newMayProceed.isFull() },
-                      new Action[] { ififo_out, ondeckFull.doFill(), newMayProceed.doDrain(),
-                                     new AssignAction(ondeck, ififo_out)  }
+                      new Object[] { ififo_out,
+                                     ondeckFull.isEmpty(),
+                                     newMayProceed.isFull(),
+                                     "!`instruction_is_clog("+ififo_out.getName()+")",
+                                     "!`instruction_is_kill(instr)",
+                                     isMassacreing.isEmpty() },
+                      new Action[] { ififo_out,
+                                     ondeckFull.doFill(),
+                                     newMayProceed.doDrain(),
+                                     new AssignAction(ondeck, ififo_out),
+                                     new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+") && !`is_standing("+ififo_out.getName()+")",
+                                                           new AssignAction(repcount2, "(repeat_counter==0?1:repeat_counter)")),
+                                     new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
+                                                           new AssignAction(repeat_counter, "1")),
+                      }
                       );
 
         // RepeatExecute
@@ -642,7 +664,8 @@ public class Generator {
                       new Object[] { doRepeat.isFull() },
                       new Action[] { doRepeat.doDrain(),
                                      ondeckFull.doFill(),
-                                     new AssignAction(instruction_count_ondeck, repcount) }
+                                     new AssignAction(repcount2, repcount)
+                      }
                       );
 
         box.addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
@@ -651,88 +674,175 @@ public class Generator {
         Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
         String data_latch_input  = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
 
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_loop_to_data(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(data_latch, loop_counter),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_data_to_loop(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(loop_counter, "data_latch_output"),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_literal_to_loop(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(loop_counter, "`instruction_loop_count_literal(ondeck)"),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_decr_loop(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)"),
+                           new AssignAction(ififo_in, ondeck),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_data_to_repeat(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(repeat_counter, "data_latch_output"),
+                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_literal_to_repeat(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(repeat_counter, "`instruction_repeat_count_literal(ondeck)"),
+                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
+                           
+                                     
         box.new Event(
                       new Object[] { ondeckFull.isFull(),
                                      isMassacreing.isEmpty(),
                                      data_out,
                                      token_out,
                                      ififo_in,
-                                     "(`instruction_is_normal(ondeck) || `instruction_is_literal(ondeck))",
+                                     "!`instruction_is_kill(instr)",
+                                     "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) ||"+
+                                     " `instruction_is_literal_lo(ondeck) || `instruction_is_literal(ondeck))",
                                      new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
                                      new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
                               },
-                              new Action[] { new SimpleAction("ondeck_full<=0;"),
-                                             new ConditionalAction("`instruction_count(ondeck)==1 || `instruction_bit_requeue(ondeck)", newMayProceed.doFill()),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1",
-                                                                   new AssignAction(ififo_in, ondeck)),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
-                                                                   new AssignAction(instruction_count_ififo_in, "0")),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
-                                                                   new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
-                                             new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
-                                             new ConditionalAction("!`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", doRepeat.doFill()),
-                                             new ConditionalAction("`instruction_count(ondeck)==0", new AssignAction(repcount, "0")),
-                                             new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
+                              new Action[] { ondeckFull.doDrain(),
+                                             new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
+                                             new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
+                                             new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
+                                             new ConditionalAction("repcount2>1", doRepeat.doFill()),
+                                             new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
+                                             new ConditionalAction("!`is_standing(ondeck)", new AssignAction(repcount, "repcount2-1")),
                                              new ConditionalAction("`instruction_is_literal(ondeck)",
-                                                                   new AssignAction(data_latch, "`instruction_literal(ondeck,data_latch_output)")),
-                                             new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
-                                             new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
-                                             new ConditionalAction("`instruction_bit_tokenout(ondeck) && (!`instruction_bit_tokenoutlast(ondeck) || `instruction_count(ondeck)==1)",
-                                                                   token_out),
+                                                                   new AssignAction(data_latch, "`instruction_literal(ondeck)")),
+                                             new ConditionalAction("`instruction_is_literal_hi(ondeck)",
+                                                                   new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")),
+                                             new ConditionalAction("`instruction_is_literal_lo(ondeck)",
+                                                                   new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")),
+                                             new ConditionalAction("`instruction_bit_datain(ondeck)",   data_in),
+                                             new ConditionalAction("`instruction_bit_dataout(ondeck)",  data_out),
+                                             new ConditionalAction("`instruction_bit_tokenin(ondeck)",  token_in),
+                                             new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out),
                                              new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
-                                             new ConditionalAction("`instruction_bit_tokenout(ondeck)",
+                                             new ConditionalAction("`instruction_path_from_data(ondeck)",
+                                                                   new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
+                                                                                    PUMP_NAME.verilogVal(data_latch_input))),
+                                             new ConditionalAction("`instruction_path_from_literal(ondeck)",
                                                                    new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
-                                                                                    "`instruction_bit_dest(ondeck)")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && !`instruction_bit_tokenout(ondeck)",
-                                                                   inbox ? new SimpleAction("")
-                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      "`instruction_bit_dest(ondeck)")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && !`instruction_bit_datain(ondeck)",
-                                                                   inbox ? new SimpleAction("")
-                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      data_out.getName()+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && `instruction_bit_datain(ondeck)",
-                                                                   inbox ? new SimpleAction("")
-                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      data_latch_input+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]"))
+                                                                                    "`instruction_path_literal(ondeck)")),
                               }
                       );
 
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        pw.println("`define instruction_bit_dest(instruction)     instruction["+(OFFSET_DEST+WIDTH_DEST_ADDR-1)+":"+OFFSET_DEST+"]");
-        pw.println("`define instruction_is_literal(i)             (i["+(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1)+":"+OFFSET_MASK_LITERAL+"]=="+MASK_LITERAL+")");
-        pw.println("`define instruction_count(i)                  (`instruction_is_literal(i)?1:i["+(OFFSET_COUNT+WIDTH_COUNT-1)+":"+OFFSET_COUNT+"])");
-        pw.println("`define instruction_is_kill(i)                (i["+(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1)+":"+OFFSET_MASK_KILL+"]=="+MASK_KILL+")");
-        pw.println("`define instruction_is_unclog(i)              (i["+(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1)+":"+OFFSET_MASK_UNCLOG+"]=="+MASK_UNCLOG+")");
-        pw.println("`define instruction_is_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))");
-
-        pw.println("`define high_half(w) (w[36:19])"); // FIXME kinda ugly that we mention numbers here
-        pw.println("`define low_half(w) (w[18:0])");
-
-        pw.println("`define instruction_bit_tokenout(i)     (!`instruction_is_literal(i) && i["+OFFSET_TO+"])");
-        pw.println("`define instruction_bit_tokenoutlast(i) (!`instruction_is_literal(i) && i["+OFFSET_IG+"])");
-        pw.println("`define instruction_bit_dataout(i)      (!`instruction_is_literal(i) && i["+OFFSET_DO+"])");
-        pw.println("`define instruction_bit_latch(i)        (!`instruction_is_literal(i) && i["+OFFSET_DL+"])");
-        pw.println("`define instruction_bit_datain(i)       (!`instruction_is_literal(i) && i["+OFFSET_DI+"])");
-        pw.println("`define instruction_bit_tokenin(i)      (!`instruction_is_literal(i) && i["+OFFSET_TI+"])");
-        pw.println("`define instruction_bit_literal_loadhigh(i)      (i["+OFFSET_LITERAL_LOADHIGH+"])");
-
-        int signextbits = WIDTH_WORD - WIDTH_LITERAL;
-        /*
-        pw.println("`define instruction_literal(i)                {{ "+signextbits+"{i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+"]}},"+
-                   " i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+":"+OFFSET_LITERAL+"]}");
-        */
-
-        pw.println("`define instruction_literal(i,d) "+
-                   " (`instruction_bit_literal_loadhigh(i) "+
-                   "  ? { (i[17:0]),  (d[18:0]) } "+
-                   "  : { (d[36:19]), (i[18:0]) }) ");
 
-        box.dump(pw);
+        pw.println("`define instruction_is_load_loop_to_data(i)      "+TAKE_LOOP.verilog("i"));
+        pw.println("`define instruction_is_load_data_to_repeat(i)    "+REPEAT_FROM_DATA.verilog("i"));
+        pw.println("`define instruction_is_load_data_to_loop(i)      "+LOOP_FROM_DATA.verilog("i"));
+        pw.println("`define instruction_is_load_literal_to_repeat(i) "+REPEAT_FROM_LITERAL.verilog("i"));
+        pw.println("`define instruction_is_load_literal_to_loop(i)   "+LOOP_FROM_LITERAL.verilog("i"));
+        pw.println("`define instruction_repeat_count_literal(i)      "+REPEAT_FROM_LITERAL.verilogVal("i"));
+        pw.println("`define instruction_loop_count_literal(i)        "+LOOP_FROM_LITERAL.verilogVal("i"));
+
+        pw.println("`define instruction_path_literal(i)              "+PATH_LITERAL.verilogVal("i"));
+        pw.println("`define instruction_path_from_literal(i)         "+PATH_LITERAL.verilog("i"));
+        pw.println("`define instruction_path_from_data(i)            "+PATH_DATA.verilog("i"));
+
+        pw.println("`define instruction_is_literal_hi(i)             "+LITERAL_HI.verilog("i"));
+        pw.println("`define instruction_is_literal_lo(i)             "+LITERAL_LO.verilog("i"));
+        pw.println("`define instruction_is_literal(i)                "+LITERAL.verilog("i"));
+        pw.println("`define instruction_kill_count(i)                "+KILL.verilogVal("i"));
+        pw.println("`define instruction_is_kill(i)                   "+KILL.verilog("i"));
+        pw.println("`define instruction_is_unclog(i)                 "+UNCLOG.verilog("i"));
+        pw.println("`define instruction_is_clog(i)                   "+CLOG.verilog("i"));
+        pw.println("`define instruction_is_massacre(i)               "+MASSACRE.verilog("i"));
+        pw.println("`define instruction_is_normal(i)                 "+MOVE.verilog("i"));
+
+        pw.println("`define instruction_is_decr_loop(i)              "+DL.verilog("i"));
+
+        pw.println("`define instruction_bit_tokenout(i)     (`instruction_is_normal(i) && "+TO.verilog("i")+")");
+        pw.println("`define instruction_bit_dataout(i)      (`instruction_is_normal(i) && "+DO.verilog("i")+")");
+        pw.println("`define instruction_bit_latch(i)        (`instruction_is_normal(i) && "+DC.verilog("i")+")");
+        pw.println("`define instruction_bit_datain(i)       (`instruction_is_normal(i) && "+DI.verilog("i")+")");
+        pw.println("`define instruction_bit_tokenin(i)      (`instruction_is_normal(i) && "+TI.verilog("i")+")");
+        pw.println("`define is_standing(i)                  (`instruction_is_normal(i) && "+STAND.verilog("i")+")");
+        pw.println("`define should_requeue(i)               (loop_counter > 0)");
+        pw.println("`define done_executing(i)               (!`is_standing(i) && (repcount2==0 || repcount2==1))");
+
+        pw.println("`define instruction_literal_hi(i,d) { (i[17:0]),  (d[18:0]) }");
+        pw.println("`define instruction_literal_lo(i,d) { (d[36:19]), (i[18:0]) }");
+
+        pw.println("`define instruction_literal_sel(i) " + LITERAL_SEL.verilogVal("i"));
+        pw.println("`define instruction_literal(i) " +
+                   "("+
+                   "  `instruction_literal_sel(i) == 0 ? { (i[17:0]),  {19{1'b0}} } "+
+                   ": `instruction_literal_sel(i) == 1 ? { (i[17:0]),  {19{1'b1}} } "+
+                   ": `instruction_literal_sel(i) == 2 ? { {18{1'b0}}, (i[18:0]) } "+
+                   ":                                    { {18{1'b1}}, (i[18:0]) } "+
+                   ")"
+                   );
+
+
+        box.dump(pw, true);
         pw.flush();
         return box;
     }
index 5e4571f..cabdca4 100644 (file)
@@ -1,84 +1,48 @@
 package edu.berkeley.fleet.ies44;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.*;
+import edu.berkeley.fleet.util.*;
 import java.io.*;
 import static edu.berkeley.fleet.util.BitManipulations.*;
+import static edu.berkeley.fleet.api.Instruction.*;
+import static edu.berkeley.fleet.api.Instruction.Counter.*;
 
 public abstract class InstructionEncoder {
 
-    public static final int WIDTH_WORD             = 37;   /* word width */
+    public static final int WIDTH_WORD             = 37;
+    public static final int WIDTH_ADDR             = 11;
     public static final int WIDTH_CODEBAG_SIZE     = 6;
-    public static final int WIDTH_PUMP_ADDR        = 11;
-    public static final int WIDTH_DEST_ADDR        = 11;
-    public static final int WIDTH_COUNT            = 7;
-
-    public static final int OFFSET_MASK_LITERAL    = 20;
-    public static final int WIDTH_MASK_LITERAL     = 6;
-    public static final int MASK_LITERAL           = 13;   // this is an excessive approximation
-
-    public static final int OFFSET_MASK_MASSACRE   = 14;
-    public static final int WIDTH_MASK_MASSACRE    = 26-14;
-    public static final int MASK_MASSACRE          = 1;
-
-    public static final int OFFSET_MASK_KILL       = 14;
-    public static final int WIDTH_MASK_KILL        = 26-14;
-    public static final int MASK_KILL              = 0;
-
-    public static final int OFFSET_MASK_UNCLOG     = 14;
-    public static final int WIDTH_MASK_UNCLOG      = 26-14;
-    public static final int MASK_UNCLOG            = 3;
-
-    public static final int OFFSET_MASK_CLOG       = 14;
-    public static final int WIDTH_MASK_CLOG        = 26-14;
-    public static final int MASK_CLOG              = 2;
-
-    public static final int OFFSET_MASK_LOAD_LOOP_TO_DATA       = 14;
-    public static final int WIDTH_MASK_LOAD_LOOP_TO_DATA        = 12;
-    public static final int MASK_LOAD_LOOP_TO_DATA         = 0;
-
-    public static final int OFFSET_MASK_LOAD_LITERAL_TO_LOOP       = 14;
-    public static final int WIDTH_MASK_LOAD_LITERAL_TO_LOOP        = 12;
-    public static final int MASK_LOAD_LITERAL_TO_LOOP              = 1;
-
-    public static final int OFFSET_MASK_LOAD_LITERAL_TO_REPEAT       = 14;
-    public static final int WIDTH_MASK_LOAD_LITERAL_TO_REPEAT        = 12;
-    public static final int MASK_LOAD_LITERAL_TO_REPEAT              = 2;
-
-    public static final int OFFSET_MASK_LOAD_DATA_TO_REPEAT       = 14;
-    public static final int WIDTH_MASK_LOAD_DATA_TO_REPEAT        = 12;
-    public static final int MASK_LOAD_DATA_TO_REPEAT              = 3;
-
-    public static final int OFFSET_MASK_LOAD_DATA_TO_LOOP       = 14;
-    public static final int WIDTH_MASK_LOAD_DATA_TO_LOOP        = 12;
-    public static final int MASK_LOAD_DATA_TO_LOOP              = 4;
-
-    public static final int OFFSET_MASK_DECR_LOOP       = 14;
-    public static final int WIDTH_MASK_DECR_LOOP        = 12;
-    public static final int MASK_DECR_LOOP              = 5;
-
-    public static final int OFFSET_MASK_NORMAL     = 25;
-    public static final int WIDTH_MASK_NORMAL      = 1;
-    public static final int MASK_NORMAL            = 1;
-
-    public static final int OFFSET_COUNTER_LITERAL     = 0;
-    public static final int WIDTH_COUNTER_LITERAL      = 6;
-
-    public static final int OFFSET_COUNT           = 0;
-    public static final int OFFSET_DEST            = OFFSET_COUNT+WIDTH_COUNT;
-    public static final int OFFSET_CONTROL         = OFFSET_DEST+WIDTH_DEST_ADDR;
-    public static final int OFFSET_RQ              = OFFSET_CONTROL+0;
-    public static final int OFFSET_IG              = OFFSET_CONTROL+1;
-    public static final int OFFSET_TO              = OFFSET_CONTROL+2;
-    public static final int OFFSET_DO              = OFFSET_CONTROL+3;
-    public static final int OFFSET_DL              = OFFSET_CONTROL+4;
-    public static final int OFFSET_DI              = OFFSET_CONTROL+5;
-    public static final int OFFSET_TI              = OFFSET_CONTROL+6;
-    public static final int OFFSET_LITERAL_LOADHIGH = 19;
-    public static final int OFFSET_INSTRUCTIONTYPE = OFFSET_CONTROL+7;
-    public static final int OFFSET_PUMP_ADDR       = OFFSET_INSTRUCTIONTYPE+1;
-
-    public static final int OFFSET_LITERAL         = 0;
-    public static final int WIDTH_LITERAL          = 19;
+    public static final int WIDTH_COUNTER_LITERAL  = 6;
+
+    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 SK                  = new Mask("...........1.........................");
+    public static final Mask DL                  = new Mask("............1........................");
+    public static final Mask P                   = new Mask(".............vv......................");
+    public static final Mask MOVE                = new Mask("...............001...................");
+    public static final Mask STAND               = new Mask("...................1.................");
+    public static final Mask TI                  = new Mask("....................1................");
+    public static final Mask DI                  = new Mask(".....................1...............");
+    public static final Mask DC                  = new Mask("......................1..............");
+    public static final Mask DO                  = new Mask(".......................1.............");
+    public static final Mask TO                  = new Mask("........................1............");
+    public static final Mask PATH_LITERAL        = new Mask(".........................1vvvvvvvvvvv");
+    public static final Mask PATH_DATA           = new Mask(".........................01..........");
+    public static final Mask PATH_NOCHANGE       = new Mask(".........................00..........");
+
+    public static final Mask LITERAL_LO          = new Mask("...............010vvvvvvvvvvvvvvvvvvv");
+    public static final Mask LITERAL_HI          = new Mask("...............011vvvvvvvvvvvvvvvvvvv");
+    public static final Mask LITERAL             = new Mask("...............1..vvvvvvvvvvvvvvvvvvv");
+    public static final Mask LITERAL_SEL         = new Mask("................vv...................");
+    public static final Mask PUMP_NAME           = new Mask("vvvvvvvvvvv..........................");
 
 
     /** get the bits describing this box's location on the DESTINATION HORN */
@@ -110,132 +74,110 @@ public abstract class InstructionEncoder {
     }
 
     public Instruction readInstruction(long inst) {
-        Pump name           = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
-
-        int count_literal = getIntField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1, OFFSET_COUNTER_LITERAL, inst);
-        if (getIntField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1, OFFSET_MASK_LOAD_LOOP_TO_DATA,inst)==MASK_LOAD_LOOP_TO_DATA)
-            return new Instruction.Counter(name, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH);
-        else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1, OFFSET_MASK_LOAD_DATA_TO_REPEAT,inst)==MASK_LOAD_DATA_TO_REPEAT)
-            return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER);
-        else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1, OFFSET_MASK_LOAD_DATA_TO_LOOP,inst)==MASK_LOAD_DATA_TO_LOOP)
-            return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER);
-        else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1, OFFSET_MASK_LOAD_LITERAL_TO_LOOP,inst)==MASK_LOAD_LITERAL_TO_LOOP)
-            return new Instruction.Counter(name, count_literal, Instruction.Counter.LOOP_COUNTER);
-        else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1, OFFSET_MASK_LOAD_LITERAL_TO_REPEAT,inst)==MASK_LOAD_LITERAL_TO_REPEAT)
-            return new Instruction.Counter(name, count_literal, Instruction.Counter.REPEAT_COUNTER);
-        else if (getIntField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP,inst)==MASK_DECR_LOOP)
-            return new Instruction.DecrLoop(name);
-
-        if (getIntField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,inst)==MASK_UNCLOG)
-            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);
-        Destination dest    = getDestByAddr   (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1,      OFFSET_DEST,      inst));
-        boolean tokenIn     = getBit(OFFSET_TI, inst);
-        boolean dataIn      = getBit(OFFSET_DI, inst);
-        boolean latch       = getBit(OFFSET_DL, inst);
-        boolean dataOut     = getBit(OFFSET_DO, inst);
-        boolean tokenOut    = getBit(OFFSET_TO, inst);
-        boolean requeue     = getBit(OFFSET_RQ, inst);
-        boolean ignoreUntilLast = getBit(OFFSET_IG, inst);
-        boolean dataOutDest = name.isOutbox() && dataOut && tokenOut;
-        boolean isLiteral   = getIntField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, inst)==MASK_LITERAL;
-        if (isLiteral)
-            return new Instruction.LocalLiteral(name, getField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), 0,
-                                                getField(OFFSET_LITERAL_LOADHIGH, OFFSET_LITERAL_LOADHIGH, inst)!=0);
-        if (dataOutDest) tokenOut = false;
+        Pump name           = getBoxByInstAddr(PUMP_NAME.getval(inst));
+
+        if (LOOP_FROM_LITERAL.get(inst))   return new Counter(name, (int)LOOP_FROM_LITERAL.getval(inst),   LOOP_COUNTER);
+        if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
+        if (LOOP_FROM_DATA.get(inst))      return new Counter(name, DATA_LATCH, LOOP_COUNTER);
+        if (REPEAT_FROM_DATA.get(inst))    return new Counter(name, DATA_LATCH, REPEAT_COUNTER);
+        if (TAKE_LOOP.get(inst))           return new Counter(name, LOOP_COUNTER, DATA_LATCH);
+
+        if (DL.get(inst))                  return new Instruction.DecrLoop(name);
+
+        if (UNCLOG.get(inst))   return new Instruction.UnClog(name);
+        if (CLOG.get(inst))     return new Instruction.Clog(name);
+        if (MASSACRE.get(inst)) return new Instruction.Massacre(name);
+        if (KILL.get(inst))     return new Instruction.Kill(name, (int)(KILL.getval(inst)+1));
+        if (LITERAL_LO.get(inst))  return new Instruction.HalfLiteral(name, LITERAL_LO.getval(inst), 0, false);
+        if (LITERAL_HI.get(inst))  return new Instruction.HalfLiteral(name, LITERAL_HI.getval(inst), 0, true);
+
+        Destination dest    = getDestByAddr(PATH_LITERAL.getval(inst));
+        boolean tokenIn     = TI.get(inst);
+        boolean dataIn      = DI.get(inst);
+        boolean latch       = DC.get(inst);
+        boolean dataOut     = DO.get(inst);
+        boolean tokenOut    = TO.get(inst);
+        boolean standing    = STAND.get(inst);
+        boolean dataOutDest = PATH_DATA.get(inst);
         return new Instruction.Move(name,
                                     dest,
-                                    count,
+                                    standing?0:1,
                                     tokenIn,
                                     dataIn,
                                     latch,
                                     dataOutDest,
                                     dataOut,
                                     tokenOut,
-                                    requeue,
-                                    ignoreUntilLast);
+                                    false,
+                                    false);
     }
 
     public long writeInstruction(Instruction d) {
         long instr = 0;
 
         if (d.pump != null)
-            instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(d.pump));
+            instr = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump));
 
         if (d instanceof Instruction.CodeBagDescriptor) {
             Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
             // MAJOR MAJOR FIXME: upper half here...
-            d = new Instruction.LocalLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
+            d = new Instruction.HalfLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
         }
 
         if (d instanceof Instruction.UnClog) {
-            instr |= putField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,       MASK_UNCLOG);
+            instr = UNCLOG.set(instr);
 
         } else if (d instanceof Instruction.Kill) {
             Instruction.Kill k = (Instruction.Kill)d;
-            instr |= putField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,       MASK_KILL);
-            instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,         OFFSET_COUNT,           k.count-1);
+            instr = KILL.set(instr);
+            instr = KILL.setval(instr, k.count);
 
         } else if (d instanceof Instruction.Clog) {
-            instr |= putField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,       MASK_CLOG);
+            instr = CLOG.set(instr);
 
         } else if (d instanceof Instruction.Massacre) {
-            instr |= putField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE,       MASK_MASSACRE);
+            instr = MASSACRE.set(instr);
 
-        } else if (d instanceof Instruction.LocalLiteral) {
-            Instruction.LocalLiteral inst = (Instruction.LocalLiteral)d;
+        } else if (d instanceof Instruction.HalfLiteral) {
+            Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
             if (inst.pump != null) {
-                instr |= putField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL,    MASK_LITERAL);
-                instr |= putField(OFFSET_LITERAL+WIDTH_LITERAL-1,           OFFSET_LITERAL,         inst.literal);
-                instr |= putField(OFFSET_LITERAL_LOADHIGH, OFFSET_LITERAL_LOADHIGH, (inst.high?1:0));
+                if (inst.high) {
+                    instr = LITERAL_HI.set(instr);
+                    instr = LITERAL_HI.setval(instr, inst.literal);
+                } else {
+                    instr = LITERAL_LO.set(instr);
+                    instr = LITERAL_LO.setval(instr, inst.literal);
+                }
             } else {
                 instr = inst.literal;
             }
 
         } else if (d instanceof Instruction.DecrLoop) {
-            instr |= putField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP, MASK_DECR_LOOP);
+            instr = DL.set(instr);
 
         } else if (d instanceof Instruction.Counter) {
             Instruction.Counter ic = (Instruction.Counter)d;
-            if (ic.dest == Instruction.Counter.DATA_LATCH && ic.source == Instruction.Counter.LOOP_COUNTER)
-                instr |= putField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1,
-                                  OFFSET_MASK_LOAD_LOOP_TO_DATA,       MASK_LOAD_LOOP_TO_DATA);
-            else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
-                instr |= putField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1,
-                                  OFFSET_MASK_LOAD_DATA_TO_REPEAT,       MASK_LOAD_DATA_TO_REPEAT);
-            else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
-                instr |= putField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1,
-                                  OFFSET_MASK_LOAD_DATA_TO_LOOP,       MASK_LOAD_DATA_TO_LOOP);
-            else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
-                instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1,
-                                  OFFSET_MASK_LOAD_LITERAL_TO_REPEAT,       MASK_LOAD_LITERAL_TO_REPEAT);
-                instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
-                                  OFFSET_COUNTER_LITERAL, ic.source);
-            } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
-                instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1,
-                                  OFFSET_MASK_LOAD_LITERAL_TO_LOOP,       MASK_LOAD_LITERAL_TO_LOOP);
-                instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
-                                  OFFSET_COUNTER_LITERAL, ic.source);
-            } else throw new RuntimeException();
+            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)                            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();
 
         } else if (d instanceof Instruction.Move) {
             Instruction.Move inst = (Instruction.Move)d;
-            instr |= putField(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1, OFFSET_MASK_NORMAL,       MASK_NORMAL);
-            instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1,      OFFSET_DEST,        inst.dest==null?0:getDestAddr(inst.dest));
-            instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,         OFFSET_COUNT,       inst.count);
-            instr |= putField(OFFSET_TI,                          OFFSET_TI,          inst.tokenIn?1:0);
-            instr |= putField(OFFSET_DI,                          OFFSET_DI,          inst.dataIn?1:0);
-            instr |= putField(OFFSET_DL,                          OFFSET_DL,          inst.latch?1:0);
-            instr |= putField(OFFSET_DO,                          OFFSET_DO,          (inst.dataOutDest||inst.dataOut)?1:0);
-            instr |= putField(OFFSET_TO,                          OFFSET_TO,          (inst.dataOutDest||inst.tokenOut)?1:0);
-            instr |= putField(OFFSET_RQ,                          OFFSET_RQ,          inst.requeue?1:0);
-            instr |= putField(OFFSET_IG,                          OFFSET_IG,          inst.ignoreUntilLast?1:0);
+            instr  = MOVE.set(instr);
+            if (inst.tokenIn)                    instr = TI.set(instr);
+            if (inst.dataIn)                     instr = DI.set(instr);
+            if (inst.latch)                      instr = DC.set(instr);
+            if (inst.dataOut)                    instr = DO.set(instr);
+            if (inst.tokenOut)                   instr = TO.set(instr);
+            if (inst.dataOutDest)                instr = PATH_DATA.set(instr);
+            else {
+                instr  = PATH_LITERAL.set(instr);
+                instr  = PATH_LITERAL.setval(instr, inst.dest==null?0:getDestAddr(inst.dest));
+            }
+            if (inst.standing)                   instr = STAND.set(instr);
 
         }
         return instr;
index a00be0f..c4ec8cf 100644 (file)
@@ -45,7 +45,7 @@ public class Inbox extends InstructionPump {
     protected long peekDataLatch() { return register.value; }
 
     /** invoked by superclass */
-    protected final boolean service(Instruction.Executable instruction_) {
+    protected final boolean service(Instruction instruction_) {
 
         // if data is stuck on itemPresentedToShip, wait for it to go somewhere before
         // considering additional instructions
@@ -54,10 +54,8 @@ public class Inbox extends InstructionPump {
         // if no instruction waiting, do nothing
         if (instruction_ == null) return false;
 
-        if (clogged>0) return false;
-        if (instruction_ instanceof Instruction.Clog) { clogged++; return true; }
-        if (instruction_ instanceof Instruction.LocalLiteral) {
-            Instruction.LocalLiteral ll = (Instruction.LocalLiteral)instruction_;
+        if (instruction_ instanceof Instruction.HalfLiteral) {
+            Instruction.HalfLiteral ll = (Instruction.HalfLiteral)instruction_;
             long val = (register==null) ? 0 : register.value;
             val =
                 ll.high
index 945e863..b600615 100644 (file)
@@ -12,15 +12,16 @@ abstract class InstructionPump extends InterpreterPump {
     public int clogged = 0;
 
     /** the currently executing instruction */
-    private Instruction.Executable executing = null;
+    private Instruction executing = null;
 
     /** all instructions waiting to be executed (excludes executing) */
-    private Queue<Instruction.Executable> instructions = new LinkedList<Instruction.Executable>();
+    private Queue<Instruction> instructions = new LinkedList<Instruction>();
 
     /** count of how many "standing instruction only" kills remain to be executed */
     private int killNextStandingInstruction = 0;
 
     public int loopCounter = 0;
+    public int repeatCounter = 1;
 
     InstructionPump(InterpreterShip ship, String name, String[] ports) {
         super(ship, name, ports);
@@ -48,7 +49,7 @@ abstract class InstructionPump extends InterpreterPump {
     }
 
     /** an instruction arrives from the instruction horn */
-    void addInstruction(Instruction.Executable instr) {
+    void addInstruction(Instruction instr) {
         if (killNextStandingInstruction > 0) { /* FIXME technically we should refuse to take the next instruction here */ }
         instructions.add(instr);
     }
@@ -59,63 +60,59 @@ abstract class InstructionPump extends InterpreterPump {
                              this + "; they are:"));
         if (executing != null)
             Log.println("   " + executing);
-        for(Instruction.Executable i : instructions)
+        for(Instruction i : instructions)
             Log.println("   " + i);
     }
 
     // interface to subclass ///////////////////////////////////////////////////////////////////////
 
     /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
-    protected abstract boolean service(Instruction.Executable instr);
+    protected abstract boolean service(Instruction instr);
 
     protected abstract void setDataLatch(long value);
     protected abstract long peekDataLatch();
-    public boolean _service(Instruction.Executable instr) {
-        if (instr instanceof Instruction.DecrLoop) {
-            if (loopCounter >= 0) loopCounter--;
-            return true;
-        }
-        if (instr instanceof Instruction.Counter) {
-            Instruction.Counter ic = (Instruction.Counter)instr;
+
+    protected final void service() {
+        if (clogged > 0) return;
+        if (executing==null && instructions.size() > 0) executing = instructions.remove();
+        if (executing==null) return;
+
+        int oldLoopCounter = loopCounter;
+        if (executing.isDL()) loopCounter = Math.max(0, loopCounter-1);
+
+        if (executing instanceof Instruction.Counter) {
+            Instruction.Counter ic = (Instruction.Counter)executing;
             if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
                 setDataLatch(loopCounter);
             } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
                 loopCounter = (int)peekDataLatch();
-                executing = null;
+            } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
+                repeatCounter = (int)peekDataLatch();
             } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
                 loopCounter = ic.source;
-                executing = null;
+            } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
+                repeatCounter = ic.source;
             }
-            return true;
-        }
-        return service(instr);
-    }
-
-    protected final void service() {
-        if (executing == null)
-            if (instructions.size() > 0)
-                executing = instructions.remove();
-            else
-                return;
-
-        if (executing != null && killNextStandingInstruction>0 && executing.isStanding()) {
+        } else if (executing instanceof Instruction.DecrLoop) {
+            executing = null;
+            return;
+        } else if (executing instanceof Instruction.Clog) {
+            clogged++;
             executing = null;
-            killNextStandingInstruction--;
             return;
+        } else {
+            if (!service(executing)) return;
         }
 
-        boolean ret = _service(executing);
-        if (!ret) return;
-        if (executing == null) return;
-        if (executing.isRequeueing() || (loopCounter > 0)) {
-            if (loopCounter == 0) executing = executing.decrementCount();
-            if (executing != null)
-                addInstruction(executing);
+        if (executing==null) return;
+        if (executing.isRepeating() && repeatCounter > 1) {
+            repeatCounter--;
+        } else if (executing.isLooping() && oldLoopCounter > 0) {
+            addInstruction(executing);
             executing = null;
-
+        } else if (executing.isStanding()) {
         } else {
-            if (executing != null && !executing.isStanding())
-                executing = executing.decrementCount();
+            executing = null;
         }
     }
 
index 507090d..3a25f4a 100644 (file)
@@ -81,11 +81,7 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
 
     public void dispatch(Instruction i, long address) {
         Log.dispatch(i);
-        if (i instanceof Instruction.Executable) {
-            InterpreterPump sourcePump = (InterpreterPump)(((Instruction.Executable)i).pump);
-            ((InstructionPump)sourcePump).addInstruction(((Instruction.Executable)i));
-
-        } else if (i instanceof Instruction.CodeBagDescriptor) {
+        if (i instanceof Instruction.CodeBagDescriptor) {
             Instruction.CodeBagDescriptor cbd = (Instruction.CodeBagDescriptor)i;
             long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
             throw new RuntimeException();
@@ -104,7 +100,8 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
             ((InstructionPump)pump).massacre();
 
         } else {
-            throw new Error("unsupported: " + i.getClass().getName());
+            InterpreterPump sourcePump = (InterpreterPump)(((Instruction)i).pump);
+            ((InstructionPump)sourcePump).addInstruction(((Instruction)i));
         }
     }
 
index 85b3926..ff7e8e2 100644 (file)
@@ -30,11 +30,9 @@ public class Outbox extends InstructionPump {
     protected void setDataLatch(long value) { register = value; }
     protected long peekDataLatch() { return register; }
 
-    protected final boolean service(Instruction.Executable instruction_) {
-        if (clogged>0) return false;
-        if (instruction_ instanceof Instruction.Clog) { clogged++; return true; }
-        if (instruction_ instanceof Instruction.LocalLiteral) {
-            Instruction.LocalLiteral ll = (Instruction.LocalLiteral)instruction_;
+    protected final boolean service(Instruction instruction_) {
+        if (instruction_ instanceof Instruction.HalfLiteral) {
+            Instruction.HalfLiteral ll = (Instruction.HalfLiteral)instruction_;
             register =
                 ll.high
                 ? setField(36, 19, ll.literal, register)
@@ -68,9 +66,7 @@ public class Outbox extends InstructionPump {
             InterpreterDestination dest = (InterpreterDestination)instruction.dest;
             if (instruction.dataOutDest) {
                 // FIXME: still not supported
-                long bits = BitManipulations.getField(InstructionEncoder.OFFSET_PUMP_ADDR+InstructionEncoder.WIDTH_PUMP_ADDR-1,
-                                                      InstructionEncoder.OFFSET_PUMP_ADDR,
-                                                      register);
+                long bits = InstructionEncoder.PUMP_NAME.getval(register);
                 getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(register), bits);
                 /*
                 dest = (InterpreterDestination)(((Interpreter)getInterpreter()).iie.getDestByAddr(bits));
diff --git a/src/edu/berkeley/fleet/util/Mask.java b/src/edu/berkeley/fleet/util/Mask.java
new file mode 100644 (file)
index 0000000..f75c4be
--- /dev/null
@@ -0,0 +1,56 @@
+package edu.berkeley.fleet.util;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.*;
+import java.io.*;
+
+public class Mask {
+
+    public final long mask;
+    public final long val;
+    public final long valmask;
+    public final int valmaskmin;
+
+
+    public String verilog(String var) {
+        return "(("+var+" & "+mask+")=="+val+")";
+    }
+    public String verilogVal(String var) {
+        return "(("+var+" & "+valmask+") >> "+valmaskmin+")";
+    }
+
+    public long getval(long in) {
+        return (in & valmask) >>> valmaskmin;
+    }
+    public long setval(long in, long targ) {
+        if (((targ << valmaskmin) & ~valmask) != 0) throw new RuntimeException("setval() with argument bigger than mask field");
+        return (in & ~valmask) | ((targ << valmaskmin) & valmask);
+    }
+    public long set(long in) {
+        return (in & ~mask) | val;
+    }
+    public boolean get(long in) {
+        return (in & mask) == val;
+    }
+
+    public Mask(String s) {
+        long mask = 0;
+        long valmask = 0;
+        long val = 0;
+        int valmaskmin = Integer.MAX_VALUE;
+        for(int i=0; i<s.length(); i++) {
+            char c = s.charAt(s.length()-1-i);
+            switch(c) {
+                case '.': break;
+                case '0': mask |= (1<<i); val |= (0<<i); break;
+                case '1': mask |= (1<<i); val |= (1<<i); break;
+                case 'v': valmask |= (1<<i); valmaskmin = Math.min(valmaskmin,i);            break;
+                default: throw new Error(""+c);
+            }
+        }
+        this.mask = mask;
+        this.val = val;
+        this.valmask = valmask;
+        this.valmaskmin = valmaskmin;
+    }
+
+}
\ No newline at end of file