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.
This commit is contained in:
Florent Kermarrec 2020-03-06 20:05:27 +01:00
parent 5ded144762
commit e801dc0261
4 changed files with 26 additions and 9 deletions

View File

@ -18,6 +18,7 @@ class CPU(Module):
interrupts = {} interrupts = {}
mem_map = {} mem_map = {}
io_regions = {} io_regions = {}
use_rom = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
pass pass

View File

@ -182,11 +182,12 @@ class Builder:
self._generate_includes() self._generate_includes()
self._generate_csr_map() self._generate_csr_map()
if self.soc.cpu_type is not None: if self.soc.cpu_type is not None:
self._prepare_rom_software() if self.soc.cpu.use_rom:
self._generate_rom_software(not self.soc.integrated_rom_initialized) self._prepare_rom_software()
if self.soc.integrated_rom_size and self.compile_software: self._generate_rom_software(not self.soc.integrated_rom_initialized)
if not self.soc.integrated_rom_initialized: if self.soc.integrated_rom_size and self.compile_software:
self._initialize_rom_software() if not self.soc.integrated_rom_initialized:
self._initialize_rom_software()
if "run" not in kwargs: if "run" not in kwargs:
kwargs["run"] = self.compile_gateware kwargs["run"] = self.compile_gateware

View File

@ -769,6 +769,7 @@ class SoC(Module):
self.csr.update_alignment(self.cpu.data_width) self.csr.update_alignment(self.cpu.data_width)
# Add Bus Masters/CSR/IRQs # Add Bus Masters/CSR/IRQs
if not isinstance(self.cpu, cpu.CPUNone): if not isinstance(self.cpu, cpu.CPUNone):
self.cpu.use_rom = (reset_address is None)
if reset_address is None: if reset_address is None:
reset_address = self.mem_map["rom"] reset_address = self.mem_map["rom"]
self.cpu.set_reset_address(reset_address) self.cpu.set_reset_address(reset_address)
@ -848,7 +849,7 @@ class SoC(Module):
# SoC CPU Check ---------------------------------------------------------------------------- # SoC CPU Check ----------------------------------------------------------------------------
if not isinstance(self.cpu, cpu.CPUNone): 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(): if name not in self.bus.regions.keys():
self.logger.error("CPU needs {} Region to be {} as Bus or Linker Region.".format( self.logger.error("CPU needs {} Region to be {} as Bus or Linker Region.".format(
colorer(name), colorer(name),
@ -856,6 +857,19 @@ class SoC(Module):
self.logger.error(self.bus) self.logger.error(self.bus)
raise 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 --------------------------------------------------------------------- # SoC IRQ Interconnect ---------------------------------------------------------------------
if hasattr(self, "cpu"): if hasattr(self, "cpu"):
if hasattr(self.cpu, "interrupt"): if hasattr(self.cpu, "interrupt"):

View File

@ -63,7 +63,7 @@ class SoCCore(LiteXSoC):
def __init__(self, platform, clk_freq, def __init__(self, platform, clk_freq,
# CPU parameters # CPU parameters
cpu_type = "vexriscv", cpu_type = "vexriscv",
cpu_reset_address = 0x00000000, cpu_reset_address = None,
cpu_variant = None, cpu_variant = None,
# ROM parameters # ROM parameters
integrated_rom_size = 0, integrated_rom_size = 0,
@ -122,7 +122,8 @@ class SoCCore(LiteXSoC):
self.config = {} self.config = {}
# Parameters management -------------------------------------------------------------------- # 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) cpu_variant = cpu.check_format_cpu_variant(cpu_variant)
if not with_wishbone: if not with_wishbone:
@ -256,7 +257,7 @@ def soc_core_args(parser):
parser.add_argument("--cpu-variant", default=None, parser.add_argument("--cpu-variant", default=None,
help="select CPU variant, (default=standard)") help="select CPU variant, (default=standard)")
parser.add_argument("--cpu-reset-address", default=None, type=auto_int, 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 # ROM parameters
parser.add_argument("--integrated-rom-size", default=0x8000, type=auto_int, parser.add_argument("--integrated-rom-size", default=0x8000, type=auto_int,
help="size/enable the integrated (BIOS) ROM (default=32KB)") help="size/enable the integrated (BIOS) ROM (default=32KB)")