Skip to content

Commit 2c01450

Browse files
authored
Merge pull request #861 from diffblue/sva-sequence-throughout
BMC: implement SVA sequence throughout
2 parents 5f864c0 + 9be62b4 commit 2c01450

File tree

6 files changed

+64
-8
lines changed

6 files changed

+64
-8
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* BMC: iterative constraint strengthening is now default;
55
use --bmc-with-assumptions to re-enable the previous algorithm.
66
* BMC: support SVA sequence intersect
7+
* BMC: support SVA sequence throughout
78
* SystemVerilog: streaming concatenation {<<{...}} and {>>{...}}
89
* SystemVerilog: set membership operator
910
* SystemVerilog: named sequences

regression/verilog/SVA/sequence_throughout1.desc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
CORE
22
sequence_throughout1.sv
3-
4-
^\[.*\] main\.x == 0 throughout main\.x == 1: FAILURE: property not supported by BMC engine$
3+
--bound 10
4+
^\[main\.p0\] main\.x >= 0 throughout \(main\.x == 0 ##1 main\.x == 1 ##1 main\.x == 2\): PROVED up to bound 10$
5+
^\[main\.p1\] main\.x <= 1 throughout \(main\.x == 0 ##1 main\.x == 1 ##1 main\.x == 2\): REFUTED$
6+
^\[main\.p2\] 1 throughout \(main\.x == 0 ##1 main\.x == 1 ##1 main\.x == 3\): REFUTED$
57
^EXIT=10$
68
^SIGNAL=0$
79
--

regression/verilog/SVA/sequence_throughout1.sv

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ module main(input clk);
55
always @(posedge clk)
66
x<=x+1;
77

8-
initial p0: assert property (x == 0 throughout x == 1);
8+
// should pass
9+
initial p0: assert property (x >= 0 throughout x==0 ##1 x==1 ##1 x==2);
10+
11+
// should fail owing to LHS
12+
initial p1: assert property (x <= 1 throughout x==0 ##1 x==1 ##1 x==2);
13+
14+
// should fail owing to RHS
15+
initial p2: assert property (1 throughout x==0 ##1 x==1 ##1 x==3);
916

1017
endmodule

src/trans-word-level/property.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,6 @@ bool bmc_supports_SVA_property(const exprt &expr)
115115
if(has_subexpr(expr, ID_sva_sequence_first_match))
116116
return false;
117117

118-
// sva_sequence_troughout is not supported yet
119-
if(has_subexpr(expr, ID_sva_sequence_throughout))
120-
return false;
121-
122118
// sva_sequence_within is not supported yet
123119
if(has_subexpr(expr, ID_sva_sequence_within))
124120
return false;

src/trans-word-level/sequence.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,32 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
166166
}
167167
else if(expr.id() == ID_sva_sequence_throughout)
168168
{
169-
PRECONDITION(false);
169+
// IEEE 1800-2017 16.9.9
170+
// exp throughout seq matches along an interval provided
171+
// - seq matches along the interval and
172+
// - exp evaluates to true at each clock tick of the interval.
173+
auto &throughout = to_sva_sequence_throughout_expr(expr);
174+
175+
const auto rhs_match_points =
176+
instantiate_sequence(throughout.rhs(), t, no_timeframes);
177+
178+
std::vector<std::pair<mp_integer, exprt>> result;
179+
180+
for(auto &rhs_match : rhs_match_points)
181+
{
182+
exprt::operandst conjuncts = {rhs_match.second};
183+
184+
for(mp_integer new_t = t; new_t <= rhs_match.first; ++new_t)
185+
{
186+
auto obligations =
187+
property_obligations(throughout.lhs(), new_t, no_timeframes);
188+
conjuncts.push_back(obligations.conjunction().second);
189+
}
190+
191+
result.emplace_back(rhs_match.first, conjunction(conjuncts));
192+
}
193+
194+
return result;
170195
}
171196
else if(expr.id() == ID_sva_sequence_within)
172197
{

src/verilog/sva_expr.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,4 +1206,29 @@ to_sva_sequence_intersect_expr(exprt &expr)
12061206
return static_cast<sva_sequence_intersect_exprt &>(expr);
12071207
}
12081208

1209+
class sva_sequence_throughout_exprt : public binary_exprt
1210+
{
1211+
public:
1212+
sva_sequence_throughout_exprt(exprt op0, exprt op1)
1213+
: binary_exprt(std::move(op0), ID_sva_sequence_throughout, std::move(op1))
1214+
{
1215+
}
1216+
};
1217+
1218+
static inline const sva_sequence_throughout_exprt &
1219+
to_sva_sequence_throughout_expr(const exprt &expr)
1220+
{
1221+
PRECONDITION(expr.id() == ID_sva_sequence_throughout);
1222+
sva_sequence_throughout_exprt::check(expr, validation_modet::INVARIANT);
1223+
return static_cast<const sva_sequence_throughout_exprt &>(expr);
1224+
}
1225+
1226+
static inline sva_sequence_throughout_exprt &
1227+
to_sva_sequence_throughout_expr(exprt &expr)
1228+
{
1229+
PRECONDITION(expr.id() == ID_sva_sequence_throughout);
1230+
sva_sequence_throughout_exprt::check(expr, validation_modet::INVARIANT);
1231+
return static_cast<sva_sequence_throughout_exprt &>(expr);
1232+
}
1233+
12091234
#endif

0 commit comments

Comments
 (0)