From 8aaa3876cc22950271d8e4cf622d1658efe93aef Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 27 Feb 2022 18:37:37 +0000 Subject: [PATCH] start on converting MUL and DIV pipelines to XLEN --- src/soc/fu/div/pipe_data.py | 21 +++++++++++++-------- src/soc/fu/div/setup_stage.py | 12 +++++++----- src/soc/fu/mul/pipe_data.py | 7 +++++-- src/soc/fu/mul/pre_stage.py | 9 +++++---- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/soc/fu/div/pipe_data.py b/src/soc/fu/div/pipe_data.py index dd4d1bed..1c807dc0 100644 --- a/src/soc/fu/div/pipe_data.py +++ b/src/soc/fu/div/pipe_data.py @@ -10,28 +10,33 @@ from ieee754.div_rem_sqrt_rsqrt.core import ( class DivInputData(FUBaseData): - regspec = [('INT', 'ra', '0:63'), # RA - ('INT', 'rb', '0:63'), # RB/immediate - ('XER', 'xer_so', '32'), ] # XER bit 32: SO - def __init__(self, pspec): super().__init__(pspec, False) # convenience self.a, self.b = self.ra, self.rb + @property + def regspec(self): + return [('INT', 'ra', self.intrange), # RA + ('INT', 'rb', self.intrange), # RB/immediate + ('XER', 'xer_so', '32'), ] # XER bit 32: SO + # output stage shared between div and mul: like ALUOutputData but no CA/32 class DivMulOutputData(FUBaseData): - regspec = [('INT', 'o', '0:63'), - ('CR', 'cr_a', '0:3'), - ('XER', 'xer_ov', '33,44'), # bit0: ov, bit1: ov32 - ('XER', 'xer_so', '32')] def __init__(self, pspec): super().__init__(pspec, True) # convenience self.cr0 = self.cr_a + @property + def regspec(self): + return [('INT', 'o', self.intrange), + ('CR', 'cr_a', '0:3'), + ('XER', 'xer_ov', '33,44'), # bit0: ov, bit1: ov32 + ('XER', 'xer_so', '32')] + class DivPipeKindConfigBase: def __init__(self, diff --git a/src/soc/fu/div/setup_stage.py b/src/soc/fu/div/setup_stage.py index 0625159e..5fe04978 100644 --- a/src/soc/fu/div/setup_stage.py +++ b/src/soc/fu/div/setup_stage.py @@ -27,6 +27,7 @@ class DivSetupStage(PipeModBase): return CoreInputData(self.pspec) def elaborate(self, platform): + XLEN = self.pspec.XLEN m = Module() comb = m.d.comb # convenience variables @@ -42,14 +43,15 @@ class DivSetupStage(PipeModBase): # work out if a/b are negative (check 32-bit / signed) comb += dividend_neg_o.eq(Mux(op.is_32bit, - a[31], a[63]) & op.is_signed) - comb += divisor_neg_o.eq(Mux(op.is_32bit, b[31], b[63]) & op.is_signed) + a[31], a[XLEN-1]) & op.is_signed) + comb += divisor_neg_o.eq(Mux(op.is_32bit, + b[31], b[XLEN-1]) & op.is_signed) # negation of a 64-bit value produces the same lower 32-bit # result as negation of just the lower 32-bits, so we don't # need to do anything special before negating - abs_dor = Signal(64, reset_less=True) # absolute of divisor - abs_dend = Signal(64, reset_less=True) # absolute of dividend + abs_dor = Signal(XLEN, reset_less=True) # absolute of divisor + abs_dend = Signal(XLEN, reset_less=True) # absolute of dividend comb += abs_dor.eq(Mux(divisor_neg_o, -b, b)) comb += abs_dend.eq(Mux(dividend_neg_o, -a, a)) @@ -78,7 +80,7 @@ class DivSetupStage(PipeModBase): with m.If(op.is_32bit): comb += dividend_o.eq(abs_dend[0:32] << 32) with m.Else(): - comb += dividend_o.eq(abs_dend[0:64] << 64) + comb += dividend_o.eq(abs_dend[0:XLEN] << XLEN) ###### sticky overflow and context, both pass-through ##### diff --git a/src/soc/fu/mul/pipe_data.py b/src/soc/fu/mul/pipe_data.py index 072c5da6..ded4c508 100644 --- a/src/soc/fu/mul/pipe_data.py +++ b/src/soc/fu/mul/pipe_data.py @@ -15,8 +15,6 @@ class MulIntermediateData(DivInputData): class MulOutputData(FUBaseData): - regspec = [('INT', 'o', '0:128'), - ('XER', 'xer_so', '32')] # XER bit 32: SO def __init__(self, pspec): super().__init__(pspec, False) # still input style @@ -25,6 +23,11 @@ class MulOutputData(FUBaseData): self.data.append(self.neg_res) self.data.append(self.neg_res32) + @property + def regspec(self): + return [('INT', 'o', "0:%d" % (self.pspec.XLEN)), + ('XER', 'xer_so', '32')] # XER bit 32: SO + class MulPipeSpec(CommonPipeSpec): regspecklses = (DivInputData, DivMulOutputData) diff --git a/src/soc/fu/mul/pre_stage.py b/src/soc/fu/mul/pre_stage.py index c5e696ae..a8a7fb4e 100644 --- a/src/soc/fu/mul/pre_stage.py +++ b/src/soc/fu/mul/pre_stage.py @@ -18,6 +18,7 @@ class MulMainStage1(PipeModBase): return MulIntermediateData(self.pspec) # pipeline stage output format def elaborate(self, platform): + XLEN = self.pspec.XLEN m = Module() comb = m.d.comb @@ -35,8 +36,8 @@ class MulMainStage1(PipeModBase): comb += is_32bit.eq(op.is_32bit) # work out if a/b are negative (check 32-bit / signed) - comb += sign_a.eq(Mux(op.is_32bit, a[31], a[63]) & op.is_signed) - comb += sign_b.eq(Mux(op.is_32bit, b[31], b[63]) & op.is_signed) + comb += sign_a.eq(Mux(op.is_32bit, a[31], a[XLEN-1]) & op.is_signed) + comb += sign_b.eq(Mux(op.is_32bit, b[31], b[XLEN-1]) & op.is_signed) comb += sign32_a.eq(a[31] & op.is_signed) comb += sign32_b.eq(b[31] & op.is_signed) @@ -47,8 +48,8 @@ class MulMainStage1(PipeModBase): # negation of a 64-bit value produces the same lower 32-bit # result as negation of just the lower 32-bits, so we don't # need to do anything special before negating - abs_a = Signal(64, reset_less=True) - abs_b = Signal(64, reset_less=True) + abs_a = Signal(XLEN, reset_less=True) + abs_b = Signal(XLEN, reset_less=True) comb += abs_a.eq(Mux(sign_a, -a, a)) comb += abs_b.eq(Mux(sign_b, -b, b)) -- 2.30.2