sorting out div/mod routines, bug in simulator
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 26 Aug 2020 14:26:09 +0000 (15:26 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 26 Aug 2020 14:26:09 +0000 (15:26 +0100)
src/nmutil/byterev.py
src/nmutil/divmod.py

index 2e5c41ab26be17c37642a372af9516f4207e02a5..52deddf22e8588d8708b4370ade4342b100963db 100644 (file)
@@ -1,4 +1,4 @@
-from nmigen import Signal
+from nmigen import Signal, Cat
 
 # TODO: turn this into a module
 def byte_reverse(m, name, data, length):
@@ -12,19 +12,20 @@ def byte_reverse(m, name, data, length):
 
     if isinstance(length, int):
         j = length
+        rev = []
         for i in range(j):
             dest = data_r.word_select(i, 8)
-            src = data.word_select(j-1-i, 8)
-            comb += dest.eq(src)
+            res.append(data.word_select(j-1-i, 8))
+        comb += data_r.eq(Cat(*rev))
         return data_r
 
     with m.Switch(length):
         for j in [1,2,4,8]:
             with m.Case(j):
+                rev = []
                 for i in range(j):
-                    dest = data_r.word_select(i, 8)
-                    src = data.word_select(j-1-i, 8)
-                    comb += dest.eq(src)
+                    rev.append(data.word_select(j-1-i, 8))
+                comb += data_r.eq(Cat(*rev))
     return data_r
 
 
index 99e6847631b1b9621d80b5bd4878d038a848fff0..f827d5379a387083fbeaa2d065b5ea62c70f090f 100644 (file)
@@ -1,15 +1,25 @@
+from copy import copy
 # this is a POWER ISA 3.0B compatible *signed* div function
 # however it is also the c, c++, rust, java *and* x86 way of doing things
 def trunc_divs(n, d):
-    abs_n = abs(n)
-    abs_d = abs(d)
+    abs_n = abs(n.to_signed_int())
+    abs_d = abs(d.to_signed_int())
+    print("trunc_div n", abs_n, n.to_signed_int())
+    print("trunc_div d", abs_d, d.to_signed_int())
     abs_q = abs_n // abs_d
-    print ("trunc_div", n.value, d.value,
-                        abs_n.value, abs_d.value, abs_q.value,
-                        n == abs_n, d == abs_d)
-    if (n == abs_n) == (d == abs_d):
-        return abs_q
-    return -abs_q
+    sign_n = n.value & (1 << (n.bits - 1)) != 0
+    sign_d = d.value & (1 << (d.bits - 1)) != 0
+    print ("trunc_div", hex(n.value), hex(d.value),
+                        hex(abs_n), hex(abs_d), hex(abs_q),
+                        sign_n, sign_d)
+    res = copy(n)
+    if (sign_n == sign_d):
+        res.value = abs_q
+        return res
+    mask = (1 << res.bits) - 1
+    res.value = (-abs_q) & mask
+
+    return res
 
 
 # this is a POWER ISA 3.0B compatible *signed* mod / remainder function