soc/cores/cpu: add CPU class and make all CPU inheritate from it
Also rename reserved_interrupts to interrupts (empty dict is no reserved interrupts)
This commit is contained in:
parent
2c3ad3f96d
commit
355072c285
|
@ -2,6 +2,23 @@
|
||||||
# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# License: BSD
|
# 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.lm32 import LM32
|
||||||
from litex.soc.cores.cpu.mor1kx import MOR1KX
|
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.rocket import RocketRV64
|
||||||
from litex.soc.cores.cpu.serv import SERV
|
from litex.soc.cores.cpu.serv import SERV
|
||||||
|
|
||||||
# CPUS ---------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CPUS = {
|
CPUS = {
|
||||||
"lm32" : LM32,
|
"lm32" : LM32,
|
||||||
"mor1kx" : MOR1KX,
|
"mor1kx" : MOR1KX,
|
||||||
|
@ -61,7 +76,6 @@ Possible Values:
|
||||||
|
|
||||||
# CPU Variants/Extensions Check/Format -------------------------------------------------------------
|
# CPU Variants/Extensions Check/Format -------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def check_format_cpu_variant(variant):
|
def check_format_cpu_variant(variant):
|
||||||
# Support the old style which used underscore for separator
|
# Support the old style which used underscore for separator
|
||||||
if variant is None:
|
if variant is None:
|
||||||
|
|
|
@ -10,22 +10,17 @@ import os
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
CPU_VARIANTS = ["minimal", "lite", "standard"]
|
CPU_VARIANTS = ["minimal", "lite", "standard"]
|
||||||
|
|
||||||
|
|
||||||
class LM32(Module):
|
class LM32(CPU):
|
||||||
@property
|
name = "lm32"
|
||||||
def name(self):
|
data_width = 32
|
||||||
return "lm32"
|
endianness = "big"
|
||||||
|
gcc_triple = "lm32-elf"
|
||||||
@property
|
linker_output_format = "elf32-lm32"
|
||||||
def endianness(self):
|
|
||||||
return "big"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def gcc_triple(self):
|
|
||||||
return "lm32-elf"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gcc_flags(self):
|
def gcc_flags(self):
|
||||||
|
@ -36,14 +31,6 @@ class LM32(Module):
|
||||||
flags += "-D__lm32__ "
|
flags += "-D__lm32__ "
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def linker_output_format(self):
|
|
||||||
return "elf32-lm32"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def reserved_interrupts(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def __init__(self, platform, variant="standard"):
|
def __init__(self, platform, variant="standard"):
|
||||||
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
|
|
|
@ -7,22 +7,17 @@ import os
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
CPU_VARIANTS = ["standard"]
|
CPU_VARIANTS = ["standard"]
|
||||||
|
|
||||||
|
|
||||||
class Minerva(Module):
|
class Minerva(CPU):
|
||||||
@property
|
name = "minerva"
|
||||||
def name(self):
|
data_width = 32
|
||||||
return "minerva"
|
endianness = "little"
|
||||||
|
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
|
||||||
@property
|
linker_output_format = "elf32-littleriscv"
|
||||||
def endianness(self):
|
|
||||||
return "little"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def gcc_triple(self):
|
|
||||||
return ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gcc_flags(self):
|
def gcc_flags(self):
|
||||||
|
@ -31,14 +26,6 @@ class Minerva(Module):
|
||||||
flags += "-D__minerva__ "
|
flags += "-D__minerva__ "
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def linker_output_format(self):
|
|
||||||
return "elf32-littleriscv"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def reserved_interrupts(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def __init__(self, platform, variant="standard"):
|
def __init__(self, platform, variant="standard"):
|
||||||
assert variant is "standard", "Unsupported variant %s" % variant
|
assert variant is "standard", "Unsupported variant %s" % variant
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
|
|
|
@ -4,25 +4,23 @@
|
||||||
# This file is Copyright (c) 2019 Mateusz Holenko <mholenko@antmicro.com>
|
# This file is Copyright (c) 2019 Mateusz Holenko <mholenko@antmicro.com>
|
||||||
# License: BSD
|
# License: BSD
|
||||||
|
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
CPU_VARIANTS = ["standard", "linux"]
|
CPU_VARIANTS = ["standard", "linux"]
|
||||||
|
|
||||||
|
|
||||||
class MOR1KX(Module):
|
class MOR1KX(CPU):
|
||||||
@property
|
name = "mor1kx"
|
||||||
def name(self):
|
data_width = 32
|
||||||
return "or1k"
|
endianness = "big"
|
||||||
|
gcc_triple = "or1k-elf"
|
||||||
@property
|
clang_triple = "or1k-linux"
|
||||||
def endianness(self):
|
linker_output_format = "elf32-or1k"
|
||||||
return "big"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mem_map_linux(self):
|
def mem_map_linux(self):
|
||||||
|
@ -48,10 +46,6 @@ class MOR1KX(Module):
|
||||||
flags += "-D__mor1kx__ "
|
flags += "-D__mor1kx__ "
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def clang_triple(self):
|
|
||||||
return "or1k-linux"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def clang_flags(self):
|
def clang_flags(self):
|
||||||
flags = "-mhard-mul "
|
flags = "-mhard-mul "
|
||||||
|
@ -62,10 +56,6 @@ class MOR1KX(Module):
|
||||||
flags += "-D__mor1kx__ "
|
flags += "-D__mor1kx__ "
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def linker_output_format(self):
|
|
||||||
return "elf32-or1k"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reserved_interrupts(self):
|
def reserved_interrupts(self):
|
||||||
return {"nmi": 0}
|
return {"nmi": 0}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import os
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
|
|
||||||
CPU_VARIANTS = ["minimal", "standard"]
|
CPU_VARIANTS = ["minimal", "standard"]
|
||||||
|
@ -29,18 +30,12 @@ GCC_FLAGS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PicoRV32(Module):
|
class PicoRV32(CPU):
|
||||||
@property
|
name = "picorv32"
|
||||||
def name(self):
|
data_width = 32
|
||||||
return "picorv32"
|
endianness = "little"
|
||||||
|
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
|
||||||
@property
|
linker_output_format = "elf32-littleriscv"
|
||||||
def endianness(self):
|
|
||||||
return "little"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def gcc_triple(self):
|
|
||||||
return ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gcc_flags(self):
|
def gcc_flags(self):
|
||||||
|
@ -49,10 +44,6 @@ class PicoRV32(Module):
|
||||||
flags += "-D__picorv32__ "
|
flags += "-D__picorv32__ "
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def linker_output_format(self):
|
|
||||||
return "elf32-littleriscv"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reserved_interrupts(self):
|
def reserved_interrupts(self):
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -35,6 +35,8 @@ from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import axi
|
from litex.soc.interconnect import axi
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
|
|
||||||
CPU_VARIANTS = {
|
CPU_VARIANTS = {
|
||||||
"standard": "freechips.rocketchip.system.LitexConfig",
|
"standard": "freechips.rocketchip.system.LitexConfig",
|
||||||
|
@ -48,14 +50,12 @@ GCC_FLAGS = {
|
||||||
"full": "-march=rv64imafdc -mabi=lp64 ",
|
"full": "-march=rv64imafdc -mabi=lp64 ",
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketRV64(Module):
|
class RocketRV64(CPU):
|
||||||
@property
|
name = "rocket"
|
||||||
def name(self):
|
data_width = 64
|
||||||
return "rocket"
|
endianness = "little"
|
||||||
|
gcc_triple = ("riscv64-unknown-elf")
|
||||||
@property
|
linker_output_format = "elf64-littleriscv"
|
||||||
def endianness(self):
|
|
||||||
return "little"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mem_map(self):
|
def mem_map(self):
|
||||||
|
@ -66,10 +66,6 @@ class RocketRV64(Module):
|
||||||
"csr" : 0x12000000,
|
"csr" : 0x12000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def gcc_triple(self):
|
|
||||||
return ("riscv64-unknown-elf")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gcc_flags(self):
|
def gcc_flags(self):
|
||||||
flags = "-mno-save-restore "
|
flags = "-mno-save-restore "
|
||||||
|
@ -77,14 +73,6 @@ class RocketRV64(Module):
|
||||||
flags += "-D__rocket__ "
|
flags += "-D__rocket__ "
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def linker_output_format(self):
|
|
||||||
return "elf64-littleriscv"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def reserved_interrupts(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def __init__(self, platform, variant="standard"):
|
def __init__(self, platform, variant="standard"):
|
||||||
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
||||||
|
|
||||||
|
|
|
@ -7,18 +7,18 @@ import os
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
|
|
||||||
CPU_VARIANTS = ["standard"]
|
CPU_VARIANTS = ["standard"]
|
||||||
|
|
||||||
|
|
||||||
class SERV(Module):
|
class SERV(CPU):
|
||||||
@property
|
name = "serv"
|
||||||
def name(self):
|
data_width = 32
|
||||||
return "serv"
|
endianness = "little"
|
||||||
|
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf")
|
||||||
@property
|
linker_output_format = "elf32-littleriscv"
|
||||||
def endianness(self):
|
|
||||||
return "little"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gcc_triple(self):
|
def gcc_triple(self):
|
||||||
|
@ -35,10 +35,6 @@ class SERV(Module):
|
||||||
def linker_output_format(self):
|
def linker_output_format(self):
|
||||||
return "elf32-littleriscv"
|
return "elf32-littleriscv"
|
||||||
|
|
||||||
@property
|
|
||||||
def reserved_interrupts(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def __init__(self, platform, variant="standard"):
|
def __init__(self, platform, variant="standard"):
|
||||||
assert variant is "standard", "Unsupported variant %s" % variant
|
assert variant is "standard", "Unsupported variant %s" % variant
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
|
@ -50,7 +46,7 @@ class SERV(Module):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
self.cpu_params -= dict(
|
self.cpu_params = dict(
|
||||||
# clock / reset
|
# clock / reset
|
||||||
i_clk = ClockSignal(),
|
i_clk = ClockSignal(),
|
||||||
i_i_rst = ResetSignal(),
|
i_i_rst = ResetSignal(),
|
||||||
|
|
|
@ -15,6 +15,7 @@ from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
from litex.soc.interconnect.csr import *
|
from litex.soc.interconnect.csr import *
|
||||||
|
from litex.soc.cores.cpu import CPU
|
||||||
|
|
||||||
|
|
||||||
CPU_VARIANTS = {
|
CPU_VARIANTS = {
|
||||||
|
@ -73,18 +74,12 @@ class VexRiscvTimer(Module, AutoCSR):
|
||||||
self.comb += self.interrupt.eq(time >= time_cmp)
|
self.comb += self.interrupt.eq(time >= time_cmp)
|
||||||
|
|
||||||
|
|
||||||
class VexRiscv(Module, AutoCSR):
|
class VexRiscv(CPU, AutoCSR):
|
||||||
@property
|
name = "vexriscv"
|
||||||
def name(self):
|
data_width = 32
|
||||||
return "vexriscv"
|
endianness = "little"
|
||||||
|
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
|
||||||
@property
|
linker_output_format = "elf32-littleriscv"
|
||||||
def endianness(self):
|
|
||||||
return "little"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def gcc_triple(self):
|
|
||||||
return ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gcc_flags(self):
|
def gcc_flags(self):
|
||||||
|
@ -92,14 +87,6 @@ class VexRiscv(Module, AutoCSR):
|
||||||
flags += " -D__vexriscv__"
|
flags += " -D__vexriscv__"
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
@property
|
|
||||||
def linker_output_format(self):
|
|
||||||
return "elf32-littleriscv"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def reserved_interrupts(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def __init__(self, platform, variant="standard"):
|
def __init__(self, platform, variant="standard"):
|
||||||
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
|
|
|
@ -178,9 +178,8 @@ class SoCCore(Module):
|
||||||
# Add the CPU
|
# Add the CPU
|
||||||
self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant))
|
self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant))
|
||||||
|
|
||||||
# Override Memory Map (if needed by CPU)
|
# Update Memory Map (if defined by CPU)
|
||||||
if hasattr(self.cpu, "mem_map"):
|
self.soc_mem_map.update(self.cpu.mem_map)
|
||||||
self.soc_mem_map.update(self.cpu.mem_map)
|
|
||||||
|
|
||||||
# Set reset address
|
# Set reset address
|
||||||
self.cpu.set_reset_address(self.soc_mem_map["rom"] if integrated_rom_size else cpu_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)
|
# Add CPU CSR (dynamic)
|
||||||
self.add_csr("cpu", allow_user_defined=True)
|
self.add_csr("cpu", allow_user_defined=True)
|
||||||
|
|
||||||
# Add CPU reserved interrupts
|
# Add CPU interrupts
|
||||||
for _name, _id in self.cpu.reserved_interrupts.items():
|
for _name, _id in self.cpu.interrupts.items():
|
||||||
self.add_interrupt(_name, _id)
|
self.add_interrupt(_name, _id)
|
||||||
|
|
||||||
# Allow SoCController to reset the CPU
|
# Allow SoCController to reset the CPU
|
||||||
if with_ctrl:
|
if with_ctrl:
|
||||||
self.comb += self.cpu.reset.eq(self.ctrl.reset)
|
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():
|
for _name, _id in self.interrupt_map.items():
|
||||||
self.add_interrupt(_name, _id)
|
self.add_interrupt(_name, _id)
|
||||||
|
|
||||||
|
@ -470,7 +469,7 @@ class SoCCore(Module):
|
||||||
if hasattr(self, "cpu"):
|
if hasattr(self, "cpu"):
|
||||||
if hasattr(self.cpu, "interrupt"):
|
if hasattr(self.cpu, "interrupt"):
|
||||||
for _name, _id in sorted(self.soc_interrupt_map.items()):
|
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
|
continue
|
||||||
if hasattr(self, _name):
|
if hasattr(self, _name):
|
||||||
module = getattr(self, _name)
|
module = getattr(self, _name)
|
||||||
|
|
Loading…
Reference in New Issue