Skip to content

Commit 087b7f0

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 087b7f0

File tree

12 files changed

+78
-39
lines changed

12 files changed

+78
-39
lines changed
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module main;
22

33
// Any arithmetic with x or z returns x.
4-
initial assert('bx / 1 === 'x);
5-
initial assert('bz / 1 === 'x);
6-
initial assert(1 / 'bx === 'x);
7-
initial assert(1 / 'bz === 'x);
4+
initial assert('bx / 1 === 32'hxxxx_xxxx);
5+
initial assert('bz / 1 === 32'hxxxx_xxxx);
6+
initial assert(1 / 'bx === 32'hxxxx_xxxx);
7+
initial assert(1 / 'bz === 32'hxxxx_xxxx);
88

99
// Division by zero returns x
10-
initial assert(1 / 0 === 'x);
11-
initial assert(1 / 0 === 'x);
10+
initial assert(1 / 0 === 32'hxxxx_xxxx);
11+
initial assert(1 / 0 === 32'hxxxx_xxxx);
1212

1313
endmodule
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
minus1.sv
33

44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The result is wrong.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
module main;
22

33
// Any arithmetic with x or z returns x.
4-
initial assert('bx - 1 === 'x);
5-
initial assert('bz - 1 === 'x);
6-
initial assert(1 - 'bx === 'x);
7-
initial assert(1 - 'bz === 'x);
4+
initial assert(32'bx - 1 === 32'hxxxx_xxxx);
5+
initial assert(32'bz - 1 === 32'hxxxx_xxxx);
6+
initial assert(1 - 32'bx === 32'hxxxx_xxxx);
7+
initial assert(1 - 32'bz === 32'hxxxx_xxxx);
88

99
endmodule
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module main;
22

33
// Any arithmetic with x or z returns x.
4-
initial assert('bx % 1 === 'x);
5-
initial assert('bz % 1 === 'x);
6-
initial assert(1 % 'bx === 'x);
7-
initial assert(1 % 'bz === 'x);
4+
initial assert(32'bx % 1 === 32'hxxxx_xxxx);
5+
initial assert(32'bz % 1 === 32'hxxxx_xxxx);
6+
initial assert(1 % 32'bx === 32'hxxxx_xxxx);
7+
initial assert(1 % 32'bz === 32'hxxxx_xxxx);
88

99
// mod-by-zero returns x
10-
initial assert(1 % 0 === 'x);
11-
initial assert(1 % 0 === 'x);
10+
initial assert(1 % 0 === 32'hxxxx_xxxx);
11+
initial assert(1 % 0 === 32'hxxxx_xxxx);
1212

1313
endmodule
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
mult1.sv
33

44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The result is wrong.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
module main;
22

33
// Any arithmetic with x or z returns x.
4-
initial assert('bx * 0 === 'x);
5-
initial assert('bz * 0 === 'x);
6-
initial assert(0 * 'bx === 'x);
7-
initial assert(0 * 'bz === 'x);
4+
initial assert(32'bx * 0 === 32'hxxxx_xxxx);
5+
initial assert(32'bz * 0 === 32'hxxxx_xxxx);
6+
initial assert(0 * 32'bx === 32'hxxxx_xxxx);
7+
initial assert(0 * 32'bz === 32'hxxxx_xxxx);
88

99
endmodule
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
plus1.sv
33

44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The result is wrong.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
module main;
22

33
// Any arithmetic with x or z returns x.
4-
initial assert('bx + 1 === 'x);
5-
initial assert('bz + 1 === 'x);
6-
initial assert(1 + 'bx === 'x);
7-
initial assert(1 + 'bz === 'x);
4+
initial assert('bx + 1 === 32'hxxxx_xxxx);
5+
initial assert('bz + 1 === 32'hxxxx_xxxx);
6+
initial assert(1 + 'bx === 32'hxxxx_xxxx);
7+
initial assert(1 + 'bz === 32'hxxxx_xxxx);
88

99
endmodule
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module main;
22

33
// Any arithmetic with x or z returns x.
4-
initial assert(-'bz === 'x);
4+
initial assert(-8'bz === 8'hxx);
55

66
endmodule

src/verilog/aval_bval_encoding.cpp

Lines changed: 33 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,33 @@ 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+
if(type.id() == ID_verilog_unsignedbv)
489+
two_valued_expr.type() = unsignedbv_typet{to_bitvector_type(type).width()};
490+
else if(type.id() == ID_verilog_signedbv)
491+
two_valued_expr.type() = signedbv_typet{to_bitvector_type(type).width()};
492+
else
493+
PRECONDITION(false);
494+
495+
return if_exprt{
496+
has_xz,
497+
make_x(type),
498+
aval_bval_conversion(two_valued_expr, lower_to_aval_bval(type))};
499+
}

0 commit comments

Comments
 (0)