Skip to content

Commit 522b68e

Browse files
authored
Merge pull request #818 from diffblue/verilog_typecheck_sva
SystemVerilog: extract typechecking for SVA
2 parents b712b0f + 36d29a8 commit 522b68e

File tree

5 files changed

+284
-216
lines changed

5 files changed

+284
-216
lines changed

src/verilog/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SRC = aval_bval_encoding.cpp \
2121
verilog_typecheck.cpp \
2222
verilog_typecheck_base.cpp \
2323
verilog_typecheck_expr.cpp \
24+
verilog_typecheck_sva.cpp \
2425
verilog_y.tab.cpp \
2526
vtype.cpp
2627

src/verilog/verilog_typecheck.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,7 @@ void verilog_typecheckt::convert_assert_assume_cover(
10461046
{
10471047
exprt &cond = module_item.condition();
10481048

1049-
convert_expr(cond);
1049+
convert_sva(cond);
10501050
make_boolean(cond);
10511051

10521052
// We create a symbol for the property.
@@ -1111,7 +1111,7 @@ void verilog_typecheckt::convert_assert_assume_cover(
11111111
{
11121112
exprt &cond = statement.condition();
11131113

1114-
convert_expr(cond);
1114+
convert_sva(cond);
11151115
make_boolean(cond);
11161116

11171117
// We create a symbol for the property.

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 0 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ Author: Daniel Kroening, [email protected]
2020
#include <util/string2int.h>
2121

2222
#include "expr2verilog.h"
23-
#include "sva_expr.h"
2423
#include "verilog_expr.h"
2524
#include "verilog_types.h"
2625
#include "vtype.h"
@@ -2540,13 +2539,6 @@ exprt verilog_typecheck_exprt::convert_unary_expr(unary_exprt expr)
25402539
make_boolean(expr.op());
25412540
}
25422541
}
2543-
else if(expr.id() == ID_sva_not)
2544-
{
2545-
convert_expr(expr.op());
2546-
make_boolean(expr.op());
2547-
expr.type() = bool_typet(); // always boolean, never x
2548-
return std::move(expr);
2549-
}
25502542
else if(expr.id()==ID_reduction_or || expr.id()==ID_reduction_and ||
25512543
expr.id()==ID_reduction_nor || expr.id()==ID_reduction_nand ||
25522544
expr.id()==ID_reduction_xor || expr.id()==ID_reduction_xnor)
@@ -2567,20 +2559,6 @@ exprt verilog_typecheck_exprt::convert_unary_expr(unary_exprt expr)
25672559
no_bool_ops(expr);
25682560
expr.type() = expr.op().type();
25692561
}
2570-
else if(
2571-
expr.id() == ID_sva_always || expr.id() == ID_sva_s_eventually ||
2572-
expr.id() == ID_sva_cycle_delay_plus ||
2573-
expr.id() == ID_sva_cycle_delay_star || expr.id() == ID_sva_weak ||
2574-
expr.id() == ID_sva_strong || expr.id() == ID_sva_nexttime ||
2575-
expr.id() == ID_sva_s_nexttime ||
2576-
expr.id() == ID_sva_sequence_first_match ||
2577-
expr.id() == ID_sva_sequence_repetition_plus ||
2578-
expr.id() == ID_sva_sequence_repetition_star)
2579-
{
2580-
convert_expr(expr.op());
2581-
make_boolean(expr.op());
2582-
expr.type()=bool_typet();
2583-
}
25842562
else if(expr.id() == ID_verilog_explicit_cast)
25852563
{
25862564
// SystemVerilog has got type'(expr). This is an explicit
@@ -2880,21 +2858,6 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
28802858

28812859
return std::move(expr);
28822860
}
2883-
else if(
2884-
expr.id() == ID_sva_and || expr.id() == ID_sva_or ||
2885-
expr.id() == ID_sva_implies || expr.id() == ID_sva_iff)
2886-
{
2887-
for(auto &op : expr.operands())
2888-
{
2889-
convert_expr(op);
2890-
make_boolean(op);
2891-
}
2892-
2893-
// always boolean, never x
2894-
expr.type() = bool_typet();
2895-
2896-
return std::move(expr);
2897-
}
28982861
else if(expr.id()==ID_equal || expr.id()==ID_notequal)
28992862
{
29002863
expr.type()=bool_typet();
@@ -3035,105 +2998,6 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
30352998

30362999
return std::move(expr);
30373000
}
3038-
else if(
3039-
expr.id() == ID_sva_disable_iff || expr.id() == ID_sva_accept_on ||
3040-
expr.id() == ID_sva_reject_on || expr.id() == ID_sva_sync_accept_on ||
3041-
expr.id() == ID_sva_sync_reject_on)
3042-
{
3043-
convert_expr(to_sva_abort_expr(expr).condition());
3044-
make_boolean(to_sva_abort_expr(expr).condition());
3045-
convert_expr(to_sva_abort_expr(expr).property());
3046-
make_boolean(to_sva_abort_expr(expr).property());
3047-
expr.type() = bool_typet();
3048-
return std::move(expr);
3049-
}
3050-
else if(expr.id() == ID_sva_indexed_nexttime)
3051-
{
3052-
convert_expr(to_sva_indexed_nexttime_expr(expr).index());
3053-
3054-
auto &op = to_sva_indexed_nexttime_expr(expr).op();
3055-
convert_expr(op);
3056-
make_boolean(op);
3057-
expr.type() = bool_typet();
3058-
3059-
return std::move(expr);
3060-
}
3061-
else if(expr.id() == ID_sva_indexed_s_nexttime)
3062-
{
3063-
convert_expr(to_sva_indexed_s_nexttime_expr(expr).index());
3064-
3065-
auto &op = to_sva_indexed_s_nexttime_expr(expr).op();
3066-
convert_expr(op);
3067-
make_boolean(op);
3068-
expr.type() = bool_typet();
3069-
3070-
return std::move(expr);
3071-
}
3072-
else if(
3073-
expr.id() == ID_sva_overlapped_implication ||
3074-
expr.id() == ID_sva_non_overlapped_implication ||
3075-
expr.id() == ID_sva_overlapped_followed_by ||
3076-
expr.id() == ID_sva_nonoverlapped_followed_by ||
3077-
expr.id() == ID_sva_until || expr.id() == ID_sva_s_until ||
3078-
expr.id() == ID_sva_until_with || expr.id() == ID_sva_s_until_with)
3079-
{
3080-
convert_expr(expr.op0());
3081-
make_boolean(expr.op0());
3082-
convert_expr(expr.op1());
3083-
make_boolean(expr.op1());
3084-
expr.type()=bool_typet();
3085-
3086-
return std::move(expr);
3087-
}
3088-
else if(expr.id() == ID_sva_sequence_concatenation) // a ##b c
3089-
{
3090-
expr.type() = bool_typet();
3091-
convert_expr(expr.op0());
3092-
make_boolean(expr.op0());
3093-
convert_expr(expr.op1());
3094-
make_boolean(expr.op1());
3095-
return std::move(expr);
3096-
}
3097-
else if(
3098-
expr.id() == ID_sva_sequence_intersect ||
3099-
expr.id() == ID_sva_sequence_throughout ||
3100-
expr.id() == ID_sva_sequence_within ||
3101-
expr.id() == ID_sva_sequence_first_match)
3102-
{
3103-
auto &binary_expr = to_binary_expr(expr);
3104-
3105-
convert_expr(binary_expr.lhs());
3106-
make_boolean(binary_expr.lhs());
3107-
convert_expr(binary_expr.rhs());
3108-
make_boolean(binary_expr.rhs());
3109-
3110-
expr.type() = bool_typet();
3111-
3112-
return std::move(expr);
3113-
}
3114-
else if(
3115-
expr.id() == ID_sva_sequence_consecutive_repetition ||
3116-
expr.id() == ID_sva_sequence_non_consecutive_repetition ||
3117-
expr.id() == ID_sva_sequence_goto_repetition)
3118-
{
3119-
auto &binary_expr = to_binary_expr(expr);
3120-
3121-
convert_expr(binary_expr.lhs());
3122-
make_boolean(binary_expr.lhs());
3123-
3124-
convert_expr(binary_expr.rhs());
3125-
3126-
mp_integer n = elaborate_constant_integer_expression(binary_expr.rhs());
3127-
if(n < 0)
3128-
throw errort().with_location(binary_expr.rhs().source_location())
3129-
<< "number of repetitions must not be negative";
3130-
3131-
binary_expr.rhs() = from_integer(n, integer_typet{});
3132-
3133-
expr.type() = bool_typet();
3134-
3135-
return std::move(expr);
3136-
}
31373001
else if(expr.id()==ID_hierarchical_identifier)
31383002
{
31393003
return convert_hierarchical_identifier(
@@ -3164,28 +3028,6 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
31643028
<< "cannot perform size cast on " << to_string(op_type);
31653029
}
31663030
}
3167-
else if(expr.id() == ID_sva_case)
3168-
{
3169-
auto &case_expr = to_sva_case_expr(expr);
3170-
convert_expr(case_expr.case_op());
3171-
3172-
for(auto &case_item : case_expr.case_items())
3173-
{
3174-
// same rules as case statement
3175-
for(auto &pattern : case_item.patterns())
3176-
{
3177-
convert_expr(pattern);
3178-
typet t = max_type(pattern.type(), case_expr.case_op().type());
3179-
propagate_type(pattern, t);
3180-
}
3181-
3182-
convert_expr(case_item.result());
3183-
make_boolean(case_item.result());
3184-
}
3185-
3186-
expr.type() = bool_typet();
3187-
return std::move(expr);
3188-
}
31893031
else if(
31903032
expr.id() == ID_verilog_streaming_concatenation_left_to_right ||
31913033
expr.id() == ID_verilog_streaming_concatenation_right_to_left)
@@ -3418,62 +3260,6 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
34183260
expr.type()=expr.op1().type();
34193261
return std::move(expr);
34203262
}
3421-
else if(expr.id() == ID_sva_cycle_delay) // ##[1:2] something
3422-
{
3423-
expr.type()=bool_typet();
3424-
convert_expr(expr.op0());
3425-
if(expr.op1().is_not_nil()) convert_expr(expr.op1());
3426-
convert_expr(expr.op2());
3427-
make_boolean(expr.op2());
3428-
return std::move(expr);
3429-
}
3430-
else if(
3431-
expr.id() == ID_sva_eventually || expr.id() == ID_sva_ranged_s_eventually ||
3432-
expr.id() == ID_sva_s_always || expr.id() == ID_sva_ranged_always)
3433-
{
3434-
auto lower = convert_integer_constant_expression(expr.op0());
3435-
3436-
expr.op0() =
3437-
from_integer(lower, natural_typet()).with_source_location(expr.op0());
3438-
3439-
if(expr.op1().id() == ID_infinity)
3440-
{
3441-
}
3442-
else
3443-
{
3444-
auto upper = convert_integer_constant_expression(expr.op1());
3445-
if(lower > upper)
3446-
{
3447-
throw errort().with_location(expr.source_location())
3448-
<< "range must be lower <= upper";
3449-
}
3450-
3451-
expr.op1() =
3452-
from_integer(upper, natural_typet()).with_source_location(expr.op1());
3453-
}
3454-
3455-
convert_expr(expr.op2());
3456-
make_boolean(expr.op2());
3457-
expr.type() = bool_typet();
3458-
3459-
return std::move(expr);
3460-
}
3461-
else if(expr.id() == ID_sva_if)
3462-
{
3463-
convert_expr(expr.op0());
3464-
make_boolean(expr.op0());
3465-
3466-
convert_expr(expr.op1());
3467-
make_boolean(expr.op1());
3468-
3469-
if(expr.op2().is_not_nil())
3470-
{
3471-
convert_expr(expr.op2());
3472-
make_boolean(expr.op2());
3473-
}
3474-
3475-
return std::move(expr);
3476-
}
34773263
else
34783264
{
34793265
throw errort().with_location(expr.source_location())

src/verilog/verilog_typecheck_expr.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
188188
void typecheck_relation(binary_exprt &);
189189
void no_bool_ops(exprt &);
190190

191+
// SVA
192+
void convert_sva(exprt &expr)
193+
{
194+
expr = convert_sva_rec(std::move(expr));
195+
}
196+
197+
[[nodiscard]] exprt convert_sva_rec(exprt);
198+
[[nodiscard]] exprt convert_unary_sva(unary_exprt);
199+
[[nodiscard]] exprt convert_binary_sva(binary_exprt);
200+
[[nodiscard]] exprt convert_ternary_sva(ternary_exprt);
201+
191202
// system functions
192203
exprt bits(const exprt &);
193204
std::optional<mp_integer> bits_rec(const typet &) const;

0 commit comments

Comments
 (0)