Skip to content

Commit 57ef9f2

Browse files
authored
Merge pull request #1046 from diffblue/require_sva_property
SVA: `require_sva_property`
2 parents 54fd314 + e7dc12f commit 57ef9f2

File tree

2 files changed

+64
-57
lines changed

2 files changed

+64
-57
lines changed

src/verilog/verilog_typecheck_expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
200200
}
201201

202202
void require_sva_sequence(const exprt &) const;
203+
void require_sva_property(exprt &);
203204

204205
[[nodiscard]] exprt convert_sva_rec(exprt);
205206
[[nodiscard]] exprt convert_unary_sva(unary_exprt);

src/verilog/verilog_typecheck_sva.cpp

Lines changed: 63 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,25 @@ Author: Daniel Kroening, [email protected]
1616

1717
exprt verilog_typecheck_exprt::convert_unary_sva(unary_exprt expr)
1818
{
19-
if(expr.id() == ID_sva_not)
19+
if(
20+
expr.id() == ID_sva_not || expr.id() == ID_sva_always ||
21+
expr.id() == ID_sva_s_eventually || expr.id() == ID_sva_nexttime ||
22+
expr.id() == ID_sva_s_nexttime)
2023
{
2124
convert_sva(expr.op());
22-
make_boolean(expr.op());
23-
expr.type() = bool_typet(); // always boolean, never x
25+
require_sva_property(expr.op());
26+
expr.type() = bool_typet{}; // always boolean, never x
2427
return std::move(expr);
2528
}
2629
else if(
27-
expr.id() == ID_sva_always || expr.id() == ID_sva_s_eventually ||
2830
expr.id() == ID_sva_cycle_delay_plus ||
2931
expr.id() == ID_sva_cycle_delay_star || expr.id() == ID_sva_weak ||
30-
expr.id() == ID_sva_strong || expr.id() == ID_sva_nexttime ||
31-
expr.id() == ID_sva_s_nexttime)
32-
{
33-
convert_sva(expr.op());
34-
make_boolean(expr.op());
35-
expr.type() = bool_typet();
36-
return std::move(expr);
37-
}
38-
else if(
32+
expr.id() == ID_sva_strong ||
3933
expr.id() == ID_sva_sequence_repetition_plus || // x[+]
4034
expr.id() == ID_sva_sequence_repetition_star) // x[*}
4135
{
42-
// These both take a sequence as argument.
43-
// The grammar allows properties to implement and/or over
36+
// These take a sequence as argument.
37+
// For some, the grammar allows properties to implement and/or over
4438
// sequences. Check here that the argument is a sequence.
4539
convert_sva(expr.op());
4640
require_sva_sequence(expr.op());
@@ -63,20 +57,35 @@ void verilog_typecheck_exprt::require_sva_sequence(const exprt &expr) const
6357
}
6458
}
6559

60+
void verilog_typecheck_exprt::require_sva_property(exprt &expr)
61+
{
62+
make_boolean(expr);
63+
}
64+
6665
exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
6766
{
68-
if(
69-
expr.id() == ID_sva_and || expr.id() == ID_sva_or ||
70-
expr.id() == ID_sva_implies || expr.id() == ID_sva_iff)
67+
if(expr.id() == ID_sva_implies || expr.id() == ID_sva_iff)
7168
{
72-
for(auto &op : expr.operands())
73-
{
74-
convert_sva(op);
75-
make_boolean(op);
76-
}
69+
convert_sva(expr.lhs());
70+
convert_sva(expr.rhs());
71+
72+
require_sva_property(expr.lhs());
73+
require_sva_property(expr.rhs());
7774

7875
// always boolean, never x
79-
expr.type() = bool_typet();
76+
expr.type() = bool_typet{};
77+
78+
return std::move(expr);
79+
}
80+
else if(expr.id() == ID_sva_and || expr.id() == ID_sva_or)
81+
{
82+
convert_sva(expr.lhs());
83+
make_boolean(expr.lhs());
84+
85+
convert_sva(expr.rhs());
86+
make_boolean(expr.rhs());
87+
88+
expr.type() = bool_typet{};
8089

8190
return std::move(expr);
8291
}
@@ -85,11 +94,15 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
8594
expr.id() == ID_sva_reject_on || expr.id() == ID_sva_sync_accept_on ||
8695
expr.id() == ID_sva_sync_reject_on)
8796
{
97+
// The condition of these is special: They are not sampled,
98+
// but evaluated directly (1800-2017 16.6).
8899
convert_expr(to_sva_abort_expr(expr).condition());
89100
make_boolean(to_sva_abort_expr(expr).condition());
101+
90102
convert_sva(to_sva_abort_expr(expr).property());
91-
make_boolean(to_sva_abort_expr(expr).property());
92-
expr.type() = bool_typet();
103+
require_sva_property(to_sva_abort_expr(expr).property());
104+
expr.type() = bool_typet{};
105+
93106
return std::move(expr);
94107
}
95108
else if(expr.id() == ID_sva_indexed_nexttime)
@@ -98,8 +111,8 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
98111

99112
auto &op = to_sva_indexed_nexttime_expr(expr).op();
100113
convert_sva(op);
101-
make_boolean(op);
102-
expr.type() = bool_typet();
114+
require_sva_property(op);
115+
expr.type() = bool_typet{};
103116

104117
return std::move(expr);
105118
}
@@ -109,8 +122,8 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
109122

110123
auto &op = to_sva_indexed_s_nexttime_expr(expr).op();
111124
convert_sva(op);
112-
make_boolean(op);
113-
expr.type() = bool_typet();
125+
require_sva_property(op);
126+
expr.type() = bool_typet{};
114127

115128
return std::move(expr);
116129
}
@@ -126,37 +139,29 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
126139
convert_sva(expr.lhs());
127140
require_sva_sequence(expr.lhs());
128141
make_boolean(expr.lhs());
142+
129143
convert_sva(expr.rhs());
130-
make_boolean(expr.rhs());
131-
expr.type() = bool_typet();
144+
require_sva_property(expr.rhs());
145+
146+
expr.type() = bool_typet{};
132147
return std::move(expr);
133148
}
134149
else if(
135150
expr.id() == ID_sva_until || expr.id() == ID_sva_s_until ||
136151
expr.id() == ID_sva_until_with || expr.id() == ID_sva_s_until_with)
137152
{
138-
convert_sva(expr.op0());
139-
make_boolean(expr.op0());
140-
convert_sva(expr.op1());
141-
make_boolean(expr.op1());
142-
expr.type() = bool_typet();
143-
144-
return std::move(expr);
145-
}
146-
else if(expr.id() == ID_sva_sequence_concatenation) // a ##b c
147-
{
148-
// This requires a sequence on the LHS.
149-
// The grammar allows properties on the LHS to implement and/or over
150-
// sequences. Check here that the LHS is a sequence.
151153
convert_sva(expr.lhs());
152-
require_sva_sequence(expr.lhs());
153-
make_boolean(expr.op0());
154-
convert_sva(expr.op1());
155-
make_boolean(expr.op1());
156-
expr.type() = bool_typet();
154+
require_sva_property(expr.lhs());
155+
156+
convert_sva(expr.rhs());
157+
require_sva_property(expr.rhs());
158+
159+
expr.type() = bool_typet{};
160+
157161
return std::move(expr);
158162
}
159163
else if(
164+
expr.id() == ID_sva_sequence_concatenation || // a ##b c
160165
expr.id() == ID_sva_sequence_intersect ||
161166
expr.id() == ID_sva_sequence_within)
162167
{
@@ -166,21 +171,22 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
166171
convert_sva(expr.lhs());
167172
require_sva_sequence(expr.lhs());
168173
make_boolean(expr.lhs());
169-
convert_sva(expr.rhs());
170-
make_boolean(expr.rhs());
171174

172-
expr.type() = bool_typet();
175+
convert_sva(expr.rhs());
176+
require_sva_property(expr.rhs());
177+
expr.type() = bool_typet{};
173178

174179
return std::move(expr);
175180
}
176181
else if(expr.id() == ID_sva_sequence_throughout)
177182
{
178183
convert_expr(expr.lhs());
179184
make_boolean(expr.lhs());
185+
180186
convert_sva(expr.rhs());
181187
make_boolean(expr.rhs());
182188

183-
expr.type() = bool_typet();
189+
expr.type() = bool_typet{};
184190

185191
return std::move(expr);
186192
}
@@ -205,7 +211,7 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
205211
convert_sva(expr.lhs());
206212
make_boolean(expr.lhs());
207213

208-
convert_sva(expr.rhs());
214+
convert_expr(expr.rhs());
209215

210216
mp_integer n = elaborate_constant_integer_expression(expr.rhs());
211217
if(n < 0)
@@ -234,10 +240,10 @@ exprt verilog_typecheck_exprt::convert_binary_sva(binary_exprt expr)
234240
}
235241

236242
convert_sva(case_item.result());
237-
make_boolean(case_item.result());
243+
require_sva_property(case_item.result());
238244
}
239245

240-
expr.type() = bool_typet();
246+
expr.type() = bool_typet{};
241247
return std::move(expr);
242248
}
243249
else

0 commit comments

Comments
 (0)