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:
Tim 'mithro' Ansell 2019-04-26 16:20:21 -05:00
parent e42de8fe52
commit 39c579baa2
6 changed files with 113 additions and 30 deletions

View File

@ -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))

View File

@ -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()

View File

@ -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":

View File

@ -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({

View File

@ -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))

View File

@ -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