off-by-one in SelectableInt slices
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 2 Apr 2020 19:17:59 +0000 (20:17 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 3 Apr 2020 14:20:38 +0000 (15:20 +0100)
src/soc/decoder/selectable_int.py

index e1fd8d64699738801e59fd5ba90c2cda26dfe09e..4ca2de366b1cf012c046d96bbfe12bc912847987 100644 (file)
@@ -55,7 +55,7 @@ class SelectableInt:
             stop = self.bits - key.start
             start = self.bits - key.stop
 
-            bits = stop - start
+            bits = stop - start + 1
             mask = (1 << bits) - 1
             value = (self.value >> start) & mask
             return SelectableInt(value, bits)
@@ -81,9 +81,9 @@ class SelectableInt:
             stop = self.bits - key.start
             start = self.bits - key.stop
 
-            bits = stop - start
+            bits = stop - start + 1
             if isinstance(value, SelectableInt):
-                assert value.bits == bits
+                assert value.bits == bits, "%d into %d" % (value.bits, bits)
                 value = value.value
             mask = ((1 << bits) - 1) << start
             value = value << start
@@ -100,6 +100,23 @@ class SelectableInt:
         return "SelectableInt(value={:x}, bits={})".format(self.value,
                                                            self.bits)
 
+# XXX this probably isn't needed...
+def selectassign(lhs, idx, rhs):
+    if isinstance(idx, tuple):
+        if len(idx) == 2:
+            lower, upper = idx
+            step = None
+        else:
+            lower, upper, step = idx
+        toidx = range(lower, upper, step)
+        fromidx = range(0, upper-lower, step) # XXX eurgh...
+    else:
+        toidx = [idx]
+        fromidx = [0]
+    for t, f in zip(toidx, fromidx):
+        lhs[t] = rhs[f]
+
+
 def selectconcat(*args):
     res = copy(args[0])
     for i in args[1:]:
@@ -154,8 +171,7 @@ class SelectableIntTestCase(unittest.TestCase):
         a[0:4] = 3
         self.assertEqual(a, 0x39)
         a[0:4] = a[4:8]
-        self.assertEqual(a, 0x99)
-
+        self.assertEqual(a, 0x199)
 
 if __name__ == "__main__":
     unittest.main()