From: whitequark Date: Mon, 19 Aug 2019 21:32:48 +0000 (+0000) Subject: hdl.xfrm: lower resets in DomainLowerer as well. X-Git-Tag: locally_working~22 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69d36dc139c54b1d6153055aee2b83ddef262ad9;p=nmigen.git hdl.xfrm: lower resets in DomainLowerer as well. Changed in preparation for introducing local clock domains. Also makes elaboration about 15% faster. --- diff --git a/nmigen/hdl/ir.py b/nmigen/hdl/ir.py index 79e308a..c21bc82 100644 --- a/nmigen/hdl/ir.py +++ b/nmigen/hdl/ir.py @@ -386,12 +386,6 @@ class Fragment: self._propagate_domains_down() return new_domains - def _insert_domain_resets(self): - from .xfrm import ResetInserter - - resets = {cd.name: cd.rst for cd in self.domains.values() if cd.rst is not None} - return ResetInserter(resets)(self) - def _lower_domain_signals(self): from .xfrm import DomainLowerer @@ -543,7 +537,6 @@ class Fragment: fragment = SampleLowerer()(self) new_domains = fragment._propagate_domains(missing_domain) fragment._resolve_hierarchy_conflicts() - fragment = fragment._insert_domain_resets() fragment = fragment._lower_domain_signals() if ports is None: fragment._propagate_ports(ports=(), all_undef_as_ports=True) diff --git a/nmigen/hdl/xfrm.py b/nmigen/hdl/xfrm.py index 2fdf707..d143b41 100644 --- a/nmigen/hdl/xfrm.py +++ b/nmigen/hdl/xfrm.py @@ -488,22 +488,34 @@ class DomainLowerer(FragmentTransformer, ValueTransformer, StatementTransformer) return not isinstance(value, (ClockSignal, ResetSignal)) def on_ClockSignal(self, value): - cd = self._resolve(value.domain, value) - return cd.clk + domain = self._resolve(value.domain, value) + return domain.clk def on_ResetSignal(self, value): - cd = self._resolve(value.domain, value) - if cd.rst is None: + domain = self._resolve(value.domain, value) + if domain.rst is None: if value.allow_reset_less: return Const(0) else: raise DomainError("Signal {!r} refers to reset of reset-less domain '{}'" .format(value, value.domain)) - return cd.rst + return domain.rst + + def _insert_resets(self, fragment): + for domain_name, signals in fragment.drivers.items(): + if domain_name is None: + continue + domain = fragment.domains[domain_name] + if domain.rst is None: + continue + stmts = [signal.eq(Const(signal.reset, signal.nbits)) + for signal in signals if not signal.reset_less] + fragment.add_statements(Switch(domain.rst, {1: stmts})) def on_fragment(self, fragment): self.domains = fragment.domains new_fragment = super().on_fragment(fragment) + self._insert_resets(new_fragment) return new_fragment diff --git a/nmigen/test/test_hdl_xfrm.py b/nmigen/test/test_hdl_xfrm.py index 1a2a6c8..d67dc6f 100644 --- a/nmigen/test/test_hdl_xfrm.py +++ b/nmigen/test/test_hdl_xfrm.py @@ -150,9 +150,10 @@ class DomainLowererTestCase(FHDLTestCase): """) def test_lower_drivers(self): + sync = ClockDomain() pix = ClockDomain() f = Fragment() - f.add_domains(pix) + f.add_domains(sync, pix) f.add_driver(ClockSignal("pix"), None) f.add_driver(ResetSignal("pix"), "sync") @@ -597,6 +598,7 @@ class UserValueTestCase(FHDLTestCase): def test_lower(self): sync = ClockDomain() f = Fragment() + f.add_domains(sync) f.add_statements( self.uv.eq(1) ) @@ -611,5 +613,8 @@ class UserValueTestCase(FHDLTestCase): (switch (sig c) (case 1 (eq (sig s) (const 1'd0))) ) + (switch (sig rst) + (case 1 (eq (sig s) (const 1'd0))) + ) ) """)