sorting out shift_rot to use new output stage data structures
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 27 Aug 2020 13:58:25 +0000 (14:58 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 27 Aug 2020 13:58:25 +0000 (14:58 +0100)
shift_rot does not modify OV/32 so needs its own output stage
similar to logical, SO is never set but is "read"

src/soc/fu/compunits/test/test_shiftrot_compunit.py
src/soc/fu/shift_rot/main_stage.py
src/soc/fu/shift_rot/output_stage.py [new file with mode: 0644]
src/soc/fu/shift_rot/pipe_data.py
src/soc/fu/shift_rot/pipeline.py
src/soc/fu/shift_rot/test/test_pipe_caller.py

index d839e5ba7572d92ad45229c9ec3bb50f27010c76..5392ce36a1c096950972ae086b4ff1024e5d2af6 100644 (file)
@@ -37,18 +37,20 @@ class ShiftRotTestRunner(TestRunner):
             self.assertEqual(expected, cu_out, code)
 
         rc = yield dec2.e.do.rc.data
+        rc_ok = yield dec2.e.do.rc.ok
         op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
-        print("check extra output", repr(code), cridx_ok, cridx)
+        print("check extra output", repr(code), "cr", cridx_ok, cridx,
+                                    "rc", rc, rc_ok)
 
-        if rc:
+        if rc and rc_ok:
             self.assertEqual(cridx_ok, 1, code)
             self.assertEqual(cridx, 0, code)
 
         # CR (CR0-7)
-        if cridx_ok:
+        if cridx_ok and rc and rc_ok:
             cr_expected = sim.crl[cridx].get_range().value
             cr_actual = res['cr_a']
             print("CR", cridx, cr_expected, cr_actual)
index 9b0d3fc05c5675cf1c315c2ac93b200ce1b12699..1a3b8eff0aadf54ade1b3d8819b5f0b0843103a7 100644 (file)
@@ -8,8 +8,8 @@
 # output stage
 from nmigen import (Module, Signal, Cat, Repl, Mux, Const)
 from nmutil.pipemodbase import PipeModBase
-from soc.fu.alu.pipe_data import ALUOutputData
-from soc.fu.shift_rot.pipe_data import ShiftRotInputData
+from soc.fu.shift_rot.pipe_data import (ShiftRotOutputData,
+                                       ShiftRotInputData)
 from ieee754.part.partsig import PartitionedSignal
 from soc.decoder.power_enums import MicrOp
 from soc.fu.shift_rot.rotator import Rotator
@@ -28,7 +28,7 @@ class ShiftRotMainStage(PipeModBase):
         return ShiftRotInputData(self.pspec)
 
     def ospec(self):
-        return ALUOutputData(self.pspec)
+        return ShiftRotOutputData(self.pspec)
 
     def elaborate(self, platform):
         m = Module()
diff --git a/src/soc/fu/shift_rot/output_stage.py b/src/soc/fu/shift_rot/output_stage.py
new file mode 100644 (file)
index 0000000..d207d4f
--- /dev/null
@@ -0,0 +1,16 @@
+# This stage is intended to handle the gating of carry and overflow
+# out, summary overflow generation, and updating the condition
+# register
+from soc.fu.common_output_stage import CommonOutputStage
+from soc.fu.shift_rot.pipe_data import (ShiftRotOutputData,
+                                      ShiftRotOutputDataFinal)
+
+
+class ShiftRotOutputStage(CommonOutputStage):
+
+    def ispec(self):
+        return ShiftRotOutputData(self.pspec)
+
+    def ospec(self):
+        return ShiftRotOutputDataFinal(self.pspec)
+
index cbcca907abc38b48eb9cecaeb7fbafb46ffba592..adafe1af08e77152c25f4b46d5fc07540234ca6e 100644 (file)
@@ -15,10 +15,32 @@ class ShiftRotInputData(IntegerData):
         self.a, self.b, self.rs = self.ra, self.rb, self.rc
 
 
-# sigh although ShiftRot never changes xer_ov it is just easier
-# right now to have it.  also SO never gets changed, although it
-# is an input (to create CR).  really need something similar to
-# MulOutputData which has xer_so yet derives from LogicalOutputData
+# input to shiftrot final stage (common output)
+class ShiftRotOutputData(IntegerData):
+    regspec = [('INT', 'o', '0:63'),        # RT
+               ('CR', 'cr_a', '0:3'),
+               ('XER', 'xer_so', '32'),    # bit0: so
+               ('XER', 'xer_ca', '34,45'), # XER bit 34/45: CA/CA32
+               ]
+    def __init__(self, pspec):
+        super().__init__(pspec, True)
+        # convenience
+        self.cr0 = self.cr_a
+
+
+# output from shiftrot final stage (common output) - note that XER.so
+# is *not* included (the only reason it's in the input is because of CR0)
+class ShiftRotOutputDataFinal(IntegerData):
+    regspec = [('INT', 'o', '0:63'),        # RT
+               ('CR', 'cr_a', '0:3'),
+               ('XER', 'xer_ca', '34,45'), # XER bit 34/45: CA/CA32
+               ]
+    def __init__(self, pspec):
+        super().__init__(pspec, True)
+        # convenience
+        self.cr0 = self.cr_a
+
+
 class ShiftRotPipeSpec(CommonPipeSpec):
-    regspec = (ShiftRotInputData.regspec, ALUOutputData.regspec)
+    regspec = (ShiftRotInputData.regspec, ShiftRotOutputDataFinal.regspec)
     opsubsetkls = CompSROpSubset
index 7af49a20e065e4c200985e1ac837faa45fa058b1..80e46038166e89194147b5c6d3a45f818fa417e8 100644 (file)
@@ -2,7 +2,7 @@ from nmutil.singlepipe import ControlBase
 from nmutil.pipemodbase import PipeModBaseChain
 from soc.fu.shift_rot.input_stage import ShiftRotInputStage
 from soc.fu.shift_rot.main_stage import ShiftRotMainStage
-from soc.fu.alu.output_stage import ALUOutputStage
+from soc.fu.shift_rot.output_stage import ShiftRotOutputStage
 
 class ShiftRotStages(PipeModBaseChain):
     def get_chain(self):
@@ -13,7 +13,7 @@ class ShiftRotStages(PipeModBaseChain):
 
 class ShiftRotStageEnd(PipeModBaseChain):
     def get_chain(self):
-        out = ALUOutputStage(self.pspec)
+        out = ShiftRotOutputStage(self.pspec)
         return [out]
 
 
index 0b2666b0f4a78ad91eeeda9703f9b0e2dd8ccf8f..62297a7ea485fc36cd4866aabf3ffe09e75dfe06 100644 (file)
@@ -217,7 +217,7 @@ class ShiftRotTestCase(TestAccumulatorBase):
         pspec = ShiftRotPipeSpec(id_wid=2)
         alu = ShiftRotBasePipe(pspec)
         vl = rtlil.convert(alu, ports=alu.ports())
-        with open("pipeline.il", "w") as f:
+        with open("shift_rot_pipeline.il", "w") as f:
             f.write(vl)
 
 
@@ -318,8 +318,6 @@ class TestRunner(unittest.TestCase):
 
         yield from ALUHelpers.get_cr_a(res, alu, dec2)
         yield from ALUHelpers.get_xer_ca(res, alu, dec2)
-        yield from ALUHelpers.get_xer_ov(res, alu, dec2)
-        yield from ALUHelpers.get_xer_so(res, alu, dec2)
         yield from ALUHelpers.get_int_o(res, alu, dec2)
 
         print ("hw outputs", res)
@@ -327,15 +325,11 @@ class TestRunner(unittest.TestCase):
         yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
         yield from ALUHelpers.get_wr_sim_cr_a(sim_o, sim, dec2)
         yield from ALUHelpers.get_wr_sim_xer_ca(sim_o, sim, dec2)
-        yield from ALUHelpers.get_sim_xer_ov(sim_o, sim, dec2)
-        yield from ALUHelpers.get_sim_xer_so(sim_o, sim, dec2)
 
         print ("sim outputs", sim_o)
 
         ALUHelpers.check_cr_a(self, res, sim_o, "CR%d %s" % (cridx, code))
         ALUHelpers.check_xer_ca(self, res, sim_o, code)
-        ALUHelpers.check_xer_so(self, res, sim_o, code)
-        ALUHelpers.check_xer_ov(self, res, sim_o, code)
         ALUHelpers.check_int_o(self, res, sim_o, code)