diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py index e19a0c505..ec57b0b23 100644 --- a/litex/soc/cores/cpu/__init__.py +++ b/litex/soc/cores/cpu/__init__.py @@ -2,6 +2,23 @@ # This file is Copyright (c) 2015-2019 Florent Kermarrec # License: BSD +from migen import * + +# CPU ---------------------------------------------------------------------------------------------- + +class CPU(Module): + name = None + data_width = None + endianness = None + gcc_triple = None + gcc_flags = None + clang_triple = None + clang_flags = None + linker_output_format = None + interrupts = {} + mem_map = {} + +# CPUS --------------------------------------------------------------------------------------------- from litex.soc.cores.cpu.lm32 import LM32 from litex.soc.cores.cpu.mor1kx import MOR1KX @@ -11,8 +28,6 @@ from litex.soc.cores.cpu.minerva import Minerva from litex.soc.cores.cpu.rocket import RocketRV64 from litex.soc.cores.cpu.serv import SERV -# CPUS --------------------------------------------------------------------------------------------- - CPUS = { "lm32" : LM32, "mor1kx" : MOR1KX, @@ -61,7 +76,6 @@ Possible Values: # CPU Variants/Extensions Check/Format ------------------------------------------------------------- - def check_format_cpu_variant(variant): # Support the old style which used underscore for separator if variant is None: diff --git a/litex/soc/cores/cpu/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py index bbb676f6b..1e30e45fc 100644 --- a/litex/soc/cores/cpu/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -10,22 +10,17 @@ import os from migen import * from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU CPU_VARIANTS = ["minimal", "lite", "standard"] -class LM32(Module): - @property - def name(self): - return "lm32" - - @property - def endianness(self): - return "big" - - @property - def gcc_triple(self): - return "lm32-elf" +class LM32(CPU): + name = "lm32" + data_width = 32 + endianness = "big" + gcc_triple = "lm32-elf" + linker_output_format = "elf32-lm32" @property def gcc_flags(self): @@ -36,14 +31,6 @@ class LM32(Module): flags += "-D__lm32__ " return flags - @property - def linker_output_format(self): - return "elf32-lm32" - - @property - def reserved_interrupts(self): - return {} - def __init__(self, platform, variant="standard"): assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant self.platform = platform diff --git a/litex/soc/cores/cpu/minerva/core.py b/litex/soc/cores/cpu/minerva/core.py index 9d13696da..24e5bc08c 100644 --- a/litex/soc/cores/cpu/minerva/core.py +++ b/litex/soc/cores/cpu/minerva/core.py @@ -7,22 +7,17 @@ import os from migen import * from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU CPU_VARIANTS = ["standard"] -class Minerva(Module): - @property - def name(self): - return "minerva" - - @property - def endianness(self): - return "little" - - @property - def gcc_triple(self): - return ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") +class Minerva(CPU): + name = "minerva" + data_width = 32 + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") + linker_output_format = "elf32-littleriscv" @property def gcc_flags(self): @@ -31,14 +26,6 @@ class Minerva(Module): flags += "-D__minerva__ " return flags - @property - def linker_output_format(self): - return "elf32-littleriscv" - - @property - def reserved_interrupts(self): - return {} - def __init__(self, platform, variant="standard"): assert variant is "standard", "Unsupported variant %s" % variant self.platform = platform diff --git a/litex/soc/cores/cpu/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py index 46f55e651..9b1e15acb 100644 --- a/litex/soc/cores/cpu/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -4,25 +4,23 @@ # This file is Copyright (c) 2019 Mateusz Holenko # License: BSD -#!/usr/bin/env python3 - import os from migen import * from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU CPU_VARIANTS = ["standard", "linux"] -class MOR1KX(Module): - @property - def name(self): - return "or1k" - - @property - def endianness(self): - return "big" +class MOR1KX(CPU): + name = "mor1kx" + data_width = 32 + endianness = "big" + gcc_triple = "or1k-elf" + clang_triple = "or1k-linux" + linker_output_format = "elf32-or1k" @property def mem_map_linux(self): @@ -48,10 +46,6 @@ class MOR1KX(Module): flags += "-D__mor1kx__ " return flags - @property - def clang_triple(self): - return "or1k-linux" - @property def clang_flags(self): flags = "-mhard-mul " @@ -62,10 +56,6 @@ class MOR1KX(Module): flags += "-D__mor1kx__ " return flags - @property - def linker_output_format(self): - return "elf32-or1k" - @property def reserved_interrupts(self): return {"nmi": 0} diff --git a/litex/soc/cores/cpu/picorv32/core.py b/litex/soc/cores/cpu/picorv32/core.py index f8c095ff9..105882ae5 100644 --- a/litex/soc/cores/cpu/picorv32/core.py +++ b/litex/soc/cores/cpu/picorv32/core.py @@ -12,6 +12,7 @@ import os from migen import * from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU CPU_VARIANTS = ["minimal", "standard"] @@ -29,18 +30,12 @@ GCC_FLAGS = { } -class PicoRV32(Module): - @property - def name(self): - return "picorv32" - - @property - def endianness(self): - return "little" - - @property - def gcc_triple(self): - return ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") +class PicoRV32(CPU): + name = "picorv32" + data_width = 32 + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") + linker_output_format = "elf32-littleriscv" @property def gcc_flags(self): @@ -49,10 +44,6 @@ class PicoRV32(Module): flags += "-D__picorv32__ " return flags - @property - def linker_output_format(self): - return "elf32-littleriscv" - @property def reserved_interrupts(self): return { diff --git a/litex/soc/cores/cpu/rocket/core.py b/litex/soc/cores/cpu/rocket/core.py index a048c3ce8..317522570 100644 --- a/litex/soc/cores/cpu/rocket/core.py +++ b/litex/soc/cores/cpu/rocket/core.py @@ -35,6 +35,8 @@ from migen import * from litex.soc.interconnect import axi from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU + CPU_VARIANTS = { "standard": "freechips.rocketchip.system.LitexConfig", @@ -48,14 +50,12 @@ GCC_FLAGS = { "full": "-march=rv64imafdc -mabi=lp64 ", } -class RocketRV64(Module): - @property - def name(self): - return "rocket" - - @property - def endianness(self): - return "little" +class RocketRV64(CPU): + name = "rocket" + data_width = 64 + endianness = "little" + gcc_triple = ("riscv64-unknown-elf") + linker_output_format = "elf64-littleriscv" @property def mem_map(self): @@ -66,10 +66,6 @@ class RocketRV64(Module): "csr" : 0x12000000, } - @property - def gcc_triple(self): - return ("riscv64-unknown-elf") - @property def gcc_flags(self): flags = "-mno-save-restore " @@ -77,14 +73,6 @@ class RocketRV64(Module): flags += "-D__rocket__ " return flags - @property - def linker_output_format(self): - return "elf64-littleriscv" - - @property - def reserved_interrupts(self): - return {} - def __init__(self, platform, variant="standard"): assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py index 8f4e239ea..d5b8ce32b 100644 --- a/litex/soc/cores/cpu/serv/core.py +++ b/litex/soc/cores/cpu/serv/core.py @@ -7,18 +7,18 @@ import os from migen import * from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU + CPU_VARIANTS = ["standard"] -class SERV(Module): - @property - def name(self): - return "serv" - - @property - def endianness(self): - return "little" +class SERV(CPU): + name = "serv" + data_width = 32 + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf") + linker_output_format = "elf32-littleriscv" @property def gcc_triple(self): @@ -35,10 +35,6 @@ class SERV(Module): def linker_output_format(self): return "elf32-littleriscv" - @property - def reserved_interrupts(self): - return {} - def __init__(self, platform, variant="standard"): assert variant is "standard", "Unsupported variant %s" % variant self.platform = platform @@ -50,7 +46,7 @@ class SERV(Module): # # # - self.cpu_params -= dict( + self.cpu_params = dict( # clock / reset i_clk = ClockSignal(), i_i_rst = ResetSignal(), diff --git a/litex/soc/cores/cpu/vexriscv/core.py b/litex/soc/cores/cpu/vexriscv/core.py index d02723c21..14d2391d3 100644 --- a/litex/soc/cores/cpu/vexriscv/core.py +++ b/litex/soc/cores/cpu/vexriscv/core.py @@ -15,6 +15,7 @@ from migen import * from litex.soc.interconnect import wishbone from litex.soc.interconnect.csr import * +from litex.soc.cores.cpu import CPU CPU_VARIANTS = { @@ -73,18 +74,12 @@ class VexRiscvTimer(Module, AutoCSR): self.comb += self.interrupt.eq(time >= time_cmp) -class VexRiscv(Module, AutoCSR): - @property - def name(self): - return "vexriscv" - - @property - def endianness(self): - return "little" - - @property - def gcc_triple(self): - return ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") +class VexRiscv(CPU, AutoCSR): + name = "vexriscv" + data_width = 32 + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed") + linker_output_format = "elf32-littleriscv" @property def gcc_flags(self): @@ -92,14 +87,6 @@ class VexRiscv(Module, AutoCSR): flags += " -D__vexriscv__" return flags - @property - def linker_output_format(self): - return "elf32-littleriscv" - - @property - def reserved_interrupts(self): - return {} - def __init__(self, platform, variant="standard"): assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant self.platform = platform diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 171ef8a02..802d9a2eb 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -178,9 +178,8 @@ class SoCCore(Module): # Add the CPU self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant)) - # Override Memory Map (if needed by CPU) - if hasattr(self.cpu, "mem_map"): - self.soc_mem_map.update(self.cpu.mem_map) + # Update Memory Map (if defined by CPU) + self.soc_mem_map.update(self.cpu.mem_map) # Set reset address self.cpu.set_reset_address(self.soc_mem_map["rom"] if integrated_rom_size else cpu_reset_address) @@ -193,15 +192,15 @@ class SoCCore(Module): # Add CPU CSR (dynamic) self.add_csr("cpu", allow_user_defined=True) - # Add CPU reserved interrupts - for _name, _id in self.cpu.reserved_interrupts.items(): + # Add CPU interrupts + for _name, _id in self.cpu.interrupts.items(): self.add_interrupt(_name, _id) # Allow SoCController to reset the CPU if with_ctrl: self.comb += self.cpu.reset.eq(self.ctrl.reset) - # Add user's interrupts (needs to be done after CPU reserved interrupts are allocated) + # Add user's interrupts (needs to be done after CPU interrupts are allocated) for _name, _id in self.interrupt_map.items(): self.add_interrupt(_name, _id) @@ -470,7 +469,7 @@ class SoCCore(Module): if hasattr(self, "cpu"): if hasattr(self.cpu, "interrupt"): for _name, _id in sorted(self.soc_interrupt_map.items()): - if _name in self.cpu.reserved_interrupts.keys(): + if _name in self.cpu.interrupts.keys(): continue if hasattr(self, _name): module = getattr(self, _name)