From 6f111118de5faee1c1cfba0aba1955756adae7bb Mon Sep 17 00:00:00 2001 From: junyao Date: Tue, 26 May 2026 00:56:07 +0800 Subject: [PATCH] proc: ignore nosync temporaries in always_latch checks --- passes/proc/proc_dlatch.cc | 11 +++++++++-- tests/various/svalways.sh | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index 5e07dbcb0..50e64f482 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -395,10 +395,17 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) int offset = 0; for (auto chunk : nolatches_bits.first.chunks()) { SigSpec lhs = chunk, rhs = nolatches_bits.second.extract(offset, chunk.width); - if (proc->get_bool_attribute(ID::always_latch)) + bool is_nosync = true; + for (auto bit : lhs) + if (bit.wire == nullptr || !bit.wire->get_bool_attribute(ID::nosync)) { + is_nosync = false; + break; + } + + if (proc->get_bool_attribute(ID::always_latch) && !is_nosync) log_error("No latch inferred for signal `%s.%s' from always_latch process `%s.%s'.\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); - else + else if (!is_nosync) log("No latch inferred for signal `%s.%s' from process `%s.%s'.\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); for (auto &bit : lhs) { diff --git a/tests/various/svalways.sh b/tests/various/svalways.sh index b73786735..80cd234d4 100755 --- a/tests/various/svalways.sh +++ b/tests/various/svalways.sh @@ -18,6 +18,20 @@ always_latch endmodule EOT +# Good case: dynamic memory writes in always_latch create nosync mem2reg +# temporaries, but only the memory words themselves should be checked for +# latch inference. +${YOSYS} -f "verilog -sv" -qp proc - <