Skip to content

Commit e305f6c

Browse files
committed
SVA: and/or as a sequence also need to work with parentheses
The SVA operators 'and' and 'or' can be used to form SVA sequences or SVA properties, depending on the types of the operands. Furthermore, any sequence expression is also a property expression. This results in a conflict in the SystemVerilog grammar, as the context is insufficient to determine whether an expression is a sequence_expr or a property_expr. This resolves the conflict by replicating the sequence_expr rules into property_expr, and allowing property_expr to be used where sequence_expr would be required. To detect malformed input programs that use a property where a sequence is required, a check is added to the type checker.
1 parent 93e7d44 commit e305f6c

16 files changed

+137
-39
lines changed

regression/verilog/SVA/sequence_and1.desc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ sequence_and1.sv
55
^\[main\.p1\] strong\(main\.x == 0 and main\.x == 1\): REFUTED$
66
^\[main\.p2\] main\.x == 0 and \(nexttime main\.x == 1\): PROVED up to bound \d+$
77
^\[main\.p3\] \(nexttime main\.x == 1\) and main\.x == 0: PROVED up to bound \d+$
8+
^\[main\.p4\] \(main\.x == 0 and main\.x != 10\) |=> main\.x == 1: PROVED up to bound \d+$
89
^EXIT=10$
910
^SIGNAL=0$
1011
--

regression/verilog/SVA/sequence_and1.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ module main(input clk);
1515
initial p2: assert property (x == 0 and nexttime x == 1);
1616
initial p3: assert property (nexttime x == 1 and x == 0);
1717

18+
// It also yields a sequence when in parentheses.
19+
initial p4: assert property ((x == 0 and x != 10) |=> x == 1);
20+
1821
endmodule

regression/verilog/SVA/sequence_first_match2.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
CORE
22
sequence_first_match2.sv
33
--bound 5
4-
^\[.*\] \(##1 1\) or \(\(##2 1\) \|-> main.x == 1\): PROVED up to bound 5$
4+
^\[.*\] \(\(##1 1\) or \(##2 1\)\) \|-> main.x == 1: PROVED up to bound 5$
55
^\[.*\] first_match\(\(##1 1\) or \(##2 1\)\) \|-> main\.x == 1: PROVED up to bound 5$
6-
^\[.*\] 1 or \(\(##1 1\) \|-> main\.x == 0\): PROVED up to bound 5$
6+
^\[.*\] \(1 or \(##1 1\)\) \|-> main\.x == 0: PROVED up to bound 5$
77
^\[.*\] first_match\(1 or \(##1 1\)\) \|-> main\.x == 0: PROVED up to bound 5$
88
^EXIT=0$
99
^SIGNAL=0$
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
sequence_implication2.sv
3+
--module main
4+
^file .* line 4: sequence required$
5+
^EXIT=2$
6+
^SIGNAL=0$
7+
--
8+
--
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module main(input clk);
2+
3+
// The RHS must be a sequence
4+
assert property (@(posedge clk) (always 1) |-> 1);
5+
6+
endmodule : main

regression/verilog/SVA/sequence_or1.desc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ sequence_or1.sv
55
^\[main\.p1\] strong\(main\.x == 0 or main\.x == 1\): PROVED$
66
^\[main\.p2\] main\.x == 0 or \(nexttime main\.x == 1\): PROVED up to bound \d+$
77
^\[main\.p3\] \(nexttime main\.x == 1\) or main\.x == 1: PROVED up to bound \d+$
8+
^\[main\.p4\] \(main\.x == 0 or main\.x != 10\) |=> main\.x == 1: PROVED up to bound \d+$
89
^EXIT=0$
910
^SIGNAL=0$
1011
--

regression/verilog/SVA/sequence_or1.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ module main(input clk);
1515
initial p2: assert property (x==0 or nexttime x == 1);
1616
initial p3: assert property (nexttime x==1 or x == 1);
1717

18+
// It also yields a sequence when in parentheses.
19+
initial p4: assert property ((x == 0 or x != 10) |=> x == 1);
20+
1821
endmodule

src/temporal-logic/normalize_property.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ exprt normalize_pre_sva_non_overlapped_implication(
2424
sva_non_overlapped_implication_exprt expr)
2525
{
2626
// Same as a->always[1:1] b if lhs is not a sequence.
27-
if(!is_SVA_sequence(expr.lhs()))
27+
if(!is_SVA_sequence_operator(expr.lhs()))
2828
{
2929
auto one = natural_typet{}.one_expr();
3030
return or_exprt{

src/temporal-logic/temporal_logic.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ bool is_LTL_past(const exprt &expr)
9292
return !has_subexpr(expr, non_LTL_past_operator);
9393
}
9494

95-
bool is_SVA_sequence(const exprt &expr)
95+
bool is_SVA_sequence_operator(const exprt &expr)
9696
{
9797
auto id = expr.id();
9898
// Note that ID_sva_overlapped_followed_by and ID_sva_nonoverlapped_followed_by
@@ -114,7 +114,7 @@ bool is_SVA_sequence(const exprt &expr)
114114
bool is_SVA_operator(const exprt &expr)
115115
{
116116
auto id = expr.id();
117-
return is_SVA_sequence(expr) || id == ID_sva_disable_iff ||
117+
return is_SVA_sequence_operator(expr) || id == ID_sva_disable_iff ||
118118
id == ID_sva_accept_on || id == ID_sva_reject_on ||
119119
id == ID_sva_sync_accept_on || id == ID_sva_sync_reject_on ||
120120
id == ID_sva_always || id == ID_sva_s_always ||

src/temporal-logic/temporal_logic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ bool is_LTL_operator(const exprt &);
5454
bool is_LTL_past_operator(const exprt &);
5555

5656
/// Returns true iff the given expression is an SVA sequence expression
57-
bool is_SVA_sequence(const exprt &);
57+
bool is_SVA_sequence_operator(const exprt &);
5858

5959
/// Returns true iff the given expression is an SVA temporal operator
6060
bool is_SVA_operator(const exprt &);

0 commit comments

Comments
 (0)