add Mask.setval(BitVector,long)
[fleet.git] / src / edu / berkeley / fleet / util / Mask.java
index f75c4be..19f1fb0 100644 (file)
@@ -5,22 +5,73 @@ import java.io.*;
 
 public class Mask {
 
+    private final String str;
+
     public final long mask;
     public final long val;
     public final long valmask;
     public final int valmaskmin;
-
+    public final int valmaskmax;
+    public final int valmaskwidth;
+    public final int allmax;
+    public final int width;
 
     public String verilog(String var) {
-        return "(("+var+" & "+mask+")=="+val+")";
-    }
-    public String verilogVal(String var) {
-        return "(("+var+" & "+valmask+") >> "+valmaskmin+")";
+        // FIXME: throw an exception if this is called when no 1-bits or 0-bits were specified (ie only v-bits)
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("{");
+        boolean first = true;
+        int count = 0;
+        for(int i=63; i>=0; i--) {
+            if ((mask & (1L << i)) == 0) continue;
+            if (!first) sb.append(",");
+            first = false;
+            sb.append(var+"["+i+"]");
+            count++;
+        }
+        sb.append("}=="+count+"'b");
+        for(int i=63; i>=0; i--) {
+            if ((mask & (1L << i)) == 0) continue;
+            sb.append( (val & (1L << i))==0 ? "0" : "1" );
+        }
+        return "("+sb.toString()+")";
+        //return "(("+var+" & "+allmax+"'b"+Long.toString(mask,2)+")=="+allmax+"'b"+Long.toString(val,2)+")";
     }
 
     public long getval(long in) {
         return (in & valmask) >>> valmaskmin;
     }
+    public BitVector getvalAsBitVector(long in) {
+        // FIXME
+        return new BitVector(getWidth()).set(getval(in));
+    }
+    public BitVector getvalAsBitVector(BitVector in) {
+        // FIXME
+        return new BitVector(getWidth()).set(getval(in.toLong()));
+    }
+    public long getval(BitVector targ) {
+        long in = 0;
+        for(int i=0; i<targ.length(); i++)
+            if (targ.get(i))
+                in |= (1L << i);
+        return (in & valmask) >>> valmaskmin;
+    }
+    public long setval(long in, BitVector targ) {
+        long ret = in;
+        if (targ.length() != (1+valmaskmax-valmaskmin))
+            throw new RuntimeException("size mismatch trying to do "+this+".setval("+targ+")");
+        for(int i=valmaskmin; i<=valmaskmax; i++)
+            if (targ.get(i-valmaskmin))
+                ret |= (1L << i);
+            else
+                ret &= ~(1L << i);
+        return ret;
+    }
+    public void setval(BitVector targ, long val) {
+        for(int i=valmaskmin; i<=valmaskmax; i++)
+            targ.set(i, ((1L<<(i-valmaskmin)) & val)!=0);
+    }
     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);
@@ -32,25 +83,53 @@ public class Mask {
         return (in & mask) == val;
     }
 
+    public String toString() {
+        return str;
+    }
+
+    public int getWidth() {
+        int ret = 0;
+        long m = 1;
+        for(int i=0; i<64; i++) {
+            if ((valmask & m)!=0) ret++;
+            m = m << 1;
+        }
+        return ret;
+    }
+
     public Mask(String s) {
+        this.str = s;
         long mask = 0;
         long valmask = 0;
         long val = 0;
         int valmaskmin = Integer.MAX_VALUE;
+        int valmaskmax = 0;
+        int allmax = 0;
+        this.width = s.length();
         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;
+                case '0': mask |= (1L<<i); val |= (0L<<i); break;
+                case '1': mask |= (1L<<i); val |= (1L<<i); break;
+                case 'v': valmask |= (1L<<i); valmaskmin = Math.min(valmaskmin,i); valmaskmax = Math.max(valmaskmax,i); break;
                 default: throw new Error(""+c);
             }
+            if (c!='.') allmax = Math.max(allmax,i);
         }
         this.mask = mask;
         this.val = val;
         this.valmask = valmask;
         this.valmaskmin = valmaskmin;
+        this.valmaskmax = valmaskmax;
+        this.allmax = allmax+1;
+        this.valmaskwidth = 1 + valmaskmax - valmaskmin;
+    }
+
+    public static long signExtend(long input, int wordWidth) {
+        if ((input & (1L << (wordWidth-1)))!=0)
+            input |= (-1L) << wordWidth;
+        return input;
     }
 
-}
\ No newline at end of file
+}