adding an extra option to issuer_verilog.py to be able to cteate a
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 3 Jan 2022 19:55:53 +0000 (19:55 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 3 Jan 2022 19:55:53 +0000 (19:55 +0000)
microwatt-core-compatible verilog file.  it needs to be compatible
with this interface, such that microwatt.v can have TestIssuerInternal
dropped directly in place

module core_512_88be32b2ccc17aa9df4dd9526954b105d7825eba(clk,
rst, alt_reset, \wishbone_insn_in.dat , \wishbone_insn_in.ack ,
\wishbone_insn_in.stall , \wishbone_data_in.dat , \wishbone_data_in.ack ,
\wishbone_data_in.stall , dmi_addr, dmi_din, dmi_req, dmi_wr, ext_irq,
\wishbone_insn_out.adr , \wishbone_insn_out.dat , \wishbone_insn_out.sel ,
\wishbone_insn_out.cyc , \wishbone_insn_out.stb , \wishbone_insn_out.we ,
\wishbone_data_out.adr , \wishbone_data_out.dat , \wishbone_data_out.sel ,
\wishbone_data_out.cyc , \wishbone_data_out.stb , \wishbone_data_out.we ,
dmi_dout, dmi_ack, terminated_out);

src/soc/experiment/dcache.py
src/soc/fu/ldst/loadstore.py
src/soc/minerva/wishbone.py
src/soc/simple/issuer.py
src/soc/simple/issuer_verilog.py

index adb36fade8245153be4ebd2a0df7aeb542671860..b9e467bbfcc7b515b0b310ef0fc374c58cf830f0 100644 (file)
@@ -676,7 +676,7 @@ class DCache(Elaboratable):
       at the end of line (this requires dealing with requests coming in
       while not idle...)
     """
-    def __init__(self):
+    def __init__(self, pspec=None):
         self.d_in      = LoadStore1ToDCacheType("d_in")
         self.d_out     = DCacheToLoadStore1Type("d_out")
 
@@ -695,6 +695,10 @@ class DCache(Elaboratable):
 
         self.log_out   = Signal(20)
 
+        # test if microwatt compatibility is to be enabled
+        self.microwatt_compat = (hasattr(pspec, "microwatt_compat") and
+                                 (pspec.microwatt_compat == True))
+
     def stage_0(self, m, r0, r1, r0_full):
         """Latch the request in r0.req as long as we're not stalling
         """
@@ -1744,7 +1748,8 @@ class DCache(Elaboratable):
         # deal with litex not doing wishbone pipeline mode
         # XXX in wrong way.  FIFOs are needed in the SRAM test
         # so that stb/ack match up. same thing done in icache.py
-        comb += self.bus.stall.eq(self.bus.cyc & ~self.bus.ack)
+        if not self.microwatt_compat:
+            comb += self.bus.stall.eq(self.bus.cyc & ~self.bus.ack)
 
         # Wire up wishbone request latch out of stage 1
         comb += self.bus.we.eq(r1.wb.we)
index 1ecac0add15494d57aed59bfaeb837387c9bfc15..97972c2f9e55f57cfed1e7f756968f83a006cadc 100644 (file)
@@ -70,7 +70,7 @@ class LoadStore1(PortInterfaceBase):
         addrwid = pspec.addr_wid
 
         super().__init__(regwid, addrwid)
-        self.dcache = DCache()
+        self.dcache = DCache(pspec)
         self.icache = ICache(pspec)
         # these names are from the perspective of here (LoadStore1)
         self.d_out  = self.dcache.d_in     # in to dcache is out for LoadStore
index f84a01ccc2f3b98f57ffe16c37cb5a2c206cf24b..6786ff5291a17bff8f210fcbbf19ff464005e92a 100644 (file)
@@ -18,6 +18,9 @@ def make_wb_layout(spec, cti=True):
     addr_wid, mask_wid, data_wid = spec.addr_wid, spec.mask_wid, spec.reg_wid
     adr_lsbs = log2_int(mask_wid) # LSBs of addr covered by mask
     badwid = spec.addr_wid-adr_lsbs    # MSBs (not covered by mask)
+    # test if microwatt compatibility is to be enabled
+    microwatt_compat = (hasattr(spec, "microwatt_compat") and
+                               (spec.microwatt_compat == True))
 
     res = [
     ("adr",   badwid  , DIR_FANOUT),
@@ -30,6 +33,9 @@ def make_wb_layout(spec, cti=True):
     ("we",            1, DIR_FANOUT),
     ("err",           1, DIR_FANIN)
     ]
+    # microwatt needs a stall signal (operates in pipeline mode)
+    if microwatt_compat:
+        res.append(("stall", 1, DIR_FANIN))
     if not cti:
         return res
     return res + [
index 85ea892f34e35b1970be79a742ee3d519d577129..2fafc6626b315e84b88ef3e00fd77d068818a3c8 100644 (file)
@@ -165,6 +165,11 @@ class TestIssuerBase(Elaboratable):
 
     def __init__(self, pspec):
 
+        # test if microwatt compatibility is to be enabled
+        self.microwatt_compat = (hasattr(pspec, "microwatt_compat") and
+                                 (pspec.microwatt_compat == True))
+        self.alt_reset = Signal(reset_less=True) # not connected yet (microwatt)
+
         # test is SVP64 is to be enabled
         self.svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True)
 
@@ -322,12 +327,18 @@ class TestIssuerBase(Elaboratable):
         csd = DomainRenamer(self.core_domain)
         dbd = DomainRenamer(self.dbg_domain)
 
-        m.submodules.core = core = csd(self.core)
+        if self.microwatt_compat:
+            m.submodules.core = core = self.core
+        else:
+            m.submodules.core = core = csd(self.core)
         # this _so_ needs sorting out.  ICache is added down inside
         # LoadStore1 and is already a submodule of LoadStore1
         if not isinstance(self.imem, ICache):
             m.submodules.imem = imem = csd(self.imem)
-        m.submodules.dbg = dbg = dbd(self.dbg)
+        if self.microwatt_compat:
+            m.submodules.dbg = dbg = self.dbg
+        else:
+            m.submodules.dbg = dbg = dbd(self.dbg)
         if self.jtag_en:
             m.submodules.jtag = jtag = dbd(self.jtag)
             # TODO: UART2GDB mux, here, from external pin
@@ -591,6 +602,39 @@ class TestIssuerBase(Elaboratable):
                 comb += self.state_w_sv.i_data.eq(self.new_svstate)
                 sync += self.sv_changed.eq(1)
 
+        # start renaming some of the ports to match microwatt
+        if self.microwatt_compat:
+            self.core.o.core_terminate_o.name = "terminated_out"
+            # names of DMI interface
+            self.dbg.dmi.addr_i.name = 'dmi_addr'
+            self.dbg.dmi.din.name    = 'dmi_din'
+            self.dbg.dmi.dout.name   = 'dmi_dout'
+            self.dbg.dmi.req_i.name  = 'dmi_req'
+            self.dbg.dmi.we_i.name   = 'dmi_wr'
+            self.dbg.dmi.ack_o.name  = 'dmi_ack'
+            # wishbone instruction bus
+            ibus = self.imem.ibus
+            ibus.adr.name = 'wishbone_insn_out.adr'
+            ibus.dat_w.name = 'wishbone_insn_out.dat'
+            ibus.sel.name = 'wishbone_insn_out.sel'
+            ibus.cyc.name = 'wishbone_insn_out.cyc'
+            ibus.stb.name = 'wishbone_insn_out.stb'
+            ibus.we.name = 'wishbone_insn_out.we'
+            ibus.dat_r.name = 'wishbone_insn_in.dat'
+            ibus.ack.name = 'wishbone_insn_in.ack'
+            ibus.stall.name = 'wishbone_insn_in.stall'
+            # wishbone data bus
+            dbus = self.core.l0.cmpi.wb_bus()
+            dbus.adr.name = 'wishbone_data_out.adr'
+            dbus.dat_w.name = 'wishbone_data_out.dat'
+            dbus.sel.name = 'wishbone_data_out.sel'
+            dbus.cyc.name = 'wishbone_data_out.cyc'
+            dbus.stb.name = 'wishbone_data_out.stb'
+            dbus.we.name = 'wishbone_data_out.we'
+            dbus.dat_r.name = 'wishbone_data_in.dat'
+            dbus.ack.name = 'wishbone_data_in.ack'
+            dbus.stall.name = 'wishbone_data_in.stall'
+
         return m
 
     def __iter__(self):
@@ -607,6 +651,22 @@ class TestIssuerBase(Elaboratable):
         return list(self)
 
     def external_ports(self):
+        if self.microwatt_compat:
+            ports = [self.core.o.core_terminate_o,
+                     self.alt_reset, # not connected yet
+                     ClockSignal(),
+                     ResetSignal(),
+                    ]
+            ports += list(self.dbg.dmi.ports())
+            # for dbus/ibus microwatt, exclude err btw and cti
+            for name, sig in self.imem.ibus.fields.items():
+                if name not in ['err', 'bte', 'cti']:
+                    ports.append(sig)
+            for name, sig in self.core.l0.cmpi.wb_bus().fields.items():
+                if name not in ['err', 'bte', 'cti']:
+                    ports.append(sig)
+            return ports
+
         ports = self.pc_i.ports()
         ports = self.msr_i.ports()
         ports += [self.pc_o, self.memerr_o, self.core_bigendian_i, self.busy_o,
index 1e9ed75afe7b04c55d30bfcf7d2d3c0b068827cf..6fead5eedfa48ecc5ee225eddf839b6c1a5f6386 100644 (file)
@@ -6,7 +6,7 @@ from nmigen.cli import verilog
 
 from openpower.consts import MSR
 from soc.config.test.test_loadstore import TestMemPspec
-from soc.simple.issuer import TestIssuer
+from soc.simple.issuer import TestIssuer, TestIssuerInternal
 
 
 if __name__ == '__main__':
@@ -59,9 +59,25 @@ if __name__ == '__main__':
     parser.add_argument("--disable-svp64", dest='svp64', action="store_false",
                         help="disable SVP64",
                         default=False)
+    # create a module that's directly compatible as a drop-in replacement
+    # in microwatt.v
+    parser.add_argument("--microwatt-compat", dest='mwcompat',
+                        action="store_true",
+                        help="generate microwatt-compatible interface",
+                        default=False)
 
     args = parser.parse_args()
 
+    # convenience: set some defaults
+    if args.mwcompat:
+        args.pll = False
+        args.debug = 'dmi'
+        args.core = True
+        args.xics = False
+        args.gpio = False
+        args.sram4x4kblock = False
+        args.svp64 = False
+
     print(args)
 
     units = {'alu': 1,
@@ -104,9 +120,12 @@ if __name__ == '__main__':
                          sram4x4kblock=args.enable_sram4x4kblock, # add SRAMs
                          debug=args.debug,      # set to jtag or dmi
                          svp64=args.svp64,      # enable SVP64
-                         microwatt_mmu=args.mmu,          # enable MMU
+                         microwatt_mmu=args.mmu,         # enable MMU
+                         microwatt_compat=args.mwcompat, # microwatt compatible
                          units=units,
                          msr_reset=msr_reset)
+    if args.mwcompat:
+        pspec.core_domain = 'sync'
 
     print("mmu", pspec.__dict__["microwatt_mmu"])
     print("nocore", pspec.__dict__["nocore"])
@@ -117,8 +136,12 @@ if __name__ == '__main__':
     print("use_pll", pspec.__dict__["use_pll"])
     print("debug", pspec.__dict__["debug"])
     print("SVP64", pspec.__dict__["svp64"])
+    print("Microwatt compatibility", pspec.__dict__["microwatt_compat"])
 
-    dut = TestIssuer(pspec)
+    if args.mwcompat:
+        dut = TestIssuerInternal(pspec)
+    else:
+        dut = TestIssuer(pspec)
 
     vl = verilog.convert(dut, ports=dut.external_ports(), name="test_issuer")
     with open(args.output_filename, "w") as f: