correct encoding of Marina predicate bits
[fleet.git] / src / edu / berkeley / fleet / two / FleetTwoFleet.java
index c6f90bc..fea301d 100644 (file)
@@ -10,7 +10,10 @@ import static edu.berkeley.fleet.api.Predicate.*;
 /** common subclass for the "FleetTwo" generation of processors, all 37-bit wide, with AM33 encoding */
 public abstract class FleetTwoFleet extends Fleet {
 
+    private final boolean hack = "true".equals(System.getProperty("inverted-dc-bit-hack", "false"));
+
     public final Mask PACKET_TOKEN;
+    public final Mask PACKET_IS_TOKEN;
     public final Mask PACKET_DATA;
     public final Mask PACKET_SIGNAL;
     public final Mask PACKET_DEST;
@@ -22,7 +25,6 @@ public abstract class FleetTwoFleet extends Fleet {
     public final Mask DISPATCH_PATH;
     public final Mask DISPATCH_INSTR;
     public final Mask NOT_INTERRUPTIBLE;
-    public final Mask OS;
     public final Mask P;
     public final Mask P_NOT_A;
     public final Mask P_A;
@@ -36,6 +38,8 @@ public abstract class FleetTwoFleet extends Fleet {
     public final Mask SHIFT;
 
     public final Mask TAIL;
+    public final Mask HEAD;
+    public final Mask ABORT;
 
     public final Mask MOVE;
     public final Mask TI;
@@ -72,13 +76,14 @@ public abstract class FleetTwoFleet extends Fleet {
     public final int  WIDTH_WORD;
     public final int  WIDTH_PACKET;
 
-    public final long DataLatch_WIDTH;
+    public final int DataLatch_WIDTH;
     private final long mask;
 
     public FleetTwoFleet() { this(false); }
 
     public FleetTwoFleet(boolean useInternalEncoding) {
         PACKET_TOKEN               = new Mask("v.................................................");
+        PACKET_IS_TOKEN            = new Mask("1.................................................");
         PACKET_DATA                = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
         PACKET_SIGNAL              = new Mask("......................................v...........");
         PACKET_DEST                = new Mask(".......................................vvvvvvvvvvv");
@@ -92,47 +97,50 @@ public abstract class FleetTwoFleet extends Fleet {
 
             DISPATCH_PATH              = new Mask("v....................................");
             DISPATCH_INSTR             = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
-            NOT_INTERRUPTIBLE          = new Mask(".................1...................");
-            OS                         = new Mask(".......1.............................");
             P                          = new Mask(".vvvvvv..............................");
-            P_NOT_A                    = new Mask(".011110..............................");
-            P_A                        = new Mask(".011101..............................");
-            P_NOT_B                    = new Mask(".011011..............................");
-            P_B                        = new Mask(".010111..............................");
-            P_UNUSED                   = new Mask(".000000..............................");
-            P_OLC_ZERO                 = new Mask(".101111..............................");
-            P_OLC_NONZERO              = new Mask(".011111..............................");
-            P_ALWAYS                   = new Mask(".111111..............................");
-
-            SHIFT                      = new Mask("..........101111.1vvvvvvvvvvvvvvvvvvv");
-
-            TAIL                       = new Mask("................1....................");
-
-            MOVE                       = new Mask("..........110111.....................");
-            TI                         = new Mask("..........110111..1..................");
-            DI                         = new Mask("..........110111...1.................");
-            FLUSH                      = new Mask(".........1110111.....................");
-            DC                         = new Mask("..........110111...11................");
-            DO                         = new Mask("..........110111.....1...............");
-            TO                         = new Mask("..........110111......1..............");
-            PATH_IMMEDIATE             = new Mask("..........110111.......0vvvvvvvvvvvvv");
-            PATH_DATA                  = new Mask("..........110111.......11............");
-            PATH_NOCHANGE              = new Mask("..........110111.......10............");
-
-            SET_OLC_FROM_IMMEDIATE     = new Mask("..........111101.0.............vvvvvv");
-            SET_OLC_FROM_DATA_LATCH    = new Mask("..........111101.1...................");
-            SET_OLC_FROM_OLC_MINUS_ONE = new Mask("..........111011.....................");
-
-            SET_ILC_FROM_IMMEDIATE     = new Mask("..........011111.0...........0.vvvvvv");
-            SET_ILC_FROM_INFINITY      = new Mask("..........011111.............1.......");
-            SET_ILC_FROM_DATA_LATCH    = new Mask("..........011111.1...................");
-
-            SET_IMMEDIATE              = new Mask("..........101111.0.....vvvvvvvvvvvvvv");
-            SET_IMMEDIATE_EXTEND       = new Mask("..........101111.0....v..............");
-
-            SET_FLAGS                  = new Mask("..........111110.....................");
-            SET_FLAGS_A                = new Mask("..........111110...............vvvvvv");
-            SET_FLAGS_B                = new Mask("..........111110.........vvvvvv......");
+            P_NOT_A                    = new Mask(".100001..............................");
+            P_A                        = new Mask(".100010..............................");
+            P_NOT_B                    = new Mask(".100100..............................");
+            P_B                        = new Mask(".101000..............................");
+            P_UNUSED                   = new Mask(".111111..............................");
+            P_OLC_ZERO                 = new Mask(".010000..............................");
+            P_OLC_NONZERO              = new Mask(".100000..............................");
+            P_ALWAYS                   = new Mask(".000000..............................");
+
+
+            // use these when Marina gets updated to 07-Jan-2009 version of internal encoding
+            HEAD                       = new Mask(".......1.............................");
+            ABORT                      = new Mask("........1............................");
+            TAIL                       = new Mask(".........1...........................");
+
+            // actually "is interruptible"
+            NOT_INTERRUPTIBLE          = new Mask("...........1....1....................");
+
+            SHIFT                      = new Mask("..........1......1vvvvvvvvvvvvvvvvvvv");
+            SET_IMMEDIATE              = new Mask("..........1......0.....vvvvvvvvvvvvvv");
+            SET_IMMEDIATE_EXTEND       = new Mask("..........1......0....v..............");
+            MOVE                       = new Mask("............1........................");
+            TI                         = new Mask("............1.....1..................");
+            DI                         = new Mask("............1......1.................");
+            FLUSH                      = new Mask("..........1......0.....011...........");
+            DC                         = new Mask("............1.......1................");
+            DO                         = new Mask("............1........1...............");
+            TO                         = new Mask("............1.........1..............");
+            PATH_IMMEDIATE             = new Mask("............1..........1vvvvvvvvvvvvv");
+            PATH_DATA                  = new Mask("............1..........00............");
+            PATH_NOCHANGE              = new Mask("............1..........01............");
+
+            SET_OLC_FROM_IMMEDIATE     = new Mask("..............1.10.............vvvvvv");
+            SET_OLC_FROM_DATA_LATCH    = new Mask("...............1.11..................");
+            SET_OLC_FROM_OLC_MINUS_ONE = new Mask("...............1.10..................");
+
+            SET_ILC_FROM_IMMEDIATE     = new Mask("...............1.00..........0.vvvvvv");
+            SET_ILC_FROM_INFINITY      = new Mask("...............1.0...........1.......");
+            SET_ILC_FROM_DATA_LATCH    = new Mask("...............1.01..................");
+
+            SET_FLAGS                  = new Mask("...............1.....................");
+            SET_FLAGS_A                = new Mask("...............1...............vvvvvv");
+            SET_FLAGS_B                = new Mask("...............1.........vvvvvv......");
 
             SET_FLAGS_VALUE_A          = new Mask(".....1");
             SET_FLAGS_VALUE_NOT_A      = new Mask("....1.");
@@ -145,7 +153,6 @@ public abstract class FleetTwoFleet extends Fleet {
             DISPATCH_PATH              = new Mask("vvvvvvvvvvv..........................");
             DISPATCH_INSTR             = new Mask("...........vvvvvvvvvvvvvvvvvvvvvvvvvv");
             NOT_INTERRUPTIBLE          = new Mask("...........1.........................");
-            OS                         = new Mask("............1........................");
             P                          = new Mask(".............vvv.....................");
             P_NOT_A                    = new Mask(".............000.....................");
             P_A                        = new Mask(".............001.....................");
@@ -158,7 +165,10 @@ public abstract class FleetTwoFleet extends Fleet {
 
             SHIFT                      = new Mask("................00vvvvvvvvvvvvvvvvvvv");
 
-            TAIL                       = new Mask("................11...................");
+            ABORT                      = new Mask("................1100.................");  // note: has a predicate!
+
+            HEAD                       = new Mask("................1110.................");
+            TAIL                       = new Mask("................1111.................");
 
             MOVE                       = new Mask("................01...................");
             TI                         = new Mask("................011..................");
@@ -208,6 +218,13 @@ public abstract class FleetTwoFleet extends Fleet {
         return false;
     }
 
+    public boolean isSmallEnoughToFit(BitVector immediate) {
+        boolean b = immediate.get((int)DataLatch_WIDTH);
+        for(int i=DataLatch_WIDTH+1; i<immediate.length(); i++)
+            if (immediate.get(i) != b) return false;
+        return true;
+    }
+
     public int getWordWidth() { return 37; }
 
     //////////////////////////////////////////////////////////////////////////////
@@ -225,7 +242,7 @@ public abstract class FleetTwoFleet extends Fleet {
                 for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {
                     for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) {
                         Path p = (Path)source.getPath(d, signal);
-                        if (getDestAddr(p).equals(dest)) return p;
+                        if (getDestAddr(p).equalsZeroExtended(dest)) return p;
                     }
                 }
             }
@@ -248,39 +265,41 @@ public abstract class FleetTwoFleet extends Fleet {
         Dock dock = getPathByAddr(dispatchFrom, DISPATCH_PATH.getvalAsBitVector(inst)).getDestination().getDock();
 
         if (TAIL.get(inst))   return new Tail(dock);
+        if (HEAD.get(inst))   return new Head(dock);
 
         Predicate predicate = Default;
-        if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
+        if (P_ALWAYS.get(inst)) predicate = IgnoreFlagD;
         if (P_OLC_NONZERO.get(inst))    predicate = Default;
-        if (P_OLC_ZERO.get(inst))    predicate = OLCZero;
+        if (P_OLC_ZERO.get(inst))    predicate = FlagD;
         if (P_A.get(inst))      predicate = FlagA;
         if (P_B.get(inst))      predicate = FlagB;
         if (P_NOT_A.get(inst))  predicate = NotFlagA;
         if (P_NOT_B.get(inst))  predicate = NotFlagB;
 
-        boolean looping = !OS.get(inst);
         if (FLUSH.get(inst))
-            return new Flush(dock, looping, predicate);
-        if (SHIFT.get(inst))                return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
+            return new Flush(dock, predicate);
+        if (ABORT.get(inst))
+            return new Abort(dock, predicate);
+        if (SHIFT.get(inst))                return new Shift(dock, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
         if (SET_IMMEDIATE.get(inst)) {
             boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
             long immediate = SET_IMMEDIATE.getval(inst);
             if (extend) immediate |= (-1L << DataLatch_WIDTH);
-            return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
+            return new Set(dock, predicate, SetDest.DataLatch, (immediate));
         }
 
         if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
-            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
+            return new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
         if (SET_OLC_FROM_IMMEDIATE.get(inst))
-            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
+            return new Set(dock, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
         if (SET_ILC_FROM_IMMEDIATE.get(inst))
-            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
+            return new Set(dock, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
         if (SET_OLC_FROM_DATA_LATCH.get(inst))
-            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
+            return new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
         if (SET_ILC_FROM_DATA_LATCH.get(inst))
-            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
+            return new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
         if (SET_ILC_FROM_INFINITY.get(inst))
-            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
+            return new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
         if (SET_FLAGS.get(inst)) {
             long flag_a = SET_FLAGS_A.getval(inst);
             long flag_b = SET_FLAGS_B.getval(inst);
@@ -298,17 +317,16 @@ public abstract class FleetTwoFleet extends Fleet {
             if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
             if (SET_FLAGS_VALUE_C    .get(flag_b)) bp = bp.add(FlagC    );
             if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
-            return new Set(dock, looping, predicate, ap, bp);
+            return new Set(dock,  predicate, ap, bp);
         }
         if (MOVE.get(inst))
             return new Move(dock,
-                            looping,
                             predicate,
                             !NOT_INTERRUPTIBLE.get(inst),
-                            getPathByAddr(dock, PATH_IMMEDIATE.getvalAsBitVector(inst)),
+                            PATH_DATA.get(inst)?null:getPathByAddr(dock, PATH_IMMEDIATE.getvalAsBitVector(inst)),
                             TI.get(inst),
                             DI.get(inst),
-                            DC.get(inst),
+                            hack?(!DC.get(inst)):DC.get(inst),
                             PATH_DATA.get(inst),
                             DO.get(inst),
                             TO.get(inst)
@@ -330,10 +348,9 @@ public abstract class FleetTwoFleet extends Fleet {
 
         boolean dl = false;
         Instruction pi = d;
-        if (!pi.looping) instr = OS.set(instr);
         switch(pi.predicate) {
-            case IgnoreOLC:         instr = P_ALWAYS.set(instr); break;
-            case OLCZero:         instr = P_OLC_ZERO.set(instr); break;
+            case IgnoreFlagD:         instr = P_ALWAYS.set(instr); break;
+            case FlagD:         instr = P_OLC_ZERO.set(instr); break;
             case Default: instr = P_OLC_NONZERO.set(instr); break;
             case FlagA:      instr = P_A.set(instr);      break;
             case FlagB:      instr = P_B.set(instr);      break;
@@ -345,6 +362,9 @@ public abstract class FleetTwoFleet extends Fleet {
         if (d instanceof Tail) {
             instr = TAIL.set(instr);
 
+        } else if (d instanceof Head) {
+            instr = HEAD.set(instr);
+
         } else if (d instanceof Shift) {
             Shift shift = (Shift)d;
             instr = SHIFT.set(instr);
@@ -353,6 +373,9 @@ public abstract class FleetTwoFleet extends Fleet {
         } else if (d instanceof Flush) {
             instr = FLUSH.set(instr);
 
+        } else if (d instanceof Abort) {
+            instr = ABORT.set(instr);
+
         } else if (d instanceof Set) {
             Set s = (Set)d;
             switch(s.dest) {
@@ -401,21 +424,26 @@ public abstract class FleetTwoFleet extends Fleet {
             instr  = MOVE.set(instr);
             if (inst.tokenIn)                    instr = TI.set(instr);
             if (inst.dataIn)                     instr = DI.set(instr);
-            if (inst.latchData)                  instr = DC.set(instr);
+            if (hack) {
+                if (!inst.latchData)                 instr = DC.set(instr);
+                System.err.println("WARNING: employing inverted-Dc-bit hack -- DO NOT FORGET TO DISABLE THIS WHEN THE NETLIST GETS UPDATED!");
+            } else {
+                if (inst.latchData)                  instr = DC.set(instr);
+            }
             if (inst.dataOut)                    instr = DO.set(instr);
             if (inst.tokenOut)                   instr = TO.set(instr);
             if (!inst.interruptible)             instr = NOT_INTERRUPTIBLE.set(instr);
 
             if (inst.latchPath)                  instr = PATH_DATA.set(instr);
-            else {
+            else if (inst.path!=null) {
                 instr  = PATH_IMMEDIATE.set(instr);
-                if (inst.path != null) {
-                    BitVector bv  = getDestAddr(inst.path);
-                    BitVector bv2 = new BitVector(PATH_IMMEDIATE.valmaskwidth);
-                    for(int i=0; i<Math.min(bv.length(),bv2.length()); i++)
-                        bv2.set(i, bv.get(i));
-                    instr  = PATH_IMMEDIATE.setval(instr, bv2);
-                }
+                BitVector bv  = getDestAddr(inst.path);
+                BitVector bv2 = new BitVector(PATH_IMMEDIATE.valmaskwidth);
+                for(int i=0; i<Math.min(bv.length(),bv2.length()); i++)
+                    bv2.set(i, bv.get(i));
+                instr  = PATH_IMMEDIATE.setval(instr, bv2);
+            } else {
+                instr  = PATH_NOCHANGE.set(instr);
             }
 
         } else {