From adf352467743da99deeb1c2a6e98daffab4477ae Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 27 Aug 2020 14:58:25 +0100 Subject: [PATCH] sorting out shift_rot to use new output stage data structures shift_rot does not modify OV/32 so needs its own output stage similar to logical, SO is never set but is "read" --- .../compunits/test/test_shiftrot_compunit.py | 8 +++-- src/soc/fu/shift_rot/main_stage.py | 6 ++-- src/soc/fu/shift_rot/output_stage.py | 16 ++++++++++ src/soc/fu/shift_rot/pipe_data.py | 32 ++++++++++++++++--- src/soc/fu/shift_rot/pipeline.py | 4 +-- src/soc/fu/shift_rot/test/test_pipe_caller.py | 8 +---- 6 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 src/soc/fu/shift_rot/output_stage.py diff --git a/src/soc/fu/compunits/test/test_shiftrot_compunit.py b/src/soc/fu/compunits/test/test_shiftrot_compunit.py index d839e5ba..5392ce36 100644 --- a/src/soc/fu/compunits/test/test_shiftrot_compunit.py +++ b/src/soc/fu/compunits/test/test_shiftrot_compunit.py @@ -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) diff --git a/src/soc/fu/shift_rot/main_stage.py b/src/soc/fu/shift_rot/main_stage.py index 9b0d3fc0..1a3b8eff 100644 --- a/src/soc/fu/shift_rot/main_stage.py +++ b/src/soc/fu/shift_rot/main_stage.py @@ -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 index 00000000..d207d4ff --- /dev/null +++ b/src/soc/fu/shift_rot/output_stage.py @@ -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) + diff --git a/src/soc/fu/shift_rot/pipe_data.py b/src/soc/fu/shift_rot/pipe_data.py index cbcca907..adafe1af 100644 --- a/src/soc/fu/shift_rot/pipe_data.py +++ b/src/soc/fu/shift_rot/pipe_data.py @@ -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 diff --git a/src/soc/fu/shift_rot/pipeline.py b/src/soc/fu/shift_rot/pipeline.py index 7af49a20..80e46038 100644 --- a/src/soc/fu/shift_rot/pipeline.py +++ b/src/soc/fu/shift_rot/pipeline.py @@ -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] diff --git a/src/soc/fu/shift_rot/test/test_pipe_caller.py b/src/soc/fu/shift_rot/test/test_pipe_caller.py index 0b2666b0..62297a7e 100644 --- a/src/soc/fu/shift_rot/test/test_pipe_caller.py +++ b/src/soc/fu/shift_rot/test/test_pipe_caller.py @@ -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) -- 2.30.2