3 from soc
.decoder
.power_fields
import BitRange
4 from operator
import (add
, sub
, mul
, truediv
, mod
, or_
, and_
, xor
, neg
, inv
)
7 def check_extsign(a
, b
):
8 if isinstance(b
, FieldSelectableInt
):
10 if isinstance(b
, int):
11 return SelectableInt(b
, a
.bits
)
14 return SelectableInt(b
.value
, a
.bits
)
17 class FieldSelectableInt
:
18 """FieldSelectableInt: allows bit-range selection onto another target
20 def __init__(self
, si
, br
):
21 self
.si
= si
# target selectable int
22 if isinstance(br
, list) or isinstance(br
, tuple):
24 for i
, v
in enumerate(br
):
27 self
.br
= br
# map of indices.
30 if isinstance(b
, SelectableInt
):
31 for i
in range(b
.bits
):
47 def __getitem__(self
, key
):
48 print ("getitem", key
, self
.br
)
49 if isinstance(key
, SelectableInt
):
51 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
54 def __setitem__(self
, key
, value
):
55 if isinstance(key
, SelectableInt
):
57 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
58 return self
.si
.__setitem
__(key
, value
)
61 return self
._op
1(negate
)
65 return self
._op
(add
, b
)
67 return self
._op
(sub
, b
)
69 return self
._op
(mul
, b
)
71 return self
._op
(truediv
, b
)
73 return self
._op
(mod
, b
)
75 return self
._op
(and_
, b
)
77 return self
._op
(or_
, b
)
79 return self
._op
(xor
, b
)
82 print ("get_range", self
.si
)
83 vi
= SelectableInt(0, len(self
.br
))
84 for k
, v
in self
.br
.items():
85 print ("get_range", k
, v
, self
.si
[v
])
87 print ("get_range", vi
)
92 for i
, v
in fi
.br
.items():
97 return "FieldSelectableInt(si=%s, br=%s)" % (self
.si
, self
.br
)
100 class FieldSelectableIntTestCase(unittest
.TestCase
):
101 def test_arith(self
):
102 a
= SelectableInt(0b10101, 5)
103 b
= SelectableInt(0b011, 3)
108 fs
= FieldSelectableInt(a
, br
)
111 #self.assertEqual(c.value, a.value + b.value)
115 def __init__(self
, value
, bits
):
116 mask
= (1 << bits
) - 1
117 self
.value
= value
& mask
124 def __add__(self
, b
):
125 if isinstance(b
, int):
126 b
= SelectableInt(b
, self
.bits
)
127 b
= check_extsign(self
, b
)
128 assert b
.bits
== self
.bits
129 return SelectableInt(self
.value
+ b
.value
, self
.bits
)
131 def __sub__(self
, b
):
132 if isinstance(b
, int):
133 b
= SelectableInt(b
, self
.bits
)
134 b
= check_extsign(self
, b
)
135 assert b
.bits
== self
.bits
136 return SelectableInt(self
.value
- b
.value
, self
.bits
)
138 def __mul__(self
, b
):
139 b
= check_extsign(self
, b
)
140 assert b
.bits
== self
.bits
141 return SelectableInt(self
.value
* b
.value
, self
.bits
)
143 def __div__(self
, b
):
144 b
= check_extsign(self
, b
)
145 assert b
.bits
== self
.bits
146 return SelectableInt(self
.value
/ b
.value
, self
.bits
)
148 def __mod__(self
, b
):
149 b
= check_extsign(self
, b
)
150 assert b
.bits
== self
.bits
151 return SelectableInt(self
.value
% b
.value
, self
.bits
)
154 b
= check_extsign(self
, b
)
155 assert b
.bits
== self
.bits
156 return SelectableInt(self
.value | b
.value
, self
.bits
)
158 def __and__(self
, b
):
159 print ("__and__", self
, b
)
160 b
= check_extsign(self
, b
)
161 assert b
.bits
== self
.bits
162 return SelectableInt(self
.value
& b
.value
, self
.bits
)
164 def __xor__(self
, b
):
165 b
= check_extsign(self
, b
)
166 assert b
.bits
== self
.bits
167 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
169 def __invert__(self
):
170 return SelectableInt(~self
.value
, self
.bits
)
173 return SelectableInt(~self
.value
+ 1, self
.bits
)
175 def __getitem__(self
, key
):
176 if isinstance(key
, int):
177 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
179 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
180 # MSB is indexed **LOWEST** (sigh)
181 key
= self
.bits
- (key
+ 1)
183 value
= (self
.value
>> key
) & 1
184 return SelectableInt(value
, 1)
185 elif isinstance(key
, slice):
186 assert key
.step
is None or key
.step
== 1
187 assert key
.start
< key
.stop
188 assert key
.start
>= 0
189 assert key
.stop
<= self
.bits
191 stop
= self
.bits
- key
.start
192 start
= self
.bits
- key
.stop
195 #print ("__getitem__ slice num bits", bits)
196 mask
= (1 << bits
) - 1
197 value
= (self
.value
>> start
) & mask
198 return SelectableInt(value
, bits
)
200 def __setitem__(self
, key
, value
):
201 if isinstance(key
, int):
202 assert key
< self
.bits
204 key
= self
.bits
- (key
+ 1)
205 if isinstance(value
, SelectableInt
):
206 assert value
.bits
== 1
211 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
212 elif isinstance(key
, slice):
213 assert key
.step
is None or key
.step
== 1
214 assert key
.start
< key
.stop
215 assert key
.start
>= 0
216 assert key
.stop
<= self
.bits
218 stop
= self
.bits
- key
.start
219 start
= self
.bits
- key
.stop
222 #print ("__setitem__ slice num bits", bits)
223 if isinstance(value
, SelectableInt
):
224 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
226 mask
= ((1 << bits
) - 1) << start
227 value
= value
<< start
228 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
230 def __ge__(self
, other
):
231 if isinstance(other
, FieldSelectableInt
):
232 other
= other
.get_range()
233 if isinstance(other
, SelectableInt
):
234 other
= check_extsign(self
, other
)
235 assert other
.bits
== self
.bits
237 if isinstance(other
, int):
238 return other
>= self
.value
241 def __le__(self
, other
):
242 if isinstance(other
, FieldSelectableInt
):
243 other
= other
.get_range()
244 if isinstance(other
, SelectableInt
):
245 other
= check_extsign(self
, other
)
246 assert other
.bits
== self
.bits
248 if isinstance(other
, int):
249 return onebit(other
<= self
.value
)
252 def __gt__(self
, other
):
253 if isinstance(other
, FieldSelectableInt
):
254 other
= other
.get_range()
255 if isinstance(other
, SelectableInt
):
256 other
= check_extsign(self
, other
)
257 assert other
.bits
== self
.bits
259 if isinstance(other
, int):
260 return onebit(other
> self
.value
)
263 def __lt__(self
, other
):
264 if isinstance(other
, FieldSelectableInt
):
265 other
= other
.get_range()
266 if isinstance(other
, SelectableInt
):
267 other
= check_extsign(self
, other
)
268 assert other
.bits
== self
.bits
270 if isinstance(other
, int):
271 return onebit(other
< self
.value
)
274 def __eq__(self
, other
):
275 print ("__eq__", self
, other
)
276 if isinstance(other
, FieldSelectableInt
):
277 other
= other
.get_range()
278 if isinstance(other
, SelectableInt
):
279 other
= check_extsign(self
, other
)
280 assert other
.bits
== self
.bits
282 if isinstance(other
, int):
283 return onebit(other
== self
.value
)
286 def narrow(self
, bits
):
287 assert bits
<= self
.bits
288 return SelectableInt(self
.value
, bits
)
291 return self
.value
!= 0
294 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
301 return SelectableInt(1 if bit
else 0, 1)
303 def selectltu(lhs
, rhs
):
304 """ less-than (unsigned)
306 if isinstance(rhs
, SelectableInt
):
308 return onebit(lhs
.value
< rhs
)
310 def selectgtu(lhs
, rhs
):
311 """ greater-than (unsigned)
313 if isinstance(rhs
, SelectableInt
):
315 return onebit(lhs
.value
> rhs
)
318 # XXX this probably isn't needed...
319 def selectassign(lhs
, idx
, rhs
):
320 if isinstance(idx
, tuple):
325 lower
, upper
, step
= idx
326 toidx
= range(lower
, upper
, step
)
327 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
331 for t
, f
in zip(toidx
, fromidx
):
335 def selectconcat(*args
, repeat
=1):
336 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
337 args
= [SelectableInt(args
[0], 1)]
338 if repeat
!= 1: # multiplies the incoming arguments
340 for i
in range(repeat
):
345 if isinstance(i
, FieldSelectableInt
):
347 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
349 res
.value
= (res
.value
<< i
.bits
) | i
.value
350 print ("concat", repeat
, res
)
354 class SelectableIntTestCase(unittest
.TestCase
):
355 def test_arith(self
):
356 a
= SelectableInt(5, 8)
357 b
= SelectableInt(9, 8)
362 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
363 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
364 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
365 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
366 self
.assertEqual(c
.bits
, a
.bits
)
367 self
.assertEqual(d
.bits
, a
.bits
)
368 self
.assertEqual(e
.bits
, a
.bits
)
370 def test_logic(self
):
371 a
= SelectableInt(0x0F, 8)
372 b
= SelectableInt(0xA5, 8)
377 self
.assertEqual(c
.value
, a
.value
& b
.value
)
378 self
.assertEqual(d
.value
, a
.value | b
.value
)
379 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
380 self
.assertEqual(f
.value
, 0xF0)
383 a
= SelectableInt(0xa2, 8)
384 # These should be big endian
385 self
.assertEqual(a
[7], 0)
386 self
.assertEqual(a
[0:4], 10)
387 self
.assertEqual(a
[4:8], 2)
390 a
= SelectableInt(0x5, 8)
391 a
[7] = SelectableInt(0, 1)
392 self
.assertEqual(a
, 4)
394 self
.assertEqual(a
, 9)
396 self
.assertEqual(a
, 0x39)
398 self
.assertEqual(a
, 0x99)
400 def test_concat(self
):
401 a
= SelectableInt(0x1, 1)
402 c
= selectconcat(a
, repeat
=8)
403 self
.assertEqual(c
, 0xff)
404 self
.assertEqual(c
.bits
, 8)
405 a
= SelectableInt(0x0, 1)
406 c
= selectconcat(a
, repeat
=8)
407 self
.assertEqual(c
, 0x00)
408 self
.assertEqual(c
.bits
, 8)
411 for i
in range(65536):
412 a
= SelectableInt(i
, 16)
414 self
.assertEqual(a
, b
)
416 if __name__
== "__main__":