Skip to content

Commit 341268f

Browse files
authored
Merge pull request #859 from diffblue/sva-sequence-intersect
BMC: Implement SVA sequence intersect
2 parents f6b6feb + 34fad8b commit 341268f

File tree

6 files changed

+79
-8
lines changed

6 files changed

+79
-8
lines changed

CHANGELOG

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

regression/verilog/SVA/sequence_intersect1.desc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
CORE
22
sequence_intersect1.sv
3-
4-
^\[.*\] main\.x == 0 intersect main\.x == 1: FAILURE: property not supported by BMC engine$
3+
--bound 10
4+
^\[main\.p0\] main\.x == 0 intersect main\.x == 1: REFUTED$
5+
^\[main\.p1\] always main\.x >= 0: PROVED up to bound 10$
6+
^\[main\.p2\] always main\.x <= 5: PROVED up to bound 10$
7+
^\[main\.p3\] always main\.x <= 3: REFUTED$
8+
^\[main\.p4\] always \(main\.x >= 0 intersect main\.x <= 5\): PROVED up to bound 10$
9+
^\[main\.p5\] always \(main\.x >= 0 intersect main\.x <= 3\): REFUTED$
510
^EXIT=10$
611
^SIGNAL=0$
712
--

regression/verilog/SVA/sequence_intersect1.sv

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,27 @@ module main(input clk);
22

33
reg [31:0] x = 0;
44

5+
// 0, 1, 2, 3, 4, 5, 5, ...
56
always @(posedge clk)
6-
x<=x+1;
7+
if(x<5)
8+
x<=x+1;
79

10+
// should fail
811
initial p0: assert property (x == 0 intersect x == 1);
912

13+
// should pass
14+
p1: assert property (x >= 0);
15+
16+
// should pass
17+
p2: assert property (x <= 5);
18+
19+
// should fail
20+
p3: assert property (x <= 3);
21+
22+
// should pass
23+
p4: assert property (x >= 0 intersect x <= 5);
24+
25+
// should fail
26+
p5: assert property (x >= 0 intersect x <= 3);
27+
1028
endmodule

src/trans-word-level/property.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ bool bmc_supports_SVA_property(const exprt &expr)
119119
if(has_subexpr(expr, ID_sva_sequence_throughout))
120120
return false;
121121

122-
// sva_sequence_intersect is not supported yet
123-
if(has_subexpr(expr, ID_sva_sequence_intersect))
124-
return false;
125-
126122
// sva_sequence_within is not supported yet
127123
if(has_subexpr(expr, ID_sva_sequence_within))
128124
return false;

src/trans-word-level/sequence.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,33 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
132132
else if(expr.id() == ID_sva_sequence_intersect)
133133
{
134134
// IEEE 1800-2017 16.9.6
135-
PRECONDITION(false);
135+
// For the intersection of the two operand sequences to match, the following
136+
// must hold:
137+
// — Both the operands shall match.
138+
// — The lengths of the two matches of the operand sequences shall be the same.
139+
auto &intersect = to_sva_sequence_intersect_expr(expr);
140+
141+
const auto lhs_match_points =
142+
instantiate_sequence(intersect.lhs(), t, no_timeframes);
143+
const auto rhs_match_points =
144+
instantiate_sequence(intersect.rhs(), t, no_timeframes);
145+
146+
std::vector<std::pair<mp_integer, exprt>> result;
147+
148+
for(auto &lhs_match : lhs_match_points)
149+
{
150+
for(auto &rhs_match : rhs_match_points)
151+
{
152+
// Same length?
153+
if(lhs_match.first == rhs_match.first)
154+
{
155+
result.emplace_back(
156+
lhs_match.first, and_exprt{lhs_match.second, rhs_match.second});
157+
}
158+
}
159+
}
160+
161+
return result;
136162
}
137163
else if(expr.id() == ID_sva_sequence_first_match)
138164
{

src/verilog/sva_expr.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,4 +1181,29 @@ to_sva_sequence_consecutive_repetition_expr(exprt &expr)
11811181
return static_cast<sva_sequence_consecutive_repetition_exprt &>(expr);
11821182
}
11831183

1184+
class sva_sequence_intersect_exprt : public binary_exprt
1185+
{
1186+
public:
1187+
sva_sequence_intersect_exprt(exprt op0, exprt op1)
1188+
: binary_exprt(std::move(op0), ID_sva_sequence_intersect, std::move(op1))
1189+
{
1190+
}
1191+
};
1192+
1193+
static inline const sva_sequence_intersect_exprt &
1194+
to_sva_sequence_intersect_expr(const exprt &expr)
1195+
{
1196+
PRECONDITION(expr.id() == ID_sva_sequence_intersect);
1197+
sva_sequence_intersect_exprt::check(expr, validation_modet::INVARIANT);
1198+
return static_cast<const sva_sequence_intersect_exprt &>(expr);
1199+
}
1200+
1201+
static inline sva_sequence_intersect_exprt &
1202+
to_sva_sequence_intersect_expr(exprt &expr)
1203+
{
1204+
PRECONDITION(expr.id() == ID_sva_sequence_intersect);
1205+
sva_sequence_intersect_exprt::check(expr, validation_modet::INVARIANT);
1206+
return static_cast<sva_sequence_intersect_exprt &>(expr);
1207+
}
1208+
11841209
#endif

0 commit comments

Comments
 (0)