start on converting MUL and DIV pipelines to XLEN
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 27 Feb 2022 18:37:37 +0000 (18:37 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 27 Feb 2022 18:37:37 +0000 (18:37 +0000)
src/soc/fu/div/pipe_data.py
src/soc/fu/div/setup_stage.py
src/soc/fu/mul/pipe_data.py
src/soc/fu/mul/pre_stage.py

index dd4d1bedc0eecb3fee67632dccd0b04480fd0f72..1c807dc05492f5b654cf70f1443e55cef99774bb 100644 (file)
@@ -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,
index 0625159e123b67658a7e667327835ec637b2a038..5fe049786ae9074e30e39a48fe4939b0e7382ba3 100644 (file)
@@ -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 #####
 
index 072c5da647451ab77d9938c88664e2becc29e243..ded4c5089a56dd22319a2343324830a9a99bd8f6 100644 (file)
@@ -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)
index c5e696ae415afbe03e294c4f386c22316c34c7d0..a8a7fb4e5201ad479d22a9a61c7d7bb7dfa14034 100644 (file)
@@ -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))