Skip to content

Commit 2a0e75f

Browse files
authored
Merge pull request #699 from diffblue/power2
Verilog: synthesis for power expressions with constant rhs
2 parents f56565d + 8861599 commit 2a0e75f

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
power2.sv
3+
--bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module main;
2+
3+
// powers with constant rhs
4+
property1: assert final (3**0==1);
5+
property2: assert final (3**1==3);
6+
property3: assert final ((-3)**1==-3);
7+
property4: assert final (3**3==27);
8+
9+
endmodule

src/verilog/verilog_synthesis.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,31 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
244244
symbol_state);
245245
return expr;
246246
}
247+
else if(expr.id() == ID_power)
248+
{
249+
auto &power_expr = to_binary_expr(expr);
250+
DATA_INVARIANT(
251+
power_expr.lhs().type() == power_expr.type(),
252+
"power expression type consistency");
253+
power_expr.lhs() = synth_expr(power_expr.lhs(), symbol_state);
254+
power_expr.rhs() = synth_expr(power_expr.rhs(), symbol_state);
255+
auto rhs_int = numeric_cast<std::size_t>(power_expr.rhs());
256+
if(rhs_int.has_value())
257+
{
258+
if(*rhs_int == 0)
259+
return from_integer(1, expr.type());
260+
else if(*rhs_int == 1)
261+
return power_expr.lhs();
262+
else // >= 2
263+
{
264+
auto factors = exprt::operandst{rhs_int.value(), power_expr.lhs()};
265+
// would prefer appropriate mult_exprt constructor
266+
return multi_ary_exprt{ID_mult, factors, expr.type()};
267+
}
268+
}
269+
else
270+
return expr;
271+
}
247272
else if(expr.id()==ID_typecast)
248273
{
249274
{

0 commit comments

Comments
 (0)