3 from soc
.decoder
.power_fields
import BitRange
4 from operator
import (add
, sub
, mul
, div
, 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 self
.br
= br
# map of indices.
30 def __getitem__(self
, key
):
34 def __setitem__(self
, key
, value
)
36 return self
.si__setitem__(key
, value
)
39 return self
._op
1(negate
)
43 return self
._op
(add
, b
)
45 return self
._op
(sub
, b
)
47 return self
._op
(mul
, b
)
49 return self
._op
(div
, b
)
51 return self
._op
(and_
, b
)
53 return self
._op
(or_
, b
)
55 return self
._op
(xor
, b
)
58 print ("get_range", self
.si
)
59 vi
= SelectableInt(0, len(self
.br
))
60 for k
, v
in self
.br
.items():
61 print ("get_range", k
, v
, self
.si
[v
])
63 print ("get_range", vi
)
68 for i
, v
in fi
.br
.items():
73 return "FieldSelectableInt(si=%s, br=%s)" % (self
.si
, self
.br
)
76 class FieldSelectableIntTestCase(unittest
.TestCase
):
78 a
= SelectableInt(0b10101, 5)
79 b
= SelectableInt(0b011, 3)
84 fs
= FieldSelectableInt(a
, br
)
87 #self.assertEqual(c.value, a.value + b.value)
91 def __init__(self
, value
, bits
):
92 mask
= (1 << bits
) - 1
93 self
.value
= value
& mask
97 if isinstance(b
, int):
98 b
= SelectableInt(b
, self
.bits
)
99 b
= check_extsign(self
, b
)
100 assert b
.bits
== self
.bits
101 return SelectableInt(self
.value
+ b
.value
, self
.bits
)
103 def __sub__(self
, b
):
104 if isinstance(b
, int):
105 b
= SelectableInt(b
, self
.bits
)
106 b
= check_extsign(self
, b
)
107 assert b
.bits
== self
.bits
108 return SelectableInt(self
.value
- b
.value
, self
.bits
)
110 def __mul__(self
, b
):
111 b
= check_extsign(self
, b
)
112 assert b
.bits
== self
.bits
113 return SelectableInt(self
.value
* b
.value
, self
.bits
)
115 def __div__(self
, b
):
116 b
= check_extsign(self
, b
)
117 assert b
.bits
== self
.bits
118 return SelectableInt(self
.value
/ b
.value
, self
.bits
)
120 def __mod__(self
, b
):
121 b
= check_extsign(self
, b
)
122 assert b
.bits
== self
.bits
123 return SelectableInt(self
.value
% b
.value
, self
.bits
)
126 b
= check_extsign(self
, b
)
127 assert b
.bits
== self
.bits
128 return SelectableInt(self
.value | b
.value
, self
.bits
)
130 def __and__(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 __xor__(self
, b
):
136 b
= check_extsign(self
, b
)
137 assert b
.bits
== self
.bits
138 return SelectableInt(self
.value ^ b
.value
, self
.bits
)
140 def __invert__(self
):
141 return SelectableInt(~self
.value
, self
.bits
)
144 return SelectableInt(~self
.value
+ 1, self
.bits
)
146 def __getitem__(self
, key
):
147 if isinstance(key
, int):
148 assert key
< self
.bits
, "key %d accessing %d" % (key
, self
.bits
)
150 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
151 # MSB is indexed **LOWEST** (sigh)
152 key
= self
.bits
- (key
+ 1)
154 value
= (self
.value
>> key
) & 1
155 return SelectableInt(value
, 1)
156 elif isinstance(key
, slice):
157 assert key
.step
is None or key
.step
== 1
158 assert key
.start
< key
.stop
159 assert key
.start
>= 0
160 assert key
.stop
<= self
.bits
162 stop
= self
.bits
- key
.start
163 start
= self
.bits
- key
.stop
165 bits
= stop
- start
+ 1
166 mask
= (1 << bits
) - 1
167 value
= (self
.value
>> start
) & mask
168 return SelectableInt(value
, bits
)
170 def __setitem__(self
, key
, value
):
171 if isinstance(key
, int):
172 assert key
< self
.bits
174 key
= self
.bits
- (key
+ 1)
175 if isinstance(value
, SelectableInt
):
176 assert value
.bits
== 1
181 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
182 elif isinstance(key
, slice):
183 assert key
.step
is None or key
.step
== 1
184 assert key
.start
< key
.stop
185 assert key
.start
>= 0
186 assert key
.stop
<= self
.bits
188 stop
= self
.bits
- key
.start
189 start
= self
.bits
- key
.stop
191 bits
= stop
- start
+ 1
192 if isinstance(value
, SelectableInt
):
193 assert value
.bits
== bits
, "%d into %d" % (value
.bits
, bits
)
195 mask
= ((1 << bits
) - 1) << start
196 value
= value
<< start
197 self
.value
= (self
.value
& ~mask
) |
(value
& mask
)
199 def __ge__(self
, other
):
200 if isinstance(other
, SelectableInt
):
201 other
= check_extsign(self
, other
)
202 assert other
.bits
== self
.bits
204 if isinstance(other
, int):
205 return other
>= self
.value
208 def __le__(self
, other
):
209 if isinstance(other
, SelectableInt
):
210 other
= check_extsign(self
, other
)
211 assert other
.bits
== self
.bits
213 if isinstance(other
, int):
214 return onebit(other
<= self
.value
)
217 def __gt__(self
, other
):
218 if isinstance(other
, SelectableInt
):
219 other
= check_extsign(self
, other
)
220 assert other
.bits
== self
.bits
222 if isinstance(other
, int):
223 return onebit(other
> self
.value
)
226 def __lt__(self
, other
):
227 if isinstance(other
, SelectableInt
):
228 other
= check_extsign(self
, other
)
229 assert other
.bits
== self
.bits
231 if isinstance(other
, int):
232 return onebit(other
< self
.value
)
235 def __eq__(self
, other
):
236 if isinstance(other
, SelectableInt
):
237 other
= check_extsign(self
, other
)
238 assert other
.bits
== self
.bits
240 if isinstance(other
, int):
241 return onebit(other
== self
.value
)
244 def narrow(self
, bits
):
245 assert bits
<= self
.bits
246 return SelectableInt(self
.value
, bits
)
249 return self
.value
!= 0
252 return "SelectableInt(value=0x{:x}, bits={})".format(self
.value
,
256 return SelectableInt(1 if bit
else 0, 1)
258 def selectltu(lhs
, rhs
):
259 """ less-than (unsigned)
261 if isinstance(rhs
, SelectableInt
):
263 return onebit(lhs
.value
< rhs
)
265 def selectgtu(lhs
, rhs
):
266 """ greater-than (unsigned)
268 if isinstance(rhs
, SelectableInt
):
270 return onebit(lhs
.value
> rhs
)
273 # XXX this probably isn't needed...
274 def selectassign(lhs
, idx
, rhs
):
275 if isinstance(idx
, tuple):
280 lower
, upper
, step
= idx
281 toidx
= range(lower
, upper
, step
)
282 fromidx
= range(0, upper
-lower
, step
) # XXX eurgh...
286 for t
, f
in zip(toidx
, fromidx
):
290 def selectconcat(*args
, repeat
=1):
291 if repeat
!= 1 and len(args
) == 1 and isinstance(args
[0], int):
292 args
= [SelectableInt(args
[0], 1)]
293 if repeat
!= 1: # multiplies the incoming arguments
295 for i
in range(repeat
):
300 assert isinstance(i
, SelectableInt
), "can only concat SIs, sorry"
302 res
.value
= (res
.value
<< i
.bits
) | i
.value
303 print ("concat", repeat
, res
)
307 class SelectableIntTestCase(unittest
.TestCase
):
308 def test_arith(self
):
309 a
= SelectableInt(5, 8)
310 b
= SelectableInt(9, 8)
315 self
.assertEqual(c
.value
, a
.value
+ b
.value
)
316 self
.assertEqual(d
.value
, (a
.value
- b
.value
) & 0xFF)
317 self
.assertEqual(e
.value
, (a
.value
* b
.value
) & 0xFF)
318 self
.assertEqual(f
.value
, (-a
.value
) & 0xFF)
319 self
.assertEqual(c
.bits
, a
.bits
)
320 self
.assertEqual(d
.bits
, a
.bits
)
321 self
.assertEqual(e
.bits
, a
.bits
)
323 def test_logic(self
):
324 a
= SelectableInt(0x0F, 8)
325 b
= SelectableInt(0xA5, 8)
330 self
.assertEqual(c
.value
, a
.value
& b
.value
)
331 self
.assertEqual(d
.value
, a
.value | b
.value
)
332 self
.assertEqual(e
.value
, a
.value ^ b
.value
)
333 self
.assertEqual(f
.value
, 0xF0)
336 a
= SelectableInt(0xa2, 8)
337 # These should be big endian
338 self
.assertEqual(a
[7], 0)
339 self
.assertEqual(a
[0:4], 10)
340 self
.assertEqual(a
[4:8], 2)
343 a
= SelectableInt(0x5, 8)
344 a
[7] = SelectableInt(0, 1)
345 self
.assertEqual(a
, 4)
347 self
.assertEqual(a
, 9)
349 self
.assertEqual(a
, 0x39)
351 self
.assertEqual(a
, 0x199)
353 def test_concat(self
):
354 a
= SelectableInt(0x1, 1)
355 c
= selectconcat(a
, repeat
=8)
356 self
.assertEqual(c
, 0xff)
357 self
.assertEqual(c
.bits
, 8)
358 a
= SelectableInt(0x0, 1)
359 c
= selectconcat(a
, repeat
=8)
360 self
.assertEqual(c
, 0x00)
361 self
.assertEqual(c
.bits
, 8)
364 for i
in range(65536):
365 a
= SelectableInt(i
, 16)
367 self
.assertEqual(a
, b
)
369 if __name__
== "__main__":