From 7473fcf93906bfe43d6eb155ab90acd0a9317eab Mon Sep 17 00:00:00 2001 From: nella Date: Mon, 15 Jun 2026 14:17:02 +0200 Subject: [PATCH] Add latch inference msg severity option. --- passes/proc/proc.cc | 13 ++++++++++- passes/proc/proc_dlatch.cc | 47 ++++++++++++++++++++++++++++++++++---- techlibs/common/synth.cc | 12 ++++++++-- tests/proc/proc_latches.ys | 32 ++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 tests/proc/proc_latches.ys diff --git a/passes/proc/proc.cc b/passes/proc/proc.cc index c18651d5e..d781d9047 100644 --- a/passes/proc/proc.cc +++ b/passes/proc/proc.cc @@ -69,10 +69,14 @@ struct ProcPass : public Pass { log(" -noopt\n"); log(" Will omit the opt_expr pass.\n"); log("\n"); + log(" -latches \n"); + log(" controls how the inference of a latch is reported.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { std::string global_arst; + std::string latches; bool ifxmode = false; bool nomux = false; bool noopt = false; @@ -104,6 +108,10 @@ struct ProcPass : public Pass { norom = true; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -121,7 +129,10 @@ struct ProcPass : public Pass { Pass::call(design, "proc_rom"); if (!nomux) Pass::call(design, ifxmode ? "proc_mux -ifx" : "proc_mux"); - Pass::call(design, "proc_dlatch"); + if (latches.empty()) + Pass::call(design, "proc_dlatch"); + else + Pass::call(design, "proc_dlatch -latches " + latches); Pass::call(design, "proc_dff"); Pass::call(design, "proc_memwr"); Pass::call(design, "proc_clean"); diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index 50e64f482..aaf5d15e7 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -345,7 +345,13 @@ struct proc_dlatch_db_t } }; -void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) +enum LatchPolicy { + POLICY_AUTO, + POLICY_WARN, + POLICY_ERROR +}; + +void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc, LatchPolicy policy) { RTLIL::SigSig latches_bits, nolatches_bits; dict latches_out_in; @@ -443,6 +449,12 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) if (proc->get_bool_attribute(ID::always_comb)) log_error("Latch inferred for signal `%s.%s' from always_comb process `%s.%s'.\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); + else if (policy == POLICY_ERROR) + log_error("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n", + db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell); + else if (policy == POLICY_WARN) + log_warning("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n", + db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell); else log("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell); @@ -458,22 +470,49 @@ struct ProcDlatchPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" proc_dlatch [selection]\n"); + log(" proc_dlatch [options] [selection]\n"); log("\n"); log("This pass identifies latches in the processes and converts them to\n"); log("d-type latches.\n"); log("\n"); + log(" -latches \n"); + log(" controls how the inference of a latch is reported. Alternatively, one\n"); + log(" can use the 'proc.latches' scratchpad variable.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { log_header(design, "Executing PROC_DLATCH pass (convert process syncs to latches).\n"); - extra_args(args, 1, design); + std::string policy_str; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + policy_str = args[++argidx]; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (policy_str.empty()) + policy_str = design->scratchpad_get_string("proc.latches", "warn"); + + LatchPolicy policy; + if (policy_str == "auto") + policy = POLICY_AUTO; + else if (policy_str == "warn") + policy = POLICY_WARN; + else if (policy_str == "error") + policy = POLICY_ERROR; + else + log_cmd_error("Invalid value '%s' for -latches (expected auto|warn|error).\n", policy_str.c_str()); for (auto mod : design->all_selected_modules()) { proc_dlatch_db_t db(mod); for (auto proc : mod->selected_processes()) - proc_dlatch(db, proc); + proc_dlatch(db, proc, policy); db.fixup_muxes(); } } diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 00d884107..3656218c5 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -78,6 +78,9 @@ struct SynthPass : public ScriptPass { log(" -nordff\n"); log(" passed to 'memory'. prohibits merging of FFs into memory read ports\n"); log("\n"); + log(" -latches \n"); + log(" controls how the inference of a latch is reported.\n"); + log("\n"); log(" -noshare\n"); log(" do not run SAT-based resource sharing\n"); log("\n"); @@ -111,7 +114,7 @@ struct SynthPass : public ScriptPass { log("\n"); } - string top_module, fsm_opts, memory_opts, abc; + string top_module, fsm_opts, memory_opts, abc, latches_opt; bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth, arith_tree, hieropt, relative_share; int lut; std::vector techmap_maps; @@ -121,6 +124,7 @@ struct SynthPass : public ScriptPass { top_module.clear(); fsm_opts.clear(); memory_opts.clear(); + latches_opt.clear(); autotop = false; flatten = false; @@ -200,6 +204,10 @@ struct SynthPass : public ScriptPass { memory_opts += " -nordff"; continue; } + if (args[argidx] == "-latches" && argidx + 1 < args.size()) { + latches_opt += " -latches " + args[++argidx]; + continue; + } if (args[argidx] == "-noshare") { noshare = true; continue; @@ -276,7 +284,7 @@ struct SynthPass : public ScriptPass { } if (check_label("coarse")) { - run("proc"); + run("proc" + latches_opt); if (flatten || help_mode) { run("check"); run("flatten", " (if -flatten)"); diff --git a/tests/proc/proc_latches.ys b/tests/proc/proc_latches.ys new file mode 100644 index 000000000..c8334dc8e --- /dev/null +++ b/tests/proc/proc_latches.ys @@ -0,0 +1,32 @@ +# warn +read_verilog <