From: Luke Kenneth Casson Leighton Date: Mon, 3 Jan 2022 19:55:53 +0000 (+0000) Subject: adding an extra option to issuer_verilog.py to be able to cteate a X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a3f89019b38d619d858b39530d774ec6dba1386d;p=soc.git adding an extra option to issuer_verilog.py to be able to cteate a 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); --- diff --git a/src/soc/experiment/dcache.py b/src/soc/experiment/dcache.py index adb36fad..b9e467bb 100644 --- a/src/soc/experiment/dcache.py +++ b/src/soc/experiment/dcache.py @@ -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) diff --git a/src/soc/fu/ldst/loadstore.py b/src/soc/fu/ldst/loadstore.py index 1ecac0ad..97972c2f 100644 --- a/src/soc/fu/ldst/loadstore.py +++ b/src/soc/fu/ldst/loadstore.py @@ -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 diff --git a/src/soc/minerva/wishbone.py b/src/soc/minerva/wishbone.py index f84a01cc..6786ff52 100644 --- a/src/soc/minerva/wishbone.py +++ b/src/soc/minerva/wishbone.py @@ -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 + [ diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 85ea892f..2fafc662 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -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, diff --git a/src/soc/simple/issuer_verilog.py b/src/soc/simple/issuer_verilog.py index 1e9ed75a..6fead5ee 100644 --- a/src/soc/simple/issuer_verilog.py +++ b/src/soc/simple/issuer_verilog.py @@ -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: