Skip to content

Commit fd25950

Browse files
committed
BMC: implement weak/strong sequences
This implements strong semantics for SVA sequences in the word-level BMC engine. Strong semantics are used with an explicit strong(...) operator or for SVA cover. The difference between weak and strong semantics arises in BMC when the sequence reaches the end of the unwinding: using weak semantics, the sequence matches, whereas using strong semantics the sequence does not.
1 parent dfd20dc commit fd25950

13 files changed

+177
-64
lines changed

regression/verilog/SVA/cover_sequence2.desc

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
KNOWNBUG
1+
CORE
22
cover_sequence2.sv
3-
--bound 2
4-
^\[main\.p0\] cover \(main\.x == 2 ##1 main\.x == 3 ##1 main\.x == 100\): PROVED$
5-
^\[main\.p1\] cover \(main\.x == 98 ##1 main\.x == 99 ##1 main\.x == 100\): REFUTED up to bound 2$
3+
--bound 5
4+
^\[main\.p0\] cover \(main\.x == 2 ##1 main\.x == 3 ##1 main\.x == 100\): REFUTED up to bound 5$
5+
^\[main\.p1\] cover \(main\.x == 98 ##1 main\.x == 99 ##1 main\.x == 100\): REFUTED up to bound 5$
6+
^\[main\.p2\] cover \(main\.x == 3 ##1 main\.x == 4 ##1 main\.x == 5\): PROVED$
7+
^\[main\.p3\] cover \(main\.x == 4 ##1 main\.x == 5 ##1 main\.x == 6\): REFUTED up to bound 5$
68
^EXIT=10$
79
^SIGNAL=0$
810
--
911
^warning: ignoring
1012
--
11-
Cover property p0 cannot ever hold, but is shown proven when using a small bound.
+9-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
module main(input clk);
22

33
// count up
4-
reg [7:0] x = 0;
4+
int x = 0;
55

6-
always @(posedge clk)
6+
always_ff @(posedge clk)
77
x++;
88

99
// expected to fail
1010
p0: cover property (x==2 ##1 x==3 ##1 x==100);
1111

12-
// expected to fail until bound reaches 100
12+
// expected to fail until x reaches 100
1313
p1: cover property (x==98 ##1 x==99 ##1 x==100);
1414

15+
// expected to pass once x reaches 5
16+
p2: cover property (x==3 ##1 x==4 ##1 x==5);
17+
18+
// expected to pass once x reaches 6
19+
p3: cover property (x==4 ##1 x==5 ##1 x==6);
20+
1521
endmodule
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
cover_sequence3.sv
3+
--bound 3
4+
^\[main\.p0\] cover \(1 \[\*10\]\): REFUTED up to bound 3$
5+
^\[main\.p1\] cover \(1 \[\*4:10\]\): PROVED$
6+
^\[main\.p2\] cover \(1 \[\*5:10\]\): REFUTED up to bound 3$
7+
^EXIT=10$
8+
^SIGNAL=0$
9+
--
10+
^warning: ignoring
11+
--
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module main(input clk);
2+
3+
// count up
4+
int x = 0;
5+
6+
always_ff @(posedge clk)
7+
x++;
8+
9+
// passes with bound >=9
10+
p0: cover property (1[*10]);
11+
12+
// passes with bound >=3
13+
p1: cover property (1[*4:10]);
14+
15+
// passes with bound >=4
16+
p2: cover property (1[*5:10]);
17+
18+
endmodule
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
KNOWNBUG
2+
cover_sequence4.sv
3+
--bound 3
4+
^\[main\.p0\] cover \(1 \[=10\]\): REFUTED up to bound 3$
5+
^\[main\.p1\] cover \(1 \[=4:10\]\): PROVED$
6+
^\[main\.p2\] cover \(1 \[=5:10\]\): REFUTED up to bound 3$
7+
^EXIT=10$
8+
^SIGNAL=0$
9+
--
10+
^warning: ignoring
11+
--
12+
Implementation of [=x:y] is missing.
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module main(input clk);
2+
3+
// count up
4+
int x = 0;
5+
6+
always_ff @(posedge clk)
7+
x++;
8+
9+
// passes with bound >=9
10+
p0: cover property (1[=10]);
11+
12+
// passes with bound >=3
13+
p1: cover property (1[=4:10]);
14+
15+
// passes with bound >=4
16+
p2: cover property (1[=5:10]);
17+
18+
endmodule

regression/verilog/SVA/sequence2.desc

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
KNOWNBUG
1+
CORE
22
sequence2.sv
3-
--bound 10 --numbered-trace
4-
^\[main\.p0] ##\[0:\$\] main\.x == 10: PROVED up to bound 10$
5-
^\[main\.p1] ##\[0:\$\] main\.x == 10: REFUTED$
3+
--bound 10
4+
^\[main\.p0] weak\(##\[0:\$\] main\.x == 10\): PROVED up to bound 10$
5+
^\[main\.p1] strong\(##\[0:\$\] main\.x == 10\): REFUTED$
66
^EXIT=10$
77
^SIGNAL=0$
88
--
99
^warning: ignoring
1010
--
11-
strong(...) is missing.

regression/verilog/SVA/sequence3.desc

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
KNOWNBUG
1+
CORE
22
sequence3.sv
33
--bound 20 --numbered-trace
4-
^\[main\.p0\] ##\[\*\] main\.x == 6: REFUTED$
5-
^\[main\.p1\] ##\[\*\] main\.x == 5: PROVED up to bound 20$
6-
^\[main\.p2\] ##\[\+\] main\.x == 0: REFUTED$
7-
^\[main\.p3\] ##\[\+\] main\.x == 5: PROVED up to bound 20$
4+
^\[main\.p0\] strong\(##\[\*\] main\.x == 6\): REFUTED$
5+
^\[main\.p1\] strong\(##\[\*\] main\.x == 5\): PROVED up to bound 20$
6+
^\[main\.p2\] strong\(##\[\+\] main\.x == 0\): REFUTED$
7+
^\[main\.p3\] strong\(##\[\+\] main\.x == 5\): PROVED up to bound 20$
88
^EXIT=10$
99
^SIGNAL=0$
1010
--
1111
^warning: ignoring
1212
--
13-
strong(...) is missing

regression/verilog/SVA/strong1.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
strong1.sv
3-
--bound 20
4-
^\[main\.p0\] strong\(##\[0:9\] main\.x == 100\): REFUTED$
3+
--bound 4
4+
^\[main\.p0\] strong\(##\[0:9\] main\.x == 5\): REFUTED$
55
^EXIT=10$
66
^SIGNAL=0$
77
--

regression/verilog/SVA/strong1.sv

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module main;
88
always @(posedge clk)
99
x<=x+1;
1010

11-
// fails
12-
initial p0: assert property (strong(##[0:9] x==100));
11+
// fails if bound is too low
12+
initial p0: assert property (strong(##[0:9] x==5));
1313

1414
endmodule

src/trans-word-level/property.cpp

+33-8
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,17 @@ static obligationst property_obligations_rec(
530530
// The sequence must not match.
531531
auto &sequence = to_sva_sequence_property_expr_base(op).sequence();
532532

533+
// clang-format off
534+
auto semantics =
535+
op.id() == ID_sva_strong ? sva_sequence_semanticst::STRONG
536+
: op.id() == ID_sva_weak ? sva_sequence_semanticst::WEAK
537+
: op.id() == ID_sva_implicit_strong ? sva_sequence_semanticst::STRONG
538+
: op.id() == ID_sva_implicit_weak ? sva_sequence_semanticst::WEAK
539+
: sva_sequence_semanticst::WEAK;
540+
// clang-format on
541+
533542
const auto matches =
534-
instantiate_sequence(sequence, current, no_timeframes);
543+
instantiate_sequence(sequence, semantics, current, no_timeframes);
535544

536545
obligationst obligations;
537546

@@ -577,10 +586,13 @@ static obligationst property_obligations_rec(
577586
auto &implication = to_binary_expr(property_expr);
578587

579588
// The LHS is a sequence, the RHS is a property.
580-
// The implication must hold for _all_ matches on the LHS,
589+
// The implication must hold for _all_ (strong) matches on the LHS,
581590
// i.e., each pair of LHS match and RHS obligation yields an obligation.
582-
const auto lhs_match_points =
583-
instantiate_sequence(implication.lhs(), current, no_timeframes);
591+
const auto lhs_match_points = instantiate_sequence(
592+
implication.lhs(),
593+
sva_sequence_semanticst::STRONG,
594+
current,
595+
no_timeframes);
584596

585597
obligationst result;
586598

@@ -620,9 +632,12 @@ static obligationst property_obligations_rec(
620632
// the result is a property expression.
621633
auto &followed_by = to_sva_followed_by_expr(property_expr);
622634

623-
// get match points for LHS sequence
624-
auto matches =
625-
instantiate_sequence(followed_by.antecedent(), current, no_timeframes);
635+
// get (proper) match points for LHS sequence
636+
auto matches = instantiate_sequence(
637+
followed_by.antecedent(),
638+
sva_sequence_semanticst::STRONG,
639+
current,
640+
no_timeframes);
626641

627642
exprt::operandst disjuncts;
628643
mp_integer t = current;
@@ -663,9 +678,19 @@ static obligationst property_obligations_rec(
663678
auto &sequence =
664679
to_sva_sequence_property_expr_base(property_expr).sequence();
665680

681+
// clang-format off
682+
auto semantics =
683+
property_expr.id() == ID_sva_strong ? sva_sequence_semanticst::STRONG
684+
: property_expr.id() == ID_sva_weak ? sva_sequence_semanticst::WEAK
685+
: property_expr.id() == ID_sva_implicit_strong ? sva_sequence_semanticst::STRONG
686+
: property_expr.id() == ID_sva_implicit_weak ? sva_sequence_semanticst::WEAK
687+
: sva_sequence_semanticst::WEAK;
688+
// clang-format on
689+
666690
// sequence expressions -- these may have multiple potential
667691
// match points, and evaluate to true if any of them matches
668-
const auto matches = instantiate_sequence(sequence, current, no_timeframes);
692+
const auto matches =
693+
instantiate_sequence(sequence, semantics, current, no_timeframes);
669694
exprt::operandst disjuncts;
670695
disjuncts.reserve(matches.size());
671696
mp_integer max = current;

0 commit comments

Comments
 (0)