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.
This commit is contained in:
Tim 'mithro' Ansell 2017-09-26 10:01:36 +10:00 committed by Tim 'mithro' Ansell
parent 2cc6a3036c
commit 44650dffd8
3 changed files with 41 additions and 9 deletions

View File

@ -6,7 +6,8 @@ from litex.soc.interconnect import wishbone
class LM32(Module): 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.ibus = i = wishbone.Interface()
self.dbus = d = wishbone.Interface() self.dbus = d = wishbone.Interface()
self.interrupt = Signal(32) self.interrupt = Signal(32)

View File

@ -6,16 +6,15 @@ from litex.soc.interconnect import wishbone
class MOR1KX(Module): 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.ibus = i = wishbone.Interface()
self.dbus = d = wishbone.Interface() self.dbus = d = wishbone.Interface()
self.interrupt = Signal(32) self.interrupt = Signal(32)
# # # # # #
i_adr_o = Signal(32) cpu_args = dict(
d_adr_o = Signal(32)
self.specials += Instance("mor1kx",
p_FEATURE_INSTRUCTIONCACHE="ENABLED", p_FEATURE_INSTRUCTIONCACHE="ENABLED",
p_OPTION_ICACHE_BLOCK_WIDTH=4, p_OPTION_ICACHE_BLOCK_WIDTH=4,
p_OPTION_ICACHE_SET_WIDTH=8, p_OPTION_ICACHE_SET_WIDTH=8,
@ -39,6 +38,35 @@ class MOR1KX(Module):
p_OPTION_RESET_PC=reset_pc, p_OPTION_RESET_PC=reset_pc,
p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
p_DBUS_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_clk=ClockSignal(),
i_rst=ResetSignal(), i_rst=ResetSignal(),

View File

@ -60,7 +60,7 @@ class SoCCore(Module):
"csr": 0x60000000, # (default shadow @0xe0000000) "csr": 0x60000000, # (default shadow @0xe0000000)
} }
def __init__(self, platform, clk_freq, 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_rom_size=0, integrated_rom_init=[],
integrated_sram_size=4096, integrated_sram_size=4096,
integrated_main_ram_size=0, integrated_main_ram_init=[], integrated_main_ram_size=0, integrated_main_ram_init=[],
@ -76,6 +76,7 @@ class SoCCore(Module):
self.clk_freq = clk_freq self.clk_freq = clk_freq
self.cpu_type = cpu_type self.cpu_type = cpu_type
self.cpu_variant = cpu_variant
if integrated_rom_size: if integrated_rom_size:
cpu_reset_address = self.mem_map["rom"] cpu_reset_address = self.mem_map["rom"]
self.cpu_reset_address = cpu_reset_address self.cpu_reset_address = cpu_reset_address
@ -103,16 +104,18 @@ class SoCCore(Module):
if cpu_type is not None: if cpu_type is not None:
if cpu_type == "lm32": 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": 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": 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: else:
raise ValueError("Unsupported CPU type: {}".format(cpu_type)) 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.ibus)
self.add_wb_master(self.cpu_or_bridge.dbus) self.add_wb_master(self.cpu_or_bridge.dbus)
self.config["CPU_TYPE"] = str(cpu_type).upper() self.config["CPU_TYPE"] = str(cpu_type).upper()
if self.cpu_variant:
self.config["CPU_VARIANT"] = str(cpu_type).upper()
if integrated_rom_size: if integrated_rom_size:
self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True, init=integrated_rom_init) self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True, init=integrated_rom_init)