Skip to content

Commit a766409

Browse files
authored
Merge pull request #1084 from diffblue/fix-sequence-simplifications
fix SVA sequence simplifications
2 parents bf5127e + 6963c3d commit a766409

File tree

10 files changed

+71
-70
lines changed

10 files changed

+71
-70
lines changed

regression/verilog/SVA/sequence2.desc

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
CORE
1+
KNOWNBUG
22
sequence2.sv
33
--bound 10 --numbered-trace
4-
^\[main\.p0] ##\[0:\$\] main\.x == 10: REFUTED$
5-
^Counterexample with \d+ states:$
6-
^main\.x@0 = 0$
7-
^main\.x@1 = 1$
8-
^main\.x@2 = 2$
9-
^main\.x@3 = 3$
10-
^main\.x@4 = 4$
11-
^main\.x@5 = 5$
12-
^main\.x@6 = 5$
4+
^\[main\.p0] ##\[0:\$\] main\.x == 10: PROVED up to bound 10$
5+
^\[main\.p1] ##\[0:\$\] main\.x == 10: REFUTED$
136
^EXIT=10$
147
^SIGNAL=0$
158
--
169
^warning: ignoring
1710
--
11+
strong(...) is missing.

regression/verilog/SVA/sequence2.sv

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ module main;
99
if(x != 5)
1010
x<=x+1;
1111

12-
// fails once we see the lasso 0, 1, 2, 3, 4, 5, 5
13-
initial p0: assert property (##[0:$] x==10);
12+
// does not match -- passes
13+
initial p0: assert property (weak(##[0:$] x==10));
14+
15+
// does not match -- fails
16+
initial p1: assert property (strong(##[0:$] x==10));
1417

1518
endmodule

regression/verilog/SVA/sequence3.desc

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
CORE
1+
KNOWNBUG
22
sequence3.sv
33
--bound 20 --numbered-trace
44
^\[main\.p0\] ##\[\*\] main\.x == 6: REFUTED$
5-
^Counterexample with 7 states:$
65
^\[main\.p1\] ##\[\*\] main\.x == 5: PROVED up to bound 20$
76
^\[main\.p2\] ##\[\+\] main\.x == 0: REFUTED$
8-
^Counterexample with 7 states:$
97
^\[main\.p3\] ##\[\+\] main\.x == 5: PROVED up to bound 20$
108
^EXIT=10$
119
^SIGNAL=0$
1210
--
1311
^warning: ignoring
1412
--
13+
strong(...) is missing

regression/verilog/SVA/sequence3.sv

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ module main;
1010
x<=x+1;
1111

1212
// ##[*] is the same as [0:$]
13-
initial p0: assert property (##[*] x==6); // should fail
14-
initial p1: assert property (##[*] x==5); // should pass
13+
initial p0: assert property (strong(##[*] x==6)); // no match
14+
initial p1: assert property (strong(##[*] x==5)); // match
1515

1616
// ##[+] is the same as [1:$]
17-
initial p2: assert property (##[+] x==0); // should fail
18-
initial p3: assert property (##[+] x==5); // should pass
17+
initial p2: assert property (strong(##[+] x==0)); // no match
18+
initial p3: assert property (strong(##[+] x==5)); // match
1919

2020
endmodule

src/temporal-logic/normalize_property.cpp

-33
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,6 @@ exprt normalize_pre_sva_non_overlapped_implication(
3434
return std::move(expr);
3535
}
3636

37-
exprt normalize_pre_sva_cycle_delay(sva_cycle_delay_exprt expr)
38-
{
39-
if(expr.is_unbounded())
40-
{
41-
if(numeric_cast_v<mp_integer>(expr.from()) == 0)
42-
{
43-
// ##[0:$] φ --> s_eventually φ
44-
return sva_s_eventually_exprt{expr.op()};
45-
}
46-
else
47-
{
48-
// ##[i:$] φ --> always[i:i] s_eventually φ
49-
return sva_ranged_always_exprt{
50-
expr.from(), expr.from(), sva_s_eventually_exprt{expr.op()}};
51-
}
52-
}
53-
else
54-
return std::move(expr);
55-
}
56-
5737
exprt normalize_property_rec(exprt expr)
5838
{
5939
// pre-traversal
@@ -84,19 +64,6 @@ exprt normalize_property_rec(exprt expr)
8464
expr = sva_s_always_exprt{
8565
nexttime_expr.index(), nexttime_expr.index(), nexttime_expr.op()};
8666
}
87-
else if(expr.id() == ID_sva_cycle_delay)
88-
{
89-
expr = normalize_pre_sva_cycle_delay(to_sva_cycle_delay_expr(expr));
90-
}
91-
else if(expr.id() == ID_sva_cycle_delay_plus)
92-
{
93-
expr = sva_s_nexttime_exprt{
94-
sva_s_eventually_exprt{to_sva_cycle_delay_plus_expr(expr).op()}};
95-
}
96-
else if(expr.id() == ID_sva_cycle_delay_star)
97-
{
98-
expr = sva_s_eventually_exprt{to_sva_cycle_delay_star_expr(expr).op()};
99-
}
10067

10168
// normalize the operands
10269
for(auto &op : expr.operands())

src/temporal-logic/temporal_logic.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ bool is_SVA_sequence_operator(const exprt &expr)
106106
// are property expressions, not sequence expressions.
107107
// Note that ID_sva_not does not yield a sequence expression.
108108
return id == ID_sva_and || id == ID_sva_or || id == ID_sva_cycle_delay ||
109+
id == ID_sva_cycle_delay_plus || id == ID_sva_cycle_delay_star ||
109110
id == ID_sva_sequence_concatenation ||
110111
id == ID_sva_sequence_intersect || id == ID_sva_sequence_first_match ||
111112
id == ID_sva_sequence_throughout || id == ID_sva_sequence_within ||

src/trans-word-level/sequence.cpp

+28-14
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,35 @@ sequence_matchest instantiate_sequence(
4242
return instantiate_sequence(
4343
sva_cycle_delay_expr.op(), u, no_timeframes);
4444
}
45-
else
45+
else // a range
4646
{
47-
mp_integer to;
47+
auto lower = t + from;
48+
mp_integer upper;
4849

4950
if(sva_cycle_delay_expr.to().id() == ID_infinity)
5051
{
5152
DATA_INVARIANT(no_timeframes != 0, "must have timeframe");
52-
to = no_timeframes - 1;
53+
upper = no_timeframes;
54+
}
55+
else
56+
{
57+
mp_integer to;
58+
if(to_integer_non_constant(sva_cycle_delay_expr.to(), to))
59+
throw "failed to convert sva_cycle_delay offsets";
60+
upper = t + to;
5361
}
54-
else if(to_integer_non_constant(sva_cycle_delay_expr.to(), to))
55-
throw "failed to convert sva_cycle_delay offsets";
5662

57-
auto lower = t + from;
58-
auto upper = t + to;
63+
sequence_matchest matches;
5964

60-
// Do we exceed the bound? Make it 'true'
65+
// Do we exceed the bound? Add an unconditional match.
6166
if(upper >= no_timeframes)
6267
{
6368
DATA_INVARIANT(no_timeframes != 0, "must have timeframe");
64-
return {{no_timeframes - 1, true_exprt()}};
69+
matches.emplace_back(no_timeframes - 1, true_exprt());
70+
upper = no_timeframes - 1;
6571
}
6672

67-
sequence_matchest matches;
68-
73+
// Add a potential match for each timeframe in the range
6974
for(mp_integer u = lower; u <= upper; ++u)
7075
{
7176
auto sub_result =
@@ -77,6 +82,16 @@ sequence_matchest instantiate_sequence(
7782
return matches;
7883
}
7984
}
85+
else if(expr.id() == ID_sva_cycle_delay_star) // ##[*] something
86+
{
87+
auto &cycle_delay_star = to_sva_cycle_delay_star_expr(expr);
88+
return instantiate_sequence(cycle_delay_star.lower(), t, no_timeframes);
89+
}
90+
else if(expr.id() == ID_sva_cycle_delay_plus) // ##[+] something
91+
{
92+
auto &cycle_delay_plus = to_sva_cycle_delay_plus_expr(expr);
93+
return instantiate_sequence(cycle_delay_plus.lower(), t, no_timeframes);
94+
}
8095
else if(expr.id() == ID_sva_sequence_concatenation)
8196
{
8297
auto &implication = to_binary_expr(expr);
@@ -378,8 +393,7 @@ sequence_matchest instantiate_sequence(
378393
else
379394
{
380395
// not a sequence, evaluate as state predicate
381-
auto obligations = property_obligations(expr, t, no_timeframes);
382-
auto conjunction = obligations.conjunction();
383-
return {{conjunction.first, conjunction.second}};
396+
auto instantiated = instantiate_property(expr, t, no_timeframes);
397+
return {{instantiated.first, instantiated.second}};
384398
}
385399
}

src/verilog/sva_expr.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ Author: Daniel Kroening, [email protected]
1111
#include <util/arith_tools.h>
1212
#include <util/mathematical_types.h>
1313

14+
exprt sva_cycle_delay_plus_exprt::lower() const
15+
{
16+
// same as ##[1:$]
17+
return sva_cycle_delay_exprt{
18+
from_integer(1, integer_typet{}),
19+
exprt{ID_infinity, integer_typet{}},
20+
op()};
21+
}
22+
23+
exprt sva_cycle_delay_star_exprt::lower() const
24+
{
25+
// same as ##[0:$]
26+
return sva_cycle_delay_exprt{
27+
from_integer(0, integer_typet{}),
28+
exprt{ID_infinity, integer_typet{}},
29+
op()};
30+
}
31+
1432
exprt sva_case_exprt::lowering() const
1533
{
1634
auto &case_items = this->case_items();

src/verilog/sva_expr.h

+6
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,9 @@ class sva_cycle_delay_plus_exprt : public unary_exprt
10041004
: unary_exprt(ID_sva_cycle_delay_plus, std::move(op), bool_typet())
10051005
{
10061006
}
1007+
1008+
// ##[1:$] op
1009+
exprt lower() const;
10071010
};
10081011

10091012
static inline const sva_cycle_delay_plus_exprt &
@@ -1029,6 +1032,9 @@ class sva_cycle_delay_star_exprt : public unary_exprt
10291032
: unary_exprt(ID_sva_cycle_delay_star, std::move(op), bool_typet())
10301033
{
10311034
}
1035+
1036+
// ##[0:$] op
1037+
exprt lower() const;
10321038
};
10331039

10341040
static inline const sva_cycle_delay_star_exprt &

src/verilog/verilog_typecheck_sva.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ exprt verilog_typecheck_exprt::convert_unary_sva(unary_exprt expr)
7777
{
7878
if(
7979
expr.id() == ID_sva_not || expr.id() == ID_sva_always ||
80-
expr.id() == ID_sva_s_eventually || expr.id() == ID_sva_cycle_delay_plus ||
81-
expr.id() == ID_sva_cycle_delay_star || expr.id() == ID_sva_nexttime ||
80+
expr.id() == ID_sva_s_eventually || expr.id() == ID_sva_nexttime ||
8281
expr.id() == ID_sva_s_nexttime)
8382
{
8483
convert_sva(expr.op());
@@ -87,8 +86,8 @@ exprt verilog_typecheck_exprt::convert_unary_sva(unary_exprt expr)
8786
return std::move(expr);
8887
}
8988
else if(
90-
expr.id() == ID_sva_cycle_delay_plus ||
91-
expr.id() == ID_sva_cycle_delay_star ||
89+
expr.id() == ID_sva_cycle_delay_plus || // ##[+]
90+
expr.id() == ID_sva_cycle_delay_star || // ##[*]
9291
expr.id() == ID_sva_sequence_repetition_plus || // x[+]
9392
expr.id() == ID_sva_sequence_repetition_star) // x[*}
9493
{

0 commit comments

Comments
 (0)