clear out DEC in core.cur_state.dec due to spurious interrupt.
[soc.git] / src / soc / fu / spr / main_stage.py
index cca0c24e3c94ac9e18071310701198d31449fa63..b3a49cb642e9509732eaa3763599180b718a41f9 100644 (file)
@@ -7,11 +7,11 @@
 from nmigen import (Module, Signal, Cat)
 from nmutil.pipemodbase import PipeModBase
 from soc.fu.spr.pipe_data import SPRInputData, SPROutputData
-from soc.decoder.power_enums import MicrOp, SPRfull, SPRreduced, XER_bits
+from openpower.decoder.power_enums import MicrOp, SPRfull, SPRreduced, XER_bits
 
-from soc.decoder.power_fields import DecodeFields
-from soc.decoder.power_fieldsn import SignalBitRange
-from soc.decoder.power_decoder2 import decode_spr_num
+from openpower.decoder.power_fields import DecodeFields
+from openpower.decoder.power_fieldsn import SignalBitRange
+from openpower.decoder.power_decoder2 import decode_spr_num
 
 
 class SPRMainStage(PipeModBase):
@@ -19,7 +19,7 @@ class SPRMainStage(PipeModBase):
         super().__init__(pspec, "spr_main")
         # test if regfiles are reduced
         self.regreduce_en = (hasattr(pspec, "regreduce") and
-                                            (pspec.regreduce == True))
+                             (pspec.regreduce == True))
 
         self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
         self.fields.create_specs()
@@ -44,6 +44,7 @@ class SPRMainStage(PipeModBase):
         so_i, ov_i, ca_i = self.i.xer_so, self.i.xer_ov, self.i.xer_ca
         so_o, ov_o, ca_o = self.o.xer_so, self.o.xer_ov, self.o.xer_ca
         o, spr1_o, fast1_o = self.o.o, self.o.spr1, self.o.fast1
+        state1_i, state1_o = self.i.state1, self.o.state1
 
         # take copy of D-Form TO field
         x_fields = self.fields.FormXFX
@@ -55,9 +56,18 @@ class SPRMainStage(PipeModBase):
             #### MTSPR ####
             with m.Case(MicrOp.OP_MTSPR):
                 with m.Switch(spr):
-                    # fast SPRs first
+                    # State SPRs first, note that this triggers a regfile write
+                    # which is monitored right the way down in TestIssuerBase.
+                    with m.Case(SPR.DEC, SPR.TB):
+                        comb += state1_o.data.eq(a_i)
+                        comb += state1_o.ok.eq(1)
+
+                    # Fast SPRs second: anything in FAST regs
                     with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0,
-                                SPR.SRR1, SPR.XER, SPR.DEC):
+                                SPR.SRR1, SPR.XER, SPR.HSRR0, SPR.HSRR1,
+                                SPR.SPRG0_priv, SPR.SPRG1_priv,
+                                SPR.SPRG2_priv, SPR.SPRG3,
+                                SPR.HSPRG0, SPR.HSPRG1, SPR.SVSRR0):
                         comb += fast1_o.data.eq(a_i)
                         comb += fast1_o.ok.eq(1)
                         # XER is constructed
@@ -83,15 +93,25 @@ class SPRMainStage(PipeModBase):
             with m.Case(MicrOp.OP_MFSPR):
                 comb += o.ok.eq(1)
                 with m.Switch(spr):
-                    # fast SPRs first
-                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1,
-                                SPR.XER, SPR.DEC, SPR.TB):
+                    # state SPRs first
+                    with m.Case(SPR.DEC, SPR.TB):
+                        comb += o.data.eq(state1_i)
+                    # TBU is upper 32-bits of State Reg
+                    with m.Case(SPR.TBU):
+                        comb += o.data[0:32].eq(state1_i[32:64])
+
+                    # fast SPRs second
+                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0,
+                                SPR.SRR1, SPR.XER, SPR.HSRR0, SPR.HSRR1,
+                                SPR.SPRG0_priv, SPR.SPRG1_priv,
+                                SPR.SPRG2_priv, SPR.SPRG3,
+                                SPR.HSPRG0, SPR.HSPRG1, SPR.SVSRR0):
                         comb += o.data.eq(fast1_i)
                         with m.If(spr == SPR.XER):
                             # bits 0:31 and 35:43 are treated as reserved
                             # and return 0s when read using mfxer
                             comb += o[32:64].eq(0)       # MBS0 bits 0-31
-                            comb += o[63-43:64-35].eq(0) # MSB0 bits 35-43
+                            comb += o[63-43:64-35].eq(0)  # MSB0 bits 35-43
                             # sticky
                             comb += o[63-XER_bits['SO']].eq(so_i)
                             # overflow
@@ -100,9 +120,6 @@ class SPRMainStage(PipeModBase):
                             # carry
                             comb += o[63-XER_bits['CA']].eq(ca_i[0])
                             comb += o[63-XER_bits['CA32']].eq(ca_i[1])
-                    with m.Case(SPR.TBU):
-                        comb += o.data[0:32].eq(fast1_i[32:64])
-
                     # slow SPRs TODO
                     with m.Default():
                         comb += o.data.eq(spr1_i)