Skip to content

Commit bad2f99

Browse files
authored
Merge pull request #1041 from diffblue/verilog_sva_sequence
Verilog: type for SVA sequences
2 parents ed453c4 + c9673b3 commit bad2f99

13 files changed

+201
-77
lines changed

regression/verilog/SVA/sequence_implication2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
sequence_implication2.sv
33
--module main
4-
^file .* line 4: sequence required$
4+
^file .* line 4: sequence required, but got property$
55
^EXIT=2$
66
^SIGNAL=0$
77
--

regression/verilog/SVA/sequence_repetition6.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
sequence_repetition6.sv
33

4-
^file .* line 4: sequence required$
4+
^file .* line 4: sequence required, but got property$
55
^EXIT=2$
66
^SIGNAL=0$
77
--

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ IREP_ID_ONE(verilog_null)
136136
IREP_ID_ONE(verilog_event)
137137
IREP_ID_ONE(verilog_event_trigger)
138138
IREP_ID_ONE(verilog_string)
139+
IREP_ID_ONE(verilog_sva_sequence)
139140
IREP_ID_ONE(reg)
140141
IREP_ID_ONE(macromodule)
141142
IREP_ID_ONE(output_register)

src/temporal-logic/normalize_property.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,6 @@ exprt normalize_property_rec(exprt expr)
9797
{
9898
expr = sva_s_eventually_exprt{to_sva_cycle_delay_star_expr(expr).op()};
9999
}
100-
else if(expr.id() == ID_sva_strong)
101-
{
102-
expr = to_sva_strong_expr(expr).op();
103-
}
104-
else if(expr.id() == ID_sva_weak)
105-
{
106-
expr = to_sva_weak_expr(expr).op();
107-
}
108100

109101
// normalize the operands
110102
for(auto &op : expr.operands())

src/temporal-logic/trivial_sva.cpp

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,29 @@ Author: Daniel Kroening, [email protected]
1212

1313
#include "temporal_logic.h"
1414

15+
static std::optional<exprt> is_state_formula(const exprt &expr)
16+
{
17+
if(expr.id() == ID_typecast && expr.type().id() == ID_verilog_sva_sequence)
18+
return to_typecast_expr(expr).op();
19+
else if(expr.type().id() == ID_bool)
20+
return expr;
21+
else
22+
return {};
23+
}
24+
1525
exprt trivial_sva(exprt expr)
1626
{
1727
// pre-traversal
1828
if(expr.id() == ID_sva_overlapped_implication)
1929
{
2030
// Same as regular implication if lhs and rhs are not sequences.
2131
auto &sva_implication = to_sva_overlapped_implication_expr(expr);
22-
if(
23-
!is_SVA_sequence_operator(sva_implication.lhs()) &&
24-
!is_SVA_sequence_operator(sva_implication.rhs()))
25-
{
26-
expr = implies_exprt{sva_implication.lhs(), sva_implication.rhs()};
27-
}
32+
33+
auto lhs = is_state_formula(sva_implication.lhs());
34+
auto rhs = is_state_formula(sva_implication.rhs());
35+
36+
if(lhs.has_value() && rhs.has_value())
37+
expr = implies_exprt{*lhs, *rhs};
2838
}
2939
else if(expr.id() == ID_sva_iff)
3040
{
@@ -38,21 +48,25 @@ exprt trivial_sva(exprt expr)
3848
}
3949
else if(expr.id() == ID_sva_and)
4050
{
41-
// Same as a ∧ b if lhs and rhs are not sequences.
4251
auto &sva_and = to_sva_and_expr(expr);
43-
if(
44-
!is_SVA_sequence_operator(sva_and.lhs()) &&
45-
!is_SVA_sequence_operator(sva_and.rhs()))
46-
expr = and_exprt{sva_and.lhs(), sva_and.rhs()};
52+
53+
// Same as a ∧ b if the expression is not a sequence.
54+
auto lhs = is_state_formula(sva_and.lhs());
55+
auto rhs = is_state_formula(sva_and.rhs());
56+
57+
if(lhs.has_value() && rhs.has_value())
58+
expr = and_exprt{*lhs, *rhs};
4759
}
4860
else if(expr.id() == ID_sva_or)
4961
{
50-
// Same as a ∧ b if lhs or rhs are not sequences.
5162
auto &sva_or = to_sva_or_expr(expr);
52-
if(
53-
!is_SVA_sequence_operator(sva_or.lhs()) &&
54-
!is_SVA_sequence_operator(sva_or.rhs()))
55-
expr = or_exprt{sva_or.lhs(), sva_or.rhs()};
63+
64+
// Same as a ∨ b if the expression is not a sequence.
65+
auto lhs = is_state_formula(sva_or.lhs());
66+
auto rhs = is_state_formula(sva_or.rhs());
67+
68+
if(lhs.has_value() && rhs.has_value())
69+
expr = or_exprt{*lhs, *rhs};
5670
}
5771
else if(expr.id() == ID_sva_not)
5872
{
@@ -93,6 +107,14 @@ exprt trivial_sva(exprt expr)
93107
op = trivial_sva(op);
94108

95109
// post-traversal
110+
if(expr.id() == ID_typecast)
111+
{
112+
// We typecast sequences to bool, and hence can drop
113+
// casts from bool to bool
114+
auto &op = to_typecast_expr(expr).op();
115+
if(expr.type().id() == ID_bool && op.type().id() == ID_bool)
116+
return op;
117+
}
96118

97119
return expr;
98120
}

src/trans-word-level/instantiate_word_level.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,15 @@ wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
119119
{
120120
return {t, timeframe_symbol(t, to_symbol_expr(std::move(expr)))};
121121
}
122-
else if(is_SVA_sequence_operator(expr))
122+
else if(
123+
expr.id() == ID_typecast && expr.type().id() == ID_bool &&
124+
to_typecast_expr(expr).op().type().id() == ID_verilog_sva_sequence)
123125
{
126+
auto &sequence = to_typecast_expr(expr).op();
127+
124128
// sequence expressions -- these may have multiple potential
125129
// match points, and evaluate to true if any of them matches
126-
const auto matches = instantiate_sequence(expr, t, no_timeframes);
130+
const auto matches = instantiate_sequence(sequence, t, no_timeframes);
127131
exprt::operandst disjuncts;
128132
disjuncts.reserve(matches.size());
129133
mp_integer max = t;

src/trans-word-level/property.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,26 @@ static obligationst property_obligations_rec(
645645
}
646646
return obligationst{t, disjunction(disjuncts)};
647647
}
648+
else if(
649+
property_expr.id() == ID_sva_strong || property_expr.id() == ID_sva_weak)
650+
{
651+
auto &sequence = to_unary_expr(property_expr).op();
652+
653+
// sequence expressions -- these may have multiple potential
654+
// match points, and evaluate to true if any of them matches
655+
const auto matches = instantiate_sequence(sequence, current, no_timeframes);
656+
exprt::operandst disjuncts;
657+
disjuncts.reserve(matches.size());
658+
mp_integer max = current;
659+
660+
for(auto &match : matches)
661+
{
662+
disjuncts.push_back(match.condition);
663+
max = std::max(max, match.end_time);
664+
}
665+
666+
return obligationst{max, disjunction(disjuncts)};
667+
}
648668
else
649669
{
650670
return obligationst{

src/verilog/expr2verilog.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,16 @@ expr2verilogt::resultt expr2verilogt::convert_sva_unary(
531531
const unary_exprt &src)
532532
{
533533
auto op = convert_rec(src.op());
534-
if(op.p == verilog_precedencet::MIN && src.op().operands().size() >= 2)
534+
535+
auto op_skip_typecast =
536+
src.op().id() == ID_typecast ? to_typecast_expr(src.op()).op() : src.op();
537+
538+
if(
539+
op.p == verilog_precedencet::MIN && op_skip_typecast.operands().size() >= 2)
540+
{
535541
op.s = "(" + op.s + ")";
542+
}
543+
536544
return {verilog_precedencet::MIN, name + " " + op.s};
537545
}
538546

src/verilog/sva_expr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ exprt sva_case_exprt::lowering() const
4141

4242
exprt sva_sequence_consecutive_repetition_exprt::lower() const
4343
{
44-
PRECONDITION(op().type().id() == ID_bool);
44+
PRECONDITION(
45+
op().type().id() == ID_bool || op().type().id() == ID_verilog_sva_sequence);
4546

4647
if(to().is_nil())
4748
{

src/verilog/sva_expr.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include <util/std_expr.h>
1313

14+
#include "verilog_types.h"
15+
1416
/// accept_on, reject_on, sync_accept_on, sync_reject_on, disable_iff
1517
class sva_abort_exprt : public binary_predicate_exprt
1618
{
@@ -1240,7 +1242,7 @@ class sva_sequence_consecutive_repetition_exprt : public ternary_exprt
12401242
std::move(__op),
12411243
std::move(__repetitions),
12421244
nil_exprt{},
1243-
bool_typet{}}
1245+
verilog_sva_sequence_typet{}}
12441246
{
12451247
}
12461248

@@ -1253,7 +1255,7 @@ class sva_sequence_consecutive_repetition_exprt : public ternary_exprt
12531255
std::move(__op),
12541256
std::move(__from),
12551257
std::move(__to),
1256-
bool_typet{}}
1258+
verilog_sva_sequence_typet{}}
12571259
{
12581260
}
12591261

src/verilog/verilog_typecheck.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ void verilog_typecheckt::convert_assert_assume_cover(
10511051
exprt &cond = module_item.condition();
10521052

10531053
convert_sva(cond);
1054-
make_boolean(cond);
1054+
require_sva_property(cond);
10551055

10561056
// We create a symbol for the property.
10571057
// The 'value' of the symbol is set by synthesis.
@@ -1116,7 +1116,7 @@ void verilog_typecheckt::convert_assert_assume_cover(
11161116
exprt &cond = statement.condition();
11171117

11181118
convert_sva(cond);
1119-
make_boolean(cond);
1119+
require_sva_property(cond);
11201120

11211121
// We create a symbol for the property.
11221122
// The 'value' is set by synthesis.
@@ -1819,11 +1819,11 @@ void verilog_typecheckt::convert_sequence_declaration(
18191819
auto base_name = declaration.base_name();
18201820
auto full_identifier = hierarchical_identifier(base_name);
18211821

1822-
convert_sva(declaration.sequence());
1822+
auto &sequence = declaration.sequence();
1823+
convert_sva(sequence);
1824+
require_sva_sequence(sequence);
18231825

1824-
auto type = bool_typet{};
1825-
type.set(ID_C_verilog_type, ID_verilog_sequence_declaration);
1826-
symbolt symbol{full_identifier, type, mode};
1826+
symbolt symbol{full_identifier, sequence.type(), mode};
18271827

18281828
symbol.module = module_identifier;
18291829
symbol.base_name = base_name;

0 commit comments

Comments
 (0)