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);
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
+}