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 return self
._op
(mul
, b
)
182 def __floordiv__(self
, b
):
183 return self
._op
(floordiv
, b
)
184 def __truediv__(self
, b
):
185 return self
._op
(truediv
, b
)
186 def __mod__(self
, b
):
187 return self
._op
(mod
, b
)
188 def __and__(self
, b
):
189 return self
._op
(and_
, b
)
191 return self
._op
(or_
, b
)
192 def __xor__(self
, b
):
193 return self
._op
(xor
, b
)
195 return SelectableInt(0, self
.bits
) - self
197 def __rsub__(self
, b
):
198 if isinstance(b
, int):
199 b
= SelectableInt(b
, self
.bits
)
200 b
= check_extsign(self
, b
)
201 assert b
.bits
== self
.bits
202 return SelectableInt(b
.value
- self
.value
, self
.bits
)
204 def __radd__(self
, b
):
205 if isinstance(b
, int):
206 b
= SelectableInt(b
, self
.bits
)
207 b
= check_extsign(self
, b
)
208 assert b
.bits
== self
.bits
209 return SelectableInt(b
.value
+ self
.value
, self
.bits
)
211 def __rxor__(self
, b
):
212 b
= check_extsign(self
, b
)
213 assert b
.bits
== self
.bits
214 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
216 def __invert__(self
):
217 return SelectableInt(~self
.value
, self
.bits
)
220 return SelectableInt(~self
.value
+ 1, self
.bits
)
222 def __lshift__(self
, b
):
223 b
= check_extsign(self
, b
)
224 return SelectableInt(self
.value
<< b
.value
, self
.bits
)
226 def __rshift__(self
, b
):
227 b
= check_extsign(self
, b
)
228 return SelectableInt(self
.value
>> b
.value
, self
.bits
)
230 def __getitem__(self
, key
):
231 if isinstance(key
, SelectableInt
):
233 if isinstance(key
, int):
234 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
236 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
237 # MSB is indexed **LOWEST** (sigh)
238 key
= self
.bits
- (key
+ 1)
240 value
= (self
.value
>> key
) & 1
241 return SelectableInt(value
, 1)
242 elif isinstance(key
, slice):
243 assert key
.step
is None or key
.step
== 1
244 assert key
.start
< key
.stop
245 assert key
.start
>= 0
246 assert key
.stop
<= self
.bits
248 stop
= self
.bits
- key
.start
249 start
= self
.bits
- key
.stop
252 #print ("__getitem__ slice num bits", bits)
253 mask
= (1 << bits
) - 1
254 value
= (self
.value
>> start
) & mask
255 return SelectableInt(value
, bits
)
257 def __setitem__(self
, key
, value
):
258 if isinstance(key
, SelectableInt
):
260 if isinstance(key
, int):
261 assert key
< self
.bits
263 key
= self
.bits
- (key
+ 1)
264 if isinstance(value
, SelectableInt
):
265 assert value
.bits
== 1
270 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
271 elif isinstance(key
, slice):
272 assert key
.step
is None or key
.step
== 1
273 assert key
.start
< key
.stop
274 assert key
.start
>= 0
275 assert key
.stop
<= self
.bits
277 stop
= self
.bits
- key
.start
278 start
= self
.bits
- key
.stop
281 #print ("__setitem__ slice num bits", bits)
282 if isinstance(value
, SelectableInt
):
283 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
285 mask
= ((1 << bits
) - 1) << start
286 value
= value
<< start
287 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
289 def __ge__(self
, other
):
290 if isinstance(other
, FieldSelectableInt
):
291 other
= other
.get_range()
292 if isinstance(other
, SelectableInt
):
293 other
= check_extsign(self
, other
)
294 assert other
.bits
== self
.bits
296 if isinstance(other
, int):
297 return onebit(self
.value
>= other
.value
)
300 def __le__(self
, other
):
301 if isinstance(other
, FieldSelectableInt
):
302 other
= other
.get_range()
303 if isinstance(other
, SelectableInt
):
304 other
= check_extsign(self
, other
)
305 assert other
.bits
== self
.bits
307 if isinstance(other
, int):
308 return onebit(self
.value
<= other
)
311 def __gt__(self
, other
):
312 if isinstance(other
, FieldSelectableInt
):
313 other
= other
.get_range()
314 if isinstance(other
, SelectableInt
):
315 other
= check_extsign(self
, other
)
316 assert other
.bits
== self
.bits
318 if isinstance(other
, int):
319 return onebit(self
.value
> other
)
322 def __lt__(self
, other
):
323 if isinstance(other
, FieldSelectableInt
):
324 other
= other
.get_range()
325 if isinstance(other
, SelectableInt
):
326 other
= check_extsign(self
, other
)
327 assert other
.bits
== self
.bits
329 if isinstance(other
, int):
330 return onebit(self
.value
< other
)
333 def __eq__(self
, other
):
334 print ("__eq__", self
, other
)
335 if isinstance(other
, FieldSelectableInt
):
336 other
= other
.get_range()
337 if isinstance(other
, SelectableInt
):
338 other
= check_extsign(self
, other
)
339 assert other
.bits
== self
.bits
341 if isinstance(other
, int):
342 return onebit(other
== self
.value
)
345 def narrow(self
, bits
):
346 assert bits
<= self
.bits
347 return SelectableInt(self
.value
, bits
)
350 return self
.value
!= 0
353 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
364 return SelectableInt(1 if bit
else 0, 1)
366 def selectltu(lhs
, rhs
):
367 """ less-than (unsigned)
369 if isinstance(rhs
, SelectableInt
):
371 return onebit(lhs
.value
< rhs
)
373 def selectgtu(lhs
, rhs
):
374 """ greater-than (unsigned)
376 if isinstance(rhs
, SelectableInt
):
378 return onebit(lhs
.value
> rhs
)
381 # XXX this probably isn't needed...
382 def selectassign(lhs
, idx
, rhs
):
383 if isinstance(idx
, tuple):
388 lower
, upper
, step
= idx
389 toidx
= range(lower
, upper
, step
)
390 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
394 for t
, f
in zip(toidx
, fromidx
):
398 def selectconcat(*args
, repeat
=1):
399 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
400 args
= [SelectableInt(args
[0], 1)]
401 if repeat
!= 1: # multiplies the incoming arguments
403 for i
in range(repeat
):
408 if isinstance(i
, FieldSelectableInt
):
410 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
412 res
.value
= (res
.value
<< i
.bits
) | i
.value
413 print ("concat", repeat
, res
)
417 class SelectableIntTestCase(unittest
.TestCase
):
418 def test_arith(self
):
419 a
= SelectableInt(5, 8)
420 b
= SelectableInt(9, 8)
427 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
428 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
429 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
430 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
431 self
.assertEqual(c
.bits
, a
.bits
)
432 self
.assertEqual(d
.bits
, a
.bits
)
433 self
.assertEqual(e
.bits
, a
.bits
)
434 self
.assertEqual(a
.bits
, f
.bits
)
435 self
.assertEqual(a
.bits
, h
.bits
)
437 def test_logic(self
):
438 a
= SelectableInt(0x0F, 8)
439 b
= SelectableInt(0xA5, 8)
444 self
.assertEqual(c
.value
, a
.value
& b
.value
)
445 self
.assertEqual(d
.value
, a
.value | b
.value
)
446 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
447 self
.assertEqual(f
.value
, 0xF0)
450 a
= SelectableInt(0xa2, 8)
451 # These should be big endian
452 self
.assertEqual(a
[7], 0)
453 self
.assertEqual(a
[0:4], 10)
454 self
.assertEqual(a
[4:8], 2)
457 a
= SelectableInt(0x5, 8)
458 a
[7] = SelectableInt(0, 1)
459 self
.assertEqual(a
, 4)
461 self
.assertEqual(a
, 9)
463 self
.assertEqual(a
, 0x39)
465 self
.assertEqual(a
, 0x99)
467 def test_concat(self
):
468 a
= SelectableInt(0x1, 1)
469 c
= selectconcat(a
, repeat
=8)
470 self
.assertEqual(c
, 0xff)
471 self
.assertEqual(c
.bits
, 8)
472 a
= SelectableInt(0x0, 1)
473 c
= selectconcat(a
, repeat
=8)
474 self
.assertEqual(c
, 0x00)
475 self
.assertEqual(c
.bits
, 8)
478 for i
in range(65536):
479 a
= SelectableInt(i
, 16)
481 self
.assertEqual(a
, b
)
484 a
= SelectableInt(10, bits
=8)
485 b
= SelectableInt(5, bits
=8)
486 self
.assertTrue(a
> b
)
487 self
.assertFalse(a
< b
)
488 self
.assertTrue(a
!= b
)
489 self
.assertFalse(a
== b
)
491 def test_unsigned(self
):
492 a
= SelectableInt(0x80, bits
=8)
493 b
= SelectableInt(0x7f, bits
=8)
494 self
.assertTrue(a
> b
)
495 self
.assertFalse(a
< b
)
496 self
.assertTrue(a
!= b
)
497 self
.assertFalse(a
== b
)
499 if __name__
== "__main__":