ir: allow non-Signals in Instance ports.

This commit is contained in:
whitequark 2018-12-20 23:38:01 +00:00
parent 8cc900c4ef
commit f7fec804ec
5 changed files with 43 additions and 25 deletions

View file

@ -15,10 +15,6 @@ class DriverConflict(UserWarning):
class Fragment:
def __init__(self):
self.black_box = None
self.port_names = SignalDict()
self.parameters = OrderedDict()
self.ports = SignalDict()
self.drivers = OrderedDict()
self.statements = []
@ -241,8 +237,11 @@ class Fragment:
def _propagate_ports(self, ports):
# Collect all signals we're driving (on LHS of statements), and signals we're using
# (on RHS of statements, or in clock domains).
self_driven = union(s._lhs_signals() for s in self.statements) or SignalSet()
self_used = union(s._rhs_signals() for s in self.statements) or SignalSet()
self_driven = union((s._lhs_signals() for s in self.statements), start=SignalSet())
self_used = union((s._rhs_signals() for s in self.statements), start=SignalSet())
if isinstance(self, Instance):
self_used |= union((p._rhs_signals() for p in self.named_ports.values()),
start=SignalSet())
for domain, _ in self.iter_sync():
cd = self.domains[domain]
self_used.add(cd.clk)
@ -296,18 +295,24 @@ class Fragment:
class Instance(Fragment):
def __init__(self, type, **kwargs):
super().__init__()
self.black_box = type
self.type = type
self.parameters = OrderedDict()
self.named_ports = OrderedDict()
for kw, arg in kwargs.items():
if kw.startswith("p_"):
self.parameters[kw[2:]] = arg
elif kw.startswith("i_"):
self.port_names[arg] = kw[2:]
self.add_ports(arg, dir="i")
self.named_ports[kw[2:]] = arg
# Unlike with "o_" and "io_", "i_" ports can be assigned an arbitrary value;
# this includes unresolved ClockSignals etc. We rely on Fragment.prepare to
# populate fragment ports for these named ports.
elif kw.startswith("o_"):
self.port_names[arg] = kw[2:]
self.named_ports[kw[2:]] = arg
self.add_ports(arg, dir="o")
elif kw.startswith("io_"):
self.port_names[arg] = kw[3:]
self.named_ports[kw[3:]] = arg
self.add_ports(arg, dir="io")
else:
raise NameError("Instance argument '{}' does not start with p_, i_, o_, or io_"

View file

@ -179,6 +179,13 @@ class FragmentTransformer:
for port, dir in fragment.ports.items():
new_fragment.add_ports(port, dir=dir)
def map_named_ports(self, fragment, new_fragment):
if hasattr(self, "on_value"):
for name, value in fragment.named_ports.items():
new_fragment.named_ports[name] = self.on_value(value)
else:
new_fragment.named_ports = OrderedDict(fragment.named_ports.items())
def map_domains(self, fragment, new_fragment):
for domain in fragment.iter_domains():
new_fragment.add_domains(fragment.domains[domain])
@ -194,10 +201,12 @@ class FragmentTransformer:
new_fragment.add_driver(signal, domain)
def on_fragment(self, fragment):
new_fragment = Fragment()
new_fragment.black_box = fragment.black_box
new_fragment.parameters = OrderedDict(fragment.parameters)
new_fragment.port_names = SignalDict(fragment.port_names.items())
if isinstance(fragment, Instance):
new_fragment = Instance(fragment.type)
new_fragment.parameters = OrderedDict(fragment.parameters)
self.map_named_ports(fragment, new_fragment)
else:
new_fragment = Fragment()
self.map_ports(fragment, new_fragment)
self.map_subfragments(fragment, new_fragment)
self.map_domains(fragment, new_fragment)