Skip to content

Commit 967a9ae

Browse files
committed
BMC: SVA sequence within
This implements the SVA sequence within operator in the word-level BMC backend.
1 parent aac75f1 commit 967a9ae

File tree

7 files changed

+81
-9
lines changed

7 files changed

+81
-9
lines changed

CHANGELOG

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* SystemVerilog: unbased unsigned literals '0, '1, 'x, 'z
77
* SystemVerilog: first_match
88
* SystemVerilog: [->n] and [=n]
9+
* SystemVerilog: within
910
* SystemVerilog: bugfix for |-> and |=>
1011
* SystemVerilog: bugfix for SVA sequence and
1112
* Verilog: 'dx, 'dz

regression/verilog/SVA/sequence_within1.desc

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
CORE
22
sequence_within1.sv
3-
--bound 5
4-
^\[.*\] main\.x == 0 within main\.x == 1: FAILURE: property not supported by BMC engine$
3+
--bound 20
4+
^\[main\.p0\] main\.x == 0 within main\.x == 1: REFUTED$
5+
^\[main\.p1\] main\.x == 0 within \(##10 1\): PROVED up to bound 20$
6+
^\[main\.p2\] main\.x == 5 within \(##10 1\): PROVED up to bound 20$
7+
^\[main\.p3\] main\.x == 10 within \(##10 1\): PROVED up to bound 20$
8+
^\[main\.p4\] main\.x == 11 within \(##10 1\): REFUTED$
59
^EXIT=10$
610
^SIGNAL=0$
711
--
+14-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
module main(input clk);
22

3-
reg [31:0] x = 0;
3+
reg [7:0] x = 0;
44

55
always @(posedge clk)
66
x<=x+1;
77

8+
// fails, no rhs match
89
initial p0: assert property (x == 0 within x == 1);
910

11+
// passes, lhs match at beginning of rhs match
12+
initial p1: assert property (x == 0 within ##10 1);
13+
14+
// passes, lhs match in the middle of rhs match
15+
initial p2: assert property (x == 5 within ##10 1);
16+
17+
// passes, lhs match at the end of rhs match
18+
initial p3: assert property (x == 10 within ##10 1);
19+
20+
// fails, lhs match just beyond the rhs match
21+
initial p4: assert property (x == 11 within ##10 1);
22+
1023
endmodule

src/trans-word-level/property.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,6 @@ Function: bmc_supports_SVA_property
111111

112112
bool bmc_supports_SVA_property(const exprt &expr)
113113
{
114-
// sva_sequence_within is not supported yet
115-
if(has_subexpr(expr, ID_sva_sequence_within))
116-
return false;
117-
118114
return true;
119115
}
120116

src/trans-word-level/sequence.cpp

+31-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,37 @@ sequence_matchest instantiate_sequence(
205205
}
206206
else if(expr.id() == ID_sva_sequence_within)
207207
{
208-
PRECONDITION(false);
208+
// If the lhs match is contained anywhere within the rhs match,
209+
// then return the rhs match.
210+
211+
auto &within_expr = to_sva_sequence_within_expr(expr);
212+
const auto matches_rhs =
213+
instantiate_sequence(within_expr.rhs(), t, no_timeframes);
214+
215+
sequence_matchest result;
216+
217+
for(auto &match_rhs : matches_rhs)
218+
{
219+
for(auto start_lhs = t; start_lhs <= match_rhs.end_time; ++start_lhs)
220+
{
221+
auto matches_lhs =
222+
instantiate_sequence(within_expr.lhs(), start_lhs, no_timeframes);
223+
224+
for(auto &match_lhs : matches_lhs)
225+
{
226+
// The end_time of the lhs match must be no later than the
227+
// end_time of the rhs match.
228+
if(match_lhs.end_time <= match_rhs.end_time)
229+
{
230+
// return the rhs end_time
231+
auto cond = and_exprt{match_lhs.condition, match_rhs.condition};
232+
result.emplace_back(match_rhs.end_time, std::move(cond));
233+
}
234+
}
235+
}
236+
}
237+
238+
return result;
209239
}
210240
else if(expr.id() == ID_sva_and)
211241
{

src/verilog/sva_expr.h

+29
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,35 @@ to_sva_sequence_intersect_expr(exprt &expr)
14981498
return static_cast<sva_sequence_intersect_exprt &>(expr);
14991499
}
15001500

1501+
class sva_sequence_within_exprt : public binary_exprt
1502+
{
1503+
public:
1504+
explicit sva_sequence_within_exprt(exprt op0, exprt op1)
1505+
: binary_exprt(
1506+
std::move(op0),
1507+
ID_sva_sequence_within,
1508+
std::move(op1),
1509+
verilog_sva_sequence_typet{})
1510+
{
1511+
}
1512+
};
1513+
1514+
static inline const sva_sequence_within_exprt &
1515+
to_sva_sequence_within_expr(const exprt &expr)
1516+
{
1517+
PRECONDITION(expr.id() == ID_sva_sequence_within);
1518+
sva_sequence_within_exprt::check(expr, validation_modet::INVARIANT);
1519+
return static_cast<const sva_sequence_within_exprt &>(expr);
1520+
}
1521+
1522+
static inline sva_sequence_within_exprt &
1523+
to_sva_sequence_within_expr(exprt &expr)
1524+
{
1525+
PRECONDITION(expr.id() == ID_sva_sequence_within);
1526+
sva_sequence_within_exprt::check(expr, validation_modet::INVARIANT);
1527+
return static_cast<sva_sequence_within_exprt &>(expr);
1528+
}
1529+
15011530
class sva_sequence_throughout_exprt : public binary_exprt
15021531
{
15031532
public:

src/verilog/verilog_typecheck_sva.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
239239

240240
convert_sva(expr.rhs());
241241
require_sva_sequence(expr.rhs());
242-
expr.type() = bool_typet{};
243242

244243
expr.type() = verilog_sva_sequence_typet{};
245244

0 commit comments

Comments
 (0)