Skip to content

Commit 8f83b6a

Browse files
committed
Verilog: fix for case statements
This fixes the synthesis of case statements where the default label is not the last.
1 parent 3afb034 commit 8f83b6a

File tree

3 files changed

+36
-20
lines changed

3 files changed

+36
-20
lines changed

regression/verilog/case/mini-alu.desc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
mini-alu.sv
33
--module alu --bound 0
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The "default:;" in the assertion block causes an invalid expression to be
10-
generated.

src/verilog/verilog_expr.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,14 +1090,19 @@ inline verilog_case_baset &to_verilog_case_base(exprt &expr)
10901090
return static_cast<verilog_case_baset &>(expr);
10911091
}
10921092

1093-
class verilog_case_itemt:public exprt
1093+
class verilog_case_itemt : public binary_exprt
10941094
{
10951095
public:
1096-
verilog_case_itemt():exprt("case_item")
1096+
verilog_case_itemt(exprt value, verilog_statementt statement)
1097+
: binary_exprt(std::move(value), ID_case_item, std::move(statement))
10971098
{
1098-
operands().resize(2);
10991099
}
1100-
1100+
1101+
bool is_default() const
1102+
{
1103+
return case_value().id() == ID_default;
1104+
}
1105+
11011106
inline exprt &case_value()
11021107
{
11031108
return op0();
@@ -1117,19 +1122,23 @@ class verilog_case_itemt:public exprt
11171122
{
11181123
return to_verilog_statement(op1());
11191124
}
1125+
1126+
protected:
1127+
using binary_exprt::op0;
1128+
using binary_exprt::op1;
11201129
};
11211130

11221131
inline const verilog_case_itemt &to_verilog_case_item(const exprt &expr)
11231132
{
11241133
PRECONDITION(expr.id() == ID_case_item);
1125-
binary_exprt::check(expr);
1134+
verilog_case_itemt::check(expr);
11261135
return static_cast<const verilog_case_itemt &>(expr);
11271136
}
11281137

11291138
inline verilog_case_itemt &to_verilog_case_item(exprt &expr)
11301139
{
11311140
PRECONDITION(expr.id() == ID_case_item);
1132-
binary_exprt::check(expr);
1141+
verilog_case_itemt::check(expr);
11331142
return static_cast<verilog_case_itemt &>(expr);
11341143
}
11351144

src/verilog/verilog_synthesis.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2866,6 +2866,7 @@ void verilog_synthesist::synth_case(
28662866
// we convert the rest to if-then-else
28672867
exprt start;
28682868
exprt *last_if=&start;
2869+
std::optional<verilog_statementt> default_case;
28692870

28702871
for(unsigned i=1; i<statement.operands().size(); i++)
28712872
{
@@ -2876,20 +2877,28 @@ void verilog_synthesist::synth_case(
28762877
throw errort() << "expected case_item";
28772878
}
28782879

2879-
if(e.operands().size()!=2)
2880+
auto &case_item = to_verilog_case_item(e);
2881+
2882+
// default?
2883+
if(case_item.is_default())
2884+
default_case = case_item.case_statement();
2885+
else
28802886
{
2881-
throw errort().with_location(e.source_location())
2882-
<< "case_item expected to have two operands";
2883-
}
2887+
exprt if_statement(ID_if);
2888+
if_statement.reserve_operands(3);
2889+
if_statement.add_to_operands(
2890+
synth_case_values(case_item.case_value(), case_operand));
2891+
if_statement.add_to_operands(case_item.case_statement());
28842892

2885-
exprt if_statement(ID_if);
2886-
if_statement.reserve_operands(3);
2887-
if_statement.add_to_operands(
2888-
synth_case_values(to_binary_expr(e).op0(), case_operand));
2889-
if_statement.add_to_operands(to_binary_expr(e).op1());
2893+
last_if->add_to_operands(std::move(if_statement));
2894+
last_if = &last_if->operands().back();
2895+
}
2896+
}
28902897

2891-
last_if->add_to_operands(std::move(if_statement));
2892-
last_if=&last_if->operands().back();
2898+
if(default_case.has_value())
2899+
{
2900+
// Attach the 'default' to the final 'if' as 'else'
2901+
last_if->add_to_operands(std::move(default_case.value()));
28932902
}
28942903

28952904
// synthesize the new if-then-else

0 commit comments

Comments
 (0)