X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Fissuer.py;h=27afb68ed4546c2751f87f35db7373f845c7464b;hb=50adde0faa929c2c1e9f305357cbae6d9f0deae7;hp=485d7e0007d0750967bbcfe015268c6d32861f77;hpb=8d375b8db0fa9ba7ad2898a35bc0a12b1e69857e;p=soc.git diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 485d7e00..27afb68e 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -23,31 +23,70 @@ 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): - # main instruction core + + # 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: + self.xics_icp = XICS_ICP() + self.xics_ics = XICS_ICS() + self.int_level_i = self.xics_ics.int_level_i + + # add GPIO peripheral? + self.gpio = hasattr(pspec, "gpio") and pspec.gpio == True + if self.gpio: + self.simple_gpio = SimpleGPIO() + self.gpio_o = self.simple_gpio.gpio_o + + # 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 @@ -65,14 +104,19 @@ 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 - self.state_r_pc = self.core.regs.rf['state'].r_ports['cia'] # PC rd - self.state_w_pc = self.core.regs.rf['state'].w_ports['d_wr1'] # PC wr - self.state_r_msr = self.core.regs.rf['state'].r_ports['msr'] # MSR rd + # 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 + self.state_r_msr = staterf.r_ports['msr'] # MSR rd # DMI interface access intrf = self.core.regs.rf['int'] + crrf = self.core.regs.rf['cr'] + xerrf = self.core.regs.rf['xer'] self.int_r = intrf.r_ports['dmi'] # INT read + self.cr_r = crrf.r_ports['full_cr_dbg'] # CR read + self.xer_r = xerrf.r_ports['full_xer'] # XER read # hack method of keeping an eye on whether branch/trap set the PC self.state_nia = self.core.regs.rf['state'].w_ports['nia'] @@ -85,14 +129,37 @@ 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 + 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 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() m.submodules.dec2 = pdecode2 = self.pdecode2 # convenience - dmi = dbg.dmi - d_reg = dbg.dbg_gpr + dmi, d_reg, d_cr, d_xer, = dbg.dmi, dbg.d_gpr, dbg.d_cr, dbg.d_xer intrf = self.core.regs.rf['int'] # clock delay power-on reset @@ -101,21 +168,21 @@ class TestIssuer(Elaboratable): core_sync = ClockDomain("coresync") m.domains += cd_por, cd_sync, core_sync - delay = Signal(range(4), reset=1) + 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()) - # XXX TODO: power-on reset delay (later) - #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) 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'] @@ -134,41 +201,40 @@ class TestIssuer(Elaboratable): # read the PC pc = Signal(64, reset_less=True) + pc_ok_delay = Signal() + sync += pc_ok_delay.eq(~self.pc_i.ok) with m.If(self.pc_i.ok): # incoming override (start from pc_i) comb += pc.eq(self.pc_i.data) with m.Else(): - # otherwise read StateRegs regfile for PC + # otherwise read StateRegs regfile for PC... comb += self.state_r_pc.ren.eq(1<