--- /dev/null
+package edu.berkeley.fleet.util;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.*;
+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) {
+ // 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 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 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 |= (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;
+ }
+
+}