1414#include < util/mathematical_types.h>
1515#include < util/std_expr.h>
1616
17+ #include " verilog_types.h"
18+
1719bv_typet aval_bval_type (std::size_t width, irep_idt source_type)
1820{
1921 PRECONDITION (!source_type.empty ());
@@ -34,12 +36,22 @@ bool is_aval_bval(const typet &type)
3436 return type.id () == ID_bv && !type.get (ID_C_verilog_aval_bval).empty ();
3537}
3638
39+ bool is_aval_bval (const exprt &expr)
40+ {
41+ return is_aval_bval (expr.type ());
42+ }
43+
3744std::size_t aval_bval_width (const typet &type)
3845{
3946 PRECONDITION (is_aval_bval (type));
4047 return to_bv_type (type).get_width () / 2 ;
4148}
4249
50+ std::size_t aval_bval_width (const exprt &expr)
51+ {
52+ return aval_bval_width (expr.type ());
53+ }
54+
4355typet aval_bval_underlying (const typet &src)
4456{
4557 auto id = src.get (ID_C_verilog_aval_bval);
@@ -198,3 +210,41 @@ exprt aval_bval_concatenation(
198210
199211 return combine_aval_bval (concatenate (new_aval), concatenate (new_bval), type);
200212}
213+
214+ // / return true iff 'expr' contains either x or z
215+ exprt has_xz (const exprt &expr)
216+ {
217+ PRECONDITION (is_aval_bval (expr));
218+ auto width = aval_bval_width (expr);
219+ return notequal_exprt{bval (expr), bv_typet{width}.all_zeros_expr ()};
220+ }
221+
222+ // / return 'x', one bit
223+ exprt make_x ()
224+ {
225+ auto type = verilog_unsignedbv_typet{1 };
226+ return lower_to_aval_bval (constant_exprt{" x" , type});
227+ }
228+
229+ exprt aval_bval (const verilog_logical_equality_exprt &expr)
230+ {
231+ auto &type = expr.type ();
232+ PRECONDITION (type.id () == ID_verilog_unsignedbv);
233+ // returns 'x' if either operand contains x or z
234+ auto has_xz = or_exprt{::has_xz (expr.lhs ()), ::has_xz (expr.rhs ())};
235+ auto equality = equal_exprt{expr.lhs (), expr.rhs ()};
236+ return if_exprt{
237+ has_xz, make_x (), aval_bval_conversion (equality, lower_to_aval_bval (type))};
238+ }
239+
240+ exprt aval_bval (const verilog_logical_inequality_exprt &expr)
241+ {
242+ auto &type = expr.type ();
243+ PRECONDITION (type.id () == ID_verilog_unsignedbv);
244+ // returns 'x' if either operand contains x or z
245+ auto has_xz = or_exprt{::has_xz (expr.lhs ()), ::has_xz (expr.rhs ())};
246+ auto x = lower_to_aval_bval (constant_exprt{" x" , type});
247+ auto equality = notequal_exprt{expr.lhs (), expr.rhs ()};
248+ return if_exprt{
249+ has_xz, x, aval_bval_conversion (equality, lower_to_aval_bval (type))};
250+ }
0 commit comments