4 def check_extsign(a
, b
):
7 return SelectableInt(b
.value
, a
.bits
)
11 def __init__(self
, value
, bits
):
12 mask
= (1 << bits
) - 1
13 self
.value
= value
& mask
17 if isinstance(b
, int):
18 b
= SelectableInt(b
, self
.bits
)
19 b
= check_extsign(self
, b
)
20 assert b
.bits
== self
.bits
21 return SelectableInt(self
.value
+ b
.value
, self
.bits
)
24 if isinstance(b
, int):
25 b
= SelectableInt(b
, self
.bits
)
26 b
= check_extsign(self
, b
)
27 assert b
.bits
== self
.bits
28 return SelectableInt(self
.value
- b
.value
, self
.bits
)
31 b
= check_extsign(self
, b
)
32 assert b
.bits
== self
.bits
33 return SelectableInt(self
.value
* b
.value
, self
.bits
)
36 b
= check_extsign(self
, b
)
37 assert b
.bits
== self
.bits
38 return SelectableInt(self
.value
/ b
.value
, self
.bits
)
41 b
= check_extsign(self
, b
)
42 assert b
.bits
== self
.bits
43 return SelectableInt(self
.value
% b
.value
, self
.bits
)
46 b
= check_extsign(self
, b
)
47 assert b
.bits
== self
.bits
48 return SelectableInt(self
.value | b
.value
, self
.bits
)
51 b
= check_extsign(self
, b
)
52 assert b
.bits
== self
.bits
53 return SelectableInt(self
.value
& b
.value
, self
.bits
)
56 b
= check_extsign(self
, b
)
57 assert b
.bits
== self
.bits
58 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
61 return SelectableInt(~self
.value
, self
.bits
)
64 return SelectableInt(~self
.value
+ 1, self
.bits
)
66 def __getitem__(self
, key
):
67 if isinstance(key
, int):
68 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
70 key
= self
.bits
- (key
+ 1)
72 value
= (self
.value
>> key
) & 1
73 return SelectableInt(value
, 1)
74 elif isinstance(key
, slice):
75 assert key
.step
is None or key
.step
== 1
76 assert key
.start
< key
.stop
78 assert key
.stop
<= self
.bits
80 stop
= self
.bits
- key
.start
81 start
= self
.bits
- key
.stop
83 bits
= stop
- start
+ 1
84 mask
= (1 << bits
) - 1
85 value
= (self
.value
>> start
) & mask
86 return SelectableInt(value
, bits
)
88 def __setitem__(self
, key
, value
):
89 if isinstance(key
, int):
90 assert key
< self
.bits
92 key
= self
.bits
- (key
+ 1)
93 if isinstance(value
, SelectableInt
):
94 assert value
.bits
== 1
99 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
100 elif isinstance(key
, slice):
101 assert key
.step
is None or key
.step
== 1
102 assert key
.start
< key
.stop
103 assert key
.start
>= 0
104 assert key
.stop
<= self
.bits
106 stop
= self
.bits
- key
.start
107 start
= self
.bits
- key
.stop
109 bits
= stop
- start
+ 1
110 if isinstance(value
, SelectableInt
):
111 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
113 mask
= ((1 << bits
) - 1) << start
114 value
= value
<< start
115 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
117 def __ge__(self
, other
):
118 if isinstance(other
, SelectableInt
):
119 other
= check_extsign(self
, other
)
120 assert other
.bits
== self
.bits
122 if isinstance(other
, int):
123 return other
>= self
.value
126 def __le__(self
, other
):
127 if isinstance(other
, SelectableInt
):
128 other
= check_extsign(self
, other
)
129 assert other
.bits
== self
.bits
131 if isinstance(other
, int):
132 return onebit(other
<= self
.value
)
135 def __gt__(self
, other
):
136 if isinstance(other
, SelectableInt
):
137 other
= check_extsign(self
, other
)
138 assert other
.bits
== self
.bits
140 if isinstance(other
, int):
141 return onebit(other
> self
.value
)
144 def __lt__(self
, other
):
145 if isinstance(other
, SelectableInt
):
146 other
= check_extsign(self
, other
)
147 assert other
.bits
== self
.bits
149 if isinstance(other
, int):
150 return onebit(other
< self
.value
)
153 def __eq__(self
, other
):
154 if isinstance(other
, SelectableInt
):
155 other
= check_extsign(self
, other
)
156 assert other
.bits
== self
.bits
158 if isinstance(other
, int):
159 return onebit(other
== self
.value
)
163 return self
.value
!= 0
166 return "SelectableInt(value={:x}, bits={})".format(self
.value
,
170 return SelectableInt(1 if bit
else 0, 1)
172 def selectltu(lhs
, rhs
):
173 """ less-than (unsigned)
175 if isinstance(rhs
, SelectableInt
):
177 return onebit(lhs
.value
< rhs
)
179 def selectgtu(lhs
, rhs
):
180 """ greater-than (unsigned)
182 if isinstance(rhs
, SelectableInt
):
184 return onebit(lhs
.value
> rhs
)
187 # XXX this probably isn't needed...
188 def selectassign(lhs
, idx
, rhs
):
189 if isinstance(idx
, tuple):
194 lower
, upper
, step
= idx
195 toidx
= range(lower
, upper
, step
)
196 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
200 for t
, f
in zip(toidx
, fromidx
):
204 def selectconcat(*args
, repeat
=1):
205 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
206 args
= [SelectableInt(args
[0], 1)]
207 if repeat
!= 1: # multiplies the incoming arguments
209 for i
in range(repeat
):
214 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
216 res
.value
= (res
.value
<< i
.bits
) | i
.value
217 print ("concat", repeat
, res
)
221 class SelectableIntTestCase(unittest
.TestCase
):
222 def test_arith(self
):
223 a
= SelectableInt(5, 8)
224 b
= SelectableInt(9, 8)
229 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
230 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
231 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
232 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
233 self
.assertEqual(c
.bits
, a
.bits
)
234 self
.assertEqual(d
.bits
, a
.bits
)
235 self
.assertEqual(e
.bits
, a
.bits
)
237 def test_logic(self
):
238 a
= SelectableInt(0x0F, 8)
239 b
= SelectableInt(0xA5, 8)
244 self
.assertEqual(c
.value
, a
.value
& b
.value
)
245 self
.assertEqual(d
.value
, a
.value | b
.value
)
246 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
247 self
.assertEqual(f
.value
, 0xF0)
250 a
= SelectableInt(0xa2, 8)
251 # These should be big endian
252 self
.assertEqual(a
[7], 0)
253 self
.assertEqual(a
[0:4], 10)
254 self
.assertEqual(a
[4:8], 2)
257 a
= SelectableInt(0x5, 8)
258 a
[7] = SelectableInt(0, 1)
259 self
.assertEqual(a
, 4)
261 self
.assertEqual(a
, 9)
263 self
.assertEqual(a
, 0x39)
265 self
.assertEqual(a
, 0x199)
267 def test_concat(self
):
268 a
= SelectableInt(0x1, 1)
269 c
= selectconcat(a
, repeat
=8)
270 self
.assertEqual(c
, 0xff)
271 self
.assertEqual(c
.bits
, 8)
272 a
= SelectableInt(0x0, 1)
273 c
= selectconcat(a
, repeat
=8)
274 self
.assertEqual(c
, 0x00)
275 self
.assertEqual(c
.bits
, 8)
278 if __name__
== "__main__":