add quick demo/test of reading DMI reg 9
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 3 Aug 2020 19:55:51 +0000 (20:55 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 3 Aug 2020 19:55:51 +0000 (20:55 +0100)
src/soc/debug/dmi.py
src/soc/simple/issuer.py
src/soc/simple/test/test_issuer.py

index bff07d70f569670f752f6dfa63a2fc285f6fd6d7..69bd0be7724830f836f34f6496022cd1bb756b9e 100644 (file)
@@ -15,14 +15,14 @@ from soc.config.state import CoreState
 
 # DMI register addresses
 class DBGCore:
-    CTRL           = 0b0000
-    STAT           = 0b0001
-    NIA            = 0b0010 # NIA register (read only for now)
-    MSR            = 0b0011 # MSR (read only)
-    GSPR_INDEX     = 0b0100 # GSPR register index
-    GSPR_DATA      = 0b0101 # GSPR register data
-    LOG_ADDR       = 0b0110 # Log buffer address register
-    LOG_DATA       = 0b0111 # Log buffer data register
+    CTRL         = 0b0000
+    STAT         = 0b0001
+    NIA          = 0b0010 # NIA register (read only for now)
+    MSR          = 0b0011 # MSR (read only)
+    GSPR_IDX     = 0b0100 # GSPR register index
+    GSPR_DATA    = 0b0101 # GSPR register data
+    LOG_ADDR     = 0b0110 # Log buffer address register
+    LOG_DATA     = 0b0111 # Log buffer data register
 
 
 # CTRL register (direct actions, write 1 to act, read back 0)
@@ -63,10 +63,10 @@ class DMIInterface(RecordObject):
 class DbgReg(RecordObject):
     def __init__(self, name):
         super().__init__(name=name)
-        self.req_o     = Signal()
-        self.ack_i     = Signal()
-        self.addr_o    = Signal(7) #  includes fast SPRs, others?
-        self.data_i    = Signal(64)
+        self.req     = Signal()
+        self.ack     = Signal()
+        self.addr    = Signal(7) #  includes fast SPRs, others?
+        self.data    = Signal(64)
 
 
 class CoreDebug(Elaboratable):
@@ -115,7 +115,7 @@ class CoreDebug(Elaboratable):
         do_icreset   = Signal()
         terminated   = Signal()
         do_gspr_rd   = Signal()
-        gspr_index   = Signal.like(self.dbg_gpr.addr_o)
+        gspr_index   = Signal.like(self.dbg_gpr.addr)
 
         log_dmi_addr = Signal(32)
         log_dmi_data = Signal(64)
@@ -127,8 +127,8 @@ class CoreDebug(Elaboratable):
 
         # Single cycle register accesses on DMI except for GSPR data
         comb += self.dmi.ack_o.eq(Mux(self.dmi.addr_i == DBGCore.GSPR_DATA,
-                                      self.dbg_gpr.ack_i, self.dmi.req_i))
-        comb += self.dbg_gpr.req_o.eq(Mux(self.dmi.addr_i == DBGCore.GSPR_DATA,
+                                      self.dbg_gpr.ack, self.dmi.req_i))
+        comb += self.dbg_gpr.req.eq(Mux(self.dmi.addr_i == DBGCore.GSPR_DATA,
                                       self.dmi.req_i, 0))
 
         # Status register read composition (DBUG_CORE_STAT_xxx)
@@ -145,7 +145,7 @@ class CoreDebug(Elaboratable):
             with m.Case( DBGCore.MSR):
                 comb += self.dmi.dout.eq(self.state.msr)
             with m.Case( DBGCore.GSPR_DATA):
-                comb += self.dmi.dout.eq(self.dbg_gpr.data_i)
+                comb += self.dmi.dout.eq(self.dbg_gpr.data)
             with m.Case( DBGCore.LOG_ADDR):
                 comb += self.dmi.dout.eq(Cat(log_dmi_addr,
                                              self.log_write_addr_o))
@@ -184,7 +184,7 @@ class CoreDebug(Elaboratable):
                         sync += terminated.eq(0)
 
                 # GSPR address
-                with m.Elif(self.dmi.addr_i == DBGCore.GSPR_INDEX):
+                with m.Elif(self.dmi.addr_i == DBGCore.GSPR_IDX):
                     sync += gspr_index.eq(self.dmi.din)
 
                 # Log address
@@ -212,7 +212,7 @@ class CoreDebug(Elaboratable):
             sync += stopping.eq(1)
             sync += terminated.eq(1)
 
-        comb += self.dbg_gpr.addr_o.eq(gspr_index)
+        comb += self.dbg_gpr.addr.eq(gspr_index)
 
         # Core control signals generated by the debug module
         comb += self.core_stop_o.eq(stopping & ~do_step)
index bf91c9bbc3fd6322af5847be988caf8f25918f80..5efc0e0ee54ba3e5cc3192774746440b68d46db0 100644 (file)
@@ -49,7 +49,6 @@ class TestIssuer(Elaboratable):
 
         # DMI interface
         self.dbg = CoreDebug()
-        self.dmi = self.dbg.dmi
 
         # instruction go/monitor
         self.pc_o = Signal(64, reset_less=True)
@@ -63,6 +62,9 @@ class TestIssuer(Elaboratable):
         self.fast_w_pc = self.core.regs.rf['fast'].w_ports['d_wr1'] # PC wr
         self.fast_r_msr = self.core.regs.rf['fast'].r_ports['msr'] # MSR rd
 
+        # DMI interface access
+        self.int_r = self.core.regs.rf['int'].r_ports['dmi'] # INT read
+
         # hack method of keeping an eye on whether branch/trap set the PC
         self.fast_nia = self.core.regs.rf['fast'].w_ports['nia']
         self.fast_nia.wen.name = 'fast_nia_wen'
@@ -75,6 +77,10 @@ class TestIssuer(Elaboratable):
         m.submodules.imem = imem = self.imem
         m.submodules.dbg = dbg = self.dbg
 
+        # convenience
+        dmi = dbg.dmi
+        d_reg = dbg.dbg_gpr
+
         # clock delay power-on reset
         cd_por  = ClockDomain(reset_less=True)
         cd_sync = ClockDomain()
@@ -209,6 +215,16 @@ class TestIssuer(Elaboratable):
                         comb += self.fast_w_pc.data_i.eq(nia)
                     m.next = "IDLE" # back to idle
 
+        # this bit doesn't have to be in the FSM: connect up to read
+        # regfiles on demand from DMI
+
+        with m.If(d_reg.req): # request for regfile access being made
+            # TODO: error-check this
+            # XXX should this be combinatorial?  sync better?
+            comb += self.int_r.ren.eq(1<<d_reg.addr)
+            comb += d_reg.data.eq(self.int_r.data_o)
+            comb += d_reg.ack.eq(1)
+
         return m
 
     def __iter__(self):
index b1df27dccae250e2b7def5ac59c65ef241831cf6..a8b0f34a77de9fca36467dc0ddd4524241791254 100644 (file)
@@ -103,6 +103,24 @@ def set_dmi(dmi, addr, data):
     yield dmi.we_i.eq(0)
 
 
+def get_dmi(dmi, addr):
+    yield dmi.req_i.eq(1)
+    yield dmi.addr_i.eq(addr)
+    yield dmi.din.eq(0)
+    yield dmi.we_i.eq(1)
+    while True:
+        ack = yield dmi.ack_o
+        if ack:
+            break
+        yield
+    yield # wait one
+    data = yield dmi.dout # get data after ack valid for 1 cycle
+    yield dmi.req_i.eq(0)
+    yield dmi.addr_i.eq(0)
+    yield dmi.we_i.eq(0)
+    return data
+
+
 class TestRunner(FHDLTestCase):
     def __init__(self, tst_data):
         super().__init__("run_all")
@@ -224,6 +242,14 @@ class TestRunner(FHDLTestCase):
                     if terminated:
                         break
 
+                # test of dmi reg get
+                int_reg = 9
+                yield from set_dmi(dmi, DBGCore.GSPR_IDX, int_reg) # int reg 9
+                value = yield from get_dmi(dmi, DBGCore.GSPR_DATA) # get data
+
+                print ("after test %s reg %x value %s" % \
+                            (test.name, int_reg, value))
+
         sim.add_sync_process(process)
         with sim.write_vcd("issuer_simulator.vcd",
                            traces=[]):