X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Fissuer.py;h=27afb68ed4546c2751f87f35db7373f845c7464b;hb=50adde0faa929c2c1e9f305357cbae6d9f0deae7;hp=17ca9df6ac61c42537c9f8183118f0114dc60913;hpb=2a187089be6e063f6bcaf8c27bfe82a5fe76570c;p=soc.git diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 17ca9df6..27afb68e 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -23,28 +23,49 @@ 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 +from soc.regfile.regfiles import StateRegs, FastRegs from soc.simple.core import NonProductionCore 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 @@ -81,7 +104,7 @@ class TestIssuer(Elaboratable): self.busy_o = Signal(reset_less=True) self.memerr_o = Signal(reset_less=True) - # FAST regfile read /write ports for PC and MSR + # FAST regfile read /write ports for PC, MSR, DEC/TB staterf = self.core.regs.rf['state'] self.state_r_pc = staterf.r_ports['cia'] # PC rd self.state_w_pc = staterf.w_ports['d_wr1'] # PC wr @@ -106,21 +129,30 @@ 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) + + cur_state = self.cur_state # XICS interrupt handler if self.xics: m.submodules.xics_icp = icp = self.xics_icp m.submodules.xics_ics = ics = self.xics_ics comb += icp.ics_i.eq(ics.icp_o) # connect ICS to ICP - comb += core.ext_irq_i.eq(icp.core_irq_o) # connect ICP to core + sync += cur_state.eint.eq(icp.core_irq_o) # connect ICP to core # GPIO test peripheral if self.gpio: m.submodules.simple_gpio = simple_gpio = self.simple_gpio - # connect one GPIO output to ICS bit 5 (like in microwatt soc.vhdl) - if self.gpio and self.xics: - comb += self.int_level_i[5].eq(simple_gpio.gpio_o[0]) + # connect one GPIO output to ICS bit 15 (like in microwatt soc.vhdl) + # 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() @@ -136,21 +168,21 @@ 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) comb += pdecode2.dec.bigendian.eq(self.core_bigendian_i) - # current state (MSR/PC at the moment - cur_state = CoreState("cur") - # temporary hack: says "go" immediately for both address gen and ST l0 = core.l0 ldst = core.fus.fus['ldst0'] @@ -187,6 +219,7 @@ class TestIssuer(Elaboratable): # don't read msr every cycle comb += self.state_r_msr.ren.eq(0) + msr_read = Signal(reset=1) # connect up debug signals # TODO comb += core.icache_rst_i.eq(dbg.icache_rst_o) @@ -202,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 @@ -215,7 +247,9 @@ class TestIssuer(Elaboratable): with m.State("IDLE"): sync += pc_changed.eq(0) sync += core.e.eq(0) - with m.If(~dbg.core_stop_o & ~core.core_reset_i): + sync += core.raw_insn_i.eq(0) + sync += core.bigendian_i.eq(0) + 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 @@ -225,8 +259,9 @@ class TestIssuer(Elaboratable): comb += self.imem.f_valid_i.eq(1) sync += cur_state.pc.eq(pc) - # initiate read of MSR + # initiate read of MSR. arrives one clock later comb += self.state_r_msr.ren.eq(1<