add Mask.setval(BitVector,long)
[fleet.git] / src / edu / berkeley / fleet / util / Mask.java
1 package edu.berkeley.fleet.util;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.*;
4 import java.io.*;
5
6 public class Mask {
7
8     private final String str;
9
10     public final long mask;
11     public final long val;
12     public final long valmask;
13     public final int valmaskmin;
14     public final int valmaskmax;
15     public final int valmaskwidth;
16     public final int allmax;
17     public final int width;
18
19     public String verilog(String var) {
20         // FIXME: throw an exception if this is called when no 1-bits or 0-bits were specified (ie only v-bits)
21
22         StringBuffer sb = new StringBuffer();
23         sb.append("{");
24         boolean first = true;
25         int count = 0;
26         for(int i=63; i>=0; i--) {
27             if ((mask & (1L << i)) == 0) continue;
28             if (!first) sb.append(",");
29             first = false;
30             sb.append(var+"["+i+"]");
31             count++;
32         }
33         sb.append("}=="+count+"'b");
34         for(int i=63; i>=0; i--) {
35             if ((mask & (1L << i)) == 0) continue;
36             sb.append( (val & (1L << i))==0 ? "0" : "1" );
37         }
38         return "("+sb.toString()+")";
39         //return "(("+var+" & "+allmax+"'b"+Long.toString(mask,2)+")=="+allmax+"'b"+Long.toString(val,2)+")";
40     }
41
42     public long getval(long in) {
43         return (in & valmask) >>> valmaskmin;
44     }
45     public BitVector getvalAsBitVector(long in) {
46         // FIXME
47         return new BitVector(getWidth()).set(getval(in));
48     }
49     public BitVector getvalAsBitVector(BitVector in) {
50         // FIXME
51         return new BitVector(getWidth()).set(getval(in.toLong()));
52     }
53     public long getval(BitVector targ) {
54         long in = 0;
55         for(int i=0; i<targ.length(); i++)
56             if (targ.get(i))
57                 in |= (1L << i);
58         return (in & valmask) >>> valmaskmin;
59     }
60     public long setval(long in, BitVector targ) {
61         long ret = in;
62         if (targ.length() != (1+valmaskmax-valmaskmin))
63             throw new RuntimeException("size mismatch trying to do "+this+".setval("+targ+")");
64         for(int i=valmaskmin; i<=valmaskmax; i++)
65             if (targ.get(i-valmaskmin))
66                 ret |= (1L << i);
67             else
68                 ret &= ~(1L << i);
69         return ret;
70     }
71     public void setval(BitVector targ, long val) {
72         for(int i=valmaskmin; i<=valmaskmax; i++)
73             targ.set(i, ((1L<<(i-valmaskmin)) & val)!=0);
74     }
75     public long setval(long in, long targ) {
76         if (((targ << valmaskmin) & ~valmask) != 0) throw new RuntimeException("setval() with argument bigger than mask field");
77         return (in & ~valmask) | ((targ << valmaskmin) & valmask);
78     }
79     public long set(long in) {
80         return (in & ~mask) | val;
81     }
82     public boolean get(long in) {
83         return (in & mask) == val;
84     }
85
86     public String toString() {
87         return str;
88     }
89
90     public int getWidth() {
91         int ret = 0;
92         long m = 1;
93         for(int i=0; i<64; i++) {
94             if ((valmask & m)!=0) ret++;
95             m = m << 1;
96         }
97         return ret;
98     }
99
100     public Mask(String s) {
101         this.str = s;
102         long mask = 0;
103         long valmask = 0;
104         long val = 0;
105         int valmaskmin = Integer.MAX_VALUE;
106         int valmaskmax = 0;
107         int allmax = 0;
108         this.width = s.length();
109         for(int i=0; i<s.length(); i++) {
110             char c = s.charAt(s.length()-1-i);
111             switch(c) {
112                 case '.': break;
113                 case '0': mask |= (1L<<i); val |= (0L<<i); break;
114                 case '1': mask |= (1L<<i); val |= (1L<<i); break;
115                 case 'v': valmask |= (1L<<i); valmaskmin = Math.min(valmaskmin,i); valmaskmax = Math.max(valmaskmax,i); break;
116                 default: throw new Error(""+c);
117             }
118             if (c!='.') allmax = Math.max(allmax,i);
119         }
120         this.mask = mask;
121         this.val = val;
122         this.valmask = valmask;
123         this.valmaskmin = valmaskmin;
124         this.valmaskmax = valmaskmax;
125         this.allmax = allmax+1;
126         this.valmaskwidth = 1 + valmaskmax - valmaskmin;
127     }
128
129     public static long signExtend(long input, int wordWidth) {
130         if ((input & (1L << (wordWidth-1)))!=0)
131             input |= (-1L) << wordWidth;
132         return input;
133     }
134
135 }