cpus: remove common cpu variants/extensions definition and simplify variant check.
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 26 May 2020 07:36:44 +0000 (09:36 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 26 May 2020 07:36:44 +0000 (09:36 +0200)
Having common cpu variants/extensions has no real additional value since we are supporting
very various CPUs where minimal/standard/full have different meanings. Checking against
common variants/extensions has also cause more issues recently when adding new CPUs than
the additional value it was supported to provide.

So let's just simplify things: a CPU provide the supported variants and we just check
against that.

13 files changed:
litex/soc/cores/cpu/__init__.py
litex/soc/cores/cpu/blackparrot/core.py
litex/soc/cores/cpu/cv32e40p/core.py
litex/soc/cores/cpu/lm32/core.py
litex/soc/cores/cpu/microwatt/core.py
litex/soc/cores/cpu/minerva/core.py
litex/soc/cores/cpu/mor1kx/core.py
litex/soc/cores/cpu/picorv32/core.py
litex/soc/cores/cpu/rocket/core.py
litex/soc/cores/cpu/serv/core.py
litex/soc/cores/cpu/vexriscv/core.py
litex/soc/integration/soc.py
litex/soc/integration/soc_core.py

index 7c0529f0fb5f79ee26d615cdd16b83f7b6b2d7eb..d0a305577ac0275fd2c7b54927f4b3c591f78648 100644 (file)
@@ -19,10 +19,12 @@ class CPU(Module):
     mem_map              = {}
     io_regions           = {}
     use_rom              = False
+
     def __init__(self, *args, **kwargs):
         pass
 
 class CPUNone(CPU):
+    variants             = ["standard"]
     data_width           = 32
     reset_address        = 0x00000000
     io_regions           = {0x00000000: 0x100000000} # origin, length
@@ -83,69 +85,3 @@ CPUS = {
     "rocket"      : RocketRV64,
     "blackparrot" : BlackParrotRV64,
 }
-
-# CPU Variants/Extensions Definition ---------------------------------------------------------------
-
-CPU_VARIANTS = {
-    # "official name": ["alias 1", "alias 2"],
-    "minimal" :   ["min",],
-    "lite" :      ["light", "zephyr", "nuttx"],
-    "standard":   [None, "std"],
-    "imac":       [],
-    "full":       [],
-    "linux" :     [],
-    "linuxd" :    [],
-    "linuxq" :    [],
-}
-CPU_VARIANTS_EXTENSIONS = ["debug", "no-dsp", "ghdl"]
-
-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:
-            msg += " - {}\n".format(e)
-        ValueError.__init__(self, msg)
-
-# CPU Variants/Extensions Check/Format -------------------------------------------------------------
-
-def check_format_cpu_variant(variant):
-       # Support the old style which used underscore for separator
-    if variant is None:
-        variant = "standard"
-    if variant == "debug":
-        variant = "standard+debug"
-    variant = variant.replace('_', '+')
-
-    # Check for valid CPU variants.
-    processor, *extensions = variant.split('+')
-    for k, v in CPU_VARIANTS.items():
-        if processor not in [k,]+v:
-            continue
-        _variant = k
-        break
-    else:
-        raise InvalidCPUVariantError(variant)
-
-    # Check for valid CPU extensions.
-    for extension in sorted(extensions):
-        if extension not in CPU_VARIANTS_EXTENSIONS:
-            raise InvalidCPUExtensionError(variant)
-        _variant += "+"+extension
-
-    return _variant
index 79ee294d84b2cce3bdadfb84f7c8aaa06084061f..b062633ed1b9d64e3649e6d0a8de84644842dea5 100644 (file)
@@ -48,6 +48,7 @@ GCC_FLAGS = {
 class BlackParrotRV64(CPU):
     name                 = "blackparrot"
     human_name           = "BlackParrotRV64[ia]"
+    variants             = CPU_VARIANTS
     data_width           = 64
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV64
@@ -73,8 +74,6 @@ class BlackParrotRV64(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
-
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
@@ -108,7 +107,7 @@ class BlackParrotRV64(CPU):
             )
 
            # add verilog sources
-        try:  
+        try:
             os.environ["BP"]
             os.environ["LITEX"]
             self.add_sources(platform, variant)
@@ -145,14 +144,14 @@ class BlackParrotRV64(CPU):
                     a = os.popen('echo '+ str(dir_))
                     dir_start = a.read()
                     vdir = dir_start[:-1] + line[s2:-1]
-                    platform.add_verilog_include_path(vdir)  
+                    platform.add_verilog_include_path(vdir)
                 elif (temp[0]=='$') :
                     s2 = line.find('/')
                     dir_ = line[0:s2]
                     a = os.popen('echo '+ str(dir_))
                     dir_start = a.read()
                     vdir = dir_start[:-1]+ line[s2:-1]
-                    platform.add_source(vdir, "systemverilog") 
+                    platform.add_source(vdir, "systemverilog")
                 elif (temp[0] == '/'):
                     assert("No support for absolute path for now")
 
index ecc9887345068b561d68916eb2f2a12af6312c95..e17b5b6816eb458960df19828079b94f92d4e51d 100644 (file)
@@ -304,6 +304,7 @@ class DebugModule(Module):
 class CV32E40P(CPU):
     name                 = "cv32e40p"
     human_name           = "CV32E40P"
+    variants             = CPU_VARIANTS
     data_width           = 32
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV32
@@ -321,7 +322,6 @@ class CV32E40P(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
index 2b6273f3d6034499d55d62f64bf6a8fd53c6c70b..9f907225840e63a7f2d17ad611a4f82d7b5f2ed9 100644 (file)
@@ -19,6 +19,7 @@ CPU_VARIANTS = ["minimal", "lite", "standard"]
 class LM32(CPU):
     name                 = "lm32"
     human_name           = "LM32"
+    variants             = CPU_VARIANTS
     data_width           = 32
     endianness           = "big"
     gcc_triple           = "lm32-elf"
@@ -36,7 +37,6 @@ class LM32(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
index b0dee76dc27a7f6c5238d37be3e243c555b554e0..edc1117bd2760bae7bb17ab7db7dcb676d856cf0 100644 (file)
@@ -17,6 +17,7 @@ CPU_VARIANTS = ["standard", "standard+ghdl"]
 class Microwatt(CPU):
     name                 = "microwatt"
     human_name           = "Microwatt"
+    variants             = CPU_VARIANTS
     data_width           = 64
     endianness           = "little"
     gcc_triple           = ("powerpc64le-linux", "powerpc64le-linux-gnu")
@@ -44,7 +45,6 @@ class Microwatt(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
index 64cf86662502870e36436f78bb8f3c143f783264..99fd876f34dcae6d6c0384feb54ceea7eb7ac603 100644 (file)
@@ -17,6 +17,7 @@ CPU_VARIANTS = ["standard"]
 class Minerva(CPU):
     name                 = "minerva"
     human_name           = "Minerva"
+    variants             = CPU_VARIANTS
     data_width           = 32
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV32
@@ -32,7 +33,6 @@ class Minerva(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
index 5f05ef340213a9a3dc56e5c02b3a9a4320f23672..510687660876a4eaf368842d747a16e339fecfb1 100644 (file)
@@ -18,6 +18,7 @@ CPU_VARIANTS = ["standard", "linux"]
 class MOR1KX(CPU):
     name                 = "mor1kx"
     human_name           = "MOR1KX"
+    variants             = CPU_VARIANTS
     data_width           = 32
     endianness           = "big"
     gcc_triple           = "or1k-elf"
@@ -65,7 +66,6 @@ class MOR1KX(CPU):
         return {"nmi": 0}
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
index 3f568db4b41795c4fb345f3ef0f00441c7040f2c..9bfa27e9a28c85af590c3f1fe893ea53ca61c0e7 100644 (file)
@@ -34,6 +34,7 @@ GCC_FLAGS = {
 class PicoRV32(CPU):
     name                 = "picorv32"
     human_name           = "PicoRV32"
+    variants             = CPU_VARIANTS
     data_width           = 32
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV64
@@ -57,7 +58,6 @@ class PicoRV32(CPU):
         }
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.trap         = Signal()
index f08019fffcaaefd1c64309fb0570f05337e8603c..d90787ca362f4aae4583f6c28bd85b5e3199f939 100644 (file)
@@ -67,6 +67,7 @@ AXI_DATA_WIDTHS = {
 class RocketRV64(CPU):
     name                 = "rocket"
     human_name           = "RocketRV64[imac]"
+    variants             = CPU_VARIANTS
     data_width           = 64
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV64
@@ -93,8 +94,6 @@ class RocketRV64(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
-
         self.platform  = platform
         self.variant   = variant
 
index 739b83b6b181ef6319e2dfe814094d30616b5301..6fe912be9b50d418c79db1e19a56219b1e2deade 100644 (file)
@@ -32,7 +32,6 @@ class SERV(CPU):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
index 9b981506f600f3678ecf20e3b79d5ecf6a5cf50c..551bfa837535904b6956f313e5ac196cd11ac4ad 100644 (file)
@@ -81,6 +81,7 @@ class VexRiscvTimer(Module, AutoCSR):
 class VexRiscv(CPU, AutoCSR):
     name                 = "vexriscv"
     human_name           = "VexRiscv"
+    variants             = CPU_VARIANTS
     data_width           = 32
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV32
@@ -104,7 +105,6 @@ class VexRiscv(CPU, AutoCSR):
         return flags
 
     def __init__(self, platform, variant="standard"):
-        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
         self.platform         = platform
         self.variant          = variant
         self.external_variant = None
index 28f69783cabc17eb4c565a25b7a10f4fe18575c9..7356a5ed3682f68b72f8dc2704704fd65493dd11 100644 (file)
@@ -773,13 +773,19 @@ class SoC(Module):
 
     def add_cpu(self, name="vexriscv", variant="standard", cls=None, reset_address=None):
         if name not in cpu.CPUS.keys():
-            self.logger.error("{} CPU {}, supporteds: {}".format(
+            self.logger.error("{} CPU {}, supporteds: {}.".format(
                 colorer(name),
                 colorer("not supported", color="red"),
                 colorer(", ".join(cpu.CPUS.keys()))))
             raise
         # Add CPU
         cpu_cls = cls if cls is not None else cpu.CPUS[name]
+        if variant not in cpu_cls.variants:
+            self.logger.error("{} CPU variant {}, supporteds: {}.".format(
+                colorer(variant),
+                colorer("not supported", color="red"),
+                colorer(", ".join(cpu_cls.variants))))
+            raise
         self.submodules.cpu = cpu_cls(self.platform, variant)
         # Update SoC with CPU constraints
         for n, (origin, size) in enumerate(self.cpu.io_regions.items()):
index 123b3b425f418722ea0ee29067ec656cc2a934d7..1b90c1ac3f4851d3985ab958ee8f57b70329fa10 100644 (file)
@@ -128,7 +128,6 @@ class SoCCore(LiteXSoC):
         # Parameters management --------------------------------------------------------------------
         cpu_type          = None if cpu_type == "None" else cpu_type
         cpu_reset_address = None if cpu_reset_address == "None" else cpu_reset_address
-        cpu_variant       = cpu.check_format_cpu_variant(cpu_variant) if cpu_cls is None else cpu_variant
 
         self.cpu_type                   = cpu_type
         self.cpu_variant                = cpu_variant