Skip to content

Commit f8a662c

Browse files
committed
ebmc: completeness threshold for SVA's always and s_always
This extends the completeness threshold logic to cover the bounded always and s_always operators.
1 parent 5c4db76 commit f8a662c

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

regression/verilog/SVA/initial1.desc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ initial1.sv
55
^\[main\.p1\] main\.counter == 100: REFUTED$
66
^\[main\.p2\] ##1 main\.counter == 1: PROVED up to bound 5$
77
^\[main\.p3\] ##1 main\.counter == 100: REFUTED$
8-
^\[main\.p4\] s_nexttime main\.counter == 1: PROVED up to bound 5$
8+
^\[main\.p4\] s_nexttime main\.counter == 1: PROVED$
9+
^\[main\.p5\] always \[1:1\] main\.counter == 1: PROVED$
910
^EXIT=10$
1011
^SIGNAL=0$
1112
--

regression/verilog/SVA/initial1.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ module main(input clk);
2626
// expected to pass if there are timeframes 0 and 1
2727
initial p4: assert property (s_nexttime counter == 1);
2828

29+
// expected to pass
30+
initial p5: assert property (always [1:1] counter == 1);
31+
2932
endmodule

src/ebmc/completeness_threshold.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Author: Daniel Kroening, [email protected]
88

99
#include "completeness_threshold.h"
1010

11+
#include <util/arith_tools.h>
12+
1113
#include <temporal-logic/ltl.h>
1214
#include <temporal-logic/temporal_logic.h>
1315
#include <verilog/sva_expr.h>
@@ -25,10 +27,41 @@ bool has_low_completeness_threshold(const exprt &expr)
2527
// X p
2628
return !has_temporal_operator(to_X_expr(expr).op());
2729
}
28-
else if(expr.id() == ID_sva_nexttime)
30+
else if(
31+
expr.id() == ID_sva_nexttime || expr.id() == ID_sva_s_nexttime ||
32+
expr.id() == ID_sva_s_nexttime)
33+
{
34+
// these are rewritten to always/s_always by normalize_property
35+
PRECONDITION(false);
36+
}
37+
else if(expr.id() == ID_sva_ranged_always)
2938
{
30-
// nexttime p
31-
return !has_temporal_operator(to_sva_nexttime_expr(expr).op());
39+
auto &always_expr = to_sva_ranged_always_expr(expr);
40+
if(has_temporal_operator(always_expr.op()))
41+
return false;
42+
else if(always_expr.upper().is_constant())
43+
{
44+
auto lower_int = numeric_cast_v<mp_integer>(always_expr.lower());
45+
auto upper_int =
46+
numeric_cast_v<mp_integer>(to_constant_expr(always_expr.upper()));
47+
return lower_int >= 0 && lower_int <= 1 && upper_int >= 0 &&
48+
upper_int <= 1;
49+
}
50+
else
51+
return false;
52+
}
53+
else if(expr.id() == ID_sva_s_always)
54+
{
55+
auto &s_always_expr = to_sva_s_always_expr(expr);
56+
if(has_temporal_operator(s_always_expr.op()))
57+
return false;
58+
else
59+
{
60+
auto lower_int = numeric_cast_v<mp_integer>(s_always_expr.lower());
61+
auto upper_int = numeric_cast_v<mp_integer>(s_always_expr.upper());
62+
return lower_int >= 0 && lower_int <= 1 && upper_int >= 0 &&
63+
upper_int <= 1;
64+
}
3265
}
3366
else
3467
return false;

0 commit comments

Comments
 (0)