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
21 def __init__(self
, si
, br
):
22 self
.si
= si
# target selectable int
23 if isinstance(br
, list) or isinstance(br
, tuple):
25 for i
, v
in enumerate(br
):
28 self
.br
= br
# map of indices.
31 if isinstance(b
, SelectableInt
):
32 for i
in range(b
.bits
):
48 def __getitem__(self
, key
):
49 print ("getitem", key
, self
.br
)
50 if isinstance(key
, SelectableInt
):
52 if isinstance(key
, int):
53 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
55 if isinstance(key
, slice):
57 return selectconcat(*[self
.si
[x
] for x
in key
])
59 def __setitem__(self
, key
, value
):
60 if isinstance(key
, SelectableInt
):
62 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
63 if isinstance(key
, int):
64 return self
.si
.__setitem
__(key
, value
)
66 if not isinstance(value
, SelectableInt
):
67 value
= SelectableInt(value
, bits
=len(key
))
68 for i
, k
in enumerate(key
):
72 return self
._op
1(negate
)
76 return self
._op
(add
, b
)
78 return self
._op
(sub
, b
)
80 return self
._op
(mul
, b
)
82 return self
._op
(truediv
, b
)
84 return self
._op
(mod
, b
)
86 return self
._op
(and_
, b
)
88 return self
._op
(or_
, b
)
90 return self
._op
(xor
, b
)
93 vi
= SelectableInt(0, len(self
.br
))
94 for k
, v
in self
.br
.items():
100 for i
, v
in fi
.br
.items():
105 return "FieldSelectableInt(si=%s, br=%s)" % (self
.si
, self
.br
)
108 class FieldSelectableIntTestCase(unittest
.TestCase
):
109 def test_arith(self
):
110 a
= SelectableInt(0b10101, 5)
111 b
= SelectableInt(0b011, 3)
116 fs
= FieldSelectableInt(a
, br
)
119 #self.assertEqual(c.value, a.value + b.value)
121 def test_select(self
):
122 a
= SelectableInt(0b00001111, 8)
128 fs
= FieldSelectableInt(a
, br
)
130 self
.assertEqual(fs
.get_range(), 0b0011)
132 def test_select_range(self
):
133 a
= SelectableInt(0b00001111, 8)
139 fs
= FieldSelectableInt(a
, br
)
141 self
.assertEqual(fs
[2:4], 0b11)
144 self
.assertEqual(fs
.get_range(), 0b1011)
148 """SelectableInt - a class that behaves exactly like python int
150 this class is designed to mirror precisely the behaviour of python int.
151 the only difference is that it must contain the context of the bitwidth
152 (number of bits) associated with that integer.
154 FieldSelectableInt can then operate on partial bits, and because there
155 is a bit width associated with SelectableInt, slices operate correctly
156 including negative start/end points.
158 def __init__(self
, value
, bits
):
159 if isinstance(value
, SelectableInt
):
161 mask
= (1 << bits
) - 1
162 self
.value
= value
& mask
169 def _op(self
, op
, b
):
170 if isinstance(b
, int):
171 b
= SelectableInt(b
, self
.bits
)
172 b
= check_extsign(self
, b
)
173 assert b
.bits
== self
.bits
174 return SelectableInt(op(self
.value
, b
.value
), self
.bits
)
176 def __add__(self
, b
):
177 return self
._op
(add
, b
)
178 def __sub__(self
, b
):
179 return self
._op
(sub
, b
)
180 def __mul__(self
, b
):
181 # different case: mul result needs to fit the total bitsize
182 if isinstance(b
, int):
183 b
= SelectableInt(b
, self
.bits
)
184 print ("SelectableInt mul", hex(self
.value
), hex(b
.value
),
186 return SelectableInt(self
.value
* b
.value
, self
.bits
+ b
.bits
)
187 def __floordiv__(self
, b
):
188 return self
._op
(floordiv
, b
)
189 def __truediv__(self
, b
):
190 return self
._op
(truediv
, b
)
191 def __mod__(self
, b
):
192 return self
._op
(mod
, b
)
193 def __and__(self
, b
):
194 return self
._op
(and_
, b
)
196 return self
._op
(or_
, b
)
197 def __xor__(self
, b
):
198 return self
._op
(xor
, b
)
200 print ("abs", self
.value
& (1<<(self
.bits
-1)))
201 if self
.value
& (1<<(self
.bits
-1)) != 0:
205 def __rsub__(self
, b
):
206 if isinstance(b
, int):
207 b
= SelectableInt(b
, self
.bits
)
208 b
= check_extsign(self
, b
)
209 assert b
.bits
== self
.bits
210 return SelectableInt(b
.value
- self
.value
, self
.bits
)
212 def __radd__(self
, b
):
213 if isinstance(b
, int):
214 b
= SelectableInt(b
, self
.bits
)
215 b
= check_extsign(self
, b
)
216 assert b
.bits
== self
.bits
217 return SelectableInt(b
.value
+ self
.value
, self
.bits
)
219 def __rxor__(self
, b
):
220 b
= check_extsign(self
, b
)
221 assert b
.bits
== self
.bits
222 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
224 def __invert__(self
):
225 return SelectableInt(~self
.value
, self
.bits
)
228 return SelectableInt(~self
.value
+ 1, self
.bits
)
230 def __lshift__(self
, b
):
231 b
= check_extsign(self
, b
)
232 return SelectableInt(self
.value
<< b
.value
, self
.bits
)
234 def __rshift__(self
, b
):
235 b
= check_extsign(self
, b
)
236 return SelectableInt(self
.value
>> b
.value
, self
.bits
)
238 def __getitem__(self
, key
):
239 if isinstance(key
, SelectableInt
):
241 if isinstance(key
, int):
242 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
244 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
245 # MSB is indexed **LOWEST** (sigh)
246 key
= self
.bits
- (key
+ 1)
248 value
= (self
.value
>> key
) & 1
249 return SelectableInt(value
, 1)
250 elif isinstance(key
, slice):
251 assert key
.step
is None or key
.step
== 1
252 assert key
.start
< key
.stop
253 assert key
.start
>= 0
254 assert key
.stop
<= self
.bits
256 stop
= self
.bits
- key
.start
257 start
= self
.bits
- key
.stop
260 #print ("__getitem__ slice num bits", bits)
261 mask
= (1 << bits
) - 1
262 value
= (self
.value
>> start
) & mask
263 return SelectableInt(value
, bits
)
265 def __setitem__(self
, key
, value
):
266 if isinstance(key
, SelectableInt
):
268 if isinstance(key
, int):
269 assert key
< self
.bits
271 key
= self
.bits
- (key
+ 1)
272 if isinstance(value
, SelectableInt
):
273 assert value
.bits
== 1
278 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
279 elif isinstance(key
, slice):
280 assert key
.step
is None or key
.step
== 1
281 assert key
.start
< key
.stop
282 assert key
.start
>= 0
283 assert key
.stop
<= self
.bits
285 stop
= self
.bits
- key
.start
286 start
= self
.bits
- key
.stop
289 #print ("__setitem__ slice num bits", bits)
290 if isinstance(value
, SelectableInt
):
291 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
293 mask
= ((1 << bits
) - 1) << start
294 value
= value
<< start
295 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
297 def __ge__(self
, other
):
298 if isinstance(other
, FieldSelectableInt
):
299 other
= other
.get_range()
300 if isinstance(other
, SelectableInt
):
301 other
= check_extsign(self
, other
)
302 assert other
.bits
== self
.bits
304 if isinstance(other
, int):
305 return onebit(self
.value
>= other
.value
)
308 def __le__(self
, other
):
309 if isinstance(other
, FieldSelectableInt
):
310 other
= other
.get_range()
311 if isinstance(other
, SelectableInt
):
312 other
= check_extsign(self
, other
)
313 assert other
.bits
== self
.bits
315 if isinstance(other
, int):
316 return onebit(self
.value
<= other
)
319 def __gt__(self
, other
):
320 if isinstance(other
, FieldSelectableInt
):
321 other
= other
.get_range()
322 if isinstance(other
, SelectableInt
):
323 other
= check_extsign(self
, other
)
324 assert other
.bits
== self
.bits
326 if isinstance(other
, int):
327 return onebit(self
.value
> other
)
330 def __lt__(self
, other
):
331 if isinstance(other
, FieldSelectableInt
):
332 other
= other
.get_range()
333 if isinstance(other
, SelectableInt
):
334 other
= check_extsign(self
, other
)
335 assert other
.bits
== self
.bits
337 if isinstance(other
, int):
338 return onebit(self
.value
< other
)
341 def __eq__(self
, other
):
342 print ("__eq__", self
, other
)
343 if isinstance(other
, FieldSelectableInt
):
344 other
= other
.get_range()
345 if isinstance(other
, SelectableInt
):
346 other
= check_extsign(self
, other
)
347 assert other
.bits
== self
.bits
349 if isinstance(other
, int):
350 return onebit(other
== self
.value
)
353 def narrow(self
, bits
):
354 assert bits
<= self
.bits
355 return SelectableInt(self
.value
, bits
)
358 return self
.value
!= 0
361 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
372 return SelectableInt(1 if bit
else 0, 1)
374 def selectltu(lhs
, rhs
):
375 """ less-than (unsigned)
377 if isinstance(rhs
, SelectableInt
):
379 return onebit(lhs
.value
< rhs
)
381 def selectgtu(lhs
, rhs
):
382 """ greater-than (unsigned)
384 if isinstance(rhs
, SelectableInt
):
386 return onebit(lhs
.value
> rhs
)
389 # XXX this probably isn't needed...
390 def selectassign(lhs
, idx
, rhs
):
391 if isinstance(idx
, tuple):
396 lower
, upper
, step
= idx
397 toidx
= range(lower
, upper
, step
)
398 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
402 for t
, f
in zip(toidx
, fromidx
):
406 def selectconcat(*args
, repeat
=1):
407 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
408 args
= [SelectableInt(args
[0], 1)]
409 if repeat
!= 1: # multiplies the incoming arguments
411 for i
in range(repeat
):
416 if isinstance(i
, FieldSelectableInt
):
418 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
420 res
.value
= (res
.value
<< i
.bits
) | i
.value
421 print ("concat", repeat
, res
)
425 class SelectableIntTestCase(unittest
.TestCase
):
426 def test_arith(self
):
427 a
= SelectableInt(5, 8)
428 b
= SelectableInt(9, 8)
435 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
436 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
437 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
438 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
439 self
.assertEqual(c
.bits
, a
.bits
)
440 self
.assertEqual(d
.bits
, a
.bits
)
441 self
.assertEqual(e
.bits
, a
.bits
)
442 self
.assertEqual(a
.bits
, f
.bits
)
443 self
.assertEqual(a
.bits
, h
.bits
)
445 def test_logic(self
):
446 a
= SelectableInt(0x0F, 8)
447 b
= SelectableInt(0xA5, 8)
452 self
.assertEqual(c
.value
, a
.value
& b
.value
)
453 self
.assertEqual(d
.value
, a
.value | b
.value
)
454 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
455 self
.assertEqual(f
.value
, 0xF0)
458 a
= SelectableInt(0xa2, 8)
459 # These should be big endian
460 self
.assertEqual(a
[7], 0)
461 self
.assertEqual(a
[0:4], 10)
462 self
.assertEqual(a
[4:8], 2)
465 a
= SelectableInt(0x5, 8)
466 a
[7] = SelectableInt(0, 1)
467 self
.assertEqual(a
, 4)
469 self
.assertEqual(a
, 9)
471 self
.assertEqual(a
, 0x39)
473 self
.assertEqual(a
, 0x99)
475 def test_concat(self
):
476 a
= SelectableInt(0x1, 1)
477 c
= selectconcat(a
, repeat
=8)
478 self
.assertEqual(c
, 0xff)
479 self
.assertEqual(c
.bits
, 8)
480 a
= SelectableInt(0x0, 1)
481 c
= selectconcat(a
, repeat
=8)
482 self
.assertEqual(c
, 0x00)
483 self
.assertEqual(c
.bits
, 8)
486 for i
in range(65536):
487 a
= SelectableInt(i
, 16)
489 self
.assertEqual(a
, b
)
492 a
= SelectableInt(10, bits
=8)
493 b
= SelectableInt(5, bits
=8)
494 self
.assertTrue(a
> b
)
495 self
.assertFalse(a
< b
)
496 self
.assertTrue(a
!= b
)
497 self
.assertFalse(a
== b
)
499 def test_unsigned(self
):
500 a
= SelectableInt(0x80, bits
=8)
501 b
= SelectableInt(0x7f, bits
=8)
502 self
.assertTrue(a
> b
)
503 self
.assertFalse(a
< b
)
504 self
.assertTrue(a
!= b
)
505 self
.assertFalse(a
== b
)
507 if __name__
== "__main__":