Skip to content

Commit 3cd2db6

Browse files
committed
Verilog: fix semantics of cover disable iff
SVA cover items do not pass when disabled.
1 parent ff06c23 commit 3cd2db6

File tree

5 files changed

+45
-16
lines changed

5 files changed

+45
-16
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# EBMC 5.8
22

33
* SystemVerilog: cover sequence
4+
* SystemVerilog: fix semantics of cover disable iff
45

56
# EBMC 5.7
67

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
cover_sequence5.sv
33
--bound 10
44
^EXIT=10$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This gives the wrong answer.

src/temporal-logic/normalize_property.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,54 @@ exprt normalize_property_rec(exprt expr)
109109
return expr;
110110
}
111111

112+
// Turn "disable iff" into an OR for assertions,
113+
// and into an AND for cover statements.
114+
void rewrite_disable_iff(exprt &expr, bool cover)
115+
{
116+
expr.visit_post(
117+
[cover](exprt &node)
118+
{
119+
if(node.id() == ID_sva_disable_iff)
120+
{
121+
auto &disable_iff = to_sva_disable_iff_expr(node);
122+
if(cover)
123+
{
124+
// a sva_disable_iff b --> ¬a ∧ b
125+
node = and_exprt{not_exprt{disable_iff.lhs()}, disable_iff.rhs()};
126+
}
127+
else // assertion
128+
{
129+
// a sva_disable_iff b --> a ∨ b
130+
node = or_exprt{disable_iff.lhs(), disable_iff.rhs()};
131+
}
132+
}
133+
else if(node.id() == ID_sva_sequence_disable_iff)
134+
{
135+
// only used in cover sequence (disable iff ...)
136+
PRECONDITION(cover);
137+
auto &disable_iff = to_sva_sequence_disable_iff_expr(node);
138+
// a sva_disable_iff b --> ¬a and b
139+
node = sva_and_exprt{
140+
sva_boolean_exprt{
141+
not_exprt{disable_iff.lhs()}, verilog_sva_sequence_typet{}},
142+
disable_iff.rhs(),
143+
verilog_sva_sequence_typet{}};
144+
}
145+
});
146+
}
147+
112148
exprt normalize_property(exprt expr)
113149
{
114150
// top-level only
115151
if(expr.id() == ID_sva_cover)
152+
{
153+
rewrite_disable_iff(to_sva_cover_expr(expr).op(), true);
116154
expr = sva_always_exprt{sva_not_exprt{to_sva_cover_expr(expr).op()}};
155+
}
156+
else
157+
{
158+
rewrite_disable_iff(expr, false);
159+
}
117160

118161
expr = trivial_sva(expr);
119162

src/temporal-logic/trivial_sva.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,6 @@ exprt trivial_sva(exprt expr)
105105
: sva_if_expr.false_case();
106106
expr = if_exprt{sva_if_expr.cond(), sva_if_expr.true_case(), false_case};
107107
}
108-
else if(expr.id() == ID_sva_disable_iff)
109-
{
110-
auto &disable_iff_expr = to_sva_disable_iff_expr(expr);
111-
expr = or_exprt{disable_iff_expr.lhs(), disable_iff_expr.rhs()};
112-
}
113-
else if(expr.id() == ID_sva_sequence_disable_iff)
114-
{
115-
auto &disable_iff_expr = to_sva_sequence_disable_iff_expr(expr);
116-
expr = sva_or_exprt{
117-
sva_boolean_exprt{disable_iff_expr.lhs(), verilog_sva_sequence_typet{}},
118-
disable_iff_expr.rhs(),
119-
verilog_sva_sequence_typet{}};
120-
}
121108
else if(expr.id() == ID_sva_accept_on || expr.id() == ID_sva_sync_accept_on)
122109
{
123110
auto &sva_abort_expr = to_sva_abort_expr(expr);

src/temporal-logic/trivial_sva.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ Author: Daniel Kroening, dkr@amazon.com
2222
/// sva_overlapped_implication --> a -> b if a and b are not sequences
2323
/// sva_if --> ? :
2424
/// sva_case --> ? :
25-
/// a sva_disable_iff b --> a ∨ b
2625
/// a sva_accept_on b --> a ∨ b
2726
/// a sva_reject_on b --> ¬a ∧ b
2827
/// a sva_sync_accept_on b --> a ∨ b

0 commit comments

Comments
 (0)