Skip to content

Commit 0abed59

Browse files
authored
Merge pull request #472 from diffblue/immediate1
Verilog: procedural assert/assume/cover are guarded
2 parents 2eadf6e + acaedf7 commit 0abed59

File tree

7 files changed

+85
-10
lines changed

7 files changed

+85
-10
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE broken-smt-backend
2+
immediate2.sv
3+
--bound 0
4+
^\[main\.property\.1\] always main\.index < 10: PROVED up to bound 0$
5+
^\[main\.property\.2\] always 0: REFUTED$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
--

regression/verilog/SVA/immediate2.sv

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module main(input [31:0] index);
2+
3+
always @index begin
4+
if(index >= 10)
5+
assume(0);
6+
7+
// should pass
8+
assert(index < 10);
9+
10+
// should fail
11+
assert(0);
12+
end
13+
14+
endmodule

src/verilog/verilog_elaborate.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,10 @@ void verilog_typecheckt::collect_symbols(const verilog_lett &let)
611611

612612
void verilog_typecheckt::collect_symbols(const verilog_statementt &statement)
613613
{
614-
if(statement.id() == ID_verilog_immediate_assert)
614+
if(
615+
statement.id() == ID_verilog_immediate_assert ||
616+
statement.id() == ID_verilog_immediate_assume ||
617+
statement.id() == ID_verilog_immediate_cover)
615618
{
616619
}
617620
else if(

src/verilog/verilog_expr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,7 @@ inline const verilog_assume_statementt &
18451845
to_verilog_assume_statement(const verilog_statementt &statement)
18461846
{
18471847
PRECONDITION(
1848+
statement.id() == ID_verilog_immediate_assume ||
18481849
statement.id() == ID_verilog_assume_property ||
18491850
statement.id() == ID_verilog_smv_assume);
18501851
binary_exprt::check(statement);
@@ -1855,6 +1856,7 @@ inline verilog_assume_statementt &
18551856
to_verilog_assume_statement(verilog_statementt &statement)
18561857
{
18571858
PRECONDITION(
1859+
statement.id() == ID_verilog_immediate_assume ||
18581860
statement.id() == ID_verilog_assume_property ||
18591861
statement.id() == ID_verilog_smv_assume);
18601862
binary_exprt::check(statement);

src/verilog/verilog_synthesis.cpp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,26 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
111111

112112
/*******************************************************************\
113113
114+
Function: verilog_synthesist::value_mapt::guarded_expr
115+
116+
Inputs:
117+
118+
Outputs:
119+
120+
Purpose:
121+
122+
\*******************************************************************/
123+
124+
exprt verilog_synthesist::value_mapt::guarded_expr(exprt expr) const
125+
{
126+
if(guard.empty())
127+
return expr;
128+
else
129+
return implies_exprt{conjunction(guard), std::move(expr)};
130+
}
131+
132+
/*******************************************************************\
133+
114134
Function: verilog_synthesist::function_locality
115135
116136
Inputs:
@@ -1838,11 +1858,17 @@ void verilog_synthesist::synth_assert_cover(
18381858
// procedural concurrent -- evaluated just before the clock tick
18391859
cond = synth_expr(statement.condition(), symbol_statet::SYMBOL);
18401860
}
1861+
1862+
// add the guard
1863+
cond = guarded_expr(cond);
18411864
}
18421865
else // one of the 'always' variants
18431866
{
18441867
cond = synth_expr(statement.condition(), symbol_statet::CURRENT);
18451868

1869+
// add the guard
1870+
cond = guarded_expr(cond);
1871+
18461872
// assertions have an implicit 'always'
18471873
if(
18481874
statement.id() != ID_verilog_cover_property &&
@@ -1923,6 +1949,9 @@ void verilog_synthesist::synth_assume(
19231949

19241950
auto condition = synth_expr(statement.condition(), symbol_statet::CURRENT);
19251951

1952+
// add the guard
1953+
condition = guarded_expr(condition);
1954+
19261955
// add it as an invariant
19271956
invars.push_back(condition);
19281957
}
@@ -2138,9 +2167,9 @@ Function: verilog_synthesist::synth_if
21382167
void verilog_synthesist::synth_if(
21392168
const verilog_ift &statement)
21402169
{
2141-
auto if_operand = synth_expr(statement.cond(), symbol_statet::CURRENT);
2170+
auto if_cond = synth_expr(statement.cond(), symbol_statet::CURRENT);
21422171

2143-
if(if_operand.is_true())
2172+
if(if_cond.is_true())
21442173
{
21452174
synth_statement(statement.then_case());
21462175
return;
@@ -2151,8 +2180,12 @@ void verilog_synthesist::synth_if(
21512180

21522181
// produce new value maps
21532182
value_mapt true_map(*value_map), false_map(*value_map);
2183+
21542184
true_map.clear_changed();
2185+
true_map.guard.push_back(if_cond);
2186+
21552187
false_map.clear_changed();
2188+
false_map.guard.push_back(not_exprt{if_cond});
21562189

21572190
// 'then' case
21582191
{
@@ -2171,10 +2204,11 @@ void verilog_synthesist::synth_if(
21712204
value_map=old_map;
21722205

21732206
// merge current map
2174-
merge(if_operand, true_map.current, false_map.current, false, value_map->current);
2175-
2207+
merge(
2208+
if_cond, true_map.current, false_map.current, false, value_map->current);
2209+
21762210
// merge final map
2177-
merge(if_operand, true_map.final, false_map.final, true, value_map->final);
2211+
merge(if_cond, true_map.final, false_map.final, true, value_map->final);
21782212
}
21792213

21802214
/*******************************************************************\
@@ -2643,6 +2677,7 @@ void verilog_synthesist::synth_statement(
26432677
synth_assert_cover(to_verilog_assert_assume_cover_statement(statement));
26442678
}
26452679
else if(
2680+
statement.id() == ID_verilog_immediate_assume ||
26462681
statement.id() == ID_verilog_assume_property ||
26472682
statement.id() == ID_verilog_smv_assume)
26482683
{

src/verilog/verilog_synthesis_class.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Author: Daniel Kroening, [email protected]
1919
#include "verilog_symbol_table.h"
2020
#include "verilog_typecheck_base.h"
2121

22-
#include <cassert>
2322
#include <map>
2423
#include <set>
2524
#include <unordered_set>
@@ -166,22 +165,33 @@ class verilog_synthesist:
166165
current.changed.clear();
167166
final.changed.clear();
168167
}
168+
169+
// current guard
170+
exprt::operandst guard;
171+
172+
exprt guarded_expr(exprt) const;
169173
};
170174

171175
exprt current_value(
172176
const value_mapt::mapt &map,
173177
const symbolt &symbol,
174178
bool use_previous_assignments);
175-
179+
180+
exprt guarded_expr(exprt expr) const
181+
{
182+
PRECONDITION(value_map != NULL);
183+
return value_map->guarded_expr(expr);
184+
}
185+
176186
inline exprt current_value(const symbolt &symbol)
177187
{
178-
assert(value_map!=NULL);
188+
PRECONDITION(value_map != NULL);
179189
return current_value(value_map->current, symbol, false);
180190
}
181191

182192
inline exprt final_value(const symbolt &symbol)
183193
{
184-
assert(value_map!=NULL);
194+
PRECONDITION(value_map != NULL);
185195
return current_value(value_map->final, symbol, true);
186196
}
187197

src/verilog/verilog_typecheck.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,7 @@ void verilog_typecheckt::convert_statement(
14431443
convert_assert_cover(to_verilog_assert_assume_cover_statement(statement));
14441444
}
14451445
else if(
1446+
statement.id() == ID_verilog_immediate_assume ||
14461447
statement.id() == ID_verilog_assume_property ||
14471448
statement.id() == ID_verilog_smv_assume)
14481449
{

0 commit comments

Comments
 (0)