hdl.ir: detect elaboratables that are created but not used.
Requres every elaboratable to inherit from Elaboratable, but still accepts ones that do not, with a warning. Fixes #3.
This commit is contained in:
parent
85ae99c1b4
commit
44711b7d08
22 changed files with 79 additions and 45 deletions
|
|
@ -9,7 +9,7 @@ from .ir import *
|
|||
from .xfrm import *
|
||||
|
||||
|
||||
__all__ = ["Module", "SyntaxError", "SyntaxWarning"]
|
||||
__all__ = ["SyntaxError", "SyntaxWarning", "Module"]
|
||||
|
||||
|
||||
class SyntaxError(Exception):
|
||||
|
|
@ -109,7 +109,7 @@ class FSM:
|
|||
return self.state == self.encoding[name]
|
||||
|
||||
|
||||
class Module(_ModuleBuilderRoot):
|
||||
class Module(_ModuleBuilderRoot, Elaboratable):
|
||||
def __init__(self):
|
||||
_ModuleBuilderRoot.__init__(self, self, depth=0)
|
||||
self.submodules = _ModuleBuilderSubmodules(self)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,30 @@
|
|||
import warnings
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from collections import defaultdict, OrderedDict
|
||||
import warnings
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
from ..tools import *
|
||||
from .ast import *
|
||||
from .cd import *
|
||||
|
||||
|
||||
__all__ = ["Fragment", "Instance", "DriverConflict"]
|
||||
__all__ = ["Elaboratable", "DriverConflict", "Fragment", "Instance"]
|
||||
|
||||
|
||||
class Elaboratable(metaclass=ABCMeta):
|
||||
def __new__(cls, *args, **kwargs):
|
||||
self = super().__new__(cls)
|
||||
self._Elaboratable__traceback = traceback.extract_stack()[:-1]
|
||||
self._Elaboratable__used = False
|
||||
return self
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, "_Elaboratable__used") and not self._Elaboratable__used:
|
||||
print("Elaboratable created but never used\n",
|
||||
"Traceback (most recent call last):\n",
|
||||
*traceback.format_list(self._Elaboratable__traceback),
|
||||
file=sys.stderr, sep="")
|
||||
|
||||
|
||||
class DriverConflict(UserWarning):
|
||||
|
|
@ -16,13 +34,22 @@ class DriverConflict(UserWarning):
|
|||
class Fragment:
|
||||
@staticmethod
|
||||
def get(obj, platform):
|
||||
if isinstance(obj, Fragment):
|
||||
return obj
|
||||
elif hasattr(obj, "elaborate"):
|
||||
frag = obj.elaborate(platform)
|
||||
else:
|
||||
raise AttributeError("Object '{!r}' cannot be elaborated".format(obj))
|
||||
return Fragment.get(frag, platform)
|
||||
while True:
|
||||
if isinstance(obj, Fragment):
|
||||
return obj
|
||||
elif isinstance(obj, Elaboratable):
|
||||
obj._Elaboratable__used = True
|
||||
obj = obj.elaborate(platform)
|
||||
elif hasattr(obj, "elaborate"):
|
||||
warnings.warn(
|
||||
message="Class {!r} is an elaboratable that does not explicitly inherit from "
|
||||
"Elaboratable; doing so would improve diagnostics"
|
||||
.format(type(obj)),
|
||||
category=RuntimeWarning,
|
||||
stacklevel=2)
|
||||
obj = obj.elaborate(platform)
|
||||
else:
|
||||
raise AttributeError("Object '{!r}' cannot be elaborated".format(obj))
|
||||
|
||||
def __init__(self):
|
||||
self.ports = SignalDict()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from .. import tracer
|
||||
from .ast import *
|
||||
from .ir import Instance
|
||||
from .ir import Elaboratable, Instance
|
||||
|
||||
|
||||
__all__ = ["Memory", "ReadPort", "WritePort", "DummyPort"]
|
||||
|
|
@ -70,7 +70,7 @@ class Memory:
|
|||
return self._array[index]
|
||||
|
||||
|
||||
class ReadPort:
|
||||
class ReadPort(Elaboratable):
|
||||
def __init__(self, memory, domain, synchronous, transparent):
|
||||
self.memory = memory
|
||||
self.domain = domain
|
||||
|
|
@ -135,7 +135,7 @@ class ReadPort:
|
|||
return f
|
||||
|
||||
|
||||
class WritePort:
|
||||
class WritePort(Elaboratable):
|
||||
def __init__(self, memory, domain, priority, granularity):
|
||||
self.memory = memory
|
||||
self.domain = domain
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ class FragmentTransformer:
|
|||
raise AttributeError("Object '{!r}' cannot be elaborated".format(value))
|
||||
|
||||
|
||||
class TransformedElaboratable:
|
||||
class TransformedElaboratable(Elaboratable):
|
||||
def __init__(self, elaboratable):
|
||||
assert hasattr(elaboratable, "elaborate")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue