3 from soc
.decoder
.power_fields
import BitRange
4 from operator
import (add
, sub
, mul
, floordiv
, truediv
, mod
, or_
, and_
, xor
,
5 neg
, inv
, lshift
, rshift
)
8 def check_extsign(a
, b
):
9 if isinstance(b
, FieldSelectableInt
):
11 if isinstance(b
, int):
12 return SelectableInt(b
, a
.bits
)
15 return SelectableInt(b
.value
, a
.bits
)
18 class FieldSelectableInt
:
19 """FieldSelectableInt: allows bit-range selection onto another target
22 def __init__(self
, si
, br
):
23 self
.si
= si
# target selectable int
24 if isinstance(br
, list) or isinstance(br
, tuple):
26 for i
, v
in enumerate(br
):
29 self
.br
= br
# map of indices.
32 if isinstance(b
, SelectableInt
):
33 for i
in range(b
.bits
):
49 def __getitem__(self
, key
):
50 print("getitem", key
, self
.br
)
51 if isinstance(key
, SelectableInt
):
53 if isinstance(key
, int):
54 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
56 if isinstance(key
, slice):
58 return selectconcat(*[self
.si
[x
] for x
in key
])
60 def __setitem__(self
, key
, value
):
61 if isinstance(key
, SelectableInt
):
63 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
64 if isinstance(key
, int):
65 return self
.si
.__setitem
__(key
, value
)
67 if not isinstance(value
, SelectableInt
):
68 value
= SelectableInt(value
, bits
=len(key
))
69 for i
, k
in enumerate(key
):
73 return self
._op
1(negate
)
79 return self
._op
(add
, b
)
82 return self
._op
(sub
, b
)
85 return self
._op
(mul
, b
)
88 return self
._op
(truediv
, b
)
91 return self
._op
(mod
, b
)
94 return self
._op
(and_
, b
)
97 return self
._op
(or_
, b
)
100 return self
._op
(xor
, b
)
103 vi
= SelectableInt(0, len(self
.br
))
104 for k
, v
in self
.br
.items():
110 for i
, v
in fi
.br
.items():
115 return "FieldSelectableInt(si=%s, br=%s)" % (self
.si
, self
.br
)
118 class FieldSelectableIntTestCase(unittest
.TestCase
):
119 def test_arith(self
):
120 a
= SelectableInt(0b10101, 5)
121 b
= SelectableInt(0b011, 3)
126 fs
= FieldSelectableInt(a
, br
)
129 #self.assertEqual(c.value, a.value + b.value)
131 def test_select(self
):
132 a
= SelectableInt(0b00001111, 8)
138 fs
= FieldSelectableInt(a
, br
)
140 self
.assertEqual(fs
.get_range(), 0b0011)
142 def test_select_range(self
):
143 a
= SelectableInt(0b00001111, 8)
149 fs
= FieldSelectableInt(a
, br
)
151 self
.assertEqual(fs
[2:4], 0b11)
154 self
.assertEqual(fs
.get_range(), 0b1011)
158 """SelectableInt - a class that behaves exactly like python int
160 this class is designed to mirror precisely the behaviour of python int.
161 the only difference is that it must contain the context of the bitwidth
162 (number of bits) associated with that integer.
164 FieldSelectableInt can then operate on partial bits, and because there
165 is a bit width associated with SelectableInt, slices operate correctly
166 including negative start/end points.
169 def __init__(self
, value
, bits
):
170 if isinstance(value
, SelectableInt
):
172 mask
= (1 << bits
) - 1
173 self
.value
= value
& mask
180 def _op(self
, op
, b
):
181 if isinstance(b
, int):
182 b
= SelectableInt(b
, self
.bits
)
183 b
= check_extsign(self
, b
)
184 assert b
.bits
== self
.bits
185 return SelectableInt(op(self
.value
, b
.value
), self
.bits
)
187 def __add__(self
, b
):
188 return self
._op
(add
, b
)
190 def __sub__(self
, b
):
191 return self
._op
(sub
, b
)
193 def __mul__(self
, b
):
194 # different case: mul result needs to fit the total bitsize
195 if isinstance(b
, int):
196 b
= SelectableInt(b
, self
.bits
)
197 print("SelectableInt mul", hex(self
.value
), hex(b
.value
),
199 return SelectableInt(self
.value
* b
.value
, self
.bits
+ b
.bits
)
201 def __floordiv__(self
, b
):
202 return self
._op
(floordiv
, b
)
204 def __truediv__(self
, b
):
205 return self
._op
(truediv
, b
)
207 def __mod__(self
, b
):
208 return self
._op
(mod
, b
)
210 def __and__(self
, b
):
211 return self
._op
(and_
, b
)
214 return self
._op
(or_
, b
)
216 def __xor__(self
, b
):
217 return self
._op
(xor
, b
)
220 print("abs", self
.value
& (1 << (self
.bits
-1)))
221 if self
.value
& (1 << (self
.bits
-1)) != 0:
225 def __rsub__(self
, b
):
226 if isinstance(b
, int):
227 b
= SelectableInt(b
, self
.bits
)
228 b
= check_extsign(self
, b
)
229 assert b
.bits
== self
.bits
230 return SelectableInt(b
.value
- self
.value
, self
.bits
)
232 def __radd__(self
, b
):
233 if isinstance(b
, int):
234 b
= SelectableInt(b
, self
.bits
)
235 b
= check_extsign(self
, b
)
236 assert b
.bits
== self
.bits
237 return SelectableInt(b
.value
+ self
.value
, self
.bits
)
239 def __rxor__(self
, b
):
240 b
= check_extsign(self
, b
)
241 assert b
.bits
== self
.bits
242 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
244 def __invert__(self
):
245 return SelectableInt(~self
.value
, self
.bits
)
248 return SelectableInt(~self
.value
+ 1, self
.bits
)
250 def __lshift__(self
, b
):
251 b
= check_extsign(self
, b
)
252 return SelectableInt(self
.value
<< b
.value
, self
.bits
)
254 def __rshift__(self
, b
):
255 b
= check_extsign(self
, b
)
256 return SelectableInt(self
.value
>> b
.value
, self
.bits
)
258 def __getitem__(self
, key
):
259 if isinstance(key
, SelectableInt
):
261 if isinstance(key
, int):
262 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
264 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
265 # MSB is indexed **LOWEST** (sigh)
266 key
= self
.bits
- (key
+ 1)
268 value
= (self
.value
>> key
) & 1
269 return SelectableInt(value
, 1)
270 elif isinstance(key
, slice):
271 assert key
.step
is None or key
.step
== 1
272 assert key
.start
< key
.stop
273 assert key
.start
>= 0
274 assert key
.stop
<= self
.bits
276 stop
= self
.bits
- key
.start
277 start
= self
.bits
- key
.stop
280 #print ("__getitem__ slice num bits", bits)
281 mask
= (1 << bits
) - 1
282 value
= (self
.value
>> start
) & mask
283 return SelectableInt(value
, bits
)
285 def __setitem__(self
, key
, value
):
286 if isinstance(key
, SelectableInt
):
288 if isinstance(key
, int):
289 assert key
< self
.bits
291 key
= self
.bits
- (key
+ 1)
292 if isinstance(value
, SelectableInt
):
293 assert value
.bits
== 1
298 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
299 elif isinstance(key
, slice):
300 assert key
.step
is None or key
.step
== 1
301 assert key
.start
< key
.stop
302 assert key
.start
>= 0
303 assert key
.stop
<= self
.bits
305 stop
= self
.bits
- key
.start
306 start
= self
.bits
- key
.stop
309 #print ("__setitem__ slice num bits", bits)
310 if isinstance(value
, SelectableInt
):
311 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
313 mask
= ((1 << bits
) - 1) << start
314 value
= value
<< start
315 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
317 def __ge__(self
, other
):
318 if isinstance(other
, FieldSelectableInt
):
319 other
= other
.get_range()
320 if isinstance(other
, SelectableInt
):
321 other
= check_extsign(self
, other
)
322 assert other
.bits
== self
.bits
324 if isinstance(other
, int):
325 return onebit(self
.value
>= other
.value
)
328 def __le__(self
, other
):
329 if isinstance(other
, FieldSelectableInt
):
330 other
= other
.get_range()
331 if isinstance(other
, SelectableInt
):
332 other
= check_extsign(self
, other
)
333 assert other
.bits
== self
.bits
335 if isinstance(other
, int):
336 return onebit(self
.value
<= other
)
339 def __gt__(self
, other
):
340 if isinstance(other
, FieldSelectableInt
):
341 other
= other
.get_range()
342 if isinstance(other
, SelectableInt
):
343 other
= check_extsign(self
, other
)
344 assert other
.bits
== self
.bits
346 if isinstance(other
, int):
347 return onebit(self
.value
> other
)
350 def __lt__(self
, other
):
351 if isinstance(other
, FieldSelectableInt
):
352 other
= other
.get_range()
353 if isinstance(other
, SelectableInt
):
354 other
= check_extsign(self
, other
)
355 assert other
.bits
== self
.bits
357 if isinstance(other
, int):
358 return onebit(self
.value
< other
)
361 def __eq__(self
, other
):
362 print("__eq__", self
, other
)
363 if isinstance(other
, FieldSelectableInt
):
364 other
= other
.get_range()
365 if isinstance(other
, SelectableInt
):
366 other
= check_extsign(self
, other
)
367 assert other
.bits
== self
.bits
369 if isinstance(other
, int):
370 return onebit(other
== self
.value
)
373 def narrow(self
, bits
):
374 assert bits
<= self
.bits
375 return SelectableInt(self
.value
, bits
)
378 return self
.value
!= 0
381 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
392 return SelectableInt(1 if bit
else 0, 1)
395 def selectltu(lhs
, rhs
):
396 """ less-than (unsigned)
398 if isinstance(rhs
, SelectableInt
):
400 return onebit(lhs
.value
< rhs
)
403 def selectgtu(lhs
, rhs
):
404 """ greater-than (unsigned)
406 if isinstance(rhs
, SelectableInt
):
408 return onebit(lhs
.value
> rhs
)
411 # XXX this probably isn't needed...
412 def selectassign(lhs
, idx
, rhs
):
413 if isinstance(idx
, tuple):
418 lower
, upper
, step
= idx
419 toidx
= range(lower
, upper
, step
)
420 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
424 for t
, f
in zip(toidx
, fromidx
):
428 def selectconcat(*args
, repeat
=1):
429 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
430 args
= [SelectableInt(args
[0], 1)]
431 if repeat
!= 1: # multiplies the incoming arguments
433 for i
in range(repeat
):
438 if isinstance(i
, FieldSelectableInt
):
440 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
442 res
.value
= (res
.value
<< i
.bits
) | i
.value
443 print("concat", repeat
, res
)
447 class SelectableIntTestCase(unittest
.TestCase
):
448 def test_arith(self
):
449 a
= SelectableInt(5, 8)
450 b
= SelectableInt(9, 8)
457 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
458 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
459 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
460 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
461 self
.assertEqual(c
.bits
, a
.bits
)
462 self
.assertEqual(d
.bits
, a
.bits
)
463 self
.assertEqual(e
.bits
, a
.bits
)
464 self
.assertEqual(a
.bits
, f
.bits
)
465 self
.assertEqual(a
.bits
, h
.bits
)
467 def test_logic(self
):
468 a
= SelectableInt(0x0F, 8)
469 b
= SelectableInt(0xA5, 8)
474 self
.assertEqual(c
.value
, a
.value
& b
.value
)
475 self
.assertEqual(d
.value
, a
.value | b
.value
)
476 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
477 self
.assertEqual(f
.value
, 0xF0)
480 a
= SelectableInt(0xa2, 8)
481 # These should be big endian
482 self
.assertEqual(a
[7], 0)
483 self
.assertEqual(a
[0:4], 10)
484 self
.assertEqual(a
[4:8], 2)
487 a
= SelectableInt(0x5, 8)
488 a
[7] = SelectableInt(0, 1)
489 self
.assertEqual(a
, 4)
491 self
.assertEqual(a
, 9)
493 self
.assertEqual(a
, 0x39)
495 self
.assertEqual(a
, 0x99)
497 def test_concat(self
):
498 a
= SelectableInt(0x1, 1)
499 c
= selectconcat(a
, repeat
=8)
500 self
.assertEqual(c
, 0xff)
501 self
.assertEqual(c
.bits
, 8)
502 a
= SelectableInt(0x0, 1)
503 c
= selectconcat(a
, repeat
=8)
504 self
.assertEqual(c
, 0x00)
505 self
.assertEqual(c
.bits
, 8)
508 for i
in range(65536):
509 a
= SelectableInt(i
, 16)
511 self
.assertEqual(a
, b
)
514 a
= SelectableInt(10, bits
=8)
515 b
= SelectableInt(5, bits
=8)
516 self
.assertTrue(a
> b
)
517 self
.assertFalse(a
< b
)
518 self
.assertTrue(a
!= b
)
519 self
.assertFalse(a
== b
)
521 def test_unsigned(self
):
522 a
= SelectableInt(0x80, bits
=8)
523 b
= SelectableInt(0x7f, bits
=8)
524 self
.assertTrue(a
> b
)
525 self
.assertFalse(a
< b
)
526 self
.assertTrue(a
!= b
)
527 self
.assertFalse(a
== b
)
530 if __name__
== "__main__":