From 8c5ed4051dd74a6347af8d52f8e397eb53218ac4 Mon Sep 17 00:00:00 2001 From: Robin Ole Heinemann Date: Thu, 19 Sep 2024 11:01:06 +0200 Subject: [PATCH] hdl._nir: AssignmentList: fix comb_edges_to Only include the condition of a assignment in the comb edges if the assignment assigns to the bit in question. --- amaranth/hdl/_nir.py | 2 +- tests/test_hdl_ir.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/amaranth/hdl/_nir.py b/amaranth/hdl/_nir.py index 2cd4d28e2..c15247a1a 100644 --- a/amaranth/hdl/_nir.py +++ b/amaranth/hdl/_nir.py @@ -921,8 +921,8 @@ def __repr__(self): def comb_edges_to(self, bit): yield (self.default[bit], self.src_loc) for assign in self.assignments: - yield (assign.cond, assign.src_loc) if bit >= assign.start and bit < assign.start + len(assign.value): + yield (assign.cond, assign.src_loc) yield (assign.value[bit - assign.start], assign.src_loc) diff --git a/tests/test_hdl_ir.py b/tests/test_hdl_ir.py index 0bacb0c12..f515d7658 100644 --- a/tests/test_hdl_ir.py +++ b/tests/test_hdl_ir.py @@ -3571,6 +3571,30 @@ def test_cycle(self): r"$"): build_netlist(Fragment.get(m, None), []) + def test_assignment_cycle(self): + a = Signal(2) + m = Module() + + with m.If(a[0]): + m.d.comb += a[0].eq(1) + + with self.assertRaisesRegex(CombinationalCycle, + r"^Combinational cycle detected, path:\n" + r".*test_hdl_ir.py:\d+: cell Matches bit 0\n" + r".*test_hdl_ir.py:\d+: signal a bit 0\n" + r".*test_hdl_ir.py:\d+: cell AssignmentList bit 0\n" + r".*test_hdl_ir.py:\d+: cell PriorityMatch bit 0\n" + r"$"): + build_netlist(Fragment.get(m, None), []) + + m = Module() + + with m.If(a[0]): + m.d.comb += a[1].eq(1) + + # no cycle here, a[1] gets assigned and a[0] gets checked + build_netlist(Fragment.get(m, None), []) + class DomainLookupTestCase(FHDLTestCase): def test_domain_lookup(self):