Skip to content

Commit dc3a36b

Browse files
authored
Merge pull request #632 from diffblue/synthesis-constant
Verilog: extract `verilog_synthesist::synthesis_constant`
2 parents ada2100 + 7ee52ad commit dc3a36b

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

src/verilog/verilog_synthesis.cpp

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,41 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
405405

406406
/*******************************************************************\
407407
408+
Function: verilog_synthesist::synthesis_constant
409+
410+
Inputs:
411+
412+
Outputs:
413+
414+
Purpose:
415+
416+
\*******************************************************************/
417+
418+
std::optional<mp_integer>
419+
verilog_synthesist::synthesis_constant(const exprt &expr)
420+
{
421+
exprt synthesised = synth_expr(expr, symbol_statet::CURRENT);
422+
423+
exprt simplified = simplify_expr(synthesised, ns);
424+
425+
if(!simplified.is_constant())
426+
return {};
427+
428+
if(simplified.type().id() == ID_bool)
429+
return simplified.is_true() ? 1 : 0;
430+
431+
auto number = numeric_cast<mp_integer>(to_constant_expr(simplified));
432+
if(!number.has_value())
433+
DATA_INVARIANT_WITH_DIAGNOSTICS(
434+
false,
435+
"synthesis_constant expects a numerical type",
436+
simplified.pretty());
437+
438+
return number.value();
439+
}
440+
441+
/*******************************************************************\
442+
408443
Function: verilog_synthesist::value_mapt::guarded_expr
409444
410445
Inputs:
@@ -2947,22 +2982,23 @@ void verilog_synthesist::synth_for(const verilog_fort &statement)
29472982
synth_statement(statement.initialization());
29482983

29492984
while(true)
2950-
{
2951-
exprt tmp_guard=statement.condition();
2952-
tmp_guard = typecast_exprt{tmp_guard, bool_typet{}};
2953-
tmp_guard = synth_expr(tmp_guard, symbol_statet::CURRENT);
2954-
simplify(tmp_guard, ns);
2955-
2956-
if(!tmp_guard.is_constant())
2985+
{
2986+
DATA_INVARIANT(
2987+
statement.condition().type().id() == ID_bool,
2988+
"for condition must be Boolean");
2989+
2990+
auto guard_value_opt = synthesis_constant(statement.condition());
2991+
2992+
if(!guard_value_opt.has_value())
29572993
{
2958-
throw errort().with_location(
2959-
to_multi_ary_expr(statement).op1().source_location())
2960-
<< "synthesis failed to evaluate loop guard: `" << to_string(tmp_guard)
2961-
<< '\'';
2994+
throw errort().with_location(statement.condition().source_location())
2995+
<< "synthesis failed to evaluate loop guard: `"
2996+
<< to_string(statement.condition()) << '\'';
29622997
}
29632998

2964-
if(tmp_guard.is_false()) break;
2965-
2999+
if(guard_value_opt.value() == 0)
3000+
break;
3001+
29663002
// copy the body
29673003
verilog_statementt tmp_body=statement.body();
29683004
synth_statement(tmp_body);

src/verilog/verilog_synthesis_class.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ class verilog_synthesist:
177177

178178
exprt guarded_expr(exprt) const;
179179
};
180-
180+
181+
// expressions
182+
[[nodiscard]] std::optional<mp_integer> synthesis_constant(const exprt &);
183+
181184
exprt current_value(
182185
const value_mapt::mapt &map,
183186
const symbolt &symbol,

0 commit comments

Comments
 (0)