diff --git a/litex/build/altera/common.py b/litex/build/altera/common.py index 1c53d8645..3ed0947ba 100644 --- a/litex/build/altera/common.py +++ b/litex/build/altera/common.py @@ -25,16 +25,16 @@ altera_reserved_jtag_pads = [ class AlteraAsyncResetSynchronizerImpl(Module): def __init__(self, cd, async_reset): - rst_meta = Signal() + rst_meta = Signal(name_override=f'ars_cd_{cd.name}_rst_meta') self.specials += [ - Instance("DFF", + Instance("DFF", name=f'ars_cd_{cd.name}_ff0', i_d = 0, i_clk = cd.clk, i_clrn = 1, i_prn = ~async_reset, o_q = rst_meta ), - Instance("DFF", + Instance("DFF", name=f'ars_cd_{cd.name}_ff1', i_d = rst_meta, i_clk = cd.clk, i_clrn = 1, diff --git a/litex/build/altera/quartus.py b/litex/build/altera/quartus.py index 7ec1360c1..74d903c0d 100644 --- a/litex/build/altera/quartus.py +++ b/litex/build/altera/quartus.py @@ -156,6 +156,7 @@ def _build_script(build_name, create_rbf): script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() script_file = "build_" + build_name + ".sh" script_contents += """ +set -e -u -x -o pipefail quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name} quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} diff --git a/litex/build/generic_platform.py b/litex/build/generic_platform.py index 3526a9501..3054103c0 100644 --- a/litex/build/generic_platform.py +++ b/litex/build/generic_platform.py @@ -230,7 +230,18 @@ class ConstraintManager: except ConstraintError: break if not len(r): - raise ValueError + raise ValueError(f"Could not request some pin(s) named '{name}'") + return Cat(r) + + def request_remaining(self, name): + r = [] + while True: + try: + r.append(self.request(name)) + except ConstraintError: + break + if not len(r): + raise ValueError(f"Could not request any pins named '{name}'") return Cat(r) def lookup_request(self, name, number=None, loose=False): @@ -321,6 +332,9 @@ class GenericPlatform: def request_all(self, *args, **kwargs): return self.constraint_manager.request_all(*args, **kwargs) + def request_remaining(self, *args, **kwargs): + return self.constraint_manager.request_remaining(*args, **kwargs) + def lookup_request(self, *args, **kwargs): return self.constraint_manager.lookup_request(*args, **kwargs) diff --git a/litex/build/openfpga/__init__.py b/litex/build/openfpga/__init__.py deleted file mode 100644 index b9fc5c1eb..000000000 --- a/litex/build/openfpga/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from litex.build.openfpga.platform import OpenFPGAPlatform diff --git a/litex/build/openfpga/blinky.py b/litex/build/openfpga/blinky.py deleted file mode 100755 index cfa504680..000000000 --- a/litex/build/openfpga/blinky.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 - -# -# This file is part of LiteX. -# -# Copyright (c) 2022 Florent Kermarrec -# SPDX-License-Identifier: BSD-2-Clause - -import os - -from migen import * - -from litex.build.generic_platform import Pins -from litex.build.openfpga import OpenFPGAPlatform - -# export LITEX_ENV_OPENFPGA=/home/florent/dev/openfpga/OpenFPGA -# export LITEX_ENV_OPENFPGA_SOFA=/home/florent/dev/openfpga/SOFA - -# Minimal Platform --------------------------------------------------------------------------------- - -_io = [ - ("clk", 0, Pins(1)), - ("led", 0, Pins(1)) -] - -class Platform(OpenFPGAPlatform): - def __init__(self): - OpenFPGAPlatform.__init__(self, "FPGA1212_QLSOFA_HD", _io) - -# Minimal Design ----------------------------------------------------------------------------------- - -platform = Platform() -clk = platform.request("clk") -led = platform.request("led") -module = Module() -module.clock_domains.cd_sys = ClockDomain("sys") -module.comb += module.cd_sys.clk.eq(clk) -counter = Signal(26) -module.comb += led.eq(counter[25]) -module.sync += counter.eq(counter + 1) - -# Build -------------------------------------------------------------------------------------------- - -platform.build(module, run=True) diff --git a/litex/build/openfpga/common.py b/litex/build/openfpga/common.py deleted file mode 100644 index dd5422536..000000000 --- a/litex/build/openfpga/common.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# This file is part of LiteX. -# -# Copyright (c) 2022 Florent Kermarrec -# SPDX-License-Identifier: BSD-2-Clause - -# OpenFPGA Special Overrides --------------------------------------------------------------------- - -openfpga_special_overrides = {} diff --git a/litex/build/openfpga/openfpga.py b/litex/build/openfpga/openfpga.py deleted file mode 100644 index 76a9f39b9..000000000 --- a/litex/build/openfpga/openfpga.py +++ /dev/null @@ -1,152 +0,0 @@ -# -# This file is part of LiteX. -# -# Copyright (c) 2022 Florent Kermarrec -# SPDX-License-Identifier: BSD-2-Clause - -import os -import sys -import subprocess -from shutil import which - -from migen.fhdl.structure import _Fragment - -from litex.build.generic_platform import * -from litex.build import tools -from litex.build.openfpga import common - -# Check Setup -------------------------------------------------------------------------------------- - -def _check_setup(): - if os.getenv("LITEX_ENV_OPENFPGA", False) == False: - msg = "Unable to find OpenFPGA toolchain, please:\n" - msg += "- Set LITEX_ENV_OPENFPGA environment variant to OpenFPGA's settings path.\n" - raise OSError(msg) - - if os.getenv("LITEX_ENV_OPENFPGA_SOFA", False) == False: - msg = "Unable to find OpenFPGA's SOFA project, please:\n" - msg += "- Set LITEX_ENV_OPENFPGA_SOFA environment variant to OpenFPGA's SOFA settings path.\n" - raise OSError(msg) - -# Task Config ------------------------------------------------------------------------------------- - -def _build_task_conf(platform, sources, build_dir, build_name): - # Get Environnment variables. - openfpga_path = os.getenv("LITEX_ENV_OPENFPGA") - openfpga_sofa_path = os.getenv("LITEX_ENV_OPENFPGA_SOFA") - - # Get PnR/Task directories from OPENFPGA/SOFA paths. - pnr_path = os.path.join(openfpga_sofa_path, platform.device + "_PNR") - task_path = os.path.join(pnr_path, platform.device + "_task") - - # Get Config file. - task_conf = os.path.join(task_path, "config", "task_simulation.conf") - - # Helpers. - def replace_openfpga_task_section(filename, section, contents): - lines = [] - # Read file and replace section with contents. - copy = True - for line in open(filename, "r"): - if not copy and line.startswith("["): - copy = True - if line.startswith(section): - copy = False - lines.append(section + "\n") - for l in contents: - lines.append(l + "\n") - lines.append("\n") - if copy: - lines.append(line) - - # Save file to .orig. - os.system(f"mv {filename} {filename}.orig") - - # Write file with replaced section. - with open(filename, "w") as f: - f.write("".join(lines)) - - # Add sources. - bench_sources = [] - for filename, language, library in sources: - if language is None: - continue - if language not in ["verilog"]: - raise ValueError("OpenFPGA flow only supports verilog") - bench_sources.append(filename) - replace_openfpga_task_section(task_conf, "[BENCHMARKS]", [f"bench0={' '.join(bench_sources)}"]) - - # Set Top-Level. - replace_openfpga_task_section(task_conf, "[SYNTHESIS_PARAM]", [f"bench0_top={build_name}"]) - -def _run_task(device): - # Get Environnment variables. - openfpga_path = os.getenv("LITEX_ENV_OPENFPGA") - openfpga_sofa_path = os.getenv("LITEX_ENV_OPENFPGA_SOFA") - - # Get PnR/Task directories from OPENFPGA/SOFA paths. - pnr_path = os.path.join(openfpga_sofa_path, device + "_PNR") - task_path = os.path.join(pnr_path, device + "_task") - - # Set OPENFPGA_PATH. - os.environ["OPENFPGA_PATH"] = os.getenv("LITEX_ENV_OPENFPGA") - - # Run OpenFPGA flow. - build_cmd = ["make", "-C", pnr_path, "clean", "runOpenFPGA"] - if subprocess.call(build_cmd) != 0: - raise OSError("Error occured during OpenFPGA's flow execution.") - - # Copy artifacts. - os.system("rm -rf run001") - os.system(f"cp -r {task_path}/run001 run001") - - # Display log. FIXME: Do it during build? - os.system("cat run001/vpr_arch/top/MIN_ROUTE_CHAN_WIDTH/openfpgashell.log") - -# OpenFPGAToolchain -------------------------------------------------------------------------------- - -class OpenFPGAToolchain: - attr_translate = {} - - special_overrides = common.openfpga_special_overrides - - def __init__(self): - self.clocks = dict() - self.false_paths = set() - - def build(self, platform, fragment, - build_dir = "build", - build_name = "top", - run = False, - **kwargs): - - # Create Build Directory. - os.makedirs(build_dir, exist_ok=True) - cwd = os.getcwd() - os.chdir(build_dir) - - # Finalize Design. - if not isinstance(fragment, _Fragment): - fragment = fragment.get_fragment() - platform.finalize(fragment) - - # Generate Verilog. - v_output = platform.get_verilog(fragment, name=build_name, **kwargs) - named_sc, named_pc = platform.resolve_signals(v_output.ns) - top_file = build_name + ".v" - v_output.write(top_file) - platform.add_source(top_file) - - # Check Setup. - _check_setup() - - # Generate Task Config. - _build_task_conf(platform, platform.sources, build_dir, build_name) - - # Run Task. - if run: - _run_task(platform.device) - - os.chdir(cwd) - - return v_output.ns diff --git a/litex/build/openfpga/platform.py b/litex/build/openfpga/platform.py deleted file mode 100644 index e339b68f2..000000000 --- a/litex/build/openfpga/platform.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# This file is part of LiteX. -# -# Copyright (c) 2022 Florent Kermarrec -# SPDX-License-Identifier: BSD-2-Clause - -import os - -from litex.build.generic_platform import GenericPlatform -from litex.build.openfpga import common, openfpga - -# OpenFPGAPlatform ------------------------------------------------------------------------------- - -class OpenFPGAPlatform(GenericPlatform): - def __init__(self, device, *args, **kwargs): - GenericPlatform.__init__(self, device, *args, **kwargs) - self.toolchain = openfpga.OpenFPGAToolchain() - - def get_verilog(self, *args, special_overrides=dict(), **kwargs): - so = dict(common.openfpga_special_overrides) - so.update(special_overrides) - return GenericPlatform.get_verilog(self, *args, - special_overrides = so, - attr_translate = self.toolchain.attr_translate, - **kwargs) - - def build(self, *args, **kwargs): - return self.toolchain.build(self, *args, **kwargs) diff --git a/litex/build/osfpga/osfpga.py b/litex/build/osfpga/osfpga.py index d69ca648d..c0a4e5419 100644 --- a/litex/build/osfpga/osfpga.py +++ b/litex/build/osfpga/osfpga.py @@ -26,18 +26,21 @@ def _build_sdc(clocks, vns, build_name): # Script ------------------------------------------------------------------------------------------- -def _build_tcl(name, device, files, build_name): +def _build_tcl(name, device, files, build_name, include_paths): tcl = [] # Create Design. tcl.append(f"create_design {build_name}") # Set Device. - # TODO (Use Macro for now). - tcl.append("set_macro P1=10 P2=20") + # FIXME: Directly pass Devices instead of Macro when possible. + macro = {"test": "P1=10 P2=20"}[device] + tcl.append(f"set_macro {macro}") # Add Include Path. - # TODO. + tcl.append("add_include_path ./") + for include_path in include_paths: + tcl.append(f"add_include_path {include_path}") # Add Sources. for f, typ, lib in files: @@ -107,10 +110,11 @@ class OSFPGAToolchain: # Generate build script (.tcl) script = _build_tcl( - name = platform.devicename, - device = platform.device, - files = platform.sources, - build_name = build_name, + name = platform.devicename, + device = platform.device, + files = platform.sources, + build_name = build_name, + include_paths = platform.verilog_include_paths, ) # Run diff --git a/litex/build/osfpga/blinky.py b/litex/build/osfpga/test_blinky.py similarity index 90% rename from litex/build/osfpga/blinky.py rename to litex/build/osfpga/test_blinky.py index 38baa7a01..89feb2bd3 100755 --- a/litex/build/osfpga/blinky.py +++ b/litex/build/osfpga/test_blinky.py @@ -22,7 +22,7 @@ _io = [ class Platform(OSFPGAPlatform): def __init__(self): - OSFPGAPlatform.__init__(self, device=None, toolchain="raptor", io=_io) # FIXME: Add device support. + OSFPGAPlatform.__init__(self, device="test", toolchain="raptor", io=_io) # Minimal Design ----------------------------------------------------------------------------------- diff --git a/litex/build/osfpga/test_soc.py b/litex/build/osfpga/test_soc.py new file mode 100755 index 000000000..3c5fd4822 --- /dev/null +++ b/litex/build/osfpga/test_soc.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX. +# +# Copyright (c) 2022 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * + +from litex.build.io import CRG +from litex.build.generic_platform import Pins, Subsignal +from litex.build.osfpga import OSFPGAPlatform + +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * + +# Platform --------------------------------------------------------------------------------- + +_io = [ + # Clk. + ("clk", 0, Pins(1)), + + # Serial. + ("serial", 0, + Subsignal("tx", Pins(1)), + Subsignal("rx", Pins(1)), + ), +] + +class Platform(OSFPGAPlatform): + def __init__(self, toolchain="foedag"): + OSFPGAPlatform.__init__(self, device="test", toolchain=toolchain, io=_io) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, platform, sys_clk_freq=int(10e6), **kwargs): + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = CRG(platform.request("clk")) + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX Test SoC on OS-FPGA", **kwargs) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + from litex.soc.integration.soc import LiteXSoCArgumentParser + parser = LiteXSoCArgumentParser(description="LiteX Test SoC on OS-FPGA") + target_group = parser.add_argument_group(title="Target options") + target_group.add_argument("--build", action="store_true", help="Build design.") + target_group.add_argument("--toolchain", default="foedag", help="FPGA toolchain.") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + platform = Platform(toolchain=args.toolchain) + soc = BaseSoC(platform,**soc_core_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + if args.build: + builder.build() + +if __name__ == "__main__": + main() diff --git a/litex/soc/cores/clock/intel_common.py b/litex/soc/cores/clock/intel_common.py index 6a0be5382..914d187d9 100644 --- a/litex/soc/cores/clock/intel_common.py +++ b/litex/soc/cores/clock/intel_common.py @@ -70,8 +70,8 @@ class IntelClocking(Module, AutoCSR): break if valid: break - if not valid: - all_valid = False + if not valid: + all_valid = False else: all_valid = False if all_valid: diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py index 28736d0ae..63b935541 100644 --- a/litex/soc/cores/cpu/__init__.py +++ b/litex/soc/cores/cpu/__init__.py @@ -42,13 +42,13 @@ class CPUNone(CPU): data_width = 32 endianness = "little" reset_address = 0x00000000 - io_regions = {0x00000000: 0x100000000} # origin, length + io_regions = {0x0000_0000: 0x1_0000_0000} # origin, length periph_buses = [] memory_buses = [] mem_map = { - "csr" : 0x00000000, - "ethmac" : 0x00020000, # FIXME: Remove. - "spiflash" : 0x10000000, # FIXME: Remove. + "csr" : 0x0000_0000, + "ethmac" : 0x0002_0000, # FIXME: Remove. + "spiflash" : 0x1000_0000, # FIXME: Remove. } CPU_GCC_TRIPLE_RISCV64 = ( diff --git a/litex/soc/cores/cpu/blackparrot/core.py b/litex/soc/cores/cpu/blackparrot/core.py index c66765562..3e1b95e57 100644 --- a/litex/soc/cores/cpu/blackparrot/core.py +++ b/litex/soc/cores/cpu/blackparrot/core.py @@ -65,17 +65,17 @@ class BlackParrot(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV64 linker_output_format = "elf64-littleriscv" nop = "nop" - io_regions = {0x50000000: 0x10000000} # Origin, Length. + io_regions = {0x5000_0000: 0x1000_0000} # Origin, Length. # Memory Mapping. @property def mem_map(self): # Keep the lower 128MBs for SoC IOs auto-allocation. return { - "csr" : 0x58000000, - "rom" : 0x70000000, - "sram" : 0x71000000, - "main_ram" : 0x80000000, + "csr" : 0x5800_0000, + "rom" : 0x7000_0000, + "sram" : 0x7100_0000, + "main_ram" : 0x8000_0000, } # GCC Flags. @@ -142,7 +142,7 @@ class BlackParrot(CPU): def set_reset_address(self, reset_address): self.reset_address = reset_address - assert reset_address == 0x70000000, "cpu_reset_addr hardcoded to 7x00000000!" + assert reset_address == 0x7000_0000, "cpu_reset_addr hardcoded to 7x00000000!" @staticmethod def add_sources(platform, variant="standard"): diff --git a/litex/soc/cores/cpu/cv32e41p/core.py b/litex/soc/cores/cpu/cv32e41p/core.py index 40a1f83ce..d0fd6561a 100644 --- a/litex/soc/cores/cpu/cv32e41p/core.py +++ b/litex/soc/cores/cpu/cv32e41p/core.py @@ -252,7 +252,7 @@ class CV32E41P(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property diff --git a/litex/soc/cores/cpu/cva6/__init__.py b/litex/soc/cores/cpu/cva6/__init__.py new file mode 100644 index 000000000..474a14aa9 --- /dev/null +++ b/litex/soc/cores/cpu/cva6/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.cva6.core import CVA6 diff --git a/litex/soc/cores/cpu/cva6/boot-helper.S b/litex/soc/cores/cpu/cva6/boot-helper.S new file mode 100644 index 000000000..657806060 --- /dev/null +++ b/litex/soc/cores/cpu/cva6/boot-helper.S @@ -0,0 +1,18 @@ +.section .text, "ax", @progbits +.global boot_helper +.global smp_ap_args +.global smp_ap_target +.global smp_ap_ready + +boot_helper: + // boot core saves args and jump target for ap cores: + sd a0, smp_ap_args, t1 + sd a1, smp_ap_args+8, t1 + sd a2, smp_ap_args+16, t1 + sd a3, smp_ap_target, t1 + fence w, w + // notify application cores to proceed with boot: + li t0, 1 + sd t0, smp_ap_ready, t1 + // boot core now also ready to boot: + jr a3 diff --git a/litex/soc/cores/cpu/cva6/core.py b/litex/soc/cores/cpu/cva6/core.py new file mode 100644 index 000000000..c607f8de1 --- /dev/null +++ b/litex/soc/cores/cpu/cva6/core.py @@ -0,0 +1,186 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2021 Hensoldt Cyber GmbH +# Copyright (c) 2022 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +import os +import re + +from migen import * + +from litex import get_data_mod +from litex.soc.interconnect import axi +from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64 + +class Open(Signal): pass + +# Variants ----------------------------------------------------------------------------------------- + +CPU_VARIANTS = ["standard", "full"] + +# GCC Flags ---------------------------------------------------------------------------------------- + +GCC_FLAGS = { + # /-------- Base ISA + # |/------- Hardware Multiply + Divide + # ||/----- Atomics + # |||/---- Compressed ISA + # ||||/--- Single-Precision Floating-Point + # |||||/-- Double-Precision Floating-Point + # imacfd + "standard": "-march=rv64imac -mabi=lp64 ", + "full": "-march=rv64gc -mabi=lp64 ", +} + +# Helpers ------------------------------------------------------------------------------------------ + +def add_manifest_sources(platform, manifest): + basedir = get_data_mod("cpu", "cva6").data_location + with open(os.path.join(basedir, manifest), 'r') as f: + for l in f: + res = re.search('\$\{CVA6_REPO_DIR\}/(.+)', l) + if res and not re.match('//', l): + if re.match('\+incdir\+', l): + platform.add_verilog_include_path(os.path.join(basedir, res.group(1))) + else: + platform.add_source(os.path.join(basedir, res.group(1))) + +# CVA6 --------------------------------------------------------------------------------------------- + +class CVA6(CPU): + family = "riscv" + name = "cva6" + human_name = "CVA6" + variants = CPU_VARIANTS + data_width = 64 + endianness = "little" + gcc_triple = CPU_GCC_TRIPLE_RISCV64 + linker_output_format = "elf64-littleriscv" + nop = "nop" + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. + + # GCC Flags. + @property + def gcc_flags(self): + flags = GCC_FLAGS[self.variant] + flags += "-D__cva6__ " + flags += f" -DUART_POLLING" + return flags + + # Memory Mapping. + @property + def mem_map(self): + return { + "rom" : 0x1000_0000, + "sram" : 0x2000_0000, + "csr" : 0x8000_0000, + } + + def __init__(self, platform, variant="standard"): + self.platform = platform + self.variant = variant + self.reset = Signal() + self.interrupt = Signal(32) + self.axi_lite_if = axi.AXILiteInterface(data_width=64, address_width=32) + self.periph_buses = [self.axi_lite_if] # Peripheral buses (Connected to main SoC's bus). + self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM). + + # # # + + # AXI <-> AXILite conversion. + axi_if = axi.AXIInterface(data_width=64, address_width=32, id_width=4) + self.submodules += axi.AXI2AXILite(axi_if, self.axi_lite_if) + + # CPU Instance. + self.cpu_params = dict( + # Clk / Rst. + i_clk_i = ClockSignal("sys"), + i_rst_n = ~ResetSignal("sys") | self.reset, + + # AXI interface. + o_AWVALID_o = axi_if.aw.valid, + i_AWREADY_i = axi_if.aw.ready, + o_AWID_o = axi_if.aw.id, + o_AWADDR_o = axi_if.aw.addr, + o_AWLEN_o = axi_if.aw.len, + o_AWSIZE_o = axi_if.aw.size, + o_AWBURST_o = axi_if.aw.burst, + o_AWLOCK_o = axi_if.aw.lock, + o_AWCACHE_o = axi_if.aw.cache, + o_AWPROT_o = axi_if.aw.prot, + o_AWQOS_o = axi_if.aw.qos, + o_AWREGION_o = Open(), + o_AWUSER_o = Open(), + + o_WVALID_o = axi_if.w.valid, + i_WREADY_i = axi_if.w.ready, + o_WDATA_o = axi_if.w.data, + o_WSTRB_o = axi_if.w.strb, + o_WLAST_o = axi_if.w.last, + o_WUSER_o = Open(), + + i_BVALID_i = axi_if.b.valid, + o_BREADY_o = axi_if.b.ready, + i_BID_i = axi_if.b.id, + i_BRESP_i = axi_if.b.resp, + i_BUSER_i = 0, + + o_ARVALID_o = axi_if.ar.valid, + i_ARREADY_i = axi_if.ar.ready, + o_ARID_o = axi_if.ar.id, + o_ARADDR_o = axi_if.ar.addr, + o_ARLEN_o = axi_if.ar.len, + o_ARSIZE_o = axi_if.ar.size, + o_ARBURST_o = axi_if.ar.burst, + o_ARLOCK_o = axi_if.ar.lock, + o_ARCACHE_o = axi_if.ar.cache, + o_ARPROT_o = axi_if.ar.prot, + o_ARQOS_o = axi_if.ar.qos, + o_ARUSER_o = Open(), + o_ARREGION_o = Open(), + + i_RVALID_i = axi_if.r.valid, + o_RREADY_o = axi_if.r.ready, + i_RID_i = axi_if.r.id, + i_RDATA_i = axi_if.r.data, + i_RRESP_i = axi_if.r.resp, + i_RLAST_i = axi_if.r.last, + i_RUSER_i = 0, + ) + + # Add Verilog sources. + # TODO: use Flist.cv64a6_imafdc_sv39 and Flist.cv32a6_imac_sv0 instead + add_manifest_sources(platform, "Flist.cv64a6_imafdc_sv39") + add_manifest_sources(platform, "Flist.cva6_wrapper") + + def add_jtag(pads): + from migen.fhdl.specials import Tristate + self.jtag_tck = Signal() + self.jtag_tms = Signal() + self.jtag_trst = Signal() + self.jtag_tdi = Signal() + self.jtag_tdo = Signal() + + tdo_o = Signal() + tdo_oe = Signal() + self.specials += Tristate(self.jtag_tdo, tdo_o, tdo_oe) + + self.cpu_params.update( + i_trst_n = self.jtag_trst, + i_tck = self.jtag_tck, + i_tms = self.jtag_tms, + i_tdi = self.jtag_tdi, + o_tdo = tdo_o, + o_tdo_oe = tdo_oe, + ) + + def set_reset_address(self, reset_address): + self.reset_address = reset_address + assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!" + + def do_finalize(self): + assert hasattr(self, "reset_address") + self.specials += Instance("cva6_wrapper", **self.cpu_params) diff --git a/litex/soc/cores/cpu/cva6/crt0.S b/litex/soc/cores/cpu/cva6/crt0.S new file mode 100644 index 000000000..677e14f8b --- /dev/null +++ b/litex/soc/cores/cpu/cva6/crt0.S @@ -0,0 +1,125 @@ +.global main +.global isr +.global _start + +.global smp_ap_args +.global smp_ap_target +.global smp_ap_ready + +_start: + j crt_init + nop + nop + nop + nop + nop + nop + nop + +trap_entry: + sd x1, - 1*8(sp) + sd x5, - 2*8(sp) + sd x6, - 3*8(sp) + sd x7, - 4*8(sp) + sd x10, - 5*8(sp) + sd x11, - 6*8(sp) + sd x12, - 7*8(sp) + sd x13, - 8*8(sp) + sd x14, - 9*8(sp) + sd x15, -10*8(sp) + sd x16, -11*8(sp) + sd x17, -12*8(sp) + sd x28, -13*8(sp) + sd x29, -14*8(sp) + sd x30, -15*8(sp) + sd x31, -16*8(sp) + addi sp,sp,-16*8 + call isr + ld x1 , 15*8(sp) + ld x5, 14*8(sp) + ld x6, 13*8(sp) + ld x7, 12*8(sp) + ld x10, 11*8(sp) + ld x11, 10*8(sp) + ld x12, 9*8(sp) + ld x13, 8*8(sp) + ld x14, 7*8(sp) + ld x15, 6*8(sp) + ld x16, 5*8(sp) + ld x17, 4*8(sp) + ld x28, 3*8(sp) + ld x29, 2*8(sp) + ld x30, 1*8(sp) + ld x31, 0*8(sp) + addi sp,sp,16*8 + mret + .text + + +crt_init: + la sp, _fstack + sd zero, smp_ap_ready, t0 + la t0, trap_entry + csrw mtvec, t0 + +smp_select_bp: + csrr a0, mhartid + beqz a0, data_init // hart 0 is bp, everyone else is ap + +smp_ap_loop: + ld t0, smp_ap_ready + beqz t0, smp_ap_loop +smp_ap_boot: + fence r, r + fence.i // i$ flush + ld a0, smp_ap_args // hart ID (but next-stage loads its own) + ld a1, smp_ap_args+8 // DTB pointer (if provded by litex bios) + ld a2, smp_ap_args+16 + ld a3, smp_ap_target + jr a3 +smp_ap_done: + +data_init: + la t0, _fdata + la t1, _edata + la t2, _fdata_rom +data_loop: + beq t0,t1,data_done + ld t3,0(t2) + sd t3,0(t0) + add t0,t0,8 + add t2,t2,8 + j data_loop +data_done: + +bss_init: + la t0, _fbss + la t1, _ebss +bss_loop: + beq t0,t1,bss_done + sd zero,0(t0) + add t0,t0,8 + j bss_loop +bss_done: + + // call plic_init // initialize external interrupt controller + li t0, 0x800 // external interrupt sources only (using LiteX timer); + // NOTE: must still enable mstatus.MIE! + csrw mie,t0 + + call main +inf_loop: + j inf_loop + +.bss + .align 8 +smp_ap_args: + .dword 0 + .dword 0 + .dword 0 + .align 8 +smp_ap_target: + .dword 0 + .align 8 +smp_ap_ready: + .dword 0 diff --git a/litex/soc/cores/cpu/cva6/csr-defs.h b/litex/soc/cores/cpu/cva6/csr-defs.h new file mode 100644 index 000000000..170bd4540 --- /dev/null +++ b/litex/soc/cores/cpu/cva6/csr-defs.h @@ -0,0 +1,8 @@ +#ifndef CSR_DEFS__H +#define CSR_DEFS__H + +#define CSR_MSTATUS_MIE 0x8 + +#define CSR_DCACHE_INFO 0xCC0 + +#endif /* CSR_DEFS__H */ diff --git a/litex/soc/cores/cpu/cva6/irq.h b/litex/soc/cores/cpu/cva6/irq.h new file mode 100644 index 000000000..3d5c4bf9d --- /dev/null +++ b/litex/soc/cores/cpu/cva6/irq.h @@ -0,0 +1,41 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +static inline unsigned int irq_getie(void) +{ + return 0; +} + +static inline void irq_setie(unsigned int ie) +{ + +} + +static inline unsigned int irq_getmask(void) +{ + return 0; +} + +static inline void irq_setmask(unsigned int mask) +{ + +} + +static inline unsigned int irq_pending(void) +{ + return 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __IRQ_H */ diff --git a/litex/soc/cores/cpu/cva6/system.h b/litex/soc/cores/cpu/cva6/system.h new file mode 100644 index 000000000..5ed09d2a5 --- /dev/null +++ b/litex/soc/cores/cpu/cva6/system.h @@ -0,0 +1,43 @@ +#ifndef __SYSTEM_H +#define __SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((unused)) static void flush_cpu_icache(void){} /* FIXME: do something useful here! */ +__attribute__((unused)) static void flush_cpu_dcache(void){}; /* FIXME: do something useful here! */ +void flush_l2_cache(void); + +void busy_wait(unsigned int ms); +void busy_wait_us(unsigned int us); + +#include + +#define csrr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define csrw(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define csrs(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); }) + +#define csrc(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); }) + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_H */ diff --git a/litex/soc/cores/cpu/femtorv/core.py b/litex/soc/cores/cpu/femtorv/core.py index d29a51847..fbb3d6a31 100644 --- a/litex/soc/cores/cpu/femtorv/core.py +++ b/litex/soc/cores/cpu/femtorv/core.py @@ -55,7 +55,7 @@ class FemtoRV(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property diff --git a/litex/soc/cores/cpu/firev/core.py b/litex/soc/cores/cpu/firev/core.py index ce8857d3f..2439d5190 100644 --- a/litex/soc/cores/cpu/firev/core.py +++ b/litex/soc/cores/cpu/firev/core.py @@ -43,7 +43,7 @@ class FireV(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property diff --git a/litex/soc/cores/cpu/gowin_emcu/core.py b/litex/soc/cores/cpu/gowin_emcu/core.py index 7cc07553c..8709334c5 100644 --- a/litex/soc/cores/cpu/gowin_emcu/core.py +++ b/litex/soc/cores/cpu/gowin_emcu/core.py @@ -68,10 +68,10 @@ class GowinEMCU(CPU): @property def mem_map(self): return { - "rom": 0x0000_0000, - "sram": 0x2000_0000, - "peripherals": 0x4000_0000, - "csr": 0xA000_0000, + "rom" : 0x0000_0000, + "sram" : 0x2000_0000, + "peripherals" : 0x4000_0000, + "csr" : 0xa000_0000, } def __init__(self, platform, variant, *args, **kwargs): diff --git a/litex/soc/cores/cpu/ibex/core.py b/litex/soc/cores/cpu/ibex/core.py index 1e4948764..f1346e755 100644 --- a/litex/soc/cores/cpu/ibex/core.py +++ b/litex/soc/cores/cpu/ibex/core.py @@ -108,7 +108,7 @@ class Ibex(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property diff --git a/litex/soc/cores/cpu/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py index 7463001f3..389331f65 100644 --- a/litex/soc/cores/cpu/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -33,7 +33,7 @@ class LM32(CPU): gcc_triple = "lm32-elf" linker_output_format = "elf32-lm32" nop = "nop" - io_regions = {0x80000000: 0x80000000} # origin, length + io_regions = {0x8000_0000: 0x8000_0000} # origin, length # GCC Flags. @property diff --git a/litex/soc/cores/cpu/marocchino/core.py b/litex/soc/cores/cpu/marocchino/core.py index 0a7847b5e..29f0865ce 100644 --- a/litex/soc/cores/cpu/marocchino/core.py +++ b/litex/soc/cores/cpu/marocchino/core.py @@ -33,7 +33,7 @@ class Marocchino(CPU): clang_triple = "or1k-linux" linker_output_format = "elf32-or1k" nop = "l.nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # Memory Mapping for Linux variant. @property @@ -42,10 +42,10 @@ class Marocchino(CPU): # address of 0x0. As we are running Linux from the MAIN_RAM region - move it to satisfy # that requirement. return { - "main_ram" : 0x00000000, - "rom" : 0x10000000, - "sram" : 0x50000000, - "csr" : 0xe0000000, + "main_ram" : 0x0000_0000, + "rom" : 0x1000_0000, + "sram" : 0x5000_0000, + "csr" : 0xe000_0000, } # GCC Flags. diff --git a/litex/soc/cores/cpu/microwatt/core.py b/litex/soc/cores/cpu/microwatt/core.py index 7f4a8cba7..c44a171d2 100644 --- a/litex/soc/cores/cpu/microwatt/core.py +++ b/litex/soc/cores/cpu/microwatt/core.py @@ -35,16 +35,16 @@ class Microwatt(CPU): gcc_triple = ("powerpc64le-linux", "powerpc64le-linux-gnu", "ppc64le-linux", "ppc64le-linux-musl") linker_output_format = "elf64-powerpcle" nop = "nop" - io_regions = {0xc0000000: 0x10000000} # Origin, Length. + io_regions = {0xc000_0000: 0x1000_0000} # Origin, Length. # Memory Mapping. @property def mem_map(self): return { # Keep the lower 128MBs for SoC IOs auto-allocation. - "csr": 0xc8000000, - "xicsicp": 0xcbff0000, - "xicsics": 0xcbff1000, + "csr": 0xc800_0000, + "xicsicp": 0xcbff_0000, + "xicsics": 0xcbff_1000, } # GCC Flags. @@ -131,7 +131,7 @@ class Microwatt(CPU): def set_reset_address(self, reset_address): self.reset_address = reset_address - assert reset_address == 0x00000000 + assert reset_address == 0x0000_0000 def add_soc_components(self, soc, soc_region_cls): if "irq" in self.variant: diff --git a/litex/soc/cores/cpu/minerva/core.py b/litex/soc/cores/cpu/minerva/core.py index 8787bddda..e8cb53e7c 100644 --- a/litex/soc/cores/cpu/minerva/core.py +++ b/litex/soc/cores/cpu/minerva/core.py @@ -31,7 +31,7 @@ class Minerva(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property diff --git a/litex/soc/cores/cpu/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py index 163c6248f..9915c18d2 100644 --- a/litex/soc/cores/cpu/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -33,7 +33,7 @@ class MOR1KX(CPU): clang_triple = "or1k-linux" linker_output_format = "elf32-or1k" nop = "l.nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # Memory Mapping for Linux variant. @property @@ -42,10 +42,10 @@ class MOR1KX(CPU): # address of 0x0. As we are running Linux from the MAIN_RAM region - move it to satisfy # that requirement. return { - "main_ram" : 0x00000000, - "rom" : 0x10000000, - "sram" : 0x50000000, - "csr" : 0xe0000000, + "main_ram" : 0x0000_0000, + "rom" : 0x1000_0000, + "sram" : 0x5000_0000, + "csr" : 0xe000_0000, } # GCC Flags. diff --git a/litex/soc/cores/cpu/naxriscv/core.py b/litex/soc/cores/cpu/naxriscv/core.py index 805544787..63e63ec07 100644 --- a/litex/soc/cores/cpu/naxriscv/core.py +++ b/litex/soc/cores/cpu/naxriscv/core.py @@ -37,7 +37,7 @@ class NaxRiscv(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # Default parameters. with_fpu = False @@ -72,12 +72,12 @@ class NaxRiscv(CPU): @property def mem_map(self): return { - "rom": 0x00000000, - "sram": 0x10000000, - "main_ram": 0x40000000, - "csr": 0xf0000000, - "clint": 0xf0010000, - "plic": 0xf0c00000, + "rom": 0x0000_0000, + "sram": 0x1000_0000, + "main_ram": 0x4000_0000, + "csr": 0xf000_0000, + "clint": 0xf001_0000, + "plic": 0xf0c0_0000, } # GCC Flags. @@ -284,7 +284,7 @@ class NaxRiscv(CPU): soc.irq.add("timer0", n=1) # Add OpenSBI region. - soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f00000, 0x80000, type="cached+linker") + soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f0_0000, 0x8_0000, type="cached+linker") # Define ISA. soc.add_constant("CPU_ISA", NaxRiscv.get_arch()) @@ -312,7 +312,7 @@ class NaxRiscv(CPU): o_peripheral_plic_rdata = plicbus.r.data, o_peripheral_plic_rresp = plicbus.r.resp, ) - soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x400000, cached=False)) + soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=False)) if NaxRiscv.jtag_tap: self.jtag_tms = Signal() @@ -394,7 +394,7 @@ class NaxRiscv(CPU): o_peripheral_clint_rdata = clintbus.r.data, o_peripheral_clint_rresp = clintbus.r.resp, ) - soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x10000, cached=False)) + soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x1_0000, cached=False)) def add_memory_buses(self, address_width, data_width): nax_data_width = 64 diff --git a/litex/soc/cores/cpu/neorv32/core.py b/litex/soc/cores/cpu/neorv32/core.py index b5d7e068d..390a5ccd2 100644 --- a/litex/soc/cores/cpu/neorv32/core.py +++ b/litex/soc/cores/cpu/neorv32/core.py @@ -41,7 +41,7 @@ class NEORV32(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property @@ -147,7 +147,7 @@ class NEORV32(CPU): def set_reset_address(self, reset_address): self.reset_address = reset_address - assert reset_address == 0x00000000 + assert reset_address == 0x0000_0000 @staticmethod def add_sources(platform): diff --git a/litex/soc/cores/cpu/picorv32/core.py b/litex/soc/cores/cpu/picorv32/core.py index 480ede6db..96f124ab9 100644 --- a/litex/soc/cores/cpu/picorv32/core.py +++ b/litex/soc/cores/cpu/picorv32/core.py @@ -47,7 +47,7 @@ class PicoRV32(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # origin, length + io_regions = {0x8000_0000: 0x8000_0000} # origin, length # GCC Flags. @property @@ -183,7 +183,7 @@ class PicoRV32(CPU): self.reset_address = reset_address self.cpu_params.update( p_PROGADDR_RESET = reset_address, - p_PROGADDR_IRQ = reset_address + 0x00000010 + p_PROGADDR_IRQ = reset_address + 0x0000_0010 ) @staticmethod diff --git a/litex/soc/cores/cpu/rocket/core.py b/litex/soc/cores/cpu/rocket/core.py index 5f3cccdd0..9301d13df 100644 --- a/litex/soc/cores/cpu/rocket/core.py +++ b/litex/soc/cores/cpu/rocket/core.py @@ -105,18 +105,18 @@ class Rocket(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV64 linker_output_format = "elf64-littleriscv" nop = "nop" - io_regions = {0x12000000: 0x70000000} # Origin, Length. + io_regions = {0x1200_0000: 0x7000_0000} # Origin, Length. # Memory Mapping. @property def mem_map(self): # Rocket reserves the first 256Mbytes for internal use, so we must change default mem_map. return { - "rom" : 0x10000000, - "sram" : 0x11000000, - "csr" : 0x12000000, - "ethmac" : 0x30000000, - "main_ram" : 0x80000000, + "rom" : 0x1000_0000, + "sram" : 0x1100_0000, + "csr" : 0x1200_0000, + "ethmac" : 0x3000_0000, + "main_ram" : 0x8000_0000, } # GCC Flags. @@ -320,7 +320,7 @@ class Rocket(CPU): def set_reset_address(self, reset_address): self.reset_address = reset_address - assert reset_address == 0x10000000, "cpu_reset_addr hardcoded in during elaboration!" + assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!" @staticmethod def add_sources(platform, variant="standard"): diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py index 49b48b8bd..58e654b0b 100644 --- a/litex/soc/cores/cpu/serv/core.py +++ b/litex/soc/cores/cpu/serv/core.py @@ -44,7 +44,7 @@ class SERV(CPU): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # GCC Flags. @property diff --git a/litex/soc/cores/cpu/vexriscv/core.py b/litex/soc/cores/cpu/vexriscv/core.py index 083e07260..ffea0552d 100644 --- a/litex/soc/cores/cpu/vexriscv/core.py +++ b/litex/soc/cores/cpu/vexriscv/core.py @@ -105,17 +105,17 @@ class VexRiscv(CPU, AutoCSR): gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length # Memory Mapping. @property def mem_map(self): return { - "rom": 0x00000000, - "sram": 0x10000000, - "main_ram": 0x40000000, - "csr": 0xf0000000, - "vexriscv_debug": 0xf00f0000, + "rom": 0x0000_0000, + "sram": 0x1000_0000, + "main_ram": 0x4000_0000, + "csr": 0xf000_0000, + "vexriscv_debug": 0xf00f_0000, } # GCC Flags. diff --git a/litex/soc/cores/cpu/vexriscv_smp/core.py b/litex/soc/cores/cpu/vexriscv_smp/core.py index 602224622..8dfe8af2e 100755 --- a/litex/soc/cores/cpu/vexriscv_smp/core.py +++ b/litex/soc/cores/cpu/vexriscv_smp/core.py @@ -20,13 +20,6 @@ import os class Open(Signal): pass -# Variants ----------------------------------------------------------------------------------------- - -CPU_VARIANTS = { - "standard": "VexRiscv", - "linux": "VexRiscv", # Similar to standard. -} - # VexRiscv SMP ------------------------------------------------------------------------------------- class VexRiscvSMP(CPU): @@ -34,13 +27,13 @@ class VexRiscvSMP(CPU): family = "riscv" name = "vexriscv" human_name = "VexRiscv SMP" - variants = CPU_VARIANTS + variants = ["standard", "linux"] data_width = 32 endianness = "little" gcc_triple = CPU_GCC_TRIPLE_RISCV32 linker_output_format = "elf32-littleriscv" nop = "nop" - io_regions = {0x80000000: 0x80000000} # Origin, Length. + io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length. # Default parameters. cpu_count = 1 @@ -138,12 +131,12 @@ class VexRiscvSMP(CPU): @property def mem_map(self): return { - "rom": 0x00000000, - "sram": 0x10000000, - "main_ram": 0x40000000, - "csr": 0xf0000000, - "clint": 0xf0010000, - "plic": 0xf0c00000, + "rom": 0x0000_0000, + "sram": 0x1000_0000, + "main_ram": 0x4000_0000, + "csr": 0xf000_0000, + "clint": 0xf001_0000, + "plic": 0xf0c0_0000, } # GCC Flags. @@ -271,8 +264,8 @@ class VexRiscvSMP(CPU): def __init__(self, platform, variant): self.platform = platform - self.variant = "standard" - self.human_name = self.human_name + "-" + variant.upper() + self.variant = "linux" + self.human_name = self.human_name + "-" + self.variant.upper() self.reset = Signal() self.jtag_clk = Signal() self.jtag_enable = Signal() @@ -353,7 +346,7 @@ class VexRiscvSMP(CPU): def set_reset_address(self, reset_address): self.reset_address = reset_address - assert reset_address == 0x00000000 + assert reset_address == 0x0000_0000 def add_sources(self, platform): vdir = get_data_mod("cpu", "vexriscv_smp").data_location @@ -388,7 +381,7 @@ class VexRiscvSMP(CPU): soc.irq.add("timer0", n=1) # Add OpenSBI region. - soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f00000, 0x80000, type="cached+linker") + soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f0_0000, 0x8_0000, type="cached+linker") # Define number of CPUs soc.add_config("CPU_COUNT", VexRiscvSMP.cpu_count) @@ -422,7 +415,7 @@ class VexRiscvSMP(CPU): o_plicWishbone_DAT_MISO = plicbus.dat_r, i_plicWishbone_DAT_MOSI = plicbus.dat_w ) - soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x400000, cached=False)) + soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=False)) # Add CLINT as Bus Slave self.clintbus = clintbus = wishbone.Interface() @@ -435,7 +428,7 @@ class VexRiscvSMP(CPU): o_clintWishbone_DAT_MISO = clintbus.dat_r, i_clintWishbone_DAT_MOSI = clintbus.dat_w, ) - soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x10000, cached=False)) + soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x1_0000, cached=False)) def add_memory_buses(self, address_width, data_width): VexRiscvSMP.litedram_width = data_width diff --git a/litex/soc/cores/cpu/zynq7000/core.py b/litex/soc/cores/cpu/zynq7000/core.py index 0ca203db8..dbaf011a1 100644 --- a/litex/soc/cores/cpu/zynq7000/core.py +++ b/litex/soc/cores/cpu/zynq7000/core.py @@ -37,7 +37,7 @@ class Zynq7000(CPU): @property def mem_map(self): return { - "sram": 0x10_0000, # DDR in fact + "sram": 0x0010_0000, # DDR in fact "rom": 0xfc00_0000, } diff --git a/litex/soc/cores/cpu/zynqmp/core.py b/litex/soc/cores/cpu/zynqmp/core.py index ba888f3a5..efc5d9e2d 100644 --- a/litex/soc/cores/cpu/zynqmp/core.py +++ b/litex/soc/cores/cpu/zynqmp/core.py @@ -24,7 +24,7 @@ class ZynqMP(CPU): linker_output_format = "elf64-littleaarch64" nop = "nop" io_regions = { # Origin, Length. - 0x8000_0000: 0x4000_0000, + 0x8000_0000: 0x00_4000_0000, 0xe000_0000: 0xff_2000_0000 # TODO: there are more details here } csr_decode = False # AXI address is decoded in AXI2Wishbone (target level). diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 6ce80c62a..0c7d4b329 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1216,7 +1216,8 @@ class LiteXSoC(SoC): self.check_if_exists(name) if with_build_time: identifier += " " + build_time() - self.add_config("WITH_BUILD_TIME") + else: + self.add_config("BIOS_NO_BUILD_TIME") setattr(self.submodules, name, Identifier(identifier)) # Add UART ------------------------------------------------------------------------------------- @@ -1774,10 +1775,11 @@ class LiteXSoC(SoC): self.add_constant("SDCARD_DEBUG") # Add SATA ------------------------------------------------------------------------------------- - def add_sata(self, name="sata", phy=None, mode="read+write"): + def add_sata(self, name="sata", phy=None, mode="read+write", with_identify=True): # Imports. from litesata.core import LiteSATACore from litesata.frontend.arbitration import LiteSATACrossbar + from litesata.frontend.identify import LiteSATAIdentify, LiteSATAIdentifyCSR from litesata.frontend.dma import LiteSATASector2MemDMA, LiteSATAMem2SectorDMA # Checks. @@ -1798,6 +1800,12 @@ class LiteXSoC(SoC): self.check_if_exists("sata_crossbar") self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core) + # Identify. + if with_identify: + sata_identify = LiteSATAIdentify(self.sata_crossbar.get_port()) + self.submodules += sata_identify + self.submodules.sata_identify = LiteSATAIdentifyCSR(sata_identify) + # Sector2Mem DMA. if "read" in mode: bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width) @@ -1818,6 +1826,20 @@ class LiteXSoC(SoC): dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus dma_bus.add_master("sata_mem2sector", master=bus) + # Interrupts. + self.submodules.sata_irq = EventManager() + if "read" in mode: + self.sata_irq.sector2mem_dma = EventSourcePulse(description="Sector2Mem DMA terminated.") + if "write" in mode: + self.sata_irq.mem2sector_dma = EventSourcePulse(description="Mem2Sector DMA terminated.") + self.sata_irq.finalize() + if "read" in mode: + self.comb += self.sata_irq.sector2mem_dma.trigger.eq(self.sata_sector2mem.irq) + if "write" in mode: + self.comb += self.sata_irq.mem2sector_dma.trigger.eq(self.sata_mem2sector.irq) + if self.irq.enabled: + self.irq.add("sata", use_loc_if_exists=True) + # Timing constraints. self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq) self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_rx.clk, 1e9/sata_clk_freq) diff --git a/litex/soc/software/bios/cmds/cmd_litesata.c b/litex/soc/software/bios/cmds/cmd_litesata.c index 27c75e78d..811998336 100644 --- a/litex/soc/software/bios/cmds/cmd_litesata.c +++ b/litex/soc/software/bios/cmds/cmd_litesata.c @@ -20,7 +20,7 @@ static void sata_init_handler(int nb_params, char **params) { printf("Initialize SATA... "); - if (sata_init()) + if (sata_init(1)) printf("Successful.\n"); else printf("Failed.\n"); diff --git a/litex/soc/software/bios/main.c b/litex/soc/software/bios/main.c index 05b6b06a9..7305c54e2 100644 --- a/litex/soc/software/bios/main.c +++ b/litex/soc/software/bios/main.c @@ -97,7 +97,7 @@ __attribute__((__used__)) int main(int i, char **c) i2c_send_init_cmds(); #endif -#ifndef CONFIG_SIM_DISABLE_BIOS_PROMPT +#ifndef CONFIG_BIOS_NO_PROMPT printf("\n"); printf("\e[1m __ _ __ _ __\e[0m\n"); printf("\e[1m / / (_) /____ | |/_/\e[0m\n"); @@ -108,10 +108,12 @@ __attribute__((__used__)) int main(int i, char **c) printf(" (c) Copyright 2012-2022 Enjoy-Digital\n"); printf(" (c) Copyright 2007-2015 M-Labs\n"); printf("\n"); -#ifdef CONFIG_WITH_BUILD_TIME +#ifndef CONFIG_BIOS_NO_BUILD_TIME printf(" BIOS built on "__DATE__" "__TIME__"\n"); #endif +#ifndef CONFIG_BIOS_NO_CRC crcbios(); +#endif printf("\n"); printf(" LiteX git sha1: "LITEX_GIT_SHA1"\n"); printf("\n"); @@ -149,7 +151,7 @@ __attribute__((__used__)) int main(int i, char **c) #endif #endif printf("\n"); -#endif // CONFIG_SIM_DISABLE_BIOS_PROMPT +#endif sdr_ok = 1; diff --git a/litex/soc/software/liblitedram/bist.c b/litex/soc/software/liblitedram/bist.c index f2079224d..044563792 100644 --- a/litex/soc/software/liblitedram/bist.c +++ b/litex/soc/software/liblitedram/bist.c @@ -23,7 +23,7 @@ uint32_t rd_errors; __attribute__((unused)) static void cdelay(int i) { -#ifndef CONFIG_DISABLE_DELAYS +#ifndef CONFIG_BIOS_NO_DELAYS while(i > 0) { __asm__ volatile(CONFIG_CPU_NOP); i--; diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index 12aea95c4..53acec829 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -43,7 +43,7 @@ __attribute__((unused)) void cdelay(int i) { -#ifndef CONFIG_DISABLE_DELAYS +#ifndef CONFIG_BIOS_NO_DELAYS while(i > 0) { __asm__ volatile(CONFIG_CPU_NOP); i--; diff --git a/litex/soc/software/liblitesata/sata.c b/litex/soc/software/liblitesata/sata.c index 1c5ecc739..75e414314 100644 --- a/litex/soc/software/liblitesata/sata.c +++ b/litex/soc/software/liblitesata/sata.c @@ -1,4 +1,4 @@ -// This file is Copyright (c) 2020 Florent Kermarrec +// This file is Copyright (c) 2020-2022 Florent Kermarrec // License: BSD #include @@ -19,9 +19,14 @@ #ifdef CSR_SATA_PHY_BASE -int sata_init(void) { +int sata_init(int show) { uint16_t timeout; - uint8_t buf[512]; + int i; + uint32_t data; + uint16_t buf[128]; + uint8_t model[38]; + uint64_t sectors; + uint32_t capacity; for (timeout=16; timeout>0; timeout--) { /* Reset SATA PHY */ @@ -37,18 +42,50 @@ int sata_init(void) { /* Re-initialize if failing */ continue; - /* Initiate a SATA Read */ - sata_sector2mem_base_write((uint64_t)(uintptr_t) buf); - sata_sector2mem_sector_write(0); - sata_sector2mem_start_write(1); + /* Initiate a SATA Identify */ + sata_identify_start_write(1); - /* Wait for 10ms */ - busy_wait(10); + /* Wait for 100ms */ + busy_wait(100); - /* Check SATA Read status */ - if ((sata_sector2mem_done_read() & 0x1) == 0) + /* Check SATA Identify status */ + if ((sata_identify_done_read() & 0x1) == 0) + /* Re-initialize if failing */ continue; + if (show) + printf("\n"); + + /* Dump Idenfify response to buf */ + i = 0; + while (sata_identify_source_valid_read() && (i < 128)) { + data = sata_identify_source_data_read(); + sata_identify_source_ready_write(1); + buf[i+0] = ((data >> 0) & 0xffff); + buf[i+1] = ((data >> 16) & 0xffff); + i += 2; + } + + /* Get Disk Model from buf */ + i = 0; + memset(model, 0, 38); + for (i=0; i<18; i++) { + model[2*i + 0] = (buf[27+i] >> 8) & 0xff; + model[2*i + 1] = (buf[27+i] >> 0) & 0xff; + } + if (show) + printf("Model: %s\n", model); + + /* Get Disk Capacity from buf */ + sectors = 0; + sectors += (((uint64_t) buf[100]) << 0); + sectors += (((uint64_t) buf[101]) << 16); + sectors += (((uint64_t) buf[102]) << 32); + sectors += (((uint64_t) buf[103]) << 48); + capacity = sectors/(1000*1000*500/256); + if (show) + printf("Capacity: %ldGB\n", capacity); + /* Init succeeded */ return 1; } @@ -127,7 +164,7 @@ static DSTATUS sata_disk_status(BYTE drv) { static DSTATUS sata_disk_initialize(BYTE drv) { if (drv) return STA_NOINIT; if (satastatus) - satastatus = sata_init() ? 0 : STA_NOINIT; + satastatus = sata_init(0) ? 0 : STA_NOINIT; return satastatus; } diff --git a/litex/soc/software/liblitesata/sata.h b/litex/soc/software/liblitesata/sata.h index 09d85ed74..bc7845702 100644 --- a/litex/soc/software/liblitesata/sata.h +++ b/litex/soc/software/liblitesata/sata.h @@ -12,7 +12,7 @@ #ifdef CSR_SATA_PHY_BASE -int sata_init(void); +int sata_init(int show); void fatfs_set_ops_sata(void); #endif diff --git a/litex/tools/litex_json2dts_linux.py b/litex/tools/litex_json2dts_linux.py index 33b713450..41f1849b4 100755 --- a/litex/tools/litex_json2dts_linux.py +++ b/litex/tools/litex_json2dts_linux.py @@ -33,9 +33,9 @@ def generate_dts(d, initrd_start=None, initrd_size=None, initrd=None, root_devic # Boot Arguments ------------------------------------------------------------------------------- cpu_architectures = { - "mor1kx": "or1k", - "marocchino": "or1k", - "vexriscv smp-linux": "riscv", + "mor1kx" : "or1k", + "marocchino" : "or1k", + "vexriscv smp-linux" : "riscv", } default_initrd_start = { "or1k": 8*mB, diff --git a/litex/tools/litex_sim.py b/litex/tools/litex_sim.py index 05a1e95a1..7960870a8 100755 --- a/litex/tools/litex_sim.py +++ b/litex/tools/litex_sim.py @@ -161,13 +161,20 @@ class SimSoC(SoCCore): platform = Platform() sys_clk_freq = int(1e6) + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = CRG(platform.request("sys_clk")) + # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, ident = "LiteX Simulation", **kwargs) - # CRG -------------------------------------------------------------------------------------- - self.submodules.crg = CRG(platform.request("sys_clk")) + # BIOS Config ------------------------------------------------------------------------------ + # FIXME: Expose? + #self.add_config("BIOS_NO_PROMPT") + #self.add_config("BIOS_NO_DELAYS") + #self.add_config("BIOS_NO_BUILD_TIME") + #self.add_config("BIOS_NO_CRC") # SDRAM ------------------------------------------------------------------------------------ if not self.integrated_main_ram_size and with_sdram: diff --git a/litex_setup.py b/litex_setup.py index 000ba5d6a..a24694930 100755 --- a/litex_setup.py +++ b/litex_setup.py @@ -69,14 +69,17 @@ class GitRepo: git_repos = { # HDL. + # ---- "migen": GitRepo(url="https://github.com/m-labs/", clone="recursive"), - # LiteX SoC builder + # LiteX SoC builder. + # ------------------ "pythondata-software-picolibc": GitRepo(url="https://github.com/litex-hub/", clone="recursive"), "pythondata-software-compiler_rt": GitRepo(url="https://github.com/litex-hub/"), "litex": GitRepo(url="https://github.com/enjoy-digital/", tag=True), # LiteX Cores Ecosystem. + # ---------------------- "liteeth": GitRepo(url="https://github.com/enjoy-digital/", tag=True), "litedram": GitRepo(url="https://github.com/enjoy-digital/", tag=True), "litepcie": GitRepo(url="https://github.com/enjoy-digital/", tag=True), @@ -88,27 +91,39 @@ git_repos = { "litespi": GitRepo(url="https://github.com/litex-hub/", tag=True), # LiteX Boards. + # ------------- "litex-boards": GitRepo(url="https://github.com/litex-hub/", clone="regular", tag=True), # LiteX pythondata. + # ----------------- + # Generic. "pythondata-misc-tapcfg": GitRepo(url="https://github.com/litex-hub/"), "pythondata-misc-usb_ohci": GitRepo(url="https://github.com/litex-hub/"), + + # LM32 CPU(s). "pythondata-cpu-lm32": GitRepo(url="https://github.com/litex-hub/"), + + # OpenRISC CPU(s). "pythondata-cpu-mor1kx": GitRepo(url="https://github.com/litex-hub/"), - "pythondata-cpu-picorv32": GitRepo(url="https://github.com/litex-hub/"), - "pythondata-cpu-serv": GitRepo(url="https://github.com/litex-hub/"), - "pythondata-cpu-vexriscv": GitRepo(url="https://github.com/litex-hub/"), - "pythondata-cpu-vexriscv-smp": GitRepo(url="https://github.com/litex-hub/", clone="recursive"), - "pythondata-cpu-naxriscv": GitRepo(url="https://github.com/litex-hub/"), - "pythondata-cpu-rocket": GitRepo(url="https://github.com/litex-hub/"), - "pythondata-cpu-minerva": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-marocchino": GitRepo(url="https://github.com/litex-hub/"), + + # OpenPower CPU(s). "pythondata-cpu-microwatt": GitRepo(url="https://github.com/litex-hub/", sha1=0xb940b55acff), + + # RISC-V CPU(s). "pythondata-cpu-blackparrot": GitRepo(url="https://github.com/litex-hub/"), "pythondata-cpu-cv32e40p": GitRepo(url="https://github.com/litex-hub/", clone="recursive"), "pythondata-cpu-cv32e41p": GitRepo(url="https://github.com/litex-hub/", clone="recursive"), "pythondata-cpu-cva5": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-cva6": GitRepo(url="https://github.com/litex-hub/", clone="recursive"), "pythondata-cpu-ibex": GitRepo(url="https://github.com/litex-hub/", clone="recursive", sha1=0xd3d53df), - "pythondata-cpu-marocchino": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-minerva": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-naxriscv": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-picorv32": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-rocket": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-serv": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-vexriscv": GitRepo(url="https://github.com/litex-hub/"), + "pythondata-cpu-vexriscv-smp": GitRepo(url="https://github.com/litex-hub/", clone="recursive"), } # Installs ----------------------------------------------------------------------------------------- @@ -118,15 +133,16 @@ minimal_repos = ["migen", "litex"] # Standard: Migen + LiteX + Cores + Software + Popular CPUs (LM32, Mor1kx, SERV, VexRiscv). standard_repos = list(git_repos.keys()) -standard_repos.remove("pythondata-cpu-picorv32") -standard_repos.remove("pythondata-cpu-rocket") -standard_repos.remove("pythondata-cpu-minerva") -standard_repos.remove("pythondata-cpu-microwatt") standard_repos.remove("pythondata-cpu-blackparrot") standard_repos.remove("pythondata-cpu-cv32e40p") standard_repos.remove("pythondata-cpu-cv32e41p") +standard_repos.remove("pythondata-cpu-cva6") standard_repos.remove("pythondata-cpu-ibex") standard_repos.remove("pythondata-cpu-marocchino") +standard_repos.remove("pythondata-cpu-minerva") +standard_repos.remove("pythondata-cpu-microwatt") +standard_repos.remove("pythondata-cpu-picorv32") +standard_repos.remove("pythondata-cpu-rocket") # Full: Migen + LiteX + Cores + Software + All CPUs. full_repos = list(git_repos.keys()) @@ -254,7 +270,7 @@ def litex_setup_install_repos(config="standard", user_mode=False): if repo.develop: print_status(f"Installing {name} Git repository...") os.chdir(os.path.join(current_path, name)) - subprocess.check_call("{python3} -m pip install --editable . {options}".format( + subprocess.check_call("\"{python3}\" -m pip install --editable . {options}".format( python3 = sys.executable, options = "--user" if user_mode else "", ), shell=True) diff --git a/test/test_cpu.py b/test/test_cpu.py index 02047107b..204280b2a 100644 --- a/test/test_cpu.py +++ b/test/test_cpu.py @@ -56,6 +56,9 @@ class TestCPU(unittest.TestCase): def test_picorv32(self): self.assertTrue(self.boot_test("picorv32")) + #def test_cva6(self): + # self.assertTrue(self.boot_test("cva6")) + # OpenRISC CPUs. #def test_mor1kx(self): # self.assertTrue(self.boot_test("mor1kx"))