From b22d2ca02bf44c74f82e19accb54c6c97b59d238 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 11 Feb 2020 15:28:02 +0100 Subject: [PATCH] soc: add linker regions management --- litex/soc/integration/soc.py | 52 +++++++++---------------------- litex/soc/integration/soc_core.py | 4 ++- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 1c3534ee9..79dbc3be6 100755 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -26,7 +26,6 @@ from litedram.frontend.wishbone import LiteDRAMWishbone2Native # TODO: # - replace raise with exit on logging error. # - add configurable CSR paging. -# - manage SoCLinkerRegion # - cleanup SoCCSRRegion logging.basicConfig(level=logging.INFO) @@ -55,12 +54,13 @@ def SoCConstant(value): # SoCRegion ---------------------------------------------------------------------------------------- class SoCRegion: - def __init__(self, origin=None, size=None, mode="rw", cached=True): + def __init__(self, origin=None, size=None, mode="rw", cached=True, linker=False): self.logger = logging.getLogger("SoCRegion") self.origin = origin self.size = size self.mode = mode self.cached = cached + self.linker = linker def decoder(self, bus): origin = self.origin @@ -81,13 +81,12 @@ class SoCRegion: if self.size is not None: r += "Size: {}, ".format(colorer("0x{:08x}".format(self.size))) r += "Mode: {}, ".format(colorer(self.mode.upper())) - r += "Cached: {}".format(colorer(self.cached)) + r += "Cached: {} ".format(colorer(self.cached)) + r += "Linker: {}".format(colorer(self.linker)) return r class SoCIORegion(SoCRegion): pass -class SoCLinkerRegion(SoCRegion): pass - # SoCCSRRegion ------------------------------------------------------------------------------------- class SoCCSRRegion: @@ -137,7 +136,6 @@ class SoCBusHandler(Module): self.slaves = {} self.regions = {} self.io_regions = {} - self.ld_regions = {} self.timeout = timeout self.logger.info("{}-bit {} Bus, {}GiB Address Space.".format( colorer(data_width), colorer(standard), colorer(2**address_width/2**30))) @@ -154,12 +152,12 @@ class SoCBusHandler(Module): # Add/Allog/Check Regions ---------------------------------------------------------------------- def add_region(self, name, region): allocated = False + if name in self.regions.keys() or name in self.io_regions.keys(): + self.logger.error("{} already declared as Region:".format(colorer(name, color="red"))) + self.logger.error(self) + raise # Check if SoCIORegion if isinstance(region, SoCIORegion): - if name in self.masters.keys(): - self.logger.error("{} already declared as IO Region:".format(colorer(name, color="red"))) - self.logger.error(self) - raise self.io_regions[name] = region overlap = self.check_regions_overlap(self.io_regions) if overlap is not None: @@ -173,25 +171,6 @@ class SoCBusHandler(Module): colorer(name, color="underline"), colorer("added", color="green"), str(region))) - # Check if SoCLinkerRegion - elif isinstance(region, SoCLinkerRegion): - if name in self.masters.keys(): - self.logger.error("{} already declared as Linker Region:".format(colorer(name, color="red"))) - self.logger.error(self) - raise - self.ld_regions[name] = region - overlap = self.check_regions_overlap(self.ld_regions) - if overlap is not None: - self.logger.error("Linker Region overlap between {} and {}:".format( - colorer(overlap[0], color="red"), - colorer(overlap[1], color="red"))) - self.logger.error(str(self.regions[overlap[0]])) - self.logger.error(str(self.regions[overlap[1]])) - raise - self.logger.info("{} Region {} {}.".format( - colorer(name, color="underline"), - colorer("added", color="green"), - str(region))) # Check if SoCRegion elif isinstance(region, SoCRegion): # If no origin specified, allocate region. @@ -257,15 +236,16 @@ class SoCBusHandler(Module): self.logger.error("Not enough Address Space to allocate Region") raise - def check_regions_overlap(self, regions): + def check_regions_overlap(self, regions, check_linker=False): i = 0 while i < len(regions): n0 = list(regions.keys())[i] r0 = regions[n0] for n1 in list(regions.keys())[i+1:]: r1 = regions[n1] - if isinstance(r0, SoCLinkerRegion) or isinstance(r1, SoCLinkerRegion): - continue + if r0.linker or r1.linker: + if not check_linker: + continue if r0.origin >= (r1.origin + r1.size): continue if r1.origin >= (r0.origin + r0.size): @@ -351,10 +331,6 @@ class SoCBusHandler(Module): io_regions = {k: v for k, v in sorted(self.io_regions.items(), key=lambda item: item[1].origin)} for name, region in io_regions.items(): r += colorer(name, color="underline") + " "*(20-len(name)) + ": " + str(region) + "\n" - r += "Linker Regions: ({})\n".format(len(self.ld_regions.keys())) if len(self.ld_regions.keys()) else "" - ld_regions = {k: v for k, v in sorted(self.ld_regions.items(), key=lambda item: item[1].origin)} - for name, region in ld_regions.items(): - r += colorer(name, color="underline") + " "*(20-len(name)) + ": " + str(region) + "\n" r += "Bus Regions: ({})\n".format(len(self.regions.keys())) if len(self.regions.keys()) else "" regions = {k: v for k, v in sorted(self.regions.items(), key=lambda item: item[1].origin)} for name, region in regions.items(): @@ -448,7 +424,7 @@ class SoCCSRHandler(SoCLocHandler): if data_width not in self.supported_data_width: self.logger.error("Unsupported data_width: {} supporteds: {:s}".format( colorer(data_width, color="red"), - colorer(", ".join(str(x) for x in self.supported_data_width)), color="green")) + colorer(", ".join(str(x) for x in self.supported_data_width), color="green"))) raise # Check Address Width @@ -819,7 +795,7 @@ class SoC(Module): # SoC CPU Check ---------------------------------------------------------------------------- if not isinstance(self.cpu, cpu.CPUNone): for name in ["rom", "sram"]: - if name not in list(self.bus.regions.keys()) + list(self.bus.ld_regions.keys()): + if name not in self.bus.regions.keys(): self.logger.error("CPU needs {} Region to be defined as Bus or Linker Region.".format( colorer(name, color="red"))) self.logger.error(self.bus) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 16c58bfb5..a42ca2224 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -202,7 +202,9 @@ class SoCCore(LiteXSoC): self.bus.add_slave(name=wb_name, slave=interface) def add_memory_region(self, name, origin, length, type="cached"): - self.bus.add_region(name, SoCRegion(origin=origin, size=length, cached="cached" in type)) + self.bus.add_region(name, SoCRegion(origin=origin, size=length, + cached="cached" in type, + linker="linker" in type)) def register_mem(self, name, address, interface, size=0x10000000): self.bus.add_slave(name, interface, SoCRegion(origin=address, size=size))