sigh, monitor DEC/TB StateRegs "properly" so that the Issuer DEC/TB FSM
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 21 Jan 2022 00:12:39 +0000 (00:12 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 21 Jan 2022 00:12:39 +0000 (00:12 +0000)
does not end up in a race condition with the SPR pipeline for writing
to DEC or TB

src/soc/simple/core.py
src/soc/simple/issuer.py

index 6c2d7388a0dc74afd47c5af19c7d8f8a9c2896a8..0479508adf1e6aa915173a114966f97a1cd2702b 100644 (file)
@@ -90,8 +90,8 @@ def bitvector_remap(regfile, rfile, port):
     # 3 bits, unary: return the port
     if regfile == 'XER':
         return port
-    # 3 bits, unary: return the port
-    if regfile == 'SVSTATE':
+    # 5 bits, unary: return the port
+    if regfile == 'STATE':
         return port
     # 9 bits (9 entries), might be unary already
     if regfile == 'FAST':
index d56a7c489111fe43c09208e125de65dc1f57323a..06bfcdf3de19d13c45a7c3be60d010ed16b04e1a 100644 (file)
@@ -307,6 +307,8 @@ class TestIssuerBase(Elaboratable):
         # hack method of keeping an eye on whether branch/trap set the PC
         self.state_nia = self.core.regs.rf['state'].w_ports['nia']
         self.state_nia.wen.name = 'state_nia_wen'
+        # and whether SPR pipeline sets DEC or TB
+        self.state_spr = self.core.regs.rf['state'].w_ports['state1']
 
         # pulse to synchronize the simulator at instruction end
         self.insn_done = Signal()
@@ -398,10 +400,6 @@ class TestIssuerBase(Elaboratable):
                 m.submodules["sram4k_%d" % i] = csd(sram)
                 comb += sram.enable.eq(self.wb_sram_en)
 
-        # terrible hack to stop a potential race condition.  if core
-        # is doing any operation (at all) pause the DEC/TB FSM
-        comb += self.pause_dec_tb.eq(core.pause_dec_tb)
-
         # XICS interrupt handler
         if self.xics:
             m.submodules.xics_icp = icp = csd(self.xics_icp)
@@ -1473,15 +1471,18 @@ class TestIssuerInternal(TestIssuerBase):
 
             # instruction started: must wait till it finishes
             with m.State("INSN_ACTIVE"):
-                # note changes to MSR, PC and SVSTATE
-                # XXX oops, really must monitor *all* State Regfile write
-                # ports looking for changes!
+                # note changes to MSR, PC and SVSTATE, and DEC/TB
+                # these last two are done together, and passed to the
+                # DEC/TB FSM
                 with m.If(self.state_nia.wen & (1 << StateRegs.SVSTATE)):
                     sync += self.sv_changed.eq(1)
                 with m.If(self.state_nia.wen & (1 << StateRegs.MSR)):
                     sync += self.msr_changed.eq(1)
                 with m.If(self.state_nia.wen & (1 << StateRegs.PC)):
                     sync += self.pc_changed.eq(1)
+                with m.If((self.state_spr.wen &
+                          ((1 << StateRegs.DEC) | (1 << StateRegs.TB))).bool()):
+                    comb += self.pause_dec_tb.eq(1)
                 with m.If(~core_busy_o):  # instruction done!
                     comb += exec_pc_o_valid.eq(1)
                     with m.If(exec_pc_i_ready):