From ad1580e6b637b821baa31d6303ec95885cb2013d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 26 Aug 2020 15:26:09 +0100 Subject: [PATCH] sorting out div/mod routines, bug in simulator --- src/nmutil/byterev.py | 13 +++++++------ src/nmutil/divmod.py | 26 ++++++++++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/nmutil/byterev.py b/src/nmutil/byterev.py index 2e5c41a..52deddf 100644 --- a/src/nmutil/byterev.py +++ b/src/nmutil/byterev.py @@ -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 diff --git a/src/nmutil/divmod.py b/src/nmutil/divmod.py index 99e6847..f827d53 100644 --- a/src/nmutil/divmod.py +++ b/src/nmutil/divmod.py @@ -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 -- 2.30.2