From: whitequark Date: Fri, 21 Dec 2018 13:52:18 +0000 (+0000) Subject: hdl.ir: do not flatten instances or collect ports from their statements. X-Git-Tag: working~157 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fc7da1be2d7e30fb1eea570418d8660249f9987e;p=nmigen.git hdl.ir: do not flatten instances or collect ports from their statements. This results in absurd behavior for memories. --- diff --git a/nmigen/hdl/ir.py b/nmigen/hdl/ir.py index 0f6a9ec..018fa9a 100644 --- a/nmigen/hdl/ir.py +++ b/nmigen/hdl/ir.py @@ -99,6 +99,10 @@ class Fragment: driver_subfrags[signal].add((None, hierarchy)) for i, (subfrag, name) in enumerate(self.subfragments): + # Never flatten instances. + if isinstance(subfrag, Instance): + continue + # First, recurse into subfragments and let them detect driver conflicts as well. if name is None: name = "".format(i) @@ -237,22 +241,25 @@ 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), start=SignalSet()) - self_used = union((s._rhs_signals() for s in self.statements), start=SignalSet()) - for domain, _ in self.iter_sync(): - cd = self.domains[domain] - self_used.add(cd.clk) - if cd.rst is not None: - self_used.add(cd.rst) if isinstance(self, Instance): # Named ports contain signals for input, output and bidirectional ports. Output # and bidirectional ports are already added to the main port dict, however, for # input ports this has to be done lazily as any expression is valid there, including # ones with deferred resolution to signals, such as ClockSignal(). + self_driven = SignalSet() + self_used = SignalSet() for named_port_used in union((p._rhs_signals() for p in self.named_ports.values()), start=SignalSet()): if named_port_used not in self.ports: self_used.add(named_port_used) + else: + 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()) + for domain, _ in self.iter_sync(): + cd = self.domains[domain] + self_used.add(cd.clk) + if cd.rst is not None: + self_used.add(cd.rst) # Our input ports are all the signals we're using but not driving. This is an over- # approximation: some of these signals may be driven by our subfragments.