diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index ee3b756b4..0c80a88d4 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -6,8 +6,9 @@ # This file is Copyright (c) 2019 Gabriel L. Somlo # SPDX-License-Identifier: BSD-2-Clause -import logging +import sys import time +import logging import datetime from math import log2, ceil @@ -44,6 +45,12 @@ def build_time(with_time=True): fmt = "%Y-%m-%d %H:%M:%S" if with_time else "%Y-%m-%d" return datetime.datetime.fromtimestamp(time.time()).strftime(fmt) +# SoCError ----------------------------------------------------------------------------------------- + +class SoCError(Exception): + def __init__(self): + sys.stderr = None # Error already described, avoid traceback/exception. + # SoCConstant -------------------------------------------------------------------------------------- def SoCConstant(value): @@ -72,7 +79,7 @@ class SoCRegion: if (origin & (size - 1)) != 0: self.logger.error("Origin needs to be aligned on size:") self.logger.error(self) - raise + raise SoCError() if (origin == 0) and (size == 2**bus.address_width): return lambda a : True origin >>= int(log2(bus.data_width//8)) # bytes to words aligned. @@ -118,7 +125,7 @@ class SoCBusHandler(Module): colorer("Bus standard", color="red"), colorer(standard), colorer(", ".join(self.supported_standard)))) - raise + raise SoCError() # Check Bus Data Width. if data_width not in self.supported_data_width: @@ -126,7 +133,7 @@ class SoCBusHandler(Module): colorer("Data Width", color="red"), colorer(data_width), colorer(", ".join(str(x) for x in self.supported_data_width)))) - raise + raise SoCError() # Check Bus Address Width. if address_width not in self.supported_address_width: @@ -134,7 +141,7 @@ class SoCBusHandler(Module): colorer("Address Width", color="red"), colorer(address_width), colorer(", ".join(str(x) for x in self.supported_address_width)))) - raise + raise SoCError() # Create Bus self.standard = standard @@ -163,7 +170,7 @@ class SoCBusHandler(Module): 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 + raise SoCError() # Check if is SoCIORegion. if isinstance(region, SoCIORegion): self.io_regions[name] = region @@ -176,7 +183,7 @@ class SoCBusHandler(Module): colorer(overlap[1]))) self.logger.error(str(self.io_regions[overlap[0]])) self.logger.error(str(self.io_regions[overlap[1]])) - raise + raise SoCError() self.logger.info("{} Region {} at {}.".format( colorer(name, color="underline"), colorer("added", color="green"), @@ -198,7 +205,7 @@ class SoCBusHandler(Module): colorer("not in IO region", color="red"), str(region))) self.logger.error(self) - raise + raise SoCError() self.regions[name] = region # Check for overlab with others IO regions. overlap = self.check_regions_overlap(self.regions) @@ -209,14 +216,14 @@ class SoCBusHandler(Module): colorer(overlap[1]))) self.logger.error(str(self.regions[overlap[0]])) self.logger.error(str(self.regions[overlap[1]])) - raise + raise SoCError() self.logger.info("{} Region {} at {}.".format( colorer(name, color="underline"), colorer("allocated" if allocated else "added", color="cyan" if allocated else "green"), str(region))) else: self.logger.error("{} is not a supported Region.".format(colorer(name, color="red"))) - raise + raise SoCError() def alloc_region(self, name, size, cached=True): self.logger.info("Allocating {} Region of size {}...".format( @@ -251,7 +258,7 @@ class SoCBusHandler(Module): return candidate self.logger.error("Not enough Address Space to allocate Region.") - raise + raise SoCError() def check_regions_overlap(self, regions, check_linker=False): i = 0 @@ -350,7 +357,7 @@ class SoCBusHandler(Module): colorer(name), colorer("already declared", color="red"))) self.logger.error(self) - raise + raise SoCError() master = self.add_adapter(name, master, "m2s") self.masters[name] = master self.logger.info("{} {} as Bus Master.".format( @@ -365,7 +372,7 @@ class SoCBusHandler(Module): colorer("specify", color="red"), colorer("name"), colorer("region"))) - raise + raise SoCError() if no_name: name = "slave{:d}".format(len(self.slaves)) if no_region: @@ -374,7 +381,7 @@ class SoCBusHandler(Module): self.logger.error("{} Region {}.".format( colorer(name), colorer("not found", color="red"))) - raise + raise SoCError() else: self.add_region(name, region) if name in self.slaves.keys(): @@ -382,7 +389,7 @@ class SoCBusHandler(Module): colorer(name), colorer("already declared", color="red"))) self.logger.error(self) - raise + raise SoCError() slave = self.add_adapter(name, slave, "s2m") self.slaves[name] = slave self.logger.info("{} {} as Bus Slave.".format( @@ -427,12 +434,12 @@ class SoCLocHandler(Module): self.logger.error("{} {} name {}.".format( colorer(name), self.name, colorer("already used", color="red"))) self.logger.error(self) - raise + raise SoCError() if n in self.locs.values(): self.logger.error("{} {} Location {}.".format( colorer(n), self.name, colorer("already used", color="red"))) self.logger.error(self) - raise + raise SoCError() if n is None: allocated = True n = self.alloc(name) @@ -442,14 +449,14 @@ class SoCLocHandler(Module): colorer(n), self.name, colorer("positive", color="red"))) - raise + raise SoCError() if n > self.n_locs: self.logger.error("{} {} Location {} than maximum: {}.".format( colorer(n), self.name, colorer("higher", color="red"), colorer(self.n_locs))) - raise + raise SoCError() self.locs[name] = n else: n = self.locs[name] @@ -466,7 +473,7 @@ class SoCLocHandler(Module): return n self.logger.error("Not enough Locations.") self.logger.error(self) - raise + raise SoCError() # Str ------------------------------------------------------------------------------------------ def __str__(self): @@ -500,7 +507,7 @@ class SoCCSRHandler(SoCLocHandler): colorer("Data Width", color="red"), colorer(data_width), colorer(", ".join(str(x) for x in self.supported_data_width)))) - raise + raise SoCError() # Check CSR Address Width. if address_width not in self.supported_address_width: @@ -508,7 +515,7 @@ class SoCCSRHandler(SoCLocHandler): colorer("Address Width", color="red"), colorer(address_width), colorer(", ".join(str(x) for x in self.supported_address_width)))) - raise + raise SoCError() # Check CSR Alignment. if alignment not in self.supported_alignment: @@ -516,13 +523,13 @@ class SoCCSRHandler(SoCLocHandler): colorer("Alignment", color="red"), colorer(alignment), colorer(", ".join(str(x) for x in self.supported_alignment)))) - raise + raise SoCError() if data_width > alignment: self.logger.error("Alignment ({}) {} Data Width ({})".format( colorer(alignment), colorer("should be >=", color="red"), colorer(data_width))) - raise + raise SoCError() # Check CSR Paging. if paging not in self.supported_paging: @@ -530,7 +537,7 @@ class SoCCSRHandler(SoCLocHandler): colorer("Paging", color="red"), colorer("{:x}".format(paging)), colorer(", ".join("0x{:x}".format(x) for x in self.supported_paging)))) - raise + raise SoCError() # Check CSR Ordering. if ordering not in self.supported_ordering: @@ -538,7 +545,7 @@ class SoCCSRHandler(SoCLocHandler): colorer("Ordering", color="red"), colorer("{}".format(paging)), colorer(", ".join("{}".format(x) for x in self.supported_ordering)))) - raise + raise SoCError() # Create CSR Handler. self.data_width = data_width @@ -572,14 +579,14 @@ class SoCCSRHandler(SoCLocHandler): colorer(name), colorer("already declared", color="red"))) self.logger.error(self) - raise + raise SoCError() if master.data_width != self.data_width: self.logger.error("{} Master/Handler Data Width {} ({} vs {}).".format( colorer(name), colorer("missmatch", color="red"), colorer(master.data_width), colorer(self.data_width))) - raise + raise SoCError() self.masters[name] = master self.logger.info("{} {} as CSR Master.".format( colorer(name, color="underline"), @@ -625,7 +632,7 @@ class SoCIRQHandler(SoCLocHandler): if n_irqs > 32: self.logger.error("Unsupported IRQs number: {} supporteds: {:s}".format( colorer(n_irqs, color="red"), colorer("Up to 32", color="green"))) - raise + raise SoCError() # Create IRQ Handler. self.logger.info("IRQ Handler (up to {} Locations).".format(colorer(n_irqs))) @@ -648,7 +655,7 @@ class SoCIRQHandler(SoCLocHandler): else: self.logger.error("Attempted to add {} IRQ but SoC does {}.".format( colorer(name), colorer("not support IRQs", color="red"))) - raise + raise SoCError() # Str ------------------------------------------------------------------------------------------ def __str__(self): @@ -773,7 +780,7 @@ class SoC(Module): self.logger.error("{} SubModule already {}.".format( colorer(name), colorer("declared", color="red"))) - raise + raise SoCError() def add_constant(self, name, value=None): name = name.upper() @@ -781,7 +788,7 @@ class SoC(Module): self.logger.error("{} Constant already {}.".format( colorer(name), colorer("declared", color="red"))) - raise + raise SoCError() self.constants[name] = SoCConstant(value) def add_config(self, name, value=None): @@ -799,7 +806,7 @@ class SoC(Module): colorer(periph), colorer("used", color="red"))) self.logger.error(self.bus) - raise + raise SoCError() # Check for required Memory Regions. for mem in ["rom", "sram"]: @@ -808,7 +815,7 @@ class SoC(Module): colorer(mem), colorer("defined", color="red"))) self.logger.error(self.bus) - raise + raise SoCError() # SoC Main Components -------------------------------------------------------------------------- def add_controller(self, name="ctrl", **kwargs): @@ -875,21 +882,21 @@ class SoC(Module): colorer(name), colorer("not supported", color="red"), colorer(", ".join(cpu.CPUS.keys())))) - raise + raise SoCError() # Add CPU. if name == "external" and cls is None: self.logger.error("{} CPU requires {} to be specified.".format( colorer(name), colorer("cpu_cls", color="red"))) - raise + raise SoCError() cpu_cls = cls if cls is not None else cpu.CPUS[name] if variant not in cpu_cls.variants: self.logger.error("{} CPU variant {}, supporteds: {}.".format( colorer(variant), colorer("not supported", color="red"), colorer(", ".join(cpu_cls.variants)))) - raise + raise SoCError() self.check_if_exists("cpu") self.submodules.cpu = cpu_cls(self.platform, variant) @@ -1089,7 +1096,7 @@ class SoC(Module): colorer("reset address 0x{:08x}".format(self.cpu.reset_address)), colorer("defined", color="red"))) self.logger.error(self.bus) - raise + raise SoCError() # SoC IRQ Interconnect --------------------------------------------------------------------- if hasattr(self, "cpu") and hasattr(self.cpu, "interrupt"): @@ -1107,7 +1114,7 @@ class SoC(Module): self.logger.error("EventManager {} in {} SubModule.".format( colorer("not found", color="red"), colorer(name))) - raise + raise SoCError() self.comb += self.cpu.interrupt[loc].eq(ev.irq) self.add_constant(name + "_INTERRUPT", loc)