From e801dc0261d7101b148135933f441ed82ca61da8 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 6 Mar 2020 20:05:27 +0100 Subject: [PATCH] soc: allow creating SoC without BIOS. By default the behaviour is unchanged and the SoC will provide a ROM: ./arty.py Bus Regions: (4) rom : Origin: 0x00000000, Size: 0x00008000, Mode: R, Cached: True Linker: False sram : Origin: 0x01000000, Size: 0x00001000, Mode: RW, Cached: True Linker: False main_ram : Origin: 0x40000000, Size: 0x10000000, Mode: RW, Cached: True Linker: False csr : Origin: 0x82000000, Size: 0x00010000, Mode: RW, Cached: False Linker: False The integrated rom can be disabled with: ./arty.py --integrated-rom-size=0 but the SoC builder will check for a user provided rom, and if not provided will complains: ERROR:SoC:CPU needs rom Region to be defined as Bus or Linker Region. When a rom is provided, the CPU will use the rom base address as cpu_reset_address. If the user just wants the CPU to start at a specified address without providing a rom, the cpu_reset_address parameter can be used: ./arty.py --integrated-rom-size=0 --cpu-reset-address=0x01000000 If the provided reset address is not located in any defined Region, an error will be produced: ERROR:SoC:CPU needs reset address 0x00000000 to be in a defined Region. When no rom is provided, the builder will not build the BIOS. --- litex/soc/cores/cpu/__init__.py | 1 + litex/soc/integration/builder.py | 11 ++++++----- litex/soc/integration/soc.py | 16 +++++++++++++++- litex/soc/integration/soc_core.py | 7 ++++--- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py index 870a9696..db9fdab7 100644 --- a/litex/soc/cores/cpu/__init__.py +++ b/litex/soc/cores/cpu/__init__.py @@ -18,6 +18,7 @@ class CPU(Module): interrupts = {} mem_map = {} io_regions = {} + use_rom = False def __init__(self, *args, **kwargs): pass diff --git a/litex/soc/integration/builder.py b/litex/soc/integration/builder.py index c923b1dc..1eea7f77 100644 --- a/litex/soc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -182,11 +182,12 @@ class Builder: self._generate_includes() self._generate_csr_map() if self.soc.cpu_type is not None: - self._prepare_rom_software() - self._generate_rom_software(not self.soc.integrated_rom_initialized) - if self.soc.integrated_rom_size and self.compile_software: - if not self.soc.integrated_rom_initialized: - self._initialize_rom_software() + if self.soc.cpu.use_rom: + self._prepare_rom_software() + self._generate_rom_software(not self.soc.integrated_rom_initialized) + if self.soc.integrated_rom_size and self.compile_software: + if not self.soc.integrated_rom_initialized: + self._initialize_rom_software() if "run" not in kwargs: kwargs["run"] = self.compile_gateware diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index b5b8575f..70e51fe1 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -769,6 +769,7 @@ class SoC(Module): self.csr.update_alignment(self.cpu.data_width) # Add Bus Masters/CSR/IRQs if not isinstance(self.cpu, cpu.CPUNone): + self.cpu.use_rom = (reset_address is None) if reset_address is None: reset_address = self.mem_map["rom"] self.cpu.set_reset_address(reset_address) @@ -848,7 +849,7 @@ class SoC(Module): # SoC CPU Check ---------------------------------------------------------------------------- if not isinstance(self.cpu, cpu.CPUNone): - for name in ["rom", "sram"]: + for name in ["sram"] + ["rom"] if self.cpu.use_rom else []: if name not in self.bus.regions.keys(): self.logger.error("CPU needs {} Region to be {} as Bus or Linker Region.".format( colorer(name), @@ -856,6 +857,19 @@ class SoC(Module): self.logger.error(self.bus) raise + cpu_reset_address_valid = False + for container in self.bus.regions.values(): + if self.bus.check_region_is_in( + region = SoCRegion(origin=self.cpu.reset_address, size=self.bus.data_width//8), + container = container): + cpu_reset_address_valid = True + if not cpu_reset_address_valid: + self.logger.error("CPU needs {} to be in a {} Region.".format( + colorer("reset address 0x{:08x}".format(self.cpu.reset_address)), + colorer("defined", color="red"))) + self.logger.error(self.bus) + raise + # SoC IRQ Interconnect --------------------------------------------------------------------- if hasattr(self, "cpu"): if hasattr(self.cpu, "interrupt"): diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 20c31879..b1209a00 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -63,7 +63,7 @@ class SoCCore(LiteXSoC): def __init__(self, platform, clk_freq, # CPU parameters cpu_type = "vexriscv", - cpu_reset_address = 0x00000000, + cpu_reset_address = None, cpu_variant = None, # ROM parameters integrated_rom_size = 0, @@ -122,7 +122,8 @@ class SoCCore(LiteXSoC): self.config = {} # Parameters management -------------------------------------------------------------------- - cpu_type = None if cpu_type == "None" else cpu_type + cpu_type = None if cpu_type == "None" else cpu_type + cpu_reset_address = None if cpu_reset_address == "None" else cpu_reset_address cpu_variant = cpu.check_format_cpu_variant(cpu_variant) if not with_wishbone: @@ -256,7 +257,7 @@ def soc_core_args(parser): parser.add_argument("--cpu-variant", default=None, help="select CPU variant, (default=standard)") parser.add_argument("--cpu-reset-address", default=None, type=auto_int, - help="CPU reset address (default=0x00000000 or ROM)") + help="CPU reset address (default=None (Integrated ROM)") # ROM parameters parser.add_argument("--integrated-rom-size", default=0x8000, type=auto_int, help="size/enable the integrated (BIOS) ROM (default=32KB)") -- 2.30.2