X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Fissuer.py;h=27afb68ed4546c2751f87f35db7373f845c7464b;hb=50adde0faa929c2c1e9f305357cbae6d9f0deae7;hp=215a6a9850bd387faf5d6e9342bc254319460a82;hpb=65f1492b3d3531687ba90c5c537453cde0e6e5fd;p=soc.git diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 215a6a98..27afb68e 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -23,6 +23,7 @@ import sys from soc.decoder.power_decoder import create_pdecode from soc.decoder.power_decoder2 import PowerDecode2 +from soc.decoder.decode2execute1 import IssuerDecode2ToOperand from soc.decoder.decode2execute1 import Data from soc.experiment.testmem import TestMemory # test only for instructions from soc.regfile.regfiles import StateRegs, FastRegs @@ -31,20 +32,40 @@ from soc.config.test.test_loadstore import TestMemPspec 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 nmutil.util import rising_edge -class TestIssuer(Elaboratable): +class TestIssuerInternal(Elaboratable): """TestIssuer - reads instructions from TestMemory and issues them efficiency and speed is not the main goal here: functional correctness is. """ 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: @@ -58,12 +79,14 @@ class TestIssuer(Elaboratable): self.simple_gpio = SimpleGPIO() self.gpio_o = self.simple_gpio.gpio_o - # main instruction core + # main instruction core25 self.core = core = NonProductionCore(pspec) - # instruction decoder + # instruction decoder. goes into Trap Record pdecode = create_pdecode() - self.pdecode2 = PowerDecode2(pdecode) # decoder + self.cur_state = CoreState("cur") # current state (MSR/PC/EINT) + self.pdecode2 = PowerDecode2(pdecode, state=self.cur_state, + opkls=IssuerDecode2ToOperand) # Test Instruction memory self.imem = ConfigFetchUnit(pspec).fu @@ -106,9 +129,13 @@ class TestIssuer(Elaboratable): m.submodules.core = core = DomainRenamer("coresync")(self.core) m.submodules.imem = imem = self.imem m.submodules.dbg = dbg = self.dbg + if self.jtag_en: + m.submodules.jtag = jtag = self.jtag + # TODO: UART2GDB mux, here, from external pin + # see https://bugs.libre-soc.org/show_bug.cgi?id=499 + sync += dbg.dmi.connect_to(jtag.dmi) - # current state (MSR/PC at the moment - cur_state = CoreState("cur") + cur_state = self.cur_state # XICS interrupt handler if self.xics: @@ -122,8 +149,10 @@ class TestIssuer(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() @@ -139,13 +168,16 @@ class TestIssuer(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) + 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) @@ -203,7 +235,6 @@ class TestIssuer(Elaboratable): dec_opcode_i = pdecode2.dec.raw_opcode_in # raw opcode insn_type = core.e.do.insn_type - dec_state = pdecode2.state # actually use a nmigen FSM for the first time (w00t) # this FSM is perhaps unusual in that it detects conditions @@ -218,7 +249,7 @@ class TestIssuer(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 @@ -255,7 +286,6 @@ class TestIssuer(Elaboratable): else: insn = f_instr_o.word_select(cur_state.pc[2], 32) comb += dec_opcode_i.eq(insn) # actual opcode - comb += dec_state.eq(cur_state) sync += core.e.eq(pdecode2.e) sync += core.state.eq(cur_state) sync += core.raw_insn_i.eq(dec_opcode_i) @@ -398,9 +428,14 @@ class TestIssuer(Elaboratable): def external_ports(self): ports = self.pc_i.ports() ports += [self.pc_o, self.memerr_o, self.core_bigendian_i, self.busy_o, - ClockSignal(), ResetSignal(), ] - ports += list(self.dbg.dmi.ports()) + + if self.jtag_en: + ports += list(self.jtag.external_ports()) + else: + # don't add DMI if JTAG is enabled + ports += list(self.dbg.dmi.ports()) + ports += list(self.imem.ibus.fields.values()) ports += list(self.core.l0.cmpi.lsmem.lsi.slavebus.fields.values()) @@ -419,6 +454,71 @@ class TestIssuer(Elaboratable): return list(self) +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 direct clock + m.submodules.ti = ti = self.ti + cd_int = ClockDomain("coresync") + + # ClockSelect runs at PLL output internal clock rate + m.submodules.clksel = clksel = DomainRenamer("pllclk")(self.clksel) + m.submodules.pll = pll = self.pll + + # add 2 clock domains established above... + cd_pll = ClockDomain("pllclk") + m.domains += cd_pll + + # 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(clksel.core_clk_o) + else: + comb += intclk.eq(ClockSignal()) + + # 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) + + # wire up external 24mhz to PLL and clksel + comb += clksel.clk_24_i.eq(ClockSignal()) + comb += pll.clk_24_i.eq(clksel.clk_24_i) + + # now wire up ResetSignals. don't mind them all being in this domain + #int_rst = ResetSignal("coresync") + pll_rst = ResetSignal("pllclk") + #comb += int_rst.eq(ResetSignal()) + comb += pll_rst.eq(ResetSignal()) + + return m + + def ports(self): + return list(self.ti.ports()) + list(self.pll.ports()) + \ + [ClockSignal(), ResetSignal()] + \ + list(self.clksel.ports()) + + 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) + return ports + + if __name__ == '__main__': units = {'alu': 1, 'cr': 1, 'branch': 1, 'trap': 1, 'logical': 1, 'spr': 1,