remove ClockSelect module, use DummyPLL
[soc.git] / src / soc / simple / issuer.py
index 61a4f2bc16f362bc77a906fa4e8dbc538af29eef..c231702f49f10fbac273da58e8da5f6e97ce50d2 100644 (file)
@@ -33,10 +33,12 @@ from soc.config.ifetch import ConfigFetchUnit
 from soc.decoder.power_enums import MicrOp
 from soc.debug.dmi import CoreDebug, DMIInterface
 from soc.debug.jtag import JTAG
+from soc.config.pinouts import get_pinspecs
 from soc.config.state import CoreState
 from soc.interrupts.xics import XICS_ICP, XICS_ICS
 from soc.bus.simple_gpio import SimpleGPIO
-from soc.clock.select import ClockSelect, DummyPLL
+from soc.clock.select import ClockSelect
+from soc.clock.dummypll import DummyPLL
 
 
 from nmutil.util import rising_edge
@@ -49,6 +51,22 @@ class TestIssuerInternal(Elaboratable):
     """
     def __init__(self, pspec):
 
+        # JTAG interface.  add this right at the start because if it's
+        # added it *modifies* the pspec, by adding enable/disable signals
+        # for parts of the rest of the core
+        self.jtag_en = hasattr(pspec, "debug") and pspec.debug == 'jtag'
+        if self.jtag_en:
+            subset = {'uart', 'mtwi', 'eint', 'gpio', 'mspi0', 'mspi1',
+                      'pwm', 'sd0', 'sdr'}
+            self.jtag = JTAG(get_pinspecs(subset=subset))
+            # add signals to pspec to enable/disable icache and dcache
+            # (or data and intstruction wishbone if icache/dcache not included)
+            # https://bugs.libre-soc.org/show_bug.cgi?id=520
+            # TODO: do we actually care if these are not domain-synchronised?
+            # honestly probably not.
+            pspec.wb_icache_en = self.jtag.wb_icache_en
+            pspec.wb_dcache_en = self.jtag.wb_dcache_en
+
         # add interrupt controller?
         self.xics = hasattr(pspec, "xics") and pspec.xics == True
         if self.xics:
@@ -80,11 +98,6 @@ class TestIssuerInternal(Elaboratable):
         # DMI interface
         self.dbg = CoreDebug()
 
-        # JTAG interface
-        self.jtag_en = hasattr(pspec, "debug") and pspec.debug == 'jtag'
-        if self.jtag_en:
-            self.jtag = JTAG()
-
         # instruction go/monitor
         self.pc_o = Signal(64, reset_less=True)
         self.pc_i = Data(64, "pc_i") # set "ok" to indicate "please change me"
@@ -137,8 +150,10 @@ class TestIssuerInternal(Elaboratable):
             m.submodules.simple_gpio = simple_gpio = self.simple_gpio
 
         # connect one GPIO output to ICS bit 15 (like in microwatt soc.vhdl)
-        if self.gpio and self.xics:
-            comb += self.int_level_i[15].eq(simple_gpio.gpio_o[0])
+        # XXX causes litex ECP5 test to get wrong idea about input and output
+        # (but works with verilator sim *sigh*)
+        #if self.gpio and self.xics:
+        #   comb += self.int_level_i[15].eq(simple_gpio.gpio_o[0])
 
         # instruction decoder
         pdecode = create_pdecode()
@@ -154,13 +169,16 @@ class TestIssuerInternal(Elaboratable):
         core_sync = ClockDomain("coresync")
         m.domains += cd_por, cd_sync, core_sync
 
+        ti_rst = Signal(reset_less=True)
         delay = Signal(range(4), reset=3)
         with m.If(delay != 0):
             m.d.por += delay.eq(delay - 1)
         comb += cd_por.clk.eq(ClockSignal())
-        comb += core_sync.clk.eq(ClockSignal())
-        # power-on reset delay 
-        comb += core.core_reset_i.eq(delay != 0 | dbg.core_rst_o)
+
+        # power-on reset delay
+        core_rst = ResetSignal("coresync")
+        comb += ti_rst.eq(delay != 0 | dbg.core_rst_o | ResetSignal())
+        comb += core_rst.eq(ti_rst)
 
         # busy/halted signals from core
         comb += self.busy_o.eq(core.busy_o)
@@ -232,7 +250,7 @@ class TestIssuerInternal(Elaboratable):
                 sync += core.e.eq(0)
                 sync += core.raw_insn_i.eq(0)
                 sync += core.bigendian_i.eq(0)
-                with m.If(~dbg.core_stop_o & ~core.core_reset_i):
+                with m.If(~dbg.core_stop_o & ~core_rst):
                     # instruction allowed to go: start by reading the PC
                     # capture the PC and also drop it into Insn Memory
                     # we have joined a pair of combinatorial memory
@@ -440,53 +458,62 @@ class TestIssuerInternal(Elaboratable):
 class TestIssuer(Elaboratable):
     def __init__(self, pspec):
         self.ti = TestIssuerInternal(pspec)
+
         self.pll = DummyPLL()
-        self.clksel = ClockSelect()
+
+        # PLL direct clock or not
+        self.pll_en = hasattr(pspec, "use_pll") and pspec.use_pll
 
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
 
-        # TestIssuer runs at internal clock rate
-        m.submodules.ti = ti = DomainRenamer("intclk")(self.ti)
-        # ClockSelect runs at PLL output internal clock rate
-        m.submodules.clksel = clksel = DomainRenamer("pllclk")(self.clksel)
-        m.submodules.pll = pll = self.pll
+        # TestIssuer runs at direct clock
+        m.submodules.ti = ti = self.ti
+        cd_int = ClockDomain("coresync")
 
-        # add 2 clock domains established above...
-        cd_int = ClockDomain("intclk")
-        cd_pll = ClockDomain("pllclk")
-        # probably don't have to add cd_int because of DomainRenamer("coresync")
-        m.domains += cd_pll
+        if self.pll_en:
+            # ClockSelect runs at PLL output internal clock rate
+            m.submodules.pll = pll = self.pll
 
-        # internal clock is set to selector clock-out.  has the side-effect of
-        # running TestIssuer at this speed (see DomainRenamer("intclk") above)
-        comb += cd_int.clk.eq(clksel.core_clk_o)
+            # add clock domains from PLL
+            cd_pll = ClockDomain("pllclk")
+            m.domains += cd_pll
+
+            # PLL clock established.  has the side-effect of running clklsel
+            # at the PLL's speed (see DomainRenamer("pllclk") above)
+            pllclk = ClockSignal("pllclk")
+            comb += pllclk.eq(pll.clk_pll_o)
 
-        # PLL clock established.  has the side-effect of running clklsel
-        # at the PLL's speed (see DomainRenamer("pllclk") above)
-        comb += cd_pll.clk.eq(pll.clk_pll_o)
+            # wire up external 24mhz to PLL
+            comb += pll.clk_24_i.eq(ClockSignal())
 
-        # wire up external 24mhz to PLL and clksel
-        comb += pll.clk_24_i.eq(clksel.clk_24_i)
+            # now wire up ResetSignals.  don't mind them being in this domain
+            pll_rst = ResetSignal("pllclk")
+            comb += pll_rst.eq(ResetSignal())
 
-        # now wire up ResetSignals.  don't mind them all being in this domain
-        comb += pll.rst.eq(ResetSignal())
-        comb += clksel.rst.eq(ResetSignal())
+        # internal clock is set to selector clock-out.  has the side-effect of
+        # running TestIssuer at this speed (see DomainRenamer("intclk") above)
+        intclk = ClockSignal("coresync")
+        if self.pll_en:
+            comb += intclk.eq(pll.clk_pll_o)
+        else:
+            comb += intclk.eq(ClockSignal())
 
         return m
 
     def ports(self):
         return list(self.ti.ports()) + list(self.pll.ports()) + \
-               [ClockSignal(), ResetSignal()] + \
-               list(self.clksel.ports())
+               [ClockSignal(), ResetSignal()]
 
     def external_ports(self):
         ports = self.ti.external_ports()
-        #ports.append(ClockSignal())
-        #ports.append(ResetSignal())
-        ports.append(self.clksel.clk_sel_i)
-        ports.append(self.clksel.pll_48_o)
+        ports.append(ClockSignal())
+        ports.append(ResetSignal())
+        if self.pll_en:
+            ports.append(self.pll.clk_sel_i)
+            ports.append(self.pll.pll_18_o)
+            ports.append(self.pll.clk_lck_o)
         return ports