soc: allow creating SoC without BIOS.
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 6 Mar 2020 19:05:27 +0000 (20:05 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 6 Mar 2020 19:05:27 +0000 (20:05 +0100)
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
litex/soc/integration/builder.py
litex/soc/integration/soc.py
litex/soc/integration/soc_core.py

index 870a96967717f1ebc03881bf4f49ede3403f9b15..db9fdab7b8a5b56507190aeb3151f297313fad81 100644 (file)
@@ -18,6 +18,7 @@ class CPU(Module):
     interrupts           = {}
     mem_map              = {}
     io_regions           = {}
+    use_rom              = False
     def __init__(self, *args, **kwargs):
         pass
 
index c923b1dca08f7ee5b24935dd9095284f2fc29666..1eea7f775982812a85f23f1a7a1e3c9cbb8c3e8a 100644 (file)
@@ -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
index b5b8575f04da8951cf83b48494d8b60236c313e5..70e51fe1c26c49bfba8a6c522a4dfdf329b1cc10 100644 (file)
@@ -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"):
index 20c31879f1cd7539710f6a0b77b514a314714a96..b1209a00d7de77e73a247cd4496709d6c8452d7e 100644 (file)
@@ -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)")