Skip to content

Commit 62673da

Browse files
committed
Fix fragment of SVA supported by word-level BMC
1) The simplifier is changed to stay within SVA when simplifying SVA. 2) The logic that recognises supported SVA is adjusted.
1 parent 1975e77 commit 62673da

File tree

4 files changed

+48
-50
lines changed

4 files changed

+48
-50
lines changed

src/temporal-logic/normalize_property.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Author: Daniel Kroening, [email protected]
99
#include "normalize_property.h"
1010

1111
#include <util/arith_tools.h>
12+
#include <util/mathematical_types.h>
1213
#include <util/std_expr.h>
1314

1415
#include <verilog/sva_expr.h>
@@ -75,9 +76,8 @@ exprt normalize_pre_implies(implies_exprt expr)
7576
exprt normalize_pre_sva_overlapped_implication(
7677
sva_overlapped_implication_exprt expr)
7778
{
78-
// Same as regular implication if lhs and rhs are not
79-
// sequences.
80-
if(!is_SVA_sequence(expr.lhs()) && !is_SVA_sequence(expr.rhs()))
79+
// Same as regular implication if the lhs is not a sequence.
80+
if(!is_SVA_sequence(expr.lhs()))
8181
return or_exprt{not_exprt{expr.lhs()}, expr.rhs()};
8282
else
8383
return std::move(expr);
@@ -86,9 +86,13 @@ exprt normalize_pre_sva_overlapped_implication(
8686
exprt normalize_pre_sva_non_overlapped_implication(
8787
sva_non_overlapped_implication_exprt expr)
8888
{
89-
// Same as a->Xb if lhs and rhs are not sequences.
90-
if(!is_SVA_sequence(expr.lhs()) && !is_SVA_sequence(expr.rhs()))
91-
return or_exprt{not_exprt{expr.lhs()}, X_exprt{expr.rhs()}};
89+
// Same as a->always[1:1] b if lhs is not a sequence.
90+
if(!is_SVA_sequence(expr.lhs()))
91+
{
92+
auto one = from_integer(1, natural_typet{});
93+
return or_exprt{
94+
not_exprt{expr.lhs()}, sva_ranged_always_exprt{one, one, expr.rhs()}};
95+
}
9296
else
9397
return std::move(expr);
9498
}
@@ -125,13 +129,14 @@ exprt normalize_pre_sva_cycle_delay(sva_cycle_delay_exprt expr)
125129
expr.from().is_constant() &&
126130
numeric_cast_v<mp_integer>(to_constant_expr(expr.from())) == 0)
127131
{
128-
// ##[0:$] φ --> F φ
129-
return F_exprt{expr.op()};
132+
// ##[0:$] φ --> s_eventually φ
133+
return sva_s_eventually_exprt{expr.op()};
130134
}
131135
else
132136
{
133-
// ##[i:$] φ --> ##i F φ
134-
return sva_cycle_delay_exprt{expr.from(), F_exprt{expr.op()}};
137+
// ##[i:$] φ --> always[i:i] s_eventually φ
138+
return sva_ranged_always_exprt{
139+
expr.from(), expr.from(), sva_s_eventually_exprt{expr.op()}};
135140
}
136141
}
137142
else
@@ -171,11 +176,13 @@ exprt normalize_property(exprt expr)
171176
expr = normalize_pre_sva_or(to_sva_or_expr(expr));
172177
else if(expr.id() == ID_sva_nexttime)
173178
{
174-
expr = X_exprt{to_sva_nexttime_expr(expr).op()};
179+
auto one = from_integer(1, natural_typet{});
180+
expr = sva_ranged_always_exprt{one, one, to_sva_nexttime_expr(expr).op()};
175181
}
176182
else if(expr.id() == ID_sva_s_nexttime)
177183
{
178-
expr = X_exprt{to_sva_s_nexttime_expr(expr).op()};
184+
auto one = from_integer(1, natural_typet{});
185+
expr = sva_s_always_exprt{one, one, to_sva_s_nexttime_expr(expr).op()};
179186
}
180187
else if(expr.id() == ID_sva_indexed_nexttime)
181188
{
@@ -190,11 +197,18 @@ exprt normalize_property(exprt expr)
190197
nexttime_expr.index(), nexttime_expr.index(), nexttime_expr.op()};
191198
}
192199
else if(expr.id() == ID_sva_cycle_delay)
200+
{
193201
expr = normalize_pre_sva_cycle_delay(to_sva_cycle_delay_expr(expr));
202+
}
194203
else if(expr.id() == ID_sva_cycle_delay_plus)
195-
expr = F_exprt{X_exprt{to_sva_cycle_delay_plus_expr(expr).op()}};
204+
{
205+
expr = sva_s_eventually_exprt{
206+
sva_s_nexttime_exprt{to_sva_cycle_delay_plus_expr(expr).op()}};
207+
}
196208
else if(expr.id() == ID_sva_cycle_delay_star)
197-
expr = F_exprt{to_sva_cycle_delay_star_expr(expr).op()};
209+
{
210+
expr = sva_s_eventually_exprt{to_sva_cycle_delay_star_expr(expr).op()};
211+
}
198212
else if(expr.id() == ID_sva_if)
199213
{
200214
auto &sva_if_expr = to_sva_if_expr(expr);

src/temporal-logic/normalize_property.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@ Author: Daniel Kroening, [email protected]
1919
/// a sva_iff b --> a <-> b
2020
/// a sva_implies b --> a -> b
2121
/// sva_not a --> ¬a
22-
/// a sva_and b --> a ∧ b if a and b are not SVA sequences
23-
/// a sva_or b --> a ∨ b if a and b are not SVA sequences
24-
/// sva_overlapped_implication --> ¬a ∨ b if a and b are not SVA sequences
25-
/// sva_non_overlapped_implication --> ¬a ∨ Xb if a and b are not SVA sequences
26-
/// sva_nexttime φ -->
22+
/// a sva_and b --> a ∧ b if a and b are not SVA sequences
23+
/// a sva_or b --> a ∨ b if a and b are not SVA sequences
24+
/// sva_overlapped_implication --> ¬a ∨ b if a is not an SVA sequence
25+
/// sva_non_overlapped_implication --> ¬a ∨ always[1:1] b if a is not an SVA sequence
26+
/// sva_nexttime φ --> sva_always[1:1] φ
2727
/// sva_nexttime[i] φ --> sva_always[i:i] φ
28-
/// sva_s_nexttime φ -->
28+
/// sva_s_nexttime φ --> sva_always[1:1] φ
2929
/// sva_s_nexttime[i] φ --> sva_s_always[i:i] φ
30+
/// ##[*] φ --> F φ
31+
/// ##[+] φ --> X F φ
3032
/// sva_if --> ? :
3133
/// a sva_disable_iff b --> a ∨ b
3234
/// a sva_accept_on b --> a ∨ b
@@ -39,8 +41,6 @@ Author: Daniel Kroening, [email protected]
3941
/// ¬¬φ --> φ
4042
/// ¬Gφ --> F¬φ
4143
/// ¬Fφ --> G¬φ
42-
/// ##[*] φ --> F φ
43-
/// ##[+] φ --> X F φ
4444
/// strong(φ) --> φ
4545
/// weak(φ) --> φ
4646
/// sva_case --> ? :

src/temporal-logic/temporal_logic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ bool is_SVA_sequence(const exprt &);
4545
/// Returns true iff the given expression is an SVA temporal operator
4646
bool is_SVA_operator(const exprt &);
4747

48-
/// Returns true iff the given expression contains an SVA temporal operator
48+
/// Returns true iff the given expression is an SVA expression
4949
bool is_SVA(const exprt &);
5050

5151
#endif

src/trans-word-level/property.cpp

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -144,33 +144,15 @@ Function: bmc_supports_SVA_property
144144

145145
bool bmc_supports_SVA_property(const exprt &expr)
146146
{
147-
if(!is_temporal_operator(expr))
148-
{
149-
if(!has_temporal_operator(expr))
150-
return true; // initial state only
151-
else if(
152-
expr.id() == ID_and || expr.id() == ID_or || expr.id() == ID_implies)
153-
{
154-
for(auto &op : expr.operands())
155-
if(!bmc_supports_property(op))
156-
return false;
157-
return true;
158-
}
159-
else
160-
return false;
161-
}
162-
else if(expr.id() == ID_sva_cycle_delay)
163-
return !has_temporal_operator(to_sva_cycle_delay_expr(expr).op());
164-
else if(expr.id() == ID_sva_nexttime)
165-
return !has_temporal_operator(to_sva_nexttime_expr(expr).op());
166-
else if(expr.id() == ID_sva_s_nexttime)
167-
return !has_temporal_operator(to_sva_s_nexttime_expr(expr).op());
168-
else if(expr.id() == ID_sva_always)
169-
return true;
170-
else if(expr.id() == ID_sva_ranged_always)
171-
return true;
172-
else
147+
// sva_nonoverlapped_followed_by is not supported yet
148+
if(has_subexpr(expr, ID_sva_nonoverlapped_followed_by))
149+
return false;
150+
151+
// sva_overlapped_followed_by is not supported yet
152+
if(has_subexpr(expr, ID_sva_overlapped_followed_by))
173153
return false;
154+
155+
return true;
174156
}
175157

176158
/*******************************************************************\
@@ -191,8 +173,10 @@ bool bmc_supports_property(const exprt &expr)
191173
return bmc_supports_LTL_property(expr);
192174
else if(is_CTL(expr))
193175
return bmc_supports_CTL_property(expr);
194-
else
176+
else if(is_SVA(expr))
195177
return bmc_supports_SVA_property(expr);
178+
else
179+
return false; // unknown category
196180
}
197181

198182
/*******************************************************************\

0 commit comments

Comments
 (0)