lib.wiring: use tracer to obtain default Signature path and src_loc.

Fixes #987.
This commit is contained in:
Wanda 2023-12-07 10:13:10 +01:00 committed by Catherine
parent 7db049f37f
commit 422ba9ea51
2 changed files with 26 additions and 20 deletions

View file

@ -5,6 +5,7 @@ import inspect
import re
import warnings
from .. import tracer
from ..hdl.ast import Shape, ShapeCastable, Const, Signal, Value, ValueCastable
from ..hdl.ir import Elaboratable
from .._utils import final
@ -219,23 +220,27 @@ class SignatureMembers(Mapping):
if member.is_signature:
yield from member.signature.members.flatten(path=(*path, name))
def create(self, *, path=()):
def create(self, *, path=None, src_loc_at=0):
if path is None:
path = (tracer.get_var_name(depth=2 + src_loc_at, default="$signature"),)
attrs = {}
for name, member in self.items():
def create_value(path):
def create_value(path, *, src_loc_at):
if member.is_port:
return Signal(member.shape, reset=member.reset,
return Signal(member.shape, reset=member.reset, src_loc_at=1 + src_loc_at,
name="__".join(str(item) for item in path))
if member.is_signature:
return member.signature.create(path=path)
return member.signature.create(path=path, src_loc_at=1 + src_loc_at)
assert False # :nocov:
def create_dimensions(dimensions, *, path):
def create_dimensions(dimensions, *, path, src_loc_at):
if not dimensions:
return create_value(path)
return create_value(path, src_loc_at=1 + src_loc_at)
dimension, *rest_of_dimensions = dimensions
return [create_dimensions(rest_of_dimensions, path=(*path, index))
return [create_dimensions(rest_of_dimensions, path=(*path, index),
src_loc_at=1 + src_loc_at)
for index in range(dimension)]
attrs[name] = create_dimensions(member.dimensions, path=(*path, name))
attrs[name] = create_dimensions(member.dimensions, path=(*path, name),
src_loc_at=1 + src_loc_at)
return attrs
def __repr__(self):
@ -503,8 +508,8 @@ class Signature(metaclass=SignatureMeta):
continue
return result
def create(self, *, path=()):
return PureInterface(self, path=path)
def create(self, *, path=None, src_loc_at=0):
return PureInterface(self, path=path, src_loc_at=1 + src_loc_at)
def __repr__(self):
if type(self) is Signature:
@ -593,18 +598,19 @@ class FlippedSignature:
except AttributeError:
delattr(self.__unflipped, name)
def create(self, *, path=()):
return flipped(self.__unflipped.create(path=path))
def create(self, *args, path=None, src_loc_at=0, **kwargs):
return flipped(self.__unflipped.create(*args, path=path, src_loc_at=1 + src_loc_at,
**kwargs))
def __repr__(self):
return f"{self.__unflipped!r}.flip()"
class PureInterface:
def __init__(self, signature, *, path):
def __init__(self, signature, *, path=None, src_loc_at=0):
self.__dict__.update({
"signature": signature,
**signature.members.create(path=path)
**signature.members.create(path=path, src_loc_at=1 + src_loc_at)
})
def __repr__(self):
@ -864,7 +870,7 @@ class Component(Elaboratable):
if hasattr(self, name):
raise NameError(f"Cannot initialize attribute for signature member {name!r} "
f"because an attribute with the same name already exists")
self.__dict__.update(self.signature.members.create())
self.__dict__.update(self.signature.members.create(path=()))
@property
def signature(self):

View file

@ -279,9 +279,9 @@ class SignatureMembersTestCase(unittest.TestCase):
self.assertEqual(list(attrs.keys()), ["a", "s"])
self.assertIsInstance(attrs["a"], Signal)
self.assertEqual(attrs["a"].shape(), unsigned(1))
self.assertEqual(attrs["a"].name, "a")
self.assertEqual(attrs["a"].name, "attrs__a")
self.assertEqual(attrs["s"].b.shape(), unsigned(2))
self.assertEqual(attrs["s"].b.name, "s__b")
self.assertEqual(attrs["s"].b.name, "attrs__s__b")
def test_create_reset(self):
members = SignatureMembers({
@ -301,7 +301,7 @@ class SignatureMembersTestCase(unittest.TestCase):
for x in members["a"]:
for y in x:
self.assertIsInstance(y, Signal)
self.assertEqual(members["a"][1][2].name, "a__1__2")
self.assertEqual(members["a"][1][2].name, "members__a__1__2")
def test_repr(self):
self.assertEqual(repr(SignatureMembers({})),
@ -773,8 +773,8 @@ class FlippedInterfaceTestCase(unittest.TestCase):
return 69
class CustomSignature(Signature):
def create(self, *, path=()):
return CustomInterface(self, path=path)
def create(self, *, path=None, src_loc_at=0):
return CustomInterface(self, path=path, src_loc_at=1 + src_loc_at)
flipped_interface = CustomSignature({}).flip().create()
self.assertTrue(hasattr(flipped_interface, "custom_method"))