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.
This commit is contained in:
Martin Povišer 2024-01-06 16:44:36 +01:00
parent 1ddb0892c1
commit 82fca50309
1 changed files with 9 additions and 3 deletions

View File

@ -1988,12 +1988,10 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw
dump_sigspec(f, sw->signal); dump_sigspec(f, sw->signal);
f << stringf(")\n"); f << stringf(")\n");
bool got_default = false;
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) { 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); dump_attributes(f, indent + " ", (*it)->attributes, '\n', /*modattr=*/false, /*regattr=*/false, /*as_comment=*/true);
if ((*it)->compare.size() == 0) { if ((*it)->compare.size() == 0) {
if (got_default)
continue;
f << stringf("%s default", indent.c_str()); f << stringf("%s default", indent.c_str());
got_default = true; got_default = true;
} else { } else {
@ -2006,6 +2004,14 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw
} }
f << stringf(":\n"); f << stringf(":\n");
dump_case_body(f, indent + " ", *it); 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()) { if (sw->cases.empty()) {