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
):
10 return SelectableInt(b
.value
, a
.bits
)
13 class FieldSelectableInt
:
14 """FieldSelectableInt: allows bit-range selection onto another target
16 def __init__(self
, si
, br
):
17 self
.si
= si
# target selectable int
18 if isinstance(br
, list) or isinstance(br
, tuple):
20 for i
, v
in enumerate(br
):
23 self
.br
= br
# map of indices.
39 def __getitem__(self
, key
):
40 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
43 def __setitem__(self
, key
, value
):
44 key
= self
.br
[key
] # don't do POWER 1.3.4 bit-inversion
45 return self
.si__setitem__(key
, value
)
48 return self
._op
1(negate
)
52 return self
._op
(add
, b
)
54 return self
._op
(sub
, b
)
56 return self
._op
(mul
, b
)
58 return self
._op
(truediv
, b
)
60 return self
._op
(mod
, b
)
62 return self
._op
(and_
, b
)
64 return self
._op
(or_
, b
)
66 return self
._op
(xor
, b
)
69 print ("get_range", self
.si
)
70 vi
= SelectableInt(0, len(self
.br
))
71 for k
, v
in self
.br
.items():
72 print ("get_range", k
, v
, self
.si
[v
])
74 print ("get_range", vi
)
79 for i
, v
in fi
.br
.items():
84 return "FieldSelectableInt(si=%s, br=%s)" % (self
.si
, self
.br
)
87 class FieldSelectableIntTestCase(unittest
.TestCase
):
89 a
= SelectableInt(0b10101, 5)
90 b
= SelectableInt(0b011, 3)
95 fs
= FieldSelectableInt(a
, br
)
98 #self.assertEqual(c.value, a.value + b.value)
102 def __init__(self
, value
, bits
):
103 mask
= (1 << bits
) - 1
104 self
.value
= value
& mask
111 def __add__(self
, b
):
112 if isinstance(b
, int):
113 b
= SelectableInt(b
, self
.bits
)
114 b
= check_extsign(self
, b
)
115 assert b
.bits
== self
.bits
116 return SelectableInt(self
.value
+ b
.value
, self
.bits
)
118 def __sub__(self
, b
):
119 if isinstance(b
, int):
120 b
= SelectableInt(b
, self
.bits
)
121 b
= check_extsign(self
, b
)
122 assert b
.bits
== self
.bits
123 return SelectableInt(self
.value
- b
.value
, self
.bits
)
125 def __mul__(self
, b
):
126 b
= check_extsign(self
, b
)
127 assert b
.bits
== self
.bits
128 return SelectableInt(self
.value
* b
.value
, self
.bits
)
130 def __div__(self
, b
):
131 b
= check_extsign(self
, b
)
132 assert b
.bits
== self
.bits
133 return SelectableInt(self
.value
/ b
.value
, self
.bits
)
135 def __mod__(self
, b
):
136 b
= check_extsign(self
, b
)
137 assert b
.bits
== self
.bits
138 return SelectableInt(self
.value
% b
.value
, self
.bits
)
141 b
= check_extsign(self
, b
)
142 assert b
.bits
== self
.bits
143 return SelectableInt(self
.value | b
.value
, self
.bits
)
145 def __and__(self
, b
):
146 print ("__and__", self
, b
)
147 b
= check_extsign(self
, b
)
148 assert b
.bits
== self
.bits
149 return SelectableInt(self
.value
& b
.value
, self
.bits
)
151 def __xor__(self
, b
):
152 b
= check_extsign(self
, b
)
153 assert b
.bits
== self
.bits
154 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
156 def __invert__(self
):
157 return SelectableInt(~self
.value
, self
.bits
)
160 return SelectableInt(~self
.value
+ 1, self
.bits
)
162 def __getitem__(self
, key
):
163 if isinstance(key
, int):
164 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
166 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
167 # MSB is indexed **LOWEST** (sigh)
168 key
= self
.bits
- (key
+ 1)
170 value
= (self
.value
>> key
) & 1
171 return SelectableInt(value
, 1)
172 elif isinstance(key
, slice):
173 assert key
.step
is None or key
.step
== 1
174 assert key
.start
< key
.stop
175 assert key
.start
>= 0
176 assert key
.stop
<= self
.bits
178 stop
= self
.bits
- key
.start
179 start
= self
.bits
- key
.stop
182 #print ("__getitem__ slice num bits", bits)
183 mask
= (1 << bits
) - 1
184 value
= (self
.value
>> start
) & mask
185 return SelectableInt(value
, bits
)
187 def __setitem__(self
, key
, value
):
188 if isinstance(key
, int):
189 assert key
< self
.bits
191 key
= self
.bits
- (key
+ 1)
192 if isinstance(value
, SelectableInt
):
193 assert value
.bits
== 1
198 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
199 elif isinstance(key
, slice):
200 assert key
.step
is None or key
.step
== 1
201 assert key
.start
< key
.stop
202 assert key
.start
>= 0
203 assert key
.stop
<= self
.bits
205 stop
= self
.bits
- key
.start
206 start
= self
.bits
- key
.stop
209 #print ("__setitem__ slice num bits", bits)
210 if isinstance(value
, SelectableInt
):
211 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
213 mask
= ((1 << bits
) - 1) << start
214 value
= value
<< start
215 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
217 def __ge__(self
, other
):
218 if isinstance(other
, FieldSelectableInt
):
219 other
= other
.get_range()
220 if isinstance(other
, SelectableInt
):
221 other
= check_extsign(self
, other
)
222 assert other
.bits
== self
.bits
224 if isinstance(other
, int):
225 return other
>= self
.value
228 def __le__(self
, other
):
229 if isinstance(other
, FieldSelectableInt
):
230 other
= other
.get_range()
231 if isinstance(other
, SelectableInt
):
232 other
= check_extsign(self
, other
)
233 assert other
.bits
== self
.bits
235 if isinstance(other
, int):
236 return onebit(other
<= self
.value
)
239 def __gt__(self
, other
):
240 if isinstance(other
, FieldSelectableInt
):
241 other
= other
.get_range()
242 if isinstance(other
, SelectableInt
):
243 other
= check_extsign(self
, other
)
244 assert other
.bits
== self
.bits
246 if isinstance(other
, int):
247 return onebit(other
> self
.value
)
250 def __lt__(self
, other
):
251 if isinstance(other
, FieldSelectableInt
):
252 other
= other
.get_range()
253 if isinstance(other
, SelectableInt
):
254 other
= check_extsign(self
, other
)
255 assert other
.bits
== self
.bits
257 if isinstance(other
, int):
258 return onebit(other
< self
.value
)
261 def __eq__(self
, other
):
262 print ("__eq__", self
, other
)
263 if isinstance(other
, FieldSelectableInt
):
264 other
= other
.get_range()
265 if isinstance(other
, SelectableInt
):
266 other
= check_extsign(self
, other
)
267 assert other
.bits
== self
.bits
269 if isinstance(other
, int):
270 return onebit(other
== self
.value
)
273 def narrow(self
, bits
):
274 assert bits
<= self
.bits
275 return SelectableInt(self
.value
, bits
)
278 return self
.value
!= 0
281 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
285 return SelectableInt(1 if bit
else 0, 1)
287 def selectltu(lhs
, rhs
):
288 """ less-than (unsigned)
290 if isinstance(rhs
, SelectableInt
):
292 return onebit(lhs
.value
< rhs
)
294 def selectgtu(lhs
, rhs
):
295 """ greater-than (unsigned)
297 if isinstance(rhs
, SelectableInt
):
299 return onebit(lhs
.value
> rhs
)
302 # XXX this probably isn't needed...
303 def selectassign(lhs
, idx
, rhs
):
304 if isinstance(idx
, tuple):
309 lower
, upper
, step
= idx
310 toidx
= range(lower
, upper
, step
)
311 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
315 for t
, f
in zip(toidx
, fromidx
):
319 def selectconcat(*args
, repeat
=1):
320 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
321 args
= [SelectableInt(args
[0], 1)]
322 if repeat
!= 1: # multiplies the incoming arguments
324 for i
in range(repeat
):
329 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
331 res
.value
= (res
.value
<< i
.bits
) | i
.value
332 print ("concat", repeat
, res
)
336 class SelectableIntTestCase(unittest
.TestCase
):
337 def test_arith(self
):
338 a
= SelectableInt(5, 8)
339 b
= SelectableInt(9, 8)
344 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
345 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
346 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
347 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
348 self
.assertEqual(c
.bits
, a
.bits
)
349 self
.assertEqual(d
.bits
, a
.bits
)
350 self
.assertEqual(e
.bits
, a
.bits
)
352 def test_logic(self
):
353 a
= SelectableInt(0x0F, 8)
354 b
= SelectableInt(0xA5, 8)
359 self
.assertEqual(c
.value
, a
.value
& b
.value
)
360 self
.assertEqual(d
.value
, a
.value | b
.value
)
361 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
362 self
.assertEqual(f
.value
, 0xF0)
365 a
= SelectableInt(0xa2, 8)
366 # These should be big endian
367 self
.assertEqual(a
[7], 0)
368 self
.assertEqual(a
[0:4], 10)
369 self
.assertEqual(a
[4:8], 2)
372 a
= SelectableInt(0x5, 8)
373 a
[7] = SelectableInt(0, 1)
374 self
.assertEqual(a
, 4)
376 self
.assertEqual(a
, 9)
378 self
.assertEqual(a
, 0x39)
380 self
.assertEqual(a
, 0x99)
382 def test_concat(self
):
383 a
= SelectableInt(0x1, 1)
384 c
= selectconcat(a
, repeat
=8)
385 self
.assertEqual(c
, 0xff)
386 self
.assertEqual(c
.bits
, 8)
387 a
= SelectableInt(0x0, 1)
388 c
= selectconcat(a
, repeat
=8)
389 self
.assertEqual(c
, 0x00)
390 self
.assertEqual(c
.bits
, 8)
393 for i
in range(65536):
394 a
= SelectableInt(i
, 16)
396 self
.assertEqual(a
, b
)
398 if __name__
== "__main__":