0df22df76323a0664a8d7f5b5751f116f6d6c01e
3 from soc
.decoder
.power_fields
import BitRange
4 from operator
import (add
, sub
, mul
, truediv
, mod
, or_
, and_
, xor
, neg
, inv
)
7 def check_extsign(a
, b
):
8 if isinstance(b
, FieldSelectableInt
):
10 if isinstance(b
, int):
11 return SelectableInt(b
, a
.bits
)
14 return SelectableInt(b
.value
, a
.bits
)
17 class FieldSelectableInt
:
18 """FieldSelectableInt: allows bit-range selection onto another target
20 def __init__(self
, si
, br
):
21 self
.si
= si
# target selectable int
22 if isinstance(br
, list) or isinstance(br
, tuple):
24 for i
, v
in enumerate(br
):
27 self
.br
= br
# map of indices.
30 if isinstance(b
, SelectableInt
):
31 for i
in range(b
.bits
):
47 def __getitem__(self
, key
):
48 print ("getitem", key
, self
.br
)
49 if isinstance(key
, SelectableInt
):
51 if isinstance(key
, int):
52 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
54 if isinstance(key
, slice):
56 return selectconcat(*[self
.si
[x
] for x
in key
])
58 def __setitem__(self
, key
, value
):
59 if isinstance(key
, SelectableInt
):
61 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
62 if isinstance(key
, int):
63 return self
.si
.__setitem
__(key
, value
)
65 if not isinstance(value
, SelectableInt
):
66 value
= SelectableInt(value
, bits
=len(key
))
67 for i
, k
in enumerate(key
):
71 return self
._op
1(negate
)
75 return self
._op
(add
, b
)
77 return self
._op
(sub
, b
)
79 return self
._op
(mul
, b
)
81 return self
._op
(truediv
, b
)
83 return self
._op
(mod
, b
)
85 return self
._op
(and_
, b
)
87 return self
._op
(or_
, b
)
89 return self
._op
(xor
, b
)
92 vi
= SelectableInt(0, len(self
.br
))
93 for k
, v
in self
.br
.items():
99 for i
, v
in fi
.br
.items():
104 return "FieldSelectableInt(si=%s, br=%s)" % (self
.si
, self
.br
)
107 class FieldSelectableIntTestCase(unittest
.TestCase
):
108 def test_arith(self
):
109 a
= SelectableInt(0b10101, 5)
110 b
= SelectableInt(0b011, 3)
115 fs
= FieldSelectableInt(a
, br
)
118 #self.assertEqual(c.value, a.value + b.value)
120 def test_select(self
):
121 a
= SelectableInt(0b00001111, 8)
127 fs
= FieldSelectableInt(a
, br
)
129 self
.assertEqual(fs
.get_range(), 0b0011)
131 def test_select_range(self
):
132 a
= SelectableInt(0b00001111, 8)
138 fs
= FieldSelectableInt(a
, br
)
140 self
.assertEqual(fs
[2:4], 0b11)
143 self
.assertEqual(fs
.get_range(), 0b1011)
147 def __init__(self
, value
, bits
):
148 if isinstance(value
, SelectableInt
):
150 mask
= (1 << bits
) - 1
151 self
.value
= value
& mask
158 def __add__(self
, b
):
159 if isinstance(b
, int):
160 b
= SelectableInt(b
, self
.bits
)
161 b
= check_extsign(self
, b
)
162 assert b
.bits
== self
.bits
163 return SelectableInt(self
.value
+ b
.value
, self
.bits
)
165 def __sub__(self
, b
):
166 if isinstance(b
, int):
167 b
= SelectableInt(b
, self
.bits
)
168 b
= check_extsign(self
, b
)
169 assert b
.bits
== self
.bits
170 return SelectableInt(self
.value
- b
.value
, self
.bits
)
172 def __rsub__(self
, b
):
173 if isinstance(b
, int):
174 b
= SelectableInt(b
, self
.bits
)
175 b
= check_extsign(self
, b
)
176 assert b
.bits
== self
.bits
177 return SelectableInt(b
.value
- self
.value
, self
.bits
)
179 def __radd__(self
, b
):
180 if isinstance(b
, int):
181 b
= SelectableInt(b
, self
.bits
)
182 b
= check_extsign(self
, b
)
183 assert b
.bits
== self
.bits
184 return SelectableInt(b
.value
+ self
.value
, self
.bits
)
186 def __mul__(self
, b
):
187 b
= check_extsign(self
, b
)
188 assert b
.bits
== self
.bits
189 return SelectableInt(self
.value
* b
.value
, self
.bits
)
191 def __div__(self
, b
):
192 b
= check_extsign(self
, b
)
193 assert b
.bits
== self
.bits
194 return SelectableInt(self
.value
/ b
.value
, self
.bits
)
196 def __mod__(self
, b
):
197 b
= check_extsign(self
, b
)
198 assert b
.bits
== self
.bits
199 return SelectableInt(self
.value
% b
.value
, self
.bits
)
202 b
= check_extsign(self
, b
)
203 assert b
.bits
== self
.bits
204 return SelectableInt(self
.value | b
.value
, self
.bits
)
206 def __and__(self
, b
):
207 print ("__and__", self
, b
)
208 b
= check_extsign(self
, b
)
209 assert b
.bits
== self
.bits
210 return SelectableInt(self
.value
& b
.value
, self
.bits
)
212 def __xor__(self
, b
):
213 b
= check_extsign(self
, b
)
214 assert b
.bits
== self
.bits
215 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
217 def __rxor__(self
, b
):
218 b
= check_extsign(self
, b
)
219 assert b
.bits
== self
.bits
220 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
222 def __invert__(self
):
223 return SelectableInt(~self
.value
, self
.bits
)
226 return SelectableInt(~self
.value
+ 1, self
.bits
)
228 def __lshift__(self
, b
):
229 b
= check_extsign(self
, b
)
230 return SelectableInt(self
.value
<< b
.value
, self
.bits
)
232 def __rshift__(self
, b
):
233 b
= check_extsign(self
, b
)
234 return SelectableInt(self
.value
>> b
.value
, self
.bits
)
236 def __getitem__(self
, key
):
237 if isinstance(key
, SelectableInt
):
239 if isinstance(key
, int):
240 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
242 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
243 # MSB is indexed **LOWEST** (sigh)
244 key
= self
.bits
- (key
+ 1)
246 value
= (self
.value
>> key
) & 1
247 return SelectableInt(value
, 1)
248 elif isinstance(key
, slice):
249 assert key
.step
is None or key
.step
== 1
250 assert key
.start
< key
.stop
251 assert key
.start
>= 0
252 assert key
.stop
<= self
.bits
254 stop
= self
.bits
- key
.start
255 start
= self
.bits
- key
.stop
258 #print ("__getitem__ slice num bits", bits)
259 mask
= (1 << bits
) - 1
260 value
= (self
.value
>> start
) & mask
261 return SelectableInt(value
, bits
)
263 def __setitem__(self
, key
, value
):
264 if isinstance(key
, SelectableInt
):
266 if isinstance(key
, int):
267 assert key
< self
.bits
269 key
= self
.bits
- (key
+ 1)
270 if isinstance(value
, SelectableInt
):
271 assert value
.bits
== 1
276 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
277 elif isinstance(key
, slice):
278 assert key
.step
is None or key
.step
== 1
279 assert key
.start
< key
.stop
280 assert key
.start
>= 0
281 assert key
.stop
<= self
.bits
283 stop
= self
.bits
- key
.start
284 start
= self
.bits
- key
.stop
287 #print ("__setitem__ slice num bits", bits)
288 if isinstance(value
, SelectableInt
):
289 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
291 mask
= ((1 << bits
) - 1) << start
292 value
= value
<< start
293 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
295 def __ge__(self
, other
):
296 if isinstance(other
, FieldSelectableInt
):
297 other
= other
.get_range()
298 if isinstance(other
, SelectableInt
):
299 other
= check_extsign(self
, other
)
300 assert other
.bits
== self
.bits
302 if isinstance(other
, int):
303 return onebit(self
.value
>= other
.value
)
306 def __le__(self
, other
):
307 if isinstance(other
, FieldSelectableInt
):
308 other
= other
.get_range()
309 if isinstance(other
, SelectableInt
):
310 other
= check_extsign(self
, other
)
311 assert other
.bits
== self
.bits
313 if isinstance(other
, int):
314 return onebit(self
.value
<= other
)
317 def __gt__(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
)
328 def __lt__(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 __eq__(self
, other
):
340 print ("__eq__", self
, other
)
341 if isinstance(other
, FieldSelectableInt
):
342 other
= other
.get_range()
343 if isinstance(other
, SelectableInt
):
344 other
= check_extsign(self
, other
)
345 assert other
.bits
== self
.bits
347 if isinstance(other
, int):
348 return onebit(other
== self
.value
)
351 def narrow(self
, bits
):
352 assert bits
<= self
.bits
353 return SelectableInt(self
.value
, bits
)
356 return self
.value
!= 0
359 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
370 return SelectableInt(1 if bit
else 0, 1)
372 def selectltu(lhs
, rhs
):
373 """ less-than (unsigned)
375 if isinstance(rhs
, SelectableInt
):
377 return onebit(lhs
.value
< rhs
)
379 def selectgtu(lhs
, rhs
):
380 """ greater-than (unsigned)
382 if isinstance(rhs
, SelectableInt
):
384 return onebit(lhs
.value
> rhs
)
387 # XXX this probably isn't needed...
388 def selectassign(lhs
, idx
, rhs
):
389 if isinstance(idx
, tuple):
394 lower
, upper
, step
= idx
395 toidx
= range(lower
, upper
, step
)
396 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
400 for t
, f
in zip(toidx
, fromidx
):
404 def selectconcat(*args
, repeat
=1):
405 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
406 args
= [SelectableInt(args
[0], 1)]
407 if repeat
!= 1: # multiplies the incoming arguments
409 for i
in range(repeat
):
414 if isinstance(i
, FieldSelectableInt
):
416 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
418 res
.value
= (res
.value
<< i
.bits
) | i
.value
419 print ("concat", repeat
, res
)
423 class SelectableIntTestCase(unittest
.TestCase
):
424 def test_arith(self
):
425 a
= SelectableInt(5, 8)
426 b
= SelectableInt(9, 8)
431 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
432 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
433 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
434 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
435 self
.assertEqual(c
.bits
, a
.bits
)
436 self
.assertEqual(d
.bits
, a
.bits
)
437 self
.assertEqual(e
.bits
, a
.bits
)
439 def test_logic(self
):
440 a
= SelectableInt(0x0F, 8)
441 b
= SelectableInt(0xA5, 8)
446 self
.assertEqual(c
.value
, a
.value
& b
.value
)
447 self
.assertEqual(d
.value
, a
.value | b
.value
)
448 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
449 self
.assertEqual(f
.value
, 0xF0)
452 a
= SelectableInt(0xa2, 8)
453 # These should be big endian
454 self
.assertEqual(a
[7], 0)
455 self
.assertEqual(a
[0:4], 10)
456 self
.assertEqual(a
[4:8], 2)
459 a
= SelectableInt(0x5, 8)
460 a
[7] = SelectableInt(0, 1)
461 self
.assertEqual(a
, 4)
463 self
.assertEqual(a
, 9)
465 self
.assertEqual(a
, 0x39)
467 self
.assertEqual(a
, 0x99)
469 def test_concat(self
):
470 a
= SelectableInt(0x1, 1)
471 c
= selectconcat(a
, repeat
=8)
472 self
.assertEqual(c
, 0xff)
473 self
.assertEqual(c
.bits
, 8)
474 a
= SelectableInt(0x0, 1)
475 c
= selectconcat(a
, repeat
=8)
476 self
.assertEqual(c
, 0x00)
477 self
.assertEqual(c
.bits
, 8)
480 for i
in range(65536):
481 a
= SelectableInt(i
, 16)
483 self
.assertEqual(a
, b
)
486 a
= SelectableInt(10, bits
=8)
487 b
= SelectableInt(5, bits
=8)
488 self
.assertTrue(a
> b
)
489 self
.assertFalse(a
< b
)
490 self
.assertTrue(a
!= b
)
491 self
.assertFalse(a
== b
)
493 def test_unsigned(self
):
494 a
= SelectableInt(0x80, bits
=8)
495 b
= SelectableInt(0x7f, bits
=8)
496 self
.assertTrue(a
> b
)
497 self
.assertFalse(a
< b
)
498 self
.assertTrue(a
!= b
)
499 self
.assertFalse(a
== b
)
501 if __name__
== "__main__":