From: Tim 'mithro' Ansell Date: Tue, 26 Sep 2017 00:01:36 +0000 (+1000) Subject: cpu: Adding "variant" support. X-Git-Tag: 24jan2021_ls180~1774^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=44650dffd8f82018840922ddbbb6570c8c1e6b08;p=litex.git cpu: Adding "variant" support. It is useful to support slightly different variants of the CPU configurations. This adds a "cpu_variant" option. For the mor1k we now have the default mor1k configuration and the "linux" variant which enables the features needed for Linux support on the mor1k. Currently there are no variants for the lm32, but we will likely add a "tiny" variant for usage on the iCE40. --- diff --git a/litex/soc/cores/cpu/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py index a6c9f339..743a61f6 100644 --- a/litex/soc/cores/cpu/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -6,7 +6,8 @@ from litex.soc.interconnect import wishbone class LM32(Module): - def __init__(self, platform, eba_reset): + def __init__(self, platform, eba_reset, variant=None): + assert variant == None, "No lm32 variants currently supported." self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.interrupt = Signal(32) diff --git a/litex/soc/cores/cpu/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py index d74e0654..87230059 100644 --- a/litex/soc/cores/cpu/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -6,16 +6,15 @@ from litex.soc.interconnect import wishbone class MOR1KX(Module): - def __init__(self, platform, reset_pc): + def __init__(self, platform, reset_pc, variant=None): + assert variant in (None, "linux"), "Unsupported variant %s" % variant self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.interrupt = Signal(32) # # # - i_adr_o = Signal(32) - d_adr_o = Signal(32) - self.specials += Instance("mor1kx", + cpu_args = dict( p_FEATURE_INSTRUCTIONCACHE="ENABLED", p_OPTION_ICACHE_BLOCK_WIDTH=4, p_OPTION_ICACHE_SET_WIDTH=8, @@ -39,6 +38,35 @@ class MOR1KX(Module): p_OPTION_RESET_PC=reset_pc, p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", + ) + + if variant == None: + # Use the default configuration + pass + elif variant == "linux": + cpu_args.update(dict( + # Linux needs the memory management units. + p_FEATURE_IMMU="ENABLED", + p_FEATURE_DMMU="ENABLED", + # FIXME: Currently we need the or1k timer when we should be + # using the litex timer. + p_FEATURE_TIMER="ENABLED", + )) + # FIXME: Check if these are needed? + use_defaults = ( + "p_FEATURE_SYSCALL", "p_FEATURE_TRAP", "p_FEATURE_RANGE", + "p_FEATURE_OVERFLOW", + ) + for to_remove in use_defaults: + del cpu_args[to_remove] + + else: + assert False, "Unsupported variant %s" % variant + + i_adr_o = Signal(32) + d_adr_o = Signal(32) + self.specials += Instance("mor1kx", + **cpu_args, i_clk=ClockSignal(), i_rst=ResetSignal(), diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 1b30c904..0a9c98b6 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -60,7 +60,7 @@ class SoCCore(Module): "csr": 0x60000000, # (default shadow @0xe0000000) } def __init__(self, platform, clk_freq, - cpu_type="lm32", cpu_reset_address=0x00000000, + cpu_type="lm32", cpu_reset_address=0x00000000, cpu_variant=None, integrated_rom_size=0, integrated_rom_init=[], integrated_sram_size=4096, integrated_main_ram_size=0, integrated_main_ram_init=[], @@ -76,6 +76,7 @@ class SoCCore(Module): self.clk_freq = clk_freq self.cpu_type = cpu_type + self.cpu_variant = cpu_variant if integrated_rom_size: cpu_reset_address = self.mem_map["rom"] self.cpu_reset_address = cpu_reset_address @@ -103,16 +104,18 @@ class SoCCore(Module): if cpu_type is not None: if cpu_type == "lm32": - self.add_cpu_or_bridge(lm32.LM32(platform, self.cpu_reset_address)) + self.add_cpu_or_bridge(lm32.LM32(platform, self.cpu_reset_address, self.cpu_variant)) elif cpu_type == "or1k": - self.add_cpu_or_bridge(mor1kx.MOR1KX(platform, self.cpu_reset_address)) + self.add_cpu_or_bridge(mor1kx.MOR1KX(platform, self.cpu_reset_address, self.cpu_variant)) elif cpu_type == "riscv32": - self.add_cpu_or_bridge(picorv32.PicoRV32(platform, self.cpu_reset_address)) + self.add_cpu_or_bridge(picorv32.PicoRV32(platform, self.cpu_reset_address, self.cpu_variant)) else: raise ValueError("Unsupported CPU type: {}".format(cpu_type)) self.add_wb_master(self.cpu_or_bridge.ibus) self.add_wb_master(self.cpu_or_bridge.dbus) self.config["CPU_TYPE"] = str(cpu_type).upper() + if self.cpu_variant: + self.config["CPU_VARIANT"] = str(cpu_type).upper() if integrated_rom_size: self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True, init=integrated_rom_init)