add support for DMI debug read of FAST Regfile SPRs
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 18 Jan 2022 18:15:17 +0000 (18:15 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 18 Jan 2022 18:15:17 +0000 (18:15 +0000)
this to be able to do a side-by-side compare against microwatt
single-stepping

src/soc/debug/dmi.py
src/soc/regfile/regfiles.py
src/soc/simple/issuer.py

index f19911e70eea5ecd9fb04f67422ff40b4418e6de..d4e9f5c2ed3b2170b6e4c66c768ae02b85b7b3f9 100644 (file)
@@ -11,6 +11,7 @@ from nmutil.iocontrol import RecordObject
 from nmigen.utils import log2_int
 from nmigen.cli import rtlil
 from soc.config.state import CoreState
+from openpower.consts import FastRegsEnum
 
 
 # DMI register addresses
@@ -106,14 +107,10 @@ class CoreDebug(Elaboratable):
         self.core_stopped_i = Signal()
         self.state = CoreState("core_dbg")
 
-        # GSPR register read port
-        self.d_gpr = DbgReg("d_gpr")
-
-        # CR register read port
-        self.d_cr = DbgReg("d_cr")
-
-        # XER register read port
-        self.d_xer = DbgReg("d_xer")
+        self.d_gpr = DbgReg("d_gpr") # GSPR register read port
+        self.d_fast = DbgReg("d_fast") # GSPR register read port
+        self.d_cr = DbgReg("d_cr")   # CR register read port
+        self.d_xer = DbgReg("d_xer") # XER register read port
 
         # Core logging data
         self.log_data_i        = Signal(256)
@@ -133,6 +130,7 @@ class CoreDebug(Elaboratable):
         m = Module()
         comb, sync = m.d.comb, m.d.sync
         dmi, d_gpr, d_cr, d_xer, = self.dmi, self.d_gpr, self.d_cr, self.d_xer
+        d_fast = self.d_fast
 
         # DMI needs fixing... make a one clock pulse
         dmi_req_i_1 = Signal()
@@ -147,7 +145,11 @@ class CoreDebug(Elaboratable):
         do_icreset   = Signal()
         terminated   = Signal()
         do_gspr_rd   = Signal()
+        # select either GPRs or FAST regs to read, based on GSPR_IDX
         gspr_index   = Signal.like(d_gpr.addr)
+        fast_index   = Signal.like(d_gpr.addr)
+        gspr_en      = Signal()
+        fast_en      = Signal()
 
         log_dmi_addr = Signal(32)
         log_dmi_data = Signal(64)
@@ -160,8 +162,12 @@ class CoreDebug(Elaboratable):
         # Single cycle register accesses on DMI except for registers
         with m.Switch(dmi.addr_i):
             with m.Case(DBGCore.GSPR_DATA):
-                comb += dmi.ack_o.eq(d_gpr.ack)
-                comb += d_gpr.req.eq(dmi.req_i)
+                with m.If(gspr_en): # GPR requested, acknowledge GPR
+                    comb += dmi.ack_o.eq(d_gpr.ack)
+                    comb += d_gpr.req.eq(dmi.req_i)
+                with m.If(fast_en): # FAST requested
+                    comb += dmi.ack_o.eq(d_fast.ack)
+                    comb += d_fast.req.eq(dmi.req_i)
             with m.Case(DBGCore.CR):
                 comb += dmi.ack_o.eq(d_cr.ack)
                 comb += d_cr.req.eq(dmi.req_i)
@@ -187,8 +193,11 @@ class CoreDebug(Elaboratable):
                 comb += dmi.dout.eq(self.state.msr)
             with m.Case( DBGCore.SVSTATE):            # SVSTATE
                 comb += dmi.dout.eq(self.state.svstate)
-            with m.Case( DBGCore.GSPR_DATA):          # GPR
-                comb += dmi.dout.eq(d_gpr.data)
+            with m.Case( DBGCore.GSPR_DATA):          # GPR/FAST regs
+                with m.If(gspr_en):
+                    comb += dmi.dout.eq(d_gpr.data)   # GPR data selected
+                with m.If(fast_en):
+                    comb += dmi.dout.eq(d_fast.data)  # FAST reg read selected
             with m.Case( DBGCore.LOG_ADDR):           # Logging
                 comb += dmi.dout.eq(Cat(log_dmi_addr, self.log_write_addr_o))
             with m.Case( DBGCore.LOG_DATA):
@@ -233,7 +242,49 @@ class CoreDebug(Elaboratable):
 
                 # GSPR address
                 with m.Elif(dmi.addr_i == DBGCore.GSPR_IDX):
-                    sync += gspr_index.eq(dmi.din)
+                    sync += gspr_index.eq(0)
+                    sync += fast_index.eq(0)
+                    sync += gspr_en.eq(0)
+                    sync += fast_en.eq(0)
+                    with m.If(dmi.din <= 31):
+                        sync += gspr_index.eq(dmi.din)
+                        sync += gspr_en.eq(1)
+                    with m.If(dmi.din == 32): # LR
+                        sync += fast_index.eq(FastRegsEnum.LR)
+                        sync += fast_en.eq(1)
+                    with m.If(dmi.din == 33): # CTR
+                        sync += fast_index.eq(FastRegsEnum.CTR)
+                        sync += fast_en.eq(1)
+                    with m.If(dmi.din == 34): # SRR0
+                        sync += fast_index.eq(FastRegsEnum.SRR0)
+                        sync += fast_en.eq(1)
+                    with m.If(dmi.din == 35): # SRR1
+                        sync += fast_index.eq(FastRegsEnum.SRR1)
+                        sync += fast_en.eq(1)
+                    with m.If(dmi.din == 44): # XER
+                        sync += fast_index.eq(FastRegsEnum.XER)
+                        sync += fast_en.eq(1)
+                    with m.If(dmi.din == 45): # TAR
+                        sync += fast_index.eq(FastRegsEnum.XER)
+                        sync += fast_en.eq(1)
+
+                    # numbering from microwatt:
+                    """
+                If(regnum == 32, Display("     LR: %016x", dbg_dout),), # LR
+                If(regnum == 33, Display("    CTR: %016x", dbg_dout),), # CTR
+                If(regnum == 34, Display("   SRR0: %016x", dbg_dout),), # SRR0
+                If(regnum == 35, Display("   SRR1: %016x", dbg_dout),), # SRR1
+                If(regnum == 36, Display("  HSRR0: %016x", dbg_dout),), # HSRR0
+                If(regnum == 37, Display("  HSRR1: %016x", dbg_dout),), # HSRR1
+                If(regnum == 38, Display("  SPRG0: %016x", dbg_dout),), # SPRG0
+                If(regnum == 39, Display("  SPRG1: %016x", dbg_dout),), # SPRG1
+                If(regnum == 40, Display("  SPRG2: %016x", dbg_dout),), # SPRG2
+                If(regnum == 41, Display("  SPRG3: %016x", dbg_dout),), # SPRG3
+                If(regnum == 42, Display(" HSPRG0: %016x", dbg_dout),), # HSPRG0
+                If(regnum == 43, Display(" HSPRG1: %016x", dbg_dout),), # HSPRG1
+                If(regnum == 44, Display("    XER: %016x", dbg_dout),), # XER
+                If(regnum == 45, Display("    TAR: %016x", dbg_dout),), # TAR
+                """
 
                 # Log address
                 with m.Elif(dmi.addr_i == DBGCore.LOG_ADDR):
@@ -266,6 +317,7 @@ class CoreDebug(Elaboratable):
             sync += terminated.eq(1)
 
         comb += d_gpr.addr.eq(gspr_index)
+        comb += d_fast.addr.eq(fast_index)
 
         # Core control signals generated by the debug module
         comb += self.core_stop_o.eq((stopping & ~do_step) | self.terminate_i)
@@ -370,6 +422,7 @@ class CoreDebug(Elaboratable):
         yield from self.d_gpr
         yield from self.d_cr
         yield from self.d_xer
+        yield from self.d_fast
         yield self.log_data_i
         yield self.log_read_addr_i
         yield self.log_read_data_o
index 754b6902e0aa04f31b82de168fa1a40a035372d3..f3531e092a335fb7ef2baa0e306af5fb1b72370d 100644 (file)
@@ -158,6 +158,7 @@ class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
                        }
         r_port_spec = {'fast1': "src1",
                        'issue': "issue", # reading DEC/TB
+                        'dmi': "dmi" # needed for Debug (DMI)
                         }
         if not self.regreduce_en:
             r_port_spec['fast2'] = "src2"
index ab21b1b95c26250f8dfc0ded8c5d98aa18ca7847..958e3f11a99d43f1a6ef520c17e5336af9c9f300 100644 (file)
@@ -291,11 +291,13 @@ class TestIssuerBase(Elaboratable):
 
         # DMI interface access
         intrf = self.core.regs.rf['int']
+        fastrf = self.core.regs.rf['fast']
         crrf = self.core.regs.rf['cr']
         xerrf = self.core.regs.rf['xer']
-        self.int_r = intrf.r_ports['dmi']  # INT read
-        self.cr_r = crrf.r_ports['full_cr_dbg']  # CR read
-        self.xer_r = xerrf.r_ports['full_xer']  # XER read
+        self.int_r = intrf.r_ports['dmi']  # INT DMI read
+        self.cr_r = crrf.r_ports['full_cr_dbg']  # CR DMI read
+        self.xer_r = xerrf.r_ports['full_xer']  # XER DMI read
+        self.fast_r = fastrf.r_ports['dmi']  # FAST DMI read
 
         if self.svp64_en:
             # for predication
@@ -425,10 +427,6 @@ class TestIssuerBase(Elaboratable):
         if self.svp64_en:
             m.submodules.svp64 = svp64 = csd(self.svp64)
 
-        # convenience
-        dmi, d_reg, d_cr, d_xer, = dbg.dmi, dbg.d_gpr, dbg.d_cr, dbg.d_xer
-        intrf = self.core.regs.rf['int']
-
         # clock delay power-on reset
         cd_por = ClockDomain(reset_less=True)
         cd_sync = ClockDomain()
@@ -482,7 +480,9 @@ class TestIssuerBase(Elaboratable):
         comb = m.d.comb
         sync = m.d.sync
         dmi, d_reg, d_cr, d_xer, = dbg.dmi, dbg.d_gpr, dbg.d_cr, dbg.d_xer
+        d_fast = dbg.d_fast
         intrf = self.core.regs.rf['int']
+        fastrf = self.core.regs.rf['fast']
 
         with m.If(d_reg.req):  # request for regfile access being made
             # TODO: error-check this
@@ -499,6 +499,20 @@ class TestIssuerBase(Elaboratable):
             comb += d_reg.data.eq(self.int_r.o_data)
             comb += d_reg.ack.eq(1)
 
+        # fast regfile
+        with m.If(d_fast.req):  # request for regfile access being made
+            if fastrf.unary:
+                comb += self.fast_r.ren.eq(1 << d_fast.addr)
+            else:
+                comb += self.fast_r.addr.eq(d_fast.addr)
+                comb += self.fast_r.ren.eq(1)
+        d_fast_delay = Signal()
+        sync += d_fast_delay.eq(d_fast.req)
+        with m.If(d_fast_delay):
+            # data arrives one clock later
+            comb += d_fast.data.eq(self.fast_r.o_data)
+            comb += d_fast.ack.eq(1)
+
         # sigh same thing for CR debug
         with m.If(d_cr.req):  # request for regfile access being made
             comb += self.cr_r.ren.eq(0b11111111)  # enable all