Standardize the `cpu_variant` strings.
Current valid `cpu_variant` values; * minimal (alias: min) * lite (alias: light, zephyr, nuttx) * standard (alias: std) - Default * full (alias: everything) * linux Fully documented in the [docs/Soft-CPU.md](docs/Soft-CPU.md) file mirrored from the [LiteX-BuildEnv Wiki](https://github.com/timvideos/litex-buildenv/wiki). Also support "extensions" which are added to the `cpu_variant` with a `+`. Currently only the `debug` extension is supported. In future hope to add `mmu` and `hmul` extensions.
This commit is contained in:
parent
e42de8fe52
commit
39c579baa2
|
@ -12,8 +12,8 @@ class LM32(Module):
|
||||||
gcc_flags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled"
|
gcc_flags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled"
|
||||||
linker_output_format = "elf32-lm32"
|
linker_output_format = "elf32-lm32"
|
||||||
|
|
||||||
def __init__(self, platform, eba_reset, variant=None):
|
def __init__(self, platform, eba_reset, variant="standard"):
|
||||||
assert variant in (None, "lite", "minimal"), "Unsupported variant %s" % variant
|
assert variant in ("standard", "lite", "minimal"), "Unsupported variant %s" % variant
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
self.ibus = i = wishbone.Interface()
|
self.ibus = i = wishbone.Interface()
|
||||||
self.dbus = d = wishbone.Interface()
|
self.dbus = d = wishbone.Interface()
|
||||||
|
@ -66,7 +66,7 @@ class LM32(Module):
|
||||||
self.add_sources(platform, variant)
|
self.add_sources(platform, variant)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_sources(platform, variant=None):
|
def add_sources(platform, variant):
|
||||||
vdir = os.path.join(
|
vdir = os.path.join(
|
||||||
os.path.abspath(os.path.dirname(__file__)), "verilog")
|
os.path.abspath(os.path.dirname(__file__)), "verilog")
|
||||||
platform.add_sources(os.path.join(vdir, "submodule", "rtl"),
|
platform.add_sources(os.path.join(vdir, "submodule", "rtl"),
|
||||||
|
@ -93,5 +93,7 @@ class LM32(Module):
|
||||||
platform.add_verilog_include_path(os.path.join(vdir, "config_minimal"))
|
platform.add_verilog_include_path(os.path.join(vdir, "config_minimal"))
|
||||||
elif variant == "lite":
|
elif variant == "lite":
|
||||||
platform.add_verilog_include_path(os.path.join(vdir, "config_lite"))
|
platform.add_verilog_include_path(os.path.join(vdir, "config_lite"))
|
||||||
else:
|
elif variant == "standard":
|
||||||
platform.add_verilog_include_path(os.path.join(vdir, "config"))
|
platform.add_verilog_include_path(os.path.join(vdir, "config"))
|
||||||
|
else:
|
||||||
|
raise TypeError("Unknown variant {}".format(variant))
|
||||||
|
|
|
@ -12,8 +12,8 @@ class Minerva(Module):
|
||||||
gcc_flags = "-D__minerva__ -march=rv32i -mabi=ilp32"
|
gcc_flags = "-D__minerva__ -march=rv32i -mabi=ilp32"
|
||||||
linker_output_format = "elf32-littleriscv"
|
linker_output_format = "elf32-littleriscv"
|
||||||
|
|
||||||
def __init__(self, platform, cpu_reset_address, variant=None):
|
def __init__(self, platform, cpu_reset_address, variant="standard"):
|
||||||
assert variant is None, "Unsupported variant %s" % variant
|
assert variant is "standard", "Unsupported variant %s" % variant
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
self.ibus = wishbone.Interface()
|
self.ibus = wishbone.Interface()
|
||||||
self.dbus = wishbone.Interface()
|
self.dbus = wishbone.Interface()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
@ -12,8 +13,8 @@ class MOR1KX(Module):
|
||||||
gcc_flags = "-mhard-mul -mhard-div -mror"
|
gcc_flags = "-mhard-mul -mhard-div -mror"
|
||||||
linker_output_format = "elf32-or1k"
|
linker_output_format = "elf32-or1k"
|
||||||
|
|
||||||
def __init__(self, platform, reset_pc, variant=None):
|
def __init__(self, platform, reset_pc, variant="standard"):
|
||||||
assert variant in (None, "linux"), "Unsupported variant %s" % variant
|
assert variant in ("standard", "linux"), "Unsupported variant %s" % variant
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
self.ibus = i = wishbone.Interface()
|
self.ibus = i = wishbone.Interface()
|
||||||
self.dbus = d = wishbone.Interface()
|
self.dbus = d = wishbone.Interface()
|
||||||
|
@ -47,7 +48,7 @@ class MOR1KX(Module):
|
||||||
p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
|
p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
|
||||||
)
|
)
|
||||||
|
|
||||||
if variant == None:
|
if variant == "standard":
|
||||||
# Use the default configuration
|
# Use the default configuration
|
||||||
pass
|
pass
|
||||||
elif variant == "linux":
|
elif variant == "linux":
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
@ -12,7 +13,7 @@ class PicoRV32(Module):
|
||||||
gcc_flags_template = "-D__picorv32__ -mno-save-restore -march=rv32{ext} -mabi=ilp32"
|
gcc_flags_template = "-D__picorv32__ -mno-save-restore -march=rv32{ext} -mabi=ilp32"
|
||||||
linker_output_format = "elf32-littleriscv"
|
linker_output_format = "elf32-littleriscv"
|
||||||
|
|
||||||
def __init__(self, platform, progaddr_reset, variant):
|
def __init__(self, platform, progaddr_reset, variant="standard"):
|
||||||
self.gcc_flags = ""
|
self.gcc_flags = ""
|
||||||
|
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
|
@ -61,7 +62,7 @@ class PicoRV32(Module):
|
||||||
"p_STACKADDR" : 0xffffffff
|
"p_STACKADDR" : 0xffffffff
|
||||||
}
|
}
|
||||||
|
|
||||||
if variant == None:
|
if variant == "standard":
|
||||||
self.gcc_flags = PicoRV32.gcc_flags_template.format(ext="im")
|
self.gcc_flags = PicoRV32.gcc_flags_template.format(ext="im")
|
||||||
elif variant == "minimal":
|
elif variant == "minimal":
|
||||||
picorv32_params.update({
|
picorv32_params.update({
|
||||||
|
|
|
@ -6,18 +6,51 @@ from litex.soc.interconnect import wishbone
|
||||||
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
||||||
|
|
||||||
|
|
||||||
|
CPU_VARIANTS = {
|
||||||
|
"minimal": "VexRiscv_Min",
|
||||||
|
"minimal+debug": "VexRiscv_MinDebug",
|
||||||
|
"lite": "VexRiscv_Lite",
|
||||||
|
"lite+debug": "VexRiscv_LiteDebug",
|
||||||
|
"standard": "VexRiscv",
|
||||||
|
"standard+debug": "VexRiscv_Debug",
|
||||||
|
"full": "VexRiscv_Full",
|
||||||
|
"full+debug": "VexRiscv_FullDebug",
|
||||||
|
"linux": "VexRiscv_Linux",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GCC_FLAGS = {
|
||||||
|
# /-------- Base ISA
|
||||||
|
# |/------- Hardware Multiply + Divide
|
||||||
|
# ||/----- Atomics
|
||||||
|
# |||/---- Compressed ISA
|
||||||
|
# ||||/--- Single-Precision Floating-Point
|
||||||
|
# |||||/-- Double-Precision Floating-Point
|
||||||
|
# imacfd
|
||||||
|
"minimal": "-march=rv32i -mabi=ilp32",
|
||||||
|
"minimal+debug": "-march=rv32i -mabi=ilp32",
|
||||||
|
"lite": "-march=rv32i -mabi=ilp32",
|
||||||
|
"lite+debug": "-march=rv32i -mabi=ilp32",
|
||||||
|
"standard": "-march=rv32im -mabi=ilp32",
|
||||||
|
"standard+debug": "-march=rv32im -mabi=ilp32",
|
||||||
|
# Does full have floating point? - Add -march=fd, and -mabi=fd
|
||||||
|
"full": "-march=rv32imac -mabi=ilp32",
|
||||||
|
"full+debug": "-march=rv32imac -mabi=ilp32",
|
||||||
|
"linux": "-march=rv32imac -mabi=ilp32",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class VexRiscv(Module, AutoCSR):
|
class VexRiscv(Module, AutoCSR):
|
||||||
name = "vexriscv"
|
name = "vexriscv"
|
||||||
endianness = "little"
|
endianness = "little"
|
||||||
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf")
|
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf")
|
||||||
gcc_flags = "-D__vexriscv__ -march=rv32im -mabi=ilp32"
|
|
||||||
linker_output_format = "elf32-littleriscv"
|
linker_output_format = "elf32-littleriscv"
|
||||||
|
|
||||||
def __init__(self, platform, cpu_reset_address, variant=None):
|
def __init__(self, platform, cpu_reset_address, variant="standard"):
|
||||||
variant = "std" if variant is None else variant
|
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
||||||
variant = "std_debug" if variant == "debug" else variant
|
|
||||||
variants = ("std", "std_debug", "lite", "lite_debug", "min", "min_debug", "full", "full_debug")
|
self.gcc_flags = GCC_FLAGS[variant]
|
||||||
assert variant in variants, "Unsupported variant %s" % variant
|
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
self.variant = variant
|
self.variant = variant
|
||||||
self.external_variant = None
|
self.external_variant = None
|
||||||
|
@ -150,18 +183,8 @@ class VexRiscv(Module, AutoCSR):
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_sources(platform, variant="std"):
|
def add_sources(platform, variant="standard"):
|
||||||
verilog_variants = {
|
cpu_filename = CPU_VARIANTS[variant]
|
||||||
"std": "VexRiscv.v",
|
|
||||||
"std_debug": "VexRiscv_Debug.v",
|
|
||||||
"lite": "VexRiscv_Lite.v",
|
|
||||||
"lite_debug": "VexRiscv_LiteDebug.v",
|
|
||||||
"min": "VexRiscv_Min.v",
|
|
||||||
"min_debug": "VexRiscv_MinDebug.v",
|
|
||||||
"full": "VexRiscv_Full.v",
|
|
||||||
"full_debug": "VexRiscv_FullDebug.v",
|
|
||||||
}
|
|
||||||
cpu_filename = verilog_variants[variant]
|
|
||||||
vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog")
|
vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog")
|
||||||
platform.add_source(os.path.join(vdir, cpu_filename))
|
platform.add_source(os.path.join(vdir, cpu_filename))
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -23,6 +24,42 @@ __all__ = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
CPU_VARIANTS = {
|
||||||
|
# "official name": ["alias 1", "alias 2"],
|
||||||
|
"minimal" : ["min",],
|
||||||
|
"lite" : ["light", "zephyr", "nuttx"],
|
||||||
|
"standard": [None, "std"],
|
||||||
|
"full": [],
|
||||||
|
"linux" : [],
|
||||||
|
}
|
||||||
|
CPU_VARIANTS_EXTENSIONS = ["debug"]
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidCPUVariantError(ValueError):
|
||||||
|
def __init__(self, variant):
|
||||||
|
msg = """\
|
||||||
|
Invalid cpu_variant value: {}
|
||||||
|
|
||||||
|
Possible Values:
|
||||||
|
""".format(variant)
|
||||||
|
for k, v in CPU_VARIANTS.items():
|
||||||
|
msg += " - {} (aliases: {})\n".format(k, ", ".join(str(s) for s in v))
|
||||||
|
ValueError.__init__(self, msg)
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidCPUExtensionError(ValueError):
|
||||||
|
def __init__(self, variant):
|
||||||
|
msg = """\
|
||||||
|
Invalid extension in cpu_variant value: {}
|
||||||
|
|
||||||
|
Possible Values:
|
||||||
|
""".format(variant)
|
||||||
|
for e in CPU_VARIANTS_EXTENSIONS.items():
|
||||||
|
msg += " - {}\n".format(e)
|
||||||
|
ValueError.__init__(self, msg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def version(with_time=True):
|
def version(with_time=True):
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
|
@ -77,6 +114,7 @@ def get_mem_data(filename, endianness="big", mem_size=None):
|
||||||
i += 1
|
i += 1
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
class ReadOnlyDict(dict):
|
class ReadOnlyDict(dict):
|
||||||
def __readonly__(self, *args, **kwargs):
|
def __readonly__(self, *args, **kwargs):
|
||||||
raise RuntimeError("Cannot modify ReadOnlyDict")
|
raise RuntimeError("Cannot modify ReadOnlyDict")
|
||||||
|
@ -162,7 +200,25 @@ class SoCCore(Module):
|
||||||
if cpu_type == "None":
|
if cpu_type == "None":
|
||||||
cpu_type = None
|
cpu_type = None
|
||||||
self.cpu_type = cpu_type
|
self.cpu_type = cpu_type
|
||||||
self.cpu_variant = cpu_variant
|
|
||||||
|
# Support the old style which used underscore for separator
|
||||||
|
cpu_variant = cpu_variant.replace('_', '+')
|
||||||
|
# Check for valid CPU variants.
|
||||||
|
cpu_variant_processor, *cpu_variant_ext = cpu_variant.split('+')
|
||||||
|
for key, values in CPU_VARIANTS.items():
|
||||||
|
if cpu_variant_processor not in [key,]+values:
|
||||||
|
continue
|
||||||
|
self.cpu_variant = key
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise InvalidCPUVariantError(cpu_variant)
|
||||||
|
|
||||||
|
# Check for valid CPU extensions.
|
||||||
|
for ext in sorted(cpu_variant_ext):
|
||||||
|
if cpu_variant_ext not in CPU_VARIANTS_EXTENSIONS:
|
||||||
|
raise InvalidCPUExtension(cpu_variant)
|
||||||
|
self.cpu_variant += "+"+ext
|
||||||
|
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue