fhdl.ir: move Fragment prepare logic from back.rtlil.
This commit is contained in:
parent
ac498414ab
commit
07c818e077
|
@ -518,17 +518,8 @@ def convert_fragment(builder, fragment, name, top):
|
||||||
return module.name, port_map
|
return module.name, port_map
|
||||||
|
|
||||||
|
|
||||||
def convert(fragment, ports=[]):
|
def convert(fragment, name="top", **kwargs):
|
||||||
fragment._propagate_domains(ensure_sync_exists=True)
|
fragment = fragment.prepare(**kwargs)
|
||||||
|
|
||||||
# Clock domain reset always takes priority over all other logic. To ensure this, insert
|
|
||||||
# decision trees for clock domain reset as the very last step before synthesis.
|
|
||||||
fragment = xfrm.ResetInserter({
|
|
||||||
cd.name: cd.rst for cd in fragment.domains.values() if cd.rst is not None
|
|
||||||
})(fragment)
|
|
||||||
|
|
||||||
ins, outs = fragment._propagate_ports(ports)
|
|
||||||
|
|
||||||
builder = _Builder()
|
builder = _Builder()
|
||||||
convert_fragment(builder, fragment, name="top", top=True)
|
convert_fragment(builder, fragment, name=name, top=True)
|
||||||
return str(builder)
|
return str(builder)
|
||||||
|
|
|
@ -728,6 +728,9 @@ class ValueKey:
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<{}.ValueKey {!r}>".format(__name__, self.value)
|
||||||
|
|
||||||
|
|
||||||
class ValueDict(MutableMapping):
|
class ValueDict(MutableMapping):
|
||||||
def __init__(self, pairs=()):
|
def __init__(self, pairs=()):
|
||||||
|
|
|
@ -48,6 +48,13 @@ class Fragment:
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
yield domain, signal
|
yield domain, signal
|
||||||
|
|
||||||
|
def iter_signals(self):
|
||||||
|
signals = ValueSet()
|
||||||
|
signals |= self.ports.keys()
|
||||||
|
for domain, domain_signals in self.drivers.items():
|
||||||
|
signals |= domain_signals
|
||||||
|
return signals
|
||||||
|
|
||||||
def add_domains(self, *domains):
|
def add_domains(self, *domains):
|
||||||
for domain in domains:
|
for domain in domains:
|
||||||
assert isinstance(domain, ClockDomain)
|
assert isinstance(domain, ClockDomain)
|
||||||
|
@ -124,12 +131,19 @@ class Fragment:
|
||||||
|
|
||||||
subfrag._propagate_domains_down()
|
subfrag._propagate_domains_down()
|
||||||
|
|
||||||
def _propagate_domains(self, ensure_sync_exists=False):
|
def _propagate_domains(self, ensure_sync_exists):
|
||||||
self._propagate_domains_up()
|
self._propagate_domains_up()
|
||||||
if ensure_sync_exists and not self.domains:
|
if ensure_sync_exists and not self.domains:
|
||||||
self.add_domains(ClockDomain("sync"))
|
self.add_domains(ClockDomain("sync"))
|
||||||
self._propagate_domains_down()
|
self._propagate_domains_down()
|
||||||
|
|
||||||
|
def _insert_domain_resets(self):
|
||||||
|
from .xfrm import ResetInserter
|
||||||
|
|
||||||
|
return ResetInserter({
|
||||||
|
cd.name: cd.rst for cd in self.domains.values() if cd.rst is not None
|
||||||
|
})(self)
|
||||||
|
|
||||||
def _propagate_ports(self, ports):
|
def _propagate_ports(self, ports):
|
||||||
# Collect all signals we're driving (on LHS of statements), and signals we're using
|
# Collect all signals we're driving (on LHS of statements), and signals we're using
|
||||||
# (on RHS of statements, or in clock domains).
|
# (on RHS of statements, or in clock domains).
|
||||||
|
@ -167,3 +181,12 @@ class Fragment:
|
||||||
self.add_ports(outs, kind="o")
|
self.add_ports(outs, kind="o")
|
||||||
|
|
||||||
return ins, outs
|
return ins, outs
|
||||||
|
|
||||||
|
def prepare(self, ports=(), ensure_sync_exists=True):
|
||||||
|
from .xfrm import FragmentTransformer
|
||||||
|
|
||||||
|
fragment = FragmentTransformer()(self)
|
||||||
|
fragment._propagate_domains(ensure_sync_exists)
|
||||||
|
fragment = fragment._insert_domain_resets()
|
||||||
|
fragment._propagate_ports(ports)
|
||||||
|
return fragment
|
||||||
|
|
|
@ -232,11 +232,11 @@ class FragmentDomainsTestCase(FHDLTestCase):
|
||||||
f1.add_domains(cd)
|
f1.add_domains(cd)
|
||||||
f1.add_subfragment(f2)
|
f1.add_subfragment(f2)
|
||||||
|
|
||||||
f1._propagate_domains()
|
f1._propagate_domains(ensure_sync_exists=False)
|
||||||
self.assertEqual(f1.domains, {"cd": cd})
|
self.assertEqual(f1.domains, {"cd": cd})
|
||||||
self.assertEqual(f2.domains, {"cd": cd})
|
self.assertEqual(f2.domains, {"cd": cd})
|
||||||
|
|
||||||
def test_propagate_default(self):
|
def test_propagate_ensure_sync(self):
|
||||||
f1 = Fragment()
|
f1 = Fragment()
|
||||||
f2 = Fragment()
|
f2 = Fragment()
|
||||||
f1.add_subfragment(f2)
|
f1.add_subfragment(f2)
|
||||||
|
|
Loading…
Reference in a new issue