add CR read to DMI interface
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 25 Aug 2020 11:26:19 +0000 (12:26 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 25 Aug 2020 11:26:19 +0000 (12:26 +0100)
src/soc/debug/dmi.py
src/soc/regfile/regfiles.py
src/soc/regfile/virtual_port.py
src/soc/simple/issuer.py
src/soc/simple/test/test_issuer.py

index 9c28d2b9f3d804c96e179c08e8c2e24648be04e1..71e493592cd30e8c1298b9434f0308c8ea975353 100644 (file)
@@ -139,7 +139,7 @@ class CoreDebug(Elaboratable):
         LOG_INDEX_BITS = log2_int(self.LOG_LENGTH)
 
         # Single cycle register accesses on DMI except for GSPR data
-        with m.Switch(.dmi.addr_i):
+        with m.Switch(dmi.addr_i):
             with m.Case(DBGCore.GSPR_DATA):
                 comb += dmi.ack_o.eq(dbg_gpr.ack)
                 comb += dbg_gpr.req.eq(dmi.req_i)
index 58211449126b764cb14bb8c249bb05735f1fccd7..505fb587d135ae98ad685916b1a8ab9e5e88f01d 100644 (file)
@@ -110,11 +110,12 @@ class CRRegs(VirtualRegPort):
     * write-through capability (read on same cycle as write)
     """
     def __init__(self):
-        super().__init__(32, 8)
+        super().__init__(32, 8, rd2=True)
         self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
                         'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
                         'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
         self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
+                        'full_cr_dbg': self.full_rd2, # for DMI
                         'cr_a': self.read_port("src1"),
                         'cr_b': self.read_port("src2"),
                         'cr_c': self.read_port("src3")}
index ec1ee2c33edfadc10f6785d81d3626a4744e4e2e..f4393e152d2030de442cc124deca0e707adc7bfb 100644 (file)
@@ -18,9 +18,10 @@ from soc.regfile.regfile import RegFileArray
 
 
 class VirtualRegPort(RegFileArray):
-    def __init__(self, bitwidth, n_regs):
+    def __init__(self, bitwidth, n_regs, rd2=False):
         self.bitwidth = bitwidth
         self.nregs = n_regs
+        self.rd2 = rd2 # eurgh hack
         self.regwidth = regwidth = bitwidth // n_regs
         super().__init__(self.regwidth, n_regs)
 
@@ -31,17 +32,15 @@ class VirtualRegPort(RegFileArray):
         self.full_rd = RecordObject([("ren", n_regs),
                                      ("data_o", bitwidth)],  # *full* wid
                                     name="full_rd")
+        if not rd2:
+            return
+        self.full_rd2 = RecordObject([("ren", n_regs),
+                                     ("data_o", bitwidth)],  # *full* wid
+                                    name="full_rd2")
 
-    def elaborate(self, platform):
-        m = super().elaborate(platform)
+    def connect_full_rd(self, m, rfull, name):
         comb = m.d.comb
-
-        # for internal use only.
-        wr_regs = self.write_reg_port(f"w")
-        rd_regs = self.read_reg_port(f"r")
-
-        # connect up full read port
-        rfull = self.full_rd
+        rd_regs = self.read_reg_port(name)
 
         # wire up the enable signals and chain-accumulate the data
         l = map(lambda port: port.data_o, rd_regs)  # get port data(s)
@@ -50,6 +49,18 @@ class VirtualRegPort(RegFileArray):
         comb += rfull.data_o.eq(Cat(*l))  # we like Cat on lists
         comb += Cat(*le).eq(rfull.ren)
 
+    def elaborate(self, platform):
+        m = super().elaborate(platform)
+        comb = m.d.comb
+
+        # for internal use only.
+        wr_regs = self.write_reg_port(f"w")
+
+        # connect up full read port
+        self.connect_full_rd(m, self.full_rd, "r")
+        if self.rd2: # hack!
+            self.connect_full_rd(m, self.full_rd2, "r2")
+
         # connect up full write port
         wfull = self.full_wr
 
index cf516099aa40f11f6d6c1ea8fa1bb69749ea8e10..1c92512a4ca208cbee559936c5232dc1c8eac0a2 100644 (file)
@@ -73,7 +73,9 @@ class TestIssuer(Elaboratable):
 
         # DMI interface access
         intrf = self.core.regs.rf['int']
+        crrf = self.core.regs.rf['cr']
         self.int_r = intrf.r_ports['dmi'] # INT read
+        self.cr_r = crrf.r_ports['full_cr_dbg'] # CR read
 
         # hack method of keeping an eye on whether branch/trap set the PC
         self.state_nia = self.core.regs.rf['state'].w_ports['nia']
@@ -92,8 +94,7 @@ class TestIssuer(Elaboratable):
         m.submodules.dec2 = pdecode2 = self.pdecode2
 
         # convenience
-        dmi = dbg.dmi
-        d_reg = dbg.dbg_gpr
+        dmi, d_reg, d_cr = dbg.dmi, dbg.dbg_gpr, dbg.dbg_cr
         intrf = self.core.regs.rf['int']
 
         # clock delay power-on reset
@@ -262,6 +263,16 @@ class TestIssuer(Elaboratable):
             comb += d_reg.data.eq(self.int_r.data_o)
             comb += d_reg.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
+        d_cr_delay  = Signal()
+        sync += d_cr_delay.eq(d_cr.req)
+        with m.If(d_cr_delay):
+            # data arrives one clock later
+            comb += d_cr.data.eq(self.cr_r.data_o)
+            comb += d_cr.ack.eq(1)
+
         return m
 
     def __iter__(self):
index 17578632c4e174427bc12ca6db9267956b3d96a4..f83c17b58db73c971acab9357c68933bb07dadbc 100644 (file)
@@ -277,6 +277,10 @@ class TestRunner(FHDLTestCase):
                 yield
                 yield
 
+                # get CR
+                cr = yield from get_dmi(dmi, DBGCore.CR)
+                print ("after test %s cr value %x" % (test.name, cr))
+
                 # test of dmi reg get
                 for int_reg in range(32):
                     yield from set_dmi(dmi, DBGCore.GSPR_IDX, int_reg)