Skip to content

Commit cdf68a3

Browse files
committed
Verilog: four-valued <=, <, >=, >
This adds the aval/bval lowering for the relational operators.
1 parent 4901b07 commit cdf68a3

File tree

5 files changed

+41
-4
lines changed

5 files changed

+41
-4
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
relational.sv
33
--module main --bound 0
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
x-related tests fail

src/verilog/aval_bval_encoding.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,23 @@ exprt aval_bval(const shift_exprt &expr)
610610
return if_exprt{distance_has_xz, x, combined};
611611
}
612612

613+
exprt aval_bval(const binary_relation_exprt &expr)
614+
{
615+
auto &type = expr.type();
616+
617+
PRECONDITION(type.id() == ID_verilog_unsignedbv);
618+
619+
auto has_xz = or_exprt{::has_xz(expr.lhs()), ::has_xz(expr.rhs())};
620+
621+
exprt two_valued_expr = binary_predicate_exprt{
622+
aval_underlying(expr.lhs()), expr.id(), aval_underlying(expr.rhs())};
623+
624+
return if_exprt{
625+
has_xz,
626+
make_x(type),
627+
aval_bval_conversion(two_valued_expr, lower_to_aval_bval(type))};
628+
}
629+
613630
exprt default_aval_bval_lowering(const exprt &expr)
614631
{
615632
auto &type = expr.type();

src/verilog/aval_bval_encoding.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ exprt aval_bval(const verilog_implies_exprt &);
6969
exprt aval_bval(const typecast_exprt &);
7070
/// lowering for shifts
7171
exprt aval_bval(const shift_exprt &);
72+
/// lowering for <=, <, etc.
73+
exprt aval_bval(const binary_relation_exprt &);
7274

7375
/// If any operand has x/z, then the result is 'x'.
7476
/// Otherwise, the result is the expression applied to the aval

src/verilog/verilog_lowering.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,17 @@ exprt verilog_lowering(exprt expr)
421421
else
422422
return expr;
423423
}
424+
else if(
425+
expr.id() == ID_le || expr.id() == ID_ge || expr.id() == ID_lt ||
426+
expr.id() == ID_ge)
427+
{
428+
if(is_four_valued(expr))
429+
{
430+
return aval_bval(to_binary_relation_expr(expr));
431+
}
432+
else
433+
return expr;
434+
}
424435
else if(expr.id() == ID_concatenation)
425436
{
426437
if(

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,11 +3203,19 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
32033203
else if(expr.id()==ID_lt || expr.id()==ID_gt ||
32043204
expr.id()==ID_le || expr.id()==ID_ge)
32053205
{
3206-
expr.type()=bool_typet();
3207-
32083206
convert_relation(expr);
32093207
no_bool_ops(expr);
32103208

3209+
// This returns 'x' if either of the operands contains x or z.
3210+
if(is_four_valued(expr.lhs().type()) || is_four_valued(expr.rhs().type()))
3211+
{
3212+
expr.type() = verilog_unsignedbv_typet(1);
3213+
}
3214+
else
3215+
{
3216+
expr.type() = bool_typet{};
3217+
}
3218+
32113219
return std::move(expr);
32123220
}
32133221
else if(expr.id() == ID_power)

0 commit comments

Comments
 (0)