Skip to content

Commit 4e9d253

Browse files
committed
Verilog: default aval/bval lowering
This introduces a default lowering for four-valued expressions. If any operand has x/z, then the result is 'x'. Otherwise, the result is the expression applied to the aval of the operands.
1 parent 5daee41 commit 4e9d253

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

src/verilog/aval_bval_encoding.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ bv_typet aval_bval_type(std::size_t width, irep_idt source_type)
3636

3737
bv_typet lower_to_aval_bval(const typet &src)
3838
{
39-
PRECONDITION(
40-
src.id() == ID_verilog_unsignedbv || src.id() == ID_verilog_signedbv);
39+
PRECONDITION(is_four_valued(src));
4140
return aval_bval_type(to_bitvector_type(src).get_width(), src.id());
4241
}
4342

@@ -75,9 +74,7 @@ typet aval_bval_underlying(const typet &src)
7574

7675
constant_exprt lower_to_aval_bval(const constant_exprt &src)
7776
{
78-
PRECONDITION(
79-
src.type().id() == ID_verilog_signedbv ||
80-
src.type().id() == ID_verilog_unsignedbv);
77+
PRECONDITION(is_four_valued(src.type()));
8178

8279
auto new_type = lower_to_aval_bval(src.type());
8380
auto width = aval_bval_width(new_type);
@@ -256,7 +253,7 @@ exprt has_xz(const exprt &expr)
256253
return false_exprt{}; // it's two-valued
257254
}
258255

259-
/// return 'x', one bit, in aval_bval encoding
256+
/// return 'x'
260257
exprt make_x(const typet &type)
261258
{
262259
PRECONDITION(is_four_valued(type));
@@ -470,3 +467,26 @@ exprt aval_bval(const shift_exprt &expr)
470467
auto x = make_x(expr.type());
471468
return if_exprt{distance_has_xz, x, combined};
472469
}
470+
471+
exprt default_aval_bval_lowering(const exprt &expr)
472+
{
473+
auto &type = expr.type();
474+
475+
PRECONDITION(is_four_valued(type));
476+
477+
exprt::operandst disjuncts;
478+
for(auto &op : expr.operands())
479+
disjuncts.push_back(has_xz(op));
480+
481+
auto has_xz = disjunction(disjuncts);
482+
483+
exprt two_valued_expr = expr; // copy
484+
485+
for(auto &op : two_valued_expr.operands())
486+
op = aval_underlying(op); // replace by aval
487+
488+
return if_exprt{
489+
has_xz,
490+
make_x(type),
491+
aval_bval_conversion(two_valued_expr, lower_to_aval_bval(type))};
492+
}

src/verilog/aval_bval_encoding.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,9 @@ exprt aval_bval(const typecast_exprt &);
6666
/// lowering for shifts
6767
exprt aval_bval(const shift_exprt &);
6868

69+
/// If any operand has x/z, then the result is 'x'.
70+
/// Otherwise, the result is the expression applied to the aval
71+
/// of the operands.
72+
exprt default_aval_bval_lowering(const exprt &);
73+
6974
#endif

0 commit comments

Comments
 (0)