move DEC and TB into StateRegs, to make room in FastRegs
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 19 Jan 2022 12:16:25 +0000 (12:16 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 19 Jan 2022 12:16:25 +0000 (12:16 +0000)
also has the advantage that DEC and TB could generate an accurate interrupt

src/soc/fu/spr/main_stage.py
src/soc/fu/spr/pipe_data.py
src/soc/regfile/regfiles.py
src/soc/simple/core.py
src/soc/simple/issuer.py
src/soc/simple/test/test_core.py

index 64676e441fcadc6cb128133311ce091342623b83..d3da831f28c1d7afb397bd6b67bdd7e1db1aa875 100644 (file)
@@ -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
@@ -56,6 +57,11 @@ class SPRMainStage(PipeModBase):
             with m.Case(MicrOp.OP_MTSPR):
                 with m.Switch(spr):
                     # fast SPRs first
+                    with m.Case(SPR.DEC, SPR.TB):
+                        comb += state1_o.data.eq(a_i)
+                        comb += state1_o.ok.eq(1)
+
+                    # state SPRs second
                     with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0,
                                 SPR.SRR1, SPR.XER, SPR.DEC, SPR.TB):
                         comb += fast1_o.data.eq(a_i)
@@ -83,9 +89,13 @@ class SPRMainStage(PipeModBase):
             with m.Case(MicrOp.OP_MFSPR):
                 comb += o.ok.eq(1)
                 with m.Switch(spr):
-                    # fast SPRs first
+                    # state SPRs first
+                    with m.Case(SPR.DEC, SPR.TB):
+                        comb += o.data.eq(fast1_i)
+
+                    # fast SPRs second
                     with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1,
-                                SPR.XER, SPR.DEC, SPR.TB):
+                                SPR.XER):
                         comb += o.data.eq(fast1_i)
                         with m.If(spr == SPR.XER):
                             # bits 0:31 and 35:43 are treated as reserved
index bd0ed97e4e0a2dc4165d8b3e942d6d4575badc84..a6677750e8f7403d54b3cd4f073e1e81f9d0e3cd 100644 (file)
@@ -19,6 +19,7 @@ class SPRInputData(FUBaseData):
     regspec = [('INT', 'ra', '0:63'),        # RA
                ('SPR', 'spr1', '0:63'),      # SPR (slow)
                ('FAST', 'fast1', '0:63'),    # SPR (fast: LR, CTR etc)
+               ('STATE', 'state1', '0:63'),  # SPR (DEC/TB)
                ('XER', 'xer_so', '32'),      # XER bit 32: SO
                ('XER', 'xer_ov', '33,44'),   # XER bit 34/45: CA/CA32
                ('XER', 'xer_ca', '34,45')]   # bit0: ov, bit1: ov32
@@ -32,6 +33,7 @@ class SPROutputData(FUBaseData):
     regspec = [('INT', 'o', '0:63'),        # RT
                ('SPR', 'spr1', '0:63'),     # SPR (slow)
                ('FAST', 'fast1', '0:63'),   # SPR (fast: LR, CTR etc)
+               ('STATE', 'state1', '0:63'), # SPR (DEC/TB)
                ('XER', 'xer_so', '32'),     # XER bit 32: SO
                ('XER', 'xer_ov', '33,44'),  # XER bit 34/45: CA/CA32
                ('XER', 'xer_ca', '34,45')]  # bit0: ov, bit1: ov32
index f3531e092a335fb7ef2baa0e306af5fb1b72370d..9738a4c77f43714634d7e373351c1bf1b0b0cb15 100644 (file)
@@ -83,6 +83,8 @@ class StateRegs(RegFileArray, StateRegsEnum):
                         'nia': "nia",
                         'msr': "msr",
                         'svstate': "svstate",
+                        'issue': "issue", # writing DEC/TB
+                        'state1': "state1", # SPR pipeline
                         # these 3 allow writing state by Issuer
                         'sv': "sv", # writing SVSTATE
                         'd_wr1': "d_wr1", # writing PC
@@ -95,6 +97,9 @@ class StateRegs(RegFileArray, StateRegsEnum):
                         'cia': "cia", # reading PC (issuer)
                         'msr': "msr", # reading MSR (issuer)
                         'sv': "sv", # reading SV (issuer)
+                        # SPR and DEC/TB FSM
+                        'issue': "issue", # reading DEC/TB
+                        'state1': "state1", # SPR pipeline
                         }
         return w_port_spec, r_port_spec
 
@@ -136,7 +141,7 @@ class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
 class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
     """FastRegs
 
-    FAST regfile  - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC, SVSRR0
+    FAST regfile  - CTR, LR, TAR, SRR1, SRR2, XER, SVSRR0
 
     * QTY 6of 64-bit registers
     * 3R2W
@@ -154,10 +159,8 @@ class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
 
     def get_port_specs(self):
         w_port_spec = {'fast1': "dest1",
-                       'issue': "issue", # writing DEC/TB
                        }
         r_port_spec = {'fast1': "src1",
-                       'issue': "issue", # reading DEC/TB
                         'dmi': "dmi" # needed for Debug (DMI)
                         }
         if not self.regreduce_en:
@@ -319,7 +322,7 @@ class RegFiles:
 if __name__ == '__main__':
     m = Module()
     from soc.config.test.test_loadstore import TestMemPspec
-    pspec = TestMemPspec()
+    pspec = TestMemPspec(regreduce_en=True)
     rf = RegFiles(pspec, make_hazard_vecs=True)
     rf.elaborate_into(m, None)
     vl = rtlil.convert(m)
index 8df7e17ad1d1525233404694cb7602e708227b4d..507302f451a18e0a4f5252d4c8f088e58e05a420 100644 (file)
@@ -164,7 +164,9 @@ class NonProductionCore(ControlBase):
             self.msr_at_reset = pspec.msr_reset
         state_resets = [0x0,               # PC at reset
                         self.msr_at_reset, # MSR at reset
-                        0x0]               # SVSTATE at reset
+                        0x0,               # SVSTATE at reset
+                        0x0,               # DEC at reset
+                        0x0]               # TB at reset
 
         # register files (yes plural)
         self.regs = RegFiles(pspec, make_hazard_vecs=self.make_hazard_vecs,
index 958e3f11a99d43f1a6ef520c17e5336af9c9f300..d56a7c489111fe43c09208e125de65dc1f57323a 100644 (file)
@@ -541,20 +541,19 @@ class TestIssuerBase(Elaboratable):
         value to DEC, however the regfile has "passthrough" on it so this
         *should* be ok.
 
-        see v3.0B p1097-1099 for Timeer Resource and p1065 and p1076
+        see v3.0B p1097-1099 for Timer Resource and p1065 and p1076
         """
 
         comb, sync = m.d.comb, m.d.sync
-        fast_rf = self.core.regs.rf['fast']
-        fast_r_dectb = fast_rf.r_ports['issue']  # DEC/TB
-        fast_w_dectb = fast_rf.w_ports['issue']  # DEC/TB
+        state_rf = self.core.regs.rf['state']
+        state_r_dectb = state_rf.r_ports['issue']  # DEC/TB
+        state_w_dectb = state_rf.w_ports['issue']  # DEC/TB
 
         with m.FSM() as fsm:
 
             # initiates read of current DEC
             with m.State("DEC_READ"):
-                comb += fast_r_dectb.addr.eq(FastRegs.DEC)
-                comb += fast_r_dectb.ren.eq(1)
+                comb += state_r_dectb.ren.eq(1<<StateRegs.DEC)
                 with m.If(~self.pause_dec_tb):
                     m.next = "DEC_WRITE"
 
@@ -567,18 +566,16 @@ class TestIssuerBase(Elaboratable):
                 with m.Else():
                     new_dec = Signal(64)
                     # TODO: MSR.LPCR 32-bit decrement mode
-                    comb += new_dec.eq(fast_r_dectb.o_data - 1)
-                    comb += fast_w_dectb.addr.eq(FastRegs.DEC)
-                    comb += fast_w_dectb.wen.eq(1)
-                    comb += fast_w_dectb.i_data.eq(new_dec)
+                    comb += new_dec.eq(state_r_dectb.o_data - 1)
+                    comb += state_w_dectb.wen.eq(1<<StateRegs.DEC)
+                    comb += state_w_dectb.i_data.eq(new_dec)
                     # copy to cur_state for decoder, for an interrupt
                     sync += spr_dec.eq(new_dec)
                     m.next = "TB_READ"
 
             # initiates read of current TB
             with m.State("TB_READ"):
-                comb += fast_r_dectb.addr.eq(FastRegs.TB)
-                comb += fast_r_dectb.ren.eq(1)
+                comb += state_r_dectb.ren.eq(1<<StateRegs.TB)
                 with m.If(~self.pause_dec_tb):
                     m.next = "TB_WRITE"
 
@@ -590,10 +587,9 @@ class TestIssuerBase(Elaboratable):
                     m.next = "TB_READ"
                 with m.Else():
                     new_tb = Signal(64)
-                    comb += new_tb.eq(fast_r_dectb.o_data + 1)
-                    comb += fast_w_dectb.addr.eq(FastRegs.TB)
-                    comb += fast_w_dectb.wen.eq(1)
-                    comb += fast_w_dectb.i_data.eq(new_tb)
+                    comb += new_tb.eq(state_r_dectb.o_data + 1)
+                    comb += state_w_dectb.wen.eq(1<<StateRegs.TB)
+                    comb += state_w_dectb.i_data.eq(new_tb)
                     m.next = "DEC_READ"
 
         return m
index eb99ef039cdf65703b9f2c91c911bcfb284eb12f..73718f279ec2c0ebb67d6540dcb7547ba6fb47fa 100644 (file)
@@ -45,7 +45,7 @@ from soc.fu.branch.test.test_pipe_caller import BranchTestCase
 from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase
 from openpower.test.general.overlap_hazards import (HazardTestCase,
                                                     RandomHazardTestCase)
-from openpower.util import spr_to_fast_reg
+from openpower.util import spr_to_fast_reg, spr_to_state_reg
 
 from openpower.consts import StateRegsEnum
 
@@ -143,6 +143,7 @@ def setup_regs(pdecode2, core, test):
     # setting both fast and slow SPRs from test data
 
     fregs = core.regs.fast
+    stateregs = core.regs.state
     sregs = core.regs.spr
     for sprname, val in test.sprs.items():
         if isinstance(val, SelectableInt):
@@ -154,8 +155,9 @@ def setup_regs(pdecode2, core, test):
         print ('set spr %s val %x' % (sprname, val))
 
         fast = spr_to_fast_reg(sprname)
+        state = spr_to_state_reg(sprname)
 
-        if fast is None:
+        if fast is None and state is None:
             # match behaviour of SPRMap in power_decoder2.py
             for i, x in enumerate(SPR):
                 if sprname == x.name:
@@ -167,6 +169,14 @@ def setup_regs(pdecode2, core, test):
                         yield from set_ldst_spr(sprname, x.value, val, core)
                     else:
                         yield sregs.memory._array[i].eq(val)
+        elif state is not None:
+            print("setting state reg %d (%s) to %x" %
+                  (state, sprname, val))
+            if stateregs.unary:
+                rval = stateregs.int.regs[state].reg
+            else:
+                rval = stateregs.memory._array[state]
+            yield rval.eq(val)
         else:
             print("setting fast reg %d (%s) to %x" %
                   (fast, sprname, val))