test actual reg values being produced in core test
[soc.git] / src / soc / decoder / selectable_int.py
1 import unittest
2 from copy import copy
3 from soc.decoder.power_fields import BitRange
4 from operator import (add, sub, mul, truediv, mod, or_, and_, xor, neg, inv)
5
6
7 def check_extsign(a, b):
8 if isinstance(b, FieldSelectableInt):
9 b = b.get_range()
10 if isinstance(b, int):
11 return SelectableInt(b, a.bits)
12 if b.bits != 256:
13 return b
14 return SelectableInt(b.value, a.bits)
15
16
17 class FieldSelectableInt:
18 """FieldSelectableInt: allows bit-range selection onto another target
19 """
20 def __init__(self, si, br):
21 self.si = si # target selectable int
22 if isinstance(br, list) or isinstance(br, tuple):
23 _br = BitRange()
24 for i, v in enumerate(br):
25 _br[i] = v
26 br = _br
27 self.br = br # map of indices.
28
29 def eq(self, b):
30 if isinstance(b, SelectableInt):
31 for i in range(b.bits):
32 self[i] = b[i]
33 else:
34 self.si = copy(b.si)
35 self.br = copy(b.br)
36
37 def _op(self, op, b):
38 vi = self.get_range()
39 vi = op(vi, b)
40 return self.merge(vi)
41
42 def _op1(self, op):
43 vi = self.get_range()
44 vi = op(vi)
45 return self.merge(vi)
46
47 def __getitem__(self, key):
48 print ("getitem", key, self.br)
49 if isinstance(key, SelectableInt):
50 key = key.value
51 if isinstance(key, int):
52 key = self.br[key] # don't do POWER 1.3.4 bit-inversion
53 return self.si[key]
54 if isinstance(key, slice):
55 key = self.br[key]
56 return selectconcat(*[self.si[x] for x in key])
57
58 def __setitem__(self, key, value):
59 if isinstance(key, SelectableInt):
60 key = key.value
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)
64 else:
65 if not isinstance(value, SelectableInt):
66 value = SelectableInt(value, bits=len(key))
67 for i, k in enumerate(key):
68 self.si[k] = value[i]
69
70 def __negate__(self):
71 return self._op1(negate)
72 def __invert__(self):
73 return self._op1(inv)
74 def __add__(self, b):
75 return self._op(add, b)
76 def __sub__(self, b):
77 return self._op(sub, b)
78 def __mul__(self, b):
79 return self._op(mul, b)
80 def __div__(self, b):
81 return self._op(truediv, b)
82 def __mod__(self, b):
83 return self._op(mod, b)
84 def __and__(self, b):
85 return self._op(and_, b)
86 def __or__(self, b):
87 return self._op(or_, b)
88 def __xor__(self, b):
89 return self._op(xor, b)
90
91 def get_range(self):
92 vi = SelectableInt(0, len(self.br))
93 for k, v in self.br.items():
94 vi[k] = self.si[v]
95 return vi
96
97 def merge(self, vi):
98 fi = copy(self)
99 for i, v in fi.br.items():
100 fi.si[v] = vi[i]
101 return fi
102
103 def __repr__(self):
104 return "FieldSelectableInt(si=%s, br=%s)" % (self.si, self.br)
105
106
107 class FieldSelectableIntTestCase(unittest.TestCase):
108 def test_arith(self):
109 a = SelectableInt(0b10101, 5)
110 b = SelectableInt(0b011, 3)
111 br = BitRange()
112 br[0] = 0
113 br[1] = 2
114 br[2] = 3
115 fs = FieldSelectableInt(a, br)
116 c = fs + b
117 print (c)
118 #self.assertEqual(c.value, a.value + b.value)
119
120 def test_select(self):
121 a = SelectableInt(0b00001111, 8)
122 br = BitRange()
123 br[0] = 0
124 br[1] = 1
125 br[2] = 4
126 br[3] = 5
127 fs = FieldSelectableInt(a, br)
128
129 self.assertEqual(fs.get_range(), 0b0011)
130
131 def test_select_range(self):
132 a = SelectableInt(0b00001111, 8)
133 br = BitRange()
134 br[0] = 0
135 br[1] = 1
136 br[2] = 4
137 br[3] = 5
138 fs = FieldSelectableInt(a, br)
139
140 self.assertEqual(fs[2:4], 0b11)
141
142 fs[0:2] = 0b10
143 self.assertEqual(fs.get_range(), 0b1011)
144
145
146
147 class SelectableInt:
148 def __init__(self, value, bits):
149 if isinstance(value, SelectableInt):
150 value = value.value
151 mask = (1 << bits) - 1
152 self.value = value & mask
153 self.bits = bits
154
155 def eq(self, b):
156 self.value = b.value
157 self.bits = b.bits
158
159 def __add__(self, 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(self.value + b.value, self.bits)
165
166 def __sub__(self, b):
167 if isinstance(b, int):
168 b = SelectableInt(b, self.bits)
169 b = check_extsign(self, b)
170 assert b.bits == self.bits
171 return SelectableInt(self.value - b.value, self.bits)
172
173 def __rsub__(self, b):
174 if isinstance(b, int):
175 b = SelectableInt(b, self.bits)
176 b = check_extsign(self, b)
177 assert b.bits == self.bits
178 return SelectableInt(b.value - self.value, self.bits)
179
180 def __radd__(self, b):
181 if isinstance(b, int):
182 b = SelectableInt(b, self.bits)
183 b = check_extsign(self, b)
184 assert b.bits == self.bits
185 return SelectableInt(b.value + self.value, self.bits)
186
187 def __mul__(self, b):
188 b = check_extsign(self, b)
189 assert b.bits == self.bits
190 return SelectableInt(self.value * b.value, self.bits)
191
192 def __div__(self, b):
193 b = check_extsign(self, b)
194 assert b.bits == self.bits
195 return SelectableInt(self.value / b.value, self.bits)
196
197 def __mod__(self, b):
198 b = check_extsign(self, b)
199 assert b.bits == self.bits
200 return SelectableInt(self.value % b.value, self.bits)
201
202 def __or__(self, b):
203 b = check_extsign(self, b)
204 assert b.bits == self.bits
205 return SelectableInt(self.value | b.value, self.bits)
206
207 def __and__(self, b):
208 print ("__and__", self, b)
209 b = check_extsign(self, b)
210 assert b.bits == self.bits
211 return SelectableInt(self.value & b.value, self.bits)
212
213 def __xor__(self, b):
214 b = check_extsign(self, b)
215 assert b.bits == self.bits
216 return SelectableInt(self.value ^ b.value, self.bits)
217
218 def __rxor__(self, b):
219 b = check_extsign(self, b)
220 assert b.bits == self.bits
221 return SelectableInt(self.value ^ b.value, self.bits)
222
223 def __invert__(self):
224 return SelectableInt(~self.value, self.bits)
225
226 def __neg__(self):
227 return SelectableInt(~self.value + 1, self.bits)
228
229 def __lshift__(self, b):
230 b = check_extsign(self, b)
231 return SelectableInt(self.value << b.value, self.bits)
232
233 def __rshift__(self, b):
234 b = check_extsign(self, b)
235 return SelectableInt(self.value >> b.value, self.bits)
236
237 def __getitem__(self, key):
238 if isinstance(key, SelectableInt):
239 key = key.value
240 if isinstance(key, int):
241 assert key < self.bits, "key %d accessing %d" % (key, self.bits)
242 assert key >= 0
243 # NOTE: POWER 3.0B annotation order! see p4 1.3.2
244 # MSB is indexed **LOWEST** (sigh)
245 key = self.bits - (key + 1)
246
247 value = (self.value >> key) & 1
248 return SelectableInt(value, 1)
249 elif isinstance(key, slice):
250 assert key.step is None or key.step == 1
251 assert key.start < key.stop
252 assert key.start >= 0
253 assert key.stop <= self.bits
254
255 stop = self.bits - key.start
256 start = self.bits - key.stop
257
258 bits = stop - start
259 #print ("__getitem__ slice num bits", bits)
260 mask = (1 << bits) - 1
261 value = (self.value >> start) & mask
262 return SelectableInt(value, bits)
263
264 def __setitem__(self, key, value):
265 if isinstance(key, SelectableInt):
266 key = key.value
267 if isinstance(key, int):
268 assert key < self.bits
269 assert key >= 0
270 key = self.bits - (key + 1)
271 if isinstance(value, SelectableInt):
272 assert value.bits == 1
273 value = value.value
274
275 value = value << key
276 mask = 1 << key
277 self.value = (self.value & ~mask) | (value & mask)
278 elif isinstance(key, slice):
279 assert key.step is None or key.step == 1
280 assert key.start < key.stop
281 assert key.start >= 0
282 assert key.stop <= self.bits
283
284 stop = self.bits - key.start
285 start = self.bits - key.stop
286
287 bits = stop - start
288 #print ("__setitem__ slice num bits", bits)
289 if isinstance(value, SelectableInt):
290 assert value.bits == bits, "%d into %d" % (value.bits, bits)
291 value = value.value
292 mask = ((1 << bits) - 1) << start
293 value = value << start
294 self.value = (self.value & ~mask) | (value & mask)
295
296 def __ge__(self, other):
297 if isinstance(other, FieldSelectableInt):
298 other = other.get_range()
299 if isinstance(other, SelectableInt):
300 other = check_extsign(self, other)
301 assert other.bits == self.bits
302 other = other.value
303 if isinstance(other, int):
304 return onebit(self.value >= other.value)
305 assert False
306
307 def __le__(self, other):
308 if isinstance(other, FieldSelectableInt):
309 other = other.get_range()
310 if isinstance(other, SelectableInt):
311 other = check_extsign(self, other)
312 assert other.bits == self.bits
313 other = other.value
314 if isinstance(other, int):
315 return onebit(self.value <= other)
316 assert False
317
318 def __gt__(self, other):
319 if isinstance(other, FieldSelectableInt):
320 other = other.get_range()
321 if isinstance(other, SelectableInt):
322 other = check_extsign(self, other)
323 assert other.bits == self.bits
324 other = other.value
325 if isinstance(other, int):
326 return onebit(self.value > other)
327 assert False
328
329 def __lt__(self, other):
330 if isinstance(other, FieldSelectableInt):
331 other = other.get_range()
332 if isinstance(other, SelectableInt):
333 other = check_extsign(self, other)
334 assert other.bits == self.bits
335 other = other.value
336 if isinstance(other, int):
337 return onebit(self.value < other)
338 assert False
339
340 def __eq__(self, other):
341 print ("__eq__", self, other)
342 if isinstance(other, FieldSelectableInt):
343 other = other.get_range()
344 if isinstance(other, SelectableInt):
345 other = check_extsign(self, other)
346 assert other.bits == self.bits
347 other = other.value
348 if isinstance(other, int):
349 return onebit(other == self.value)
350 assert False
351
352 def narrow(self, bits):
353 assert bits <= self.bits
354 return SelectableInt(self.value, bits)
355
356 def __bool__(self):
357 return self.value != 0
358
359 def __repr__(self):
360 return "SelectableInt(value=0x{:x}, bits={})".format(self.value,
361 self.bits)
362
363 def __len__(self):
364 return self.bits
365
366 def asint(self):
367 return self.value
368
369 def onebit(bit):
370 return SelectableInt(1 if bit else 0, 1)
371
372 def selectltu(lhs, rhs):
373 """ less-than (unsigned)
374 """
375 if isinstance(rhs, SelectableInt):
376 rhs = rhs.value
377 return onebit(lhs.value < rhs)
378
379 def selectgtu(lhs, rhs):
380 """ greater-than (unsigned)
381 """
382 if isinstance(rhs, SelectableInt):
383 rhs = rhs.value
384 return onebit(lhs.value > rhs)
385
386
387 # XXX this probably isn't needed...
388 def selectassign(lhs, idx, rhs):
389 if isinstance(idx, tuple):
390 if len(idx) == 2:
391 lower, upper = idx
392 step = None
393 else:
394 lower, upper, step = idx
395 toidx = range(lower, upper, step)
396 fromidx = range(0, upper-lower, step) # XXX eurgh...
397 else:
398 toidx = [idx]
399 fromidx = [0]
400 for t, f in zip(toidx, fromidx):
401 lhs[t] = rhs[f]
402
403
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
408 tmp = []
409 for i in range(repeat):
410 tmp += args
411 args = tmp
412 res = copy(args[0])
413 for i in args[1:]:
414 if isinstance(i, FieldSelectableInt):
415 i = i.si
416 assert isinstance(i, SelectableInt), "can only concat SIs, sorry"
417 res.bits += i.bits
418 res.value = (res.value << i.bits) | i.value
419 print ("concat", repeat, res)
420 return res
421
422
423 class SelectableIntTestCase(unittest.TestCase):
424 def test_arith(self):
425 a = SelectableInt(5, 8)
426 b = SelectableInt(9, 8)
427 c = a + b
428 d = a - b
429 e = a * b
430 f = -a
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)
438
439 def test_logic(self):
440 a = SelectableInt(0x0F, 8)
441 b = SelectableInt(0xA5, 8)
442 c = a & b
443 d = a | b
444 e = a ^ b
445 f = ~a
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)
450
451 def test_get(self):
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)
457
458 def test_set(self):
459 a = SelectableInt(0x5, 8)
460 a[7] = SelectableInt(0, 1)
461 self.assertEqual(a, 4)
462 a[4:8] = 9
463 self.assertEqual(a, 9)
464 a[0:4] = 3
465 self.assertEqual(a, 0x39)
466 a[0:4] = a[4:8]
467 self.assertEqual(a, 0x99)
468
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)
478
479 def test_repr(self):
480 for i in range(65536):
481 a = SelectableInt(i, 16)
482 b = eval(repr(a))
483 self.assertEqual(a, b)
484
485 def test_cmp(self):
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)
492
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)
500
501 if __name__ == "__main__":
502 unittest.main()