Skip to content

Commit 4f0cf7d

Browse files
committed
introduce verilog_sva_property_typet
This introduces a type for Verilog SVA properties to distinguish properties from state predicates and sequences.
1 parent b4375fc commit 4f0cf7d

File tree

8 files changed

+174
-91
lines changed

8 files changed

+174
-91
lines changed

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ IREP_ID_ONE(verilog_null)
147147
IREP_ID_ONE(verilog_event)
148148
IREP_ID_ONE(verilog_event_trigger)
149149
IREP_ID_ONE(verilog_string)
150+
IREP_ID_ONE(verilog_sva_property)
150151
IREP_ID_ONE(verilog_sva_sequence)
151152
IREP_ID_ONE(reg)
152153
IREP_ID_ONE(macromodule)

src/temporal-logic/normalize_property.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ exprt normalize_property(exprt expr)
105105
{
106106
// top-level only
107107
if(expr.id() == ID_sva_cover)
108-
expr = sva_always_exprt{not_exprt{to_sva_cover_expr(expr).op()}};
108+
expr = sva_always_exprt{sva_not_exprt{to_sva_cover_expr(expr).op()}};
109109

110110
expr = trivial_sva(expr);
111111

src/temporal-logic/trivial_sva.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,38 @@ exprt trivial_sva(exprt expr)
3838
auto rhs = is_state_predicate(sva_implication.rhs());
3939

4040
if(lhs.has_value() && rhs.has_value())
41-
expr = implies_exprt{*lhs, *rhs};
41+
expr = sva_boolean_exprt{implies_exprt{*lhs, *rhs}, expr.type()};
4242
}
4343
else if(expr.id() == ID_sva_iff)
4444
{
45+
// same as boolean iff when both lhs/rhs are state predicates
4546
auto &sva_iff = to_sva_iff_expr(expr);
46-
expr = equal_exprt{sva_iff.lhs(), sva_iff.rhs()};
47+
48+
auto lhs = is_state_predicate(sva_iff.lhs());
49+
auto rhs = is_state_predicate(sva_iff.rhs());
50+
51+
if(lhs.has_value() && rhs.has_value())
52+
expr = sva_boolean_exprt{equal_exprt{*lhs, *rhs}, expr.type()};
4753
}
4854
else if(expr.id() == ID_sva_implies)
4955
{
56+
// same as boolean implication when both lhs/rhs are state predicates
5057
auto &sva_implies = to_sva_implies_expr(expr);
51-
expr = implies_exprt{sva_implies.lhs(), sva_implies.rhs()};
58+
59+
auto lhs = is_state_predicate(sva_implies.lhs());
60+
auto rhs = is_state_predicate(sva_implies.rhs());
61+
62+
if(lhs.has_value() && rhs.has_value())
63+
expr = sva_boolean_exprt{implies_exprt{*lhs, *rhs}, expr.type()};
5264
}
5365
else if(expr.id() == ID_sva_and)
5466
{
5567
auto &sva_and = to_sva_and_expr(expr);
5668

5769
// can be sequence or property
58-
if(expr.type().id() == ID_verilog_sva_sequence)
70+
if(
71+
expr.type().id() == ID_verilog_sva_sequence ||
72+
expr.type().id() == ID_verilog_sva_property)
5973
{
6074
// Same as a ∧ b if the expression is not a sequence.
6175
auto lhs = is_state_predicate(sva_and.lhs());
@@ -64,37 +78,36 @@ exprt trivial_sva(exprt expr)
6478
if(lhs.has_value() && rhs.has_value())
6579
expr = sva_boolean_exprt{and_exprt{*lhs, *rhs}, expr.type()};
6680
}
67-
else
68-
{
69-
expr = and_exprt{sva_and.lhs(), sva_and.rhs()};
70-
}
7181
}
7282
else if(expr.id() == ID_sva_or)
7383
{
7484
auto &sva_or = to_sva_or_expr(expr);
7585

7686
// can be sequence or property
77-
if(expr.type().id() == ID_verilog_sva_sequence)
87+
if(
88+
expr.type().id() == ID_verilog_sva_sequence ||
89+
expr.type().id() == ID_verilog_sva_property)
7890
{
79-
// Same as a ∨ b if the expression is not a sequence.
91+
// Same as a ∨ b if the expression is a state predicate.
8092
auto lhs = is_state_predicate(sva_or.lhs());
8193
auto rhs = is_state_predicate(sva_or.rhs());
8294

8395
if(lhs.has_value() && rhs.has_value())
8496
expr = sva_boolean_exprt{or_exprt{*lhs, *rhs}, expr.type()};
8597
}
86-
else
87-
{
88-
expr = or_exprt{sva_or.lhs(), sva_or.rhs()};
89-
}
9098
}
9199
else if(expr.id() == ID_sva_not)
92100
{
93-
// Same as regular 'not'. These do not apply to sequences.
94-
expr = not_exprt{to_sva_not_expr(expr).op()};
101+
// Same as boolean 'not' when applied to a state predicate.
102+
auto &op = to_sva_not_expr(expr).op();
103+
auto predicate = is_state_predicate(op);
104+
if(predicate.has_value())
105+
expr =
106+
sva_boolean_exprt{not_exprt{*predicate}, verilog_sva_property_typet{}};
95107
}
96108
else if(expr.id() == ID_sva_if)
97109
{
110+
// same as boolean 'if' when both cases are state predicates.
98111
auto &sva_if_expr = to_sva_if_expr(expr);
99112
auto false_case = sva_if_expr.false_case().is_nil()
100113
? true_exprt{}

src/trans-word-level/property.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,10 @@ static obligationst property_obligations_rec(
530530
return property_obligations_rec(
531531
to_typecast_expr(property_expr).op(), current, no_timeframes);
532532
}
533-
else if(property_expr.id() == ID_not)
533+
else if(property_expr.id() == ID_sva_not)
534534
{
535535
// We need NNF, try to eliminate the negation.
536-
auto &op = to_not_expr(property_expr).op();
536+
auto &op = to_sva_not_expr(property_expr).op();
537537

538538
auto op_negated_opt = negate_property_node(op);
539539

@@ -570,8 +570,9 @@ static obligationst property_obligations_rec(
570570
else
571571
{
572572
// state formula
573-
return obligationst{
574-
current, instantiate_property(property_expr, current, no_timeframes)};
573+
auto sampled =
574+
instantiate_property(not_exprt{op}, current, no_timeframes);
575+
return obligationst{current, sampled};
575576
}
576577
}
577578
else if(property_expr.id() == ID_sva_implies)

src/verilog/sva_expr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ Author: Daniel Kroening, [email protected]
1111
#include <util/arith_tools.h>
1212
#include <util/mathematical_types.h>
1313

14+
exprt sva_iff_exprt::implications() const
15+
{
16+
return sva_and_exprt{
17+
sva_implies_exprt{lhs(), rhs()}, sva_implies_exprt{rhs(), lhs()}, type()};
18+
}
19+
1420
exprt sva_cycle_delay_plus_exprt::lower() const
1521
{
1622
// same as ##[1:$]

0 commit comments

Comments
 (0)