diff --git a/litex/boards/targets/arty.py b/litex/boards/targets/arty.py index d8f3f8242..7552d9a6b 100755 --- a/litex/boards/targets/arty.py +++ b/litex/boards/targets/arty.py @@ -137,7 +137,7 @@ class EthernetSoC(BaseSoC): self.submodules.ethphy = LiteEthPHYMII(self.platform.request("eth_clocks"), self.platform.request("eth")) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, - interface="wishbone", endianness=self.cpu_endianness) + interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) diff --git a/litex/boards/targets/genesys2.py b/litex/boards/targets/genesys2.py index 3046ec4cf..8f2cb9ac8 100755 --- a/litex/boards/targets/genesys2.py +++ b/litex/boards/targets/genesys2.py @@ -119,7 +119,7 @@ class EthernetSoC(BaseSoC): self.submodules.ethphy = LiteEthPHYRGMII(self.platform.request("eth_clocks"), self.platform.request("eth")) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, - interface="wishbone", endianness=self.cpu_endianness) + interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) diff --git a/litex/boards/targets/kc705.py b/litex/boards/targets/kc705.py index 65730af53..cdc9c8ab5 100755 --- a/litex/boards/targets/kc705.py +++ b/litex/boards/targets/kc705.py @@ -119,7 +119,7 @@ class EthernetSoC(BaseSoC): self.submodules.ethphy = LiteEthPHY(self.platform.request("eth_clocks"), self.platform.request("eth"), clk_freq=self.clk_freq) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, - interface="wishbone", endianness=self.cpu_endianness) + interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) diff --git a/litex/boards/targets/nexys_video.py b/litex/boards/targets/nexys_video.py index 4f297deb1..c3fc82f74 100755 --- a/litex/boards/targets/nexys_video.py +++ b/litex/boards/targets/nexys_video.py @@ -126,7 +126,7 @@ class EthernetSoC(BaseSoC): self.submodules.ethphy = LiteEthPHYRGMII(self.platform.request("eth_clocks"), self.platform.request("eth")) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, - interface="wishbone", endianness=self.cpu_endianness) + interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) diff --git a/litex/boards/targets/sim.py b/litex/boards/targets/sim.py index 7291274fc..9d8e1cce3 100755 --- a/litex/boards/targets/sim.py +++ b/litex/boards/targets/sim.py @@ -109,7 +109,7 @@ class SimSoC(SoCSDRAM): self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth", 0)) # eth mac ethmac = LiteEthMAC(phy=self.ethphy, dw=32, - interface="wishbone", endianness=self.cpu_endianness) + interface="wishbone", endianness=self.cpu.endianness) if with_etherbone: ethmac = ClockDomainsRenamer({"eth_tx": "ethphy_eth_tx", "eth_rx": "ethphy_eth_rx"})(ethmac) self.submodules.ethmac = ethmac diff --git a/litex/boards/targets/simple.py b/litex/boards/targets/simple.py index de7cc60d8..03d9cc6fa 100755 --- a/litex/boards/targets/simple.py +++ b/litex/boards/targets/simple.py @@ -45,7 +45,7 @@ class EthernetSoC(BaseSoC): self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"), platform.request("eth")) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, - interface="wishbone", endianness=self.cpu_endianness, with_preamble_crc=False) + interface="wishbone", endianness=self.cpu.endianness, with_preamble_crc=False) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py index e69de29bb..5eccde2dc 100644 --- a/litex/soc/cores/cpu/__init__.py +++ b/litex/soc/cores/cpu/__init__.py @@ -0,0 +1,5 @@ +from litex.soc.cores.cpu.lm32 import LM32 +from litex.soc.cores.cpu.mor1kx import MOR1KX +from litex.soc.cores.cpu.picorv32 import PicoRV32 +from litex.soc.cores.cpu.vexriscv import VexRiscv +from litex.soc.cores.cpu.minerva import Minerva diff --git a/litex/soc/cores/cpu/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py index f68be81ab..d32d7ba64 100644 --- a/litex/soc/cores/cpu/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -6,6 +6,12 @@ from litex.soc.interconnect import wishbone class LM32(Module): + name = "lm32" + endianness = "big" + gcc_triple = "lm32-elf" + gcc_flags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled" + linker_output_format = "elf32-lm32" + def __init__(self, platform, eba_reset, variant=None): assert variant in (None, "lite", "minimal"), "Unsupported variant %s" % variant self.reset = Signal() diff --git a/litex/soc/cores/cpu/minerva/core.py b/litex/soc/cores/cpu/minerva/core.py index 8ae8623bb..c864f3ae9 100644 --- a/litex/soc/cores/cpu/minerva/core.py +++ b/litex/soc/cores/cpu/minerva/core.py @@ -6,6 +6,12 @@ from litex.soc.interconnect import wishbone class Minerva(Module): + name = "minerva" + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf") + gcc_flags = "-D__minerva__ -march=rv32i -mabi=ilp32" + linker_output_format = "elf32-littleriscv" + def __init__(self, platform, cpu_reset_address, variant=None): assert variant is None, "Unsupported variant %s" % variant self.reset = Signal() diff --git a/litex/soc/cores/cpu/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py index 3c7b451ad..7428211e9 100644 --- a/litex/soc/cores/cpu/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -6,6 +6,14 @@ from litex.soc.interconnect import wishbone class MOR1KX(Module): + name = "or1k" + endianness = "big" + gcc_triple = "or1k-elf" + gcc_flags = "-mhard-mul -mhard-div -mror" + clang_triple = "or1k-linux" + clang_flags = "-mhard-mul -mhard-div -mror -mffl1 -maddc" + linker_output_format = "elf32-or1k" + def __init__(self, platform, reset_pc, variant=None): assert variant in (None, "linux"), "Unsupported variant %s" % variant self.reset = Signal() diff --git a/litex/soc/cores/cpu/picorv32/core.py b/litex/soc/cores/cpu/picorv32/core.py index fb271209e..7fe830d66 100644 --- a/litex/soc/cores/cpu/picorv32/core.py +++ b/litex/soc/cores/cpu/picorv32/core.py @@ -6,6 +6,12 @@ from litex.soc.interconnect import wishbone class PicoRV32(Module): + name = "picorv32" + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf") + gcc_flags = "-D__picorv32__ -mno-save-restore -march=rv32im -mabi=ilp32" + linker_output_format = "elf32-littleriscv" + def __init__(self, platform, progaddr_reset, variant): self.reset = Signal() self.ibus = i = wishbone.Interface() diff --git a/litex/soc/cores/cpu/vexriscv/core.py b/litex/soc/cores/cpu/vexriscv/core.py index 1fef0edc3..aff606fb1 100644 --- a/litex/soc/cores/cpu/vexriscv/core.py +++ b/litex/soc/cores/cpu/vexriscv/core.py @@ -5,7 +5,14 @@ from migen import * from litex.soc.interconnect import wishbone from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage + class VexRiscv(Module, AutoCSR): + name = "vexriscv" + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf") + gcc_flags = "-D__vexriscv__ -march=rv32im -mabi=ilp32" + linker_output_format = "elf32-littleriscv" + def __init__(self, platform, cpu_reset_address, variant=None): assert variant in (None, "debug"), "Unsupported variant %s" % variant self.reset = Signal() diff --git a/litex/soc/integration/builder.py b/litex/soc/integration/builder.py index e74c4a06c..1bd23bdfe 100644 --- a/litex/soc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -56,7 +56,6 @@ class Builder: def _generate_includes(self): cpu_type = self.soc.cpu_type - cpu_variant = self.soc.cpu_variant memory_regions = self.soc.get_memory_regions() flash_boot_address = getattr(self.soc, "flash_boot_address", None) csr_regions = self.soc.get_csr_regions() @@ -69,7 +68,7 @@ class Builder: variables_contents = [] def define(k, v): variables_contents.append("{}={}\n".format(k, _makefile_escape(v))) - for k, v in cpu_interface.get_cpu_mak(cpu_type, cpu_variant): + for k, v in cpu_interface.get_cpu_mak(self.soc.cpu_or_bridge): define(k, v) # Distinguish between applications running from main RAM and # flash for user-provided software packages. @@ -88,7 +87,7 @@ class Builder: write_to_file( os.path.join(generated_dir, "output_format.ld"), - cpu_interface.get_linker_output_format(cpu_type)) + cpu_interface.get_linker_output_format(self.soc.cpu_or_bridge)) write_to_file( os.path.join(generated_dir, "regions.ld"), cpu_interface.get_linker_regions(memory_regions)) @@ -137,7 +136,7 @@ class Builder: def _initialize_rom(self): bios_file = os.path.join(self.output_dir, "software", "bios", "bios.bin") - endianness = cpu_interface.cpu_endianness[self.soc.cpu_type] + endianness = self.soc.cpu_or_bridge.endianness with open(bios_file, "rb") as boot_file: boot_data = [] while True: diff --git a/litex/soc/integration/cpu_interface.py b/litex/soc/integration/cpu_interface.py index 0819b0a0a..21cbd2725 100644 --- a/litex/soc/integration/cpu_interface.py +++ b/litex/soc/integration/cpu_interface.py @@ -5,83 +5,52 @@ from migen import * from litex.soc.interconnect.csr import CSRStatus -cpu_endianness = { - None: "big", - "lm32": "big", - "or1k": "big", - "picorv32": "little", - "vexriscv": "little", - "minerva": "little", -} - -def get_cpu_mak(cpu, variant): +def get_cpu_mak(cpu): + # select between clang and gcc clang = os.getenv("CLANG", "") if clang != "": clang = bool(int(clang)) else: clang = None - - if cpu == "lm32": - assert not clang, "lm32 not supported with clang." - triple = "lm32-elf" - cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled" - clang = False - elif cpu == "or1k": - # Default to CLANG unless told otherwise - if clang is None: - clang = True - - triple = "or1k-elf" - cpuflags = "-mhard-mul -mhard-div -mror" + if not hasattr(cpu, "clang_triple"): if clang: - triple = "or1k-linux" - cpuflags += "-mffl1 -maddc" - elif cpu == "picorv32": - assert not clang, "picorv32 not supported with clang." - if which("riscv64-unknown-elf-gcc"): - triple = "riscv64-unknown-elf" + raise ValueError(cpu.name + "not supported with clang.") else: - triple = "riscv32-unknown-elf" - cpuflags = "-D__picorv32__ -mno-save-restore -march=rv32im -mabi=ilp32" - clang = False - elif cpu == "vexriscv": - assert not clang, "vexriscv not supported with clang." - if which("riscv64-unknown-elf-gcc"): - triple = "riscv64-unknown-elf" - else: - triple = "riscv32-unknown-elf" - cpuflags = "-D__vexriscv__ -march=rv32im -mabi=ilp32" - clang = False - elif cpu == "minerva": - assert not clang, "minerva not supported with clang." - if which("riscv64-unknown-elf-gcc"): - triple = "riscv64-unknown-elf" - else: - triple = "riscv32-unknown-elf" - cpuflags = "-D__minerva__ -march=rv32i -mabi=ilp32" - clang = False + clang = False else: - raise ValueError("Unsupported CPU type: "+cpu) - + # Default to clang unless told otherwise + if clang is None: + clang = True assert isinstance(clang, bool) + if clang: + triple = cpu.clang_triple + flags = cpu.clang_flags + else: + triple = cpu.gcc_triple + flags = cpu.gcc_flags + + # select triple when more than one + def select_triple(triple): + if isinstance(triple, tuple): + for i in range(len(triple)): + t = triple[i] + if which(t+"-gcc"): + return t + else: + return triple + + # return informations return [ - ("TRIPLE", triple), - ("CPU", cpu), - ("CPUFLAGS", cpuflags), - ("CPUENDIANNESS", cpu_endianness[cpu]), + ("TRIPLE", select_triple(triple)), + ("CPU", cpu.name), + ("CPUFLAGS", flags), + ("CPUENDIANNESS", cpu.endianness), ("CLANG", str(int(clang))) ] -def get_linker_output_format(cpu_type): - linker_output_formats = { - "lm32": "elf32-lm32", - "or1k": "elf32-or1k", - "picorv32": "elf32-littleriscv", - "vexriscv": "elf32-littleriscv", - "minerva": "elf32-littleriscv", - } - return "OUTPUT_FORMAT(\"" + linker_output_formats[cpu_type] + "\")\n" +def get_linker_output_format(cpu): + return "OUTPUT_FORMAT(\"" + cpu.linker_output_format + "\")\n" def get_linker_regions(regions): diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index bfbeacce1..87678a316 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -5,10 +5,9 @@ from operator import itemgetter from migen import * from litex.soc.cores import identifier, timer, uart -from litex.soc.cores.cpu import lm32, mor1kx, picorv32, vexriscv, minerva +from litex.soc.cores.cpu import * from litex.soc.interconnect.csr import * from litex.soc.interconnect import wishbone, csr_bus, wishbone2csr -from litex.soc.integration.cpu_interface import cpu_endianness __all__ = ["mem_decoder", "get_mem_data", "SoCCore", "soc_core_args", "soc_core_argdict"] @@ -124,7 +123,6 @@ class SoCCore(Module): self.cpu_type = cpu_type self.cpu_variant = cpu_variant - self.cpu_endianness = cpu_endianness[cpu_type] if integrated_rom_size: cpu_reset_address = self.mem_map["rom"] self.cpu_reset_address = cpu_reset_address