soc: Raise custom SoCError Exception and disable traceback/exception since already described.

This commit is contained in:
Florent Kermarrec 2021-10-12 08:35:14 +02:00
parent 975ec20d1e
commit 96cfb44851
1 changed files with 46 additions and 39 deletions

View File

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