create common input pipe spec to avoid code-duplication
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 22 May 2020 15:32:44 +0000 (16:32 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 22 May 2020 15:32:44 +0000 (16:32 +0100)
src/soc/fu/common_input_stage.py [new file with mode: 0644]
src/soc/fu/shift_rot/formal/proof_main_stage.py
src/soc/fu/shift_rot/input_stage.py
src/soc/fu/shift_rot/main_stage.py
src/soc/fu/shift_rot/pipe_data.py
src/soc/fu/shift_rot/test/test_pipe_caller.py

diff --git a/src/soc/fu/common_input_stage.py b/src/soc/fu/common_input_stage.py
new file mode 100644 (file)
index 0000000..39c56a8
--- /dev/null
@@ -0,0 +1,44 @@
+# This stage is intended to adjust the input data before sending it to
+# the acutal ALU. Things like handling inverting the input, carry_in
+# generation for subtraction, should happen here
+from nmigen import (Module, Signal)
+from nmutil.pipemodbase import PipeModBase
+from soc.decoder.power_enums import InternalOp
+from soc.decoder.power_enums import CryIn
+
+
+class CommonInputStage(PipeModBase):
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        ##### operand A #####
+
+        # operand a to be as-is or inverted
+        a = Signal.like(self.i.a)
+
+        with m.If(self.i.ctx.op.invert_a):
+            comb += a.eq(~self.i.a)
+        with m.Else():
+            comb += a.eq(self.i.a)
+
+        comb += self.o.a.eq(a)
+
+        ##### carry-in #####
+
+        # either copy incoming carry or set to 1/0 as defined by op
+        with m.Switch(self.i.ctx.op.input_carry):
+            with m.Case(CryIn.ZERO):
+                comb += self.o.xer_ca.eq(0b00)
+            with m.Case(CryIn.ONE):
+                comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
+            with m.Case(CryIn.CA):
+                comb += self.o.xer_ca.eq(self.i.xer_ca)
+
+        ##### sticky overflow and context (both pass-through) #####
+
+        comb += self.o.xer_so.eq(self.i.xer_so)
+        comb += self.o.ctx.eq(self.i.ctx)
+
+        return m
index afcf12e7dcb6837b776cc0e108876b415b7b605e..129a95794e1362833e2ea8f0af18ac8957a38c6a 100644 (file)
@@ -26,20 +26,17 @@ class Driver(Elaboratable):
         comb = m.d.comb
 
         rec = CompALUOpSubset()
-        recwidth = 0
         # Setup random inputs for dut.op
         for p in rec.ports():
-            width = p.width
-            recwidth += width
-            comb += p.eq(AnyConst(width))
+            comb += p.eq(AnyConst(p.width))
 
-        pspec = ALUPipeSpec(id_wid=2, op_wid=recwidth)
+        pspec = ALUPipeSpec(id_wid=2)
         m.submodules.dut = dut = ShiftRotMainStage(pspec)
 
         # convenience variables
         a = dut.i.rs
         b = dut.i.rb
-        ra = dut.i.ra
+        ra = dut.i.a
         carry_in = dut.i.xer_ca[0]
         carry_in32 = dut.i.xer_ca[1]
         so_in = dut.i.xer_so
index 83df5a7fe162b70674ba18e3541bb87577692a71..f195b40e82e3a1294662ea739f61b5651ade3f06 100644 (file)
@@ -2,15 +2,11 @@
 # the acutal ALU. Things like handling inverting the input, carry_in
 # generation for subtraction, and handling of immediates should happen
 # here
-from nmigen import (Module, Signal, Cat, Const, Mux, Repl, signed,
-                    unsigned)
-from nmutil.pipemodbase import PipeModBase
-from soc.decoder.power_enums import InternalOp
+from soc.fu.common_input_stage import CommonInputStage
 from soc.fu.shift_rot.pipe_data import ShiftRotInputData
-from soc.decoder.power_enums import CryIn
 
 
-class ShiftRotInputStage(PipeModBase):
+class ShiftRotInputStage(CommonInputStage):
     def __init__(self, pspec):
         super().__init__(pspec, "input")
 
@@ -21,38 +17,11 @@ class ShiftRotInputStage(PipeModBase):
         return ShiftRotInputData(self.pspec)
 
     def elaborate(self, platform):
-        m = Module()
+        m = super().elaborate(platform) # handles A, carry and sticky overflow
         comb = m.d.comb
 
-        ##### operand A #####
-
-        # operand a to be as-is or inverted
-        a = Signal.like(self.i.ra)
-
-        with m.If(self.i.ctx.op.invert_a):
-            comb += a.eq(~self.i.ra)
-        with m.Else():
-            comb += a.eq(self.i.ra)
-
-        comb += self.o.ra.eq(a)
+        # operands ra and rb
         comb += self.o.rb.eq(self.i.rb)
         comb += self.o.rs.eq(self.i.rs)
 
-
-        ##### carry-in #####
-
-        # either copy incoming carry or set to 1/0 as defined by op
-        with m.Switch(self.i.ctx.op.input_carry):
-            with m.Case(CryIn.ZERO):
-                comb += self.o.xer_ca.eq(0b00)
-            with m.Case(CryIn.ONE):
-                comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
-            with m.Case(CryIn.CA):
-                comb += self.o.xer_ca.eq(self.i.xer_ca)
-
-        ##### sticky overflow and context (both pass-through) #####
-
-        comb += self.o.xer_so.eq(self.i.xer_so)
-        comb += self.o.ctx.eq(self.i.ctx)
-
         return m
index be5b47d54b871c23fde2d6124bd460851f39cf14..10949c550a5580f2e9935a4fd47a3308184d1724 100644 (file)
@@ -29,6 +29,7 @@ class ShiftRotMainStage(PipeModBase):
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
+        op = self.i.ctx.op
 
         # obtain me and mb fields from instruction.
         m_fields = self.fields.instrs['M']
@@ -47,15 +48,15 @@ class ShiftRotMainStage(PipeModBase):
             rotator.mb.eq(mb),
             rotator.mb_extra.eq(mb_extra),
             rotator.rs.eq(self.i.rs),
-            rotator.ra.eq(self.i.ra),
+            rotator.ra.eq(self.i.a),
             rotator.shift.eq(self.i.rb),
-            rotator.is_32bit.eq(self.i.ctx.op.is_32bit),
-            rotator.arith.eq(self.i.ctx.op.is_signed),
+            rotator.is_32bit.eq(op.is_32bit),
+            rotator.arith.eq(op.is_signed),
         ]
 
         # instruction rotate type
         mode = Signal(3, reset_less=True)
-        with m.Switch(self.i.ctx.op.insn_type):
+        with m.Switch(op.insn_type):
             with m.Case(InternalOp.OP_SHL):  comb += mode.eq(0b000)
             with m.Case(InternalOp.OP_SHR):  comb += mode.eq(0b001) # R-shift
             with m.Case(InternalOp.OP_RLC):  comb += mode.eq(0b110) # clear LR
index 8b0139e187937a3f0cbc25c8d6daa4ba46144759..1375ae0a26041c2a8dcfab1743103040ec8b1574 100644 (file)
@@ -8,14 +8,14 @@ from nmutil.dynamicpipe import SimpleHandshakeRedir
 
 
 class ShiftRotInputData(IntegerData):
-    regspec = [('INT', 'ra', '0:63'),
+    regspec = [('INT', 'a', '0:63'),
                ('INT', 'rs', '0:63'),
                ('INT', 'rb', '0:63'),
                ('XER', 'xer_so', '32'),
                ('XER', 'xer_ca', '34,45')]
     def __init__(self, pspec):
         super().__init__(pspec)
-        self.ra = Signal(64, reset_less=True) # RA
+        self.a = Signal(64, reset_less=True) # RA
         self.rs = Signal(64, reset_less=True) # RS
         self.rb = Signal(64, reset_less=True) # RB/immediate
         self.xer_so = Signal(reset_less=True)    # XER bit 32: SO
@@ -23,7 +23,7 @@ class ShiftRotInputData(IntegerData):
 
     def __iter__(self):
         yield from super().__iter__()
-        yield self.ra
+        yield self.a
         yield self.rs
         yield self.rb
         yield self.xer_ca
@@ -31,7 +31,7 @@ class ShiftRotInputData(IntegerData):
 
     def eq(self, i):
         lst = super().eq(i)
-        return lst + [self.rs.eq(i.rs), self.ra.eq(i.ra),
+        return lst + [self.rs.eq(i.rs), self.a.eq(i.a),
                       self.rb.eq(i.rb),
                       self.xer_ca.eq(i.xer_ca),
                       self.xer_so.eq(i.xer_so)]
index bddda2194532d2cbc20a71927d3172717a139dd0..fb370525bade385e5e6d7bd9f6049c633d0a6e3e 100644 (file)
@@ -53,7 +53,7 @@ def set_alu_inputs(alu, dec2, sim):
     else:
         data2 = 0
 
-    yield alu.p.data_i.ra.eq(data1)
+    yield alu.p.data_i.a.eq(data1)
     yield alu.p.data_i.rb.eq(data2)
     yield alu.p.data_i.rs.eq(data3)