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 def __init__(self
, value
, bits
):
149 if isinstance(value
, SelectableInt
):
151 mask
= (1 << bits
) - 1
152 self
.value
= value
& mask
159 def _op(self
, op
, b
):
160 if isinstance(b
, int):
161 b
= SelectableInt(b
, self
.bits
)
162 b
= check_extsign(self
, b
)
163 assert b
.bits
== self
.bits
164 return SelectableInt(op(self
.value
, b
.value
), self
.bits
)
166 def __add__(self
, b
):
167 return self
._op
(add
, b
)
168 def __sub__(self
, b
):
169 return self
._op
(sub
, b
)
170 def __mul__(self
, b
):
171 return self
._op
(mul
, b
)
172 def __floordiv__(self
, b
):
173 return self
._op
(floordiv
, b
)
174 def __truediv__(self
, b
):
175 return self
._op
(truediv
, b
)
176 def __mod__(self
, b
):
177 return self
._op
(mod
, b
)
178 def __and__(self
, b
):
179 return self
._op
(and_
, b
)
181 return self
._op
(or_
, b
)
182 def __xor__(self
, b
):
183 return self
._op
(xor
, b
)
185 return SelectableInt(0, self
.bits
) - self
187 def __rsub__(self
, b
):
188 if isinstance(b
, int):
189 b
= SelectableInt(b
, self
.bits
)
190 b
= check_extsign(self
, b
)
191 assert b
.bits
== self
.bits
192 return SelectableInt(b
.value
- self
.value
, self
.bits
)
194 def __radd__(self
, b
):
195 if isinstance(b
, int):
196 b
= SelectableInt(b
, self
.bits
)
197 b
= check_extsign(self
, b
)
198 assert b
.bits
== self
.bits
199 return SelectableInt(b
.value
+ self
.value
, self
.bits
)
201 def __rxor__(self
, b
):
202 b
= check_extsign(self
, b
)
203 assert b
.bits
== self
.bits
204 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
206 def __invert__(self
):
207 return SelectableInt(~self
.value
, self
.bits
)
210 return SelectableInt(~self
.value
+ 1, self
.bits
)
212 def __lshift__(self
, b
):
213 b
= check_extsign(self
, b
)
214 return SelectableInt(self
.value
<< b
.value
, self
.bits
)
216 def __rshift__(self
, b
):
217 b
= check_extsign(self
, b
)
218 return SelectableInt(self
.value
>> b
.value
, self
.bits
)
220 def __getitem__(self
, key
):
221 if isinstance(key
, SelectableInt
):
223 if isinstance(key
, int):
224 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
226 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
227 # MSB is indexed **LOWEST** (sigh)
228 key
= self
.bits
- (key
+ 1)
230 value
= (self
.value
>> key
) & 1
231 return SelectableInt(value
, 1)
232 elif isinstance(key
, slice):
233 assert key
.step
is None or key
.step
== 1
234 assert key
.start
< key
.stop
235 assert key
.start
>= 0
236 assert key
.stop
<= self
.bits
238 stop
= self
.bits
- key
.start
239 start
= self
.bits
- key
.stop
242 #print ("__getitem__ slice num bits", bits)
243 mask
= (1 << bits
) - 1
244 value
= (self
.value
>> start
) & mask
245 return SelectableInt(value
, bits
)
247 def __setitem__(self
, key
, value
):
248 if isinstance(key
, SelectableInt
):
250 if isinstance(key
, int):
251 assert key
< self
.bits
253 key
= self
.bits
- (key
+ 1)
254 if isinstance(value
, SelectableInt
):
255 assert value
.bits
== 1
260 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
261 elif isinstance(key
, slice):
262 assert key
.step
is None or key
.step
== 1
263 assert key
.start
< key
.stop
264 assert key
.start
>= 0
265 assert key
.stop
<= self
.bits
267 stop
= self
.bits
- key
.start
268 start
= self
.bits
- key
.stop
271 #print ("__setitem__ slice num bits", bits)
272 if isinstance(value
, SelectableInt
):
273 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
275 mask
= ((1 << bits
) - 1) << start
276 value
= value
<< start
277 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
279 def __ge__(self
, other
):
280 if isinstance(other
, FieldSelectableInt
):
281 other
= other
.get_range()
282 if isinstance(other
, SelectableInt
):
283 other
= check_extsign(self
, other
)
284 assert other
.bits
== self
.bits
286 if isinstance(other
, int):
287 return onebit(self
.value
>= other
.value
)
290 def __le__(self
, other
):
291 if isinstance(other
, FieldSelectableInt
):
292 other
= other
.get_range()
293 if isinstance(other
, SelectableInt
):
294 other
= check_extsign(self
, other
)
295 assert other
.bits
== self
.bits
297 if isinstance(other
, int):
298 return onebit(self
.value
<= other
)
301 def __gt__(self
, other
):
302 if isinstance(other
, FieldSelectableInt
):
303 other
= other
.get_range()
304 if isinstance(other
, SelectableInt
):
305 other
= check_extsign(self
, other
)
306 assert other
.bits
== self
.bits
308 if isinstance(other
, int):
309 return onebit(self
.value
> other
)
312 def __lt__(self
, other
):
313 if isinstance(other
, FieldSelectableInt
):
314 other
= other
.get_range()
315 if isinstance(other
, SelectableInt
):
316 other
= check_extsign(self
, other
)
317 assert other
.bits
== self
.bits
319 if isinstance(other
, int):
320 return onebit(self
.value
< other
)
323 def __eq__(self
, other
):
324 print ("__eq__", self
, other
)
325 if isinstance(other
, FieldSelectableInt
):
326 other
= other
.get_range()
327 if isinstance(other
, SelectableInt
):
328 other
= check_extsign(self
, other
)
329 assert other
.bits
== self
.bits
331 if isinstance(other
, int):
332 return onebit(other
== self
.value
)
335 def narrow(self
, bits
):
336 assert bits
<= self
.bits
337 return SelectableInt(self
.value
, bits
)
340 return self
.value
!= 0
343 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
354 return SelectableInt(1 if bit
else 0, 1)
356 def selectltu(lhs
, rhs
):
357 """ less-than (unsigned)
359 if isinstance(rhs
, SelectableInt
):
361 return onebit(lhs
.value
< rhs
)
363 def selectgtu(lhs
, rhs
):
364 """ greater-than (unsigned)
366 if isinstance(rhs
, SelectableInt
):
368 return onebit(lhs
.value
> rhs
)
371 # XXX this probably isn't needed...
372 def selectassign(lhs
, idx
, rhs
):
373 if isinstance(idx
, tuple):
378 lower
, upper
, step
= idx
379 toidx
= range(lower
, upper
, step
)
380 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
384 for t
, f
in zip(toidx
, fromidx
):
388 def selectconcat(*args
, repeat
=1):
389 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
390 args
= [SelectableInt(args
[0], 1)]
391 if repeat
!= 1: # multiplies the incoming arguments
393 for i
in range(repeat
):
398 if isinstance(i
, FieldSelectableInt
):
400 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
402 res
.value
= (res
.value
<< i
.bits
) | i
.value
403 print ("concat", repeat
, res
)
407 class SelectableIntTestCase(unittest
.TestCase
):
408 def test_arith(self
):
409 a
= SelectableInt(5, 8)
410 b
= SelectableInt(9, 8)
415 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
416 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
417 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
418 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
419 self
.assertEqual(c
.bits
, a
.bits
)
420 self
.assertEqual(d
.bits
, a
.bits
)
421 self
.assertEqual(e
.bits
, a
.bits
)
423 def test_logic(self
):
424 a
= SelectableInt(0x0F, 8)
425 b
= SelectableInt(0xA5, 8)
430 self
.assertEqual(c
.value
, a
.value
& b
.value
)
431 self
.assertEqual(d
.value
, a
.value | b
.value
)
432 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
433 self
.assertEqual(f
.value
, 0xF0)
436 a
= SelectableInt(0xa2, 8)
437 # These should be big endian
438 self
.assertEqual(a
[7], 0)
439 self
.assertEqual(a
[0:4], 10)
440 self
.assertEqual(a
[4:8], 2)
443 a
= SelectableInt(0x5, 8)
444 a
[7] = SelectableInt(0, 1)
445 self
.assertEqual(a
, 4)
447 self
.assertEqual(a
, 9)
449 self
.assertEqual(a
, 0x39)
451 self
.assertEqual(a
, 0x99)
453 def test_concat(self
):
454 a
= SelectableInt(0x1, 1)
455 c
= selectconcat(a
, repeat
=8)
456 self
.assertEqual(c
, 0xff)
457 self
.assertEqual(c
.bits
, 8)
458 a
= SelectableInt(0x0, 1)
459 c
= selectconcat(a
, repeat
=8)
460 self
.assertEqual(c
, 0x00)
461 self
.assertEqual(c
.bits
, 8)
464 for i
in range(65536):
465 a
= SelectableInt(i
, 16)
467 self
.assertEqual(a
, b
)
470 a
= SelectableInt(10, bits
=8)
471 b
= SelectableInt(5, bits
=8)
472 self
.assertTrue(a
> b
)
473 self
.assertFalse(a
< b
)
474 self
.assertTrue(a
!= b
)
475 self
.assertFalse(a
== b
)
477 def test_unsigned(self
):
478 a
= SelectableInt(0x80, bits
=8)
479 b
= SelectableInt(0x7f, bits
=8)
480 self
.assertTrue(a
> b
)
481 self
.assertFalse(a
< b
)
482 self
.assertTrue(a
!= b
)
483 self
.assertFalse(a
== b
)
485 if __name__
== "__main__":