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 return SelectableInt(0, self
.bits
) - self
202 def __rsub__(self
, b
):
203 if isinstance(b
, int):
204 b
= SelectableInt(b
, self
.bits
)
205 b
= check_extsign(self
, b
)
206 assert b
.bits
== self
.bits
207 return SelectableInt(b
.value
- self
.value
, self
.bits
)
209 def __radd__(self
, b
):
210 if isinstance(b
, int):
211 b
= SelectableInt(b
, self
.bits
)
212 b
= check_extsign(self
, b
)
213 assert b
.bits
== self
.bits
214 return SelectableInt(b
.value
+ self
.value
, self
.bits
)
216 def __rxor__(self
, b
):
217 b
= check_extsign(self
, b
)
218 assert b
.bits
== self
.bits
219 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
221 def __invert__(self
):
222 return SelectableInt(~self
.value
, self
.bits
)
225 return SelectableInt(~self
.value
+ 1, self
.bits
)
227 def __lshift__(self
, b
):
228 b
= check_extsign(self
, b
)
229 return SelectableInt(self
.value
<< b
.value
, self
.bits
)
231 def __rshift__(self
, b
):
232 b
= check_extsign(self
, b
)
233 return SelectableInt(self
.value
>> b
.value
, self
.bits
)
235 def __getitem__(self
, key
):
236 if isinstance(key
, SelectableInt
):
238 if isinstance(key
, int):
239 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
241 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
242 # MSB is indexed **LOWEST** (sigh)
243 key
= self
.bits
- (key
+ 1)
245 value
= (self
.value
>> key
) & 1
246 return SelectableInt(value
, 1)
247 elif isinstance(key
, slice):
248 assert key
.step
is None or key
.step
== 1
249 assert key
.start
< key
.stop
250 assert key
.start
>= 0
251 assert key
.stop
<= self
.bits
253 stop
= self
.bits
- key
.start
254 start
= self
.bits
- key
.stop
257 #print ("__getitem__ slice num bits", bits)
258 mask
= (1 << bits
) - 1
259 value
= (self
.value
>> start
) & mask
260 return SelectableInt(value
, bits
)
262 def __setitem__(self
, key
, value
):
263 if isinstance(key
, SelectableInt
):
265 if isinstance(key
, int):
266 assert key
< self
.bits
268 key
= self
.bits
- (key
+ 1)
269 if isinstance(value
, SelectableInt
):
270 assert value
.bits
== 1
275 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
276 elif isinstance(key
, slice):
277 assert key
.step
is None or key
.step
== 1
278 assert key
.start
< key
.stop
279 assert key
.start
>= 0
280 assert key
.stop
<= self
.bits
282 stop
= self
.bits
- key
.start
283 start
= self
.bits
- key
.stop
286 #print ("__setitem__ slice num bits", bits)
287 if isinstance(value
, SelectableInt
):
288 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
290 mask
= ((1 << bits
) - 1) << start
291 value
= value
<< start
292 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
294 def __ge__(self
, other
):
295 if isinstance(other
, FieldSelectableInt
):
296 other
= other
.get_range()
297 if isinstance(other
, SelectableInt
):
298 other
= check_extsign(self
, other
)
299 assert other
.bits
== self
.bits
301 if isinstance(other
, int):
302 return onebit(self
.value
>= other
.value
)
305 def __le__(self
, other
):
306 if isinstance(other
, FieldSelectableInt
):
307 other
= other
.get_range()
308 if isinstance(other
, SelectableInt
):
309 other
= check_extsign(self
, other
)
310 assert other
.bits
== self
.bits
312 if isinstance(other
, int):
313 return onebit(self
.value
<= other
)
316 def __gt__(self
, other
):
317 if isinstance(other
, FieldSelectableInt
):
318 other
= other
.get_range()
319 if isinstance(other
, SelectableInt
):
320 other
= check_extsign(self
, other
)
321 assert other
.bits
== self
.bits
323 if isinstance(other
, int):
324 return onebit(self
.value
> other
)
327 def __lt__(self
, other
):
328 if isinstance(other
, FieldSelectableInt
):
329 other
= other
.get_range()
330 if isinstance(other
, SelectableInt
):
331 other
= check_extsign(self
, other
)
332 assert other
.bits
== self
.bits
334 if isinstance(other
, int):
335 return onebit(self
.value
< other
)
338 def __eq__(self
, other
):
339 print ("__eq__", 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(other
== self
.value
)
350 def narrow(self
, bits
):
351 assert bits
<= self
.bits
352 return SelectableInt(self
.value
, bits
)
355 return self
.value
!= 0
358 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
369 return SelectableInt(1 if bit
else 0, 1)
371 def selectltu(lhs
, rhs
):
372 """ less-than (unsigned)
374 if isinstance(rhs
, SelectableInt
):
376 return onebit(lhs
.value
< rhs
)
378 def selectgtu(lhs
, rhs
):
379 """ greater-than (unsigned)
381 if isinstance(rhs
, SelectableInt
):
383 return onebit(lhs
.value
> rhs
)
386 # XXX this probably isn't needed...
387 def selectassign(lhs
, idx
, rhs
):
388 if isinstance(idx
, tuple):
393 lower
, upper
, step
= idx
394 toidx
= range(lower
, upper
, step
)
395 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
399 for t
, f
in zip(toidx
, fromidx
):
403 def selectconcat(*args
, repeat
=1):
404 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
405 args
= [SelectableInt(args
[0], 1)]
406 if repeat
!= 1: # multiplies the incoming arguments
408 for i
in range(repeat
):
413 if isinstance(i
, FieldSelectableInt
):
415 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
417 res
.value
= (res
.value
<< i
.bits
) | i
.value
418 print ("concat", repeat
, res
)
422 class SelectableIntTestCase(unittest
.TestCase
):
423 def test_arith(self
):
424 a
= SelectableInt(5, 8)
425 b
= SelectableInt(9, 8)
432 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
433 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
434 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
435 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
436 self
.assertEqual(c
.bits
, a
.bits
)
437 self
.assertEqual(d
.bits
, a
.bits
)
438 self
.assertEqual(e
.bits
, a
.bits
)
439 self
.assertEqual(a
.bits
, f
.bits
)
440 self
.assertEqual(a
.bits
, h
.bits
)
442 def test_logic(self
):
443 a
= SelectableInt(0x0F, 8)
444 b
= SelectableInt(0xA5, 8)
449 self
.assertEqual(c
.value
, a
.value
& b
.value
)
450 self
.assertEqual(d
.value
, a
.value | b
.value
)
451 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
452 self
.assertEqual(f
.value
, 0xF0)
455 a
= SelectableInt(0xa2, 8)
456 # These should be big endian
457 self
.assertEqual(a
[7], 0)
458 self
.assertEqual(a
[0:4], 10)
459 self
.assertEqual(a
[4:8], 2)
462 a
= SelectableInt(0x5, 8)
463 a
[7] = SelectableInt(0, 1)
464 self
.assertEqual(a
, 4)
466 self
.assertEqual(a
, 9)
468 self
.assertEqual(a
, 0x39)
470 self
.assertEqual(a
, 0x99)
472 def test_concat(self
):
473 a
= SelectableInt(0x1, 1)
474 c
= selectconcat(a
, repeat
=8)
475 self
.assertEqual(c
, 0xff)
476 self
.assertEqual(c
.bits
, 8)
477 a
= SelectableInt(0x0, 1)
478 c
= selectconcat(a
, repeat
=8)
479 self
.assertEqual(c
, 0x00)
480 self
.assertEqual(c
.bits
, 8)
483 for i
in range(65536):
484 a
= SelectableInt(i
, 16)
486 self
.assertEqual(a
, b
)
489 a
= SelectableInt(10, bits
=8)
490 b
= SelectableInt(5, bits
=8)
491 self
.assertTrue(a
> b
)
492 self
.assertFalse(a
< b
)
493 self
.assertTrue(a
!= b
)
494 self
.assertFalse(a
== b
)
496 def test_unsigned(self
):
497 a
= SelectableInt(0x80, bits
=8)
498 b
= SelectableInt(0x7f, bits
=8)
499 self
.assertTrue(a
> b
)
500 self
.assertFalse(a
< b
)
501 self
.assertTrue(a
!= b
)
502 self
.assertFalse(a
== b
)
504 if __name__
== "__main__":