From: Michael Nolan Date: Wed, 1 Apr 2020 18:22:28 +0000 (-0400) Subject: selectable_int now in power ordering, add setitem X-Git-Tag: div_pipeline~1574 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6461fe7a0d01821ee3d63ef98856e6ca782c6419;p=soc.git selectable_int now in power ordering, add setitem --- diff --git a/src/soc/decoder/selectable_int.py b/src/soc/decoder/selectable_int.py index daa834ac..ad3bfdc1 100644 --- a/src/soc/decoder/selectable_int.py +++ b/src/soc/decoder/selectable_int.py @@ -1,4 +1,6 @@ import unittest + + class SelectableInt: def __init__(self, value, bits): self.value = value @@ -12,6 +14,7 @@ class SelectableInt: if isinstance(key, int): assert key < self.bits assert key >= 0 + key = self.bits - (key + 1) value = (self.value >> key) & 1 return SelectableInt(value, 1) @@ -21,11 +24,43 @@ class SelectableInt: assert key.start >= 0 assert key.stop <= self.bits - bits = key.stop - key.start + stop = self.bits - key.start + start = self.bits - key.stop + + bits = stop - start mask = (1 << bits) - 1 - value = (self.value >> key.start) & mask + value = (self.value >> start) & mask return SelectableInt(value, bits) - + + def __setitem__(self, key, value): + if isinstance(key, int): + assert key < self.bits + assert key >= 0 + key = self.bits - (key + 1) + if isinstance(value, SelectableInt): + assert value.bits == 1 + value = value.value + + value = value << key + mask = 1 << key + self.value = (self.value & ~mask) | (value & mask) + elif isinstance(key, slice): + assert key.step is None or key.step == 1 + assert key.start < key.stop + assert key.start >= 0 + assert key.stop <= self.bits + + stop = self.bits - key.start + start = self.bits - key.stop + + bits = stop - start + if isinstance(value, SelectableInt): + assert value.bits == bits + value = value.value + mask = ((1 << bits) - 1) << start + value = value << start + self.value = (self.value & ~mask) | (value & mask) + def __eq__(self, other): if isinstance(other, SelectableInt): return other.value == self.value and other.bits == self.bits @@ -34,7 +69,8 @@ class SelectableInt: assert False def __repr__(self): - return "SelectableInt(value={:x}, bits={})".format(self.value, self.bits) + return "SelectableInt(value={:x}, bits={})".format(self.value, + self.bits) class SelectableIntTestCase(unittest.TestCase): @@ -45,12 +81,23 @@ class SelectableIntTestCase(unittest.TestCase): assert c.value == a.value + b.value assert c.bits == a.bits - def test_select(self): - a = SelectableInt(0xa5, 8) - assert a[0] == 1 - assert a[0:1] == 1 - assert a[0:4] == 5 - assert a[4:8] == 10 + def test_get(self): + a = SelectableInt(0xa2, 8) + # These should be big endian + assert a[7] == 0 + assert a[0:4] == 10 + assert a[4:8] == 2 + + def test_set(self): + a = SelectableInt(0x5, 8) + a[7] = SelectableInt(0, 1) + self.assertEqual(a, 4) + a[4:8] = 9 + self.assertEqual(a, 9) + a[0:4] = 3 + self.assertEqual(a, 0x39) + a[0:4] = a[4:8] + self.assertEqual(a, 0x99) if __name__ == "__main__":