From: whitequark Date: Sat, 22 Dec 2018 00:31:31 +0000 (+0000) Subject: hdl.ir: fix port propagation between siblings, in the other direction. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a1ebe2be4dce3c41b58051705ad9552dbf1991d6;p=nmigen.git hdl.ir: fix port propagation between siblings, in the other direction. --- diff --git a/nmigen/hdl/ir.py b/nmigen/hdl/ir.py index 1d6a79f..f9a4774 100644 --- a/nmigen/hdl/ir.py +++ b/nmigen/hdl/ir.py @@ -268,16 +268,20 @@ class Fragment: # an underapproximation: some of these signals may be driven by subfragments. outs = ports & self_driven - # Go through subfragments and refine our approximation for ports. + # Go through subfragments and refine our approximation for inputs. + for subfrag, name in self.subfragments: + # Refine the input port approximation: if a subfragment requires a signal as an input, + # and we aren't driving it, it has to be our input as well. + sub_ins, sub_outs, sub_inouts = subfrag._propagate_ports(ports=()) + ins |= sub_ins - self_driven + for subfrag, name in self.subfragments: # Always ask subfragments to provide all signals that are our inputs. # If the subfragment is not driving it, it will silently ignore it. sub_ins, sub_outs, sub_inouts = subfrag._propagate_ports(ports=ins | ports) - # Refine the input port approximation: if a subfragment is driving a signal, - # it is definitely not our input. But, if a subfragment requires a signal as an input, - # and we aren't driving it, it has to be our input as well. + # Refine the input port appropximation further: if any subfragment is driving a signal + # that we currently think should be our input, it shouldn't actually be our input. ins -= sub_outs - ins |= sub_ins - self_driven # Refine the output port approximation: if a subfragment is driving a signal, # and we're asked to provide it, we can provide it now. outs |= ports & sub_outs diff --git a/nmigen/test/test_hdl_ir.py b/nmigen/test/test_hdl_ir.py index 06c45e3..0df49ab 100644 --- a/nmigen/test/test_hdl_ir.py +++ b/nmigen/test/test_hdl_ir.py @@ -134,6 +134,23 @@ class FragmentPortsTestCase(FHDLTestCase): f1._propagate_ports(ports=()) self.assertEqual(f1.ports, SignalDict()) + def test_output_input_sibling(self): + f1 = Fragment() + f2 = Fragment() + f2.add_statements( + self.c2.eq(0) + ) + f2.add_driver(self.c2) + f1.add_subfragment(f2) + f3 = Fragment() + f3.add_statements( + self.c1.eq(self.c2) + ) + f1.add_subfragment(f3) + + f1._propagate_ports(ports=()) + self.assertEqual(f1.ports, SignalDict()) + def test_input_cd(self): sync = ClockDomain() f = Fragment()