Skip to content

Commit c01aecf

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 c01aecf

File tree

8 files changed

+172
-91
lines changed

8 files changed

+172
-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: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,39 @@ 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{
42+
implies_exprt{*lhs, *rhs}, expr.type()};
4243
}
4344
else if(expr.id() == ID_sva_iff)
4445
{
46+
// same as boolean iff when both lhs/rhs are state predicates
4547
auto &sva_iff = to_sva_iff_expr(expr);
46-
expr = equal_exprt{sva_iff.lhs(), sva_iff.rhs()};
48+
49+
auto lhs = is_state_predicate(sva_iff.lhs());
50+
auto rhs = is_state_predicate(sva_iff.rhs());
51+
52+
if(lhs.has_value() && rhs.has_value())
53+
expr = sva_boolean_exprt{
54+
equal_exprt{*lhs, *rhs}, expr.type()};
4755
}
4856
else if(expr.id() == ID_sva_implies)
4957
{
58+
// same as boolean implication when both lhs/rhs are state predicates
5059
auto &sva_implies = to_sva_implies_expr(expr);
51-
expr = implies_exprt{sva_implies.lhs(), sva_implies.rhs()};
60+
61+
auto lhs = is_state_predicate(sva_implies.lhs());
62+
auto rhs = is_state_predicate(sva_implies.rhs());
63+
64+
if(lhs.has_value() && rhs.has_value())
65+
expr = sva_boolean_exprt{
66+
implies_exprt{*lhs, *rhs}, expr.type()};
5267
}
5368
else if(expr.id() == ID_sva_and)
5469
{
5570
auto &sva_and = to_sva_and_expr(expr);
5671

5772
// can be sequence or property
58-
if(expr.type().id() == ID_verilog_sva_sequence)
73+
if(expr.type().id() == ID_verilog_sva_sequence || expr.type().id() == ID_verilog_sva_property)
5974
{
6075
// Same as a ∧ b if the expression is not a sequence.
6176
auto lhs = is_state_predicate(sva_and.lhs());
@@ -64,37 +79,34 @@ exprt trivial_sva(exprt expr)
6479
if(lhs.has_value() && rhs.has_value())
6580
expr = sva_boolean_exprt{and_exprt{*lhs, *rhs}, expr.type()};
6681
}
67-
else
68-
{
69-
expr = and_exprt{sva_and.lhs(), sva_and.rhs()};
70-
}
7182
}
7283
else if(expr.id() == ID_sva_or)
7384
{
7485
auto &sva_or = to_sva_or_expr(expr);
7586

7687
// can be sequence or property
77-
if(expr.type().id() == ID_verilog_sva_sequence)
88+
if(expr.type().id() == ID_verilog_sva_sequence || expr.type().id() == ID_verilog_sva_property)
7889
{
79-
// Same as a ∨ b if the expression is not a sequence.
90+
// Same as a ∨ b if the expression is a state predicate.
8091
auto lhs = is_state_predicate(sva_or.lhs());
8192
auto rhs = is_state_predicate(sva_or.rhs());
8293

8394
if(lhs.has_value() && rhs.has_value())
8495
expr = sva_boolean_exprt{or_exprt{*lhs, *rhs}, expr.type()};
8596
}
86-
else
87-
{
88-
expr = or_exprt{sva_or.lhs(), sva_or.rhs()};
89-
}
9097
}
9198
else if(expr.id() == ID_sva_not)
9299
{
93-
// Same as regular 'not'. These do not apply to sequences.
94-
expr = not_exprt{to_sva_not_expr(expr).op()};
100+
// Same as boolean 'not' when applied to a state predicate.
101+
auto &op = to_sva_not_expr(expr).op();
102+
auto predicate = is_state_predicate(op);
103+
if(predicate.has_value())
104+
expr =
105+
sva_boolean_exprt{not_exprt{*predicate}, verilog_sva_property_typet{}};
95106
}
96107
else if(expr.id() == ID_sva_if)
97108
{
109+
// same as boolean 'if' when both cases are state predicates.
98110
auto &sva_if_expr = to_sva_if_expr(expr);
99111
auto false_case = sva_if_expr.false_case().is_nil()
100112
? 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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ 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{sva_implies_exprt{lhs(), rhs()}, sva_implies_exprt{rhs(), lhs()}, type()};
17+
}
18+
1419
exprt sva_cycle_delay_plus_exprt::lower() const
1520
{
1621
// same as ##[1:$]

0 commit comments

Comments
 (0)