From 141d1216d42b5b6cf12791be2560927ec176b40f Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 7 Jun 2020 15:23:20 +0100 Subject: [PATCH] update rotator.py to match microwatt rotator.vhdl --- src/soc/fu/shift_rot/main_stage.py | 4 +++- src/soc/fu/shift_rot/rotator.py | 23 +++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/soc/fu/shift_rot/main_stage.py b/src/soc/fu/shift_rot/main_stage.py index eac9253b..ae9d59fb 100644 --- a/src/soc/fu/shift_rot/main_stage.py +++ b/src/soc/fu/shift_rot/main_stage.py @@ -53,6 +53,8 @@ class ShiftRotMainStage(PipeModBase): rotator.shift.eq(self.i.rb), rotator.is_32bit.eq(op.is_32bit), rotator.arith.eq(op.is_signed), + # rot_sign_ext <= '1' when e_in.insn_type = OP_EXTSWSLI else '0'; + rotator.sign_ext_rs.eq(0), # XXX TODO ] comb += o.ok.eq(1) # defaults to enabled @@ -71,7 +73,7 @@ class ShiftRotMainStage(PipeModBase): comb += Cat(rotator.right_shift, rotator.clear_left, rotator.clear_right).eq(mode) - + # outputs from the microwatt rotator module comb += [o.data.eq(rotator.result_o), self.o.xer_ca.data.eq(Repl(rotator.carry_out_o, 2))] diff --git a/src/soc/fu/shift_rot/rotator.py b/src/soc/fu/shift_rot/rotator.py index 4d2d659a..b5dc80ee 100644 --- a/src/soc/fu/shift_rot/rotator.py +++ b/src/soc/fu/shift_rot/rotator.py @@ -1,9 +1,11 @@ # Manual translation and adaptation of rotator.vhdl from microwatt into nmigen # -from nmigen import (Elaboratable, Signal, Module, Const, Cat, +from nmigen import (Elaboratable, Signal, Module, Const, Cat, Repl, unsigned, signed) from soc.fu.shift_rot.rotl import ROTL +from nmutil.extend import exts + # note BE bit numbering def right_mask(m, mask_begin): @@ -49,6 +51,7 @@ class Rotator(Elaboratable): self.arith = Signal(reset_less=True) self.clear_left = Signal(reset_less=True) self.clear_right = Signal(reset_less=True) + self.sign_ext_rs = Signal(reset_less=True) # output self.result_o = Signal(64, reset_less=True) self.carry_out_o = Signal(reset_less=True) @@ -59,7 +62,6 @@ class Rotator(Elaboratable): ra, rs = self.ra, self.rs # temporaries - rot_in = Signal(64, reset_less=True) rot_count = Signal(6, reset_less=True) rot = Signal(64, reset_less=True) sh = Signal(7, reset_less=True) @@ -68,13 +70,18 @@ class Rotator(Elaboratable): mr = Signal(64, reset_less=True) ml = Signal(64, reset_less=True) output_mode = Signal(2, reset_less=True) + hi32 = Signal(32, reset_less=True) + repl32 = Signal(64, reset_less=True) # First replicate bottom 32 bits to both halves if 32-bit - comb += rot_in[0:32].eq(rs[0:32]) with m.If(self.is_32bit): - comb += rot_in[32:64].eq(rs[0:32]) + comb += hi32.eq(rs[0:32]) + with m.Elif(self.sign_ext_rs): + # sign-extend bottom 32 bits + comb += hi32.eq(Repl(rs[31], 32)) with m.Else(): - comb += rot_in[32:64].eq(rs[32:64]) + comb += hi32.eq(rs[32:64]) + comb += repl32.eq(Cat(rs[0:32], hi32)) shift_signed = Signal(signed(6)) comb += shift_signed.eq(self.shift[0:6]) @@ -87,7 +94,7 @@ class Rotator(Elaboratable): # ROTL submodule m.submodules.rotl = rotl = ROTL(64) - comb += rotl.a.eq(rot_in) + comb += rotl.a.eq(repl32) comb += rotl.b.eq(rot_count) comb += rot.eq(rotl.o) @@ -133,7 +140,7 @@ class Rotator(Elaboratable): # 10 for rldicl, sr[wd] # 1z for sra[wd][i], z = 1 if rs is negative with m.If((self.clear_left & ~self.clear_right) | self.right_shift): - comb += output_mode.eq(Cat(self.arith & rot_in[63], Const(1, 1))) + comb += output_mode.eq(Cat(self.arith & repl32[63], Const(1, 1))) with m.Else(): mbgt = self.clear_right & (mb[0:6] > me[0:6]) comb += output_mode.eq(Cat(mbgt, Const(0, 1))) @@ -149,7 +156,7 @@ class Rotator(Elaboratable): with m.Case(0b11): comb += self.result_o.eq(rot | ~mr) # Generate carry output for arithmetic shift right of -ve value - comb += self.carry_out_o.eq(rs & ~ml) + comb += self.carry_out_o.eq((rs & ~ml).bool() & rs[0]) return m -- 2.30.2