From 82fca5030974f77a63b2cbd197a63ebadfeb9671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sat, 6 Jan 2024 16:44:36 +0100 Subject: [PATCH] write_verilog: Handle edge case with non-pruned processes This change only matters for processes that weren't processed by `proc_rmdead` for which follow-up cases after a default case are treated differently in Verilog and RTLIL semantics. --- backends/verilog/verilog_backend.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 735672a43..fd70695d3 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1988,12 +1988,10 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw dump_sigspec(f, sw->signal); f << stringf(")\n"); - bool got_default = false; for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) { + bool got_default = false; dump_attributes(f, indent + " ", (*it)->attributes, '\n', /*modattr=*/false, /*regattr=*/false, /*as_comment=*/true); if ((*it)->compare.size() == 0) { - if (got_default) - continue; f << stringf("%s default", indent.c_str()); got_default = true; } else { @@ -2006,6 +2004,14 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw } f << stringf(":\n"); dump_case_body(f, indent + " ", *it); + + if (got_default) { + // If we followed up the default with more cases the Verilog + // semantics would be to match those *before* the default, but + // the RTLIL semantics are to match those *after* the default + // (so they can never be selected). Exit now. + break; + } } if (sw->cases.empty()) {