@@ -20,6 +20,7 @@ Author: Daniel Kroening, kroening@kroening.com
20
20
#include < util/std_expr.h>
21
21
#include < util/string2int.h>
22
22
23
+ #include " aval_bval_encoding.h"
23
24
#include " convert_literals.h"
24
25
#include " expr2verilog.h"
25
26
#include " verilog_bits.h"
@@ -488,6 +489,31 @@ exprt verilog_typecheck_exprt::convert_expr_function_call(
488
489
489
490
/* ******************************************************************\
490
491
492
+ Function: verilog_typecheck_exprt::isunknown
493
+
494
+ Inputs:
495
+
496
+ Outputs:
497
+
498
+ Purpose:
499
+
500
+ \*******************************************************************/
501
+
502
+ constant_exprt verilog_typecheck_exprt::isunknown (const constant_exprt &expr)
503
+ {
504
+ // constant folding for $isunknown
505
+ auto bval = ::bval (expr);
506
+ auto bval_simplified = verilog_simplifier (bval, ns);
507
+ CHECK_RETURN (bval_simplified.is_constant ());
508
+ auto all_zeros = to_bv_type (bval_simplified.type ()).all_zeros_expr ();
509
+ if (bval_simplified == all_zeros)
510
+ return false_exprt{};
511
+ else
512
+ return true_exprt{};
513
+ }
514
+
515
+ /* ******************************************************************\
516
+
491
517
Function: verilog_typecheck_exprt::bits
492
518
493
519
Inputs:
@@ -979,6 +1005,18 @@ exprt verilog_typecheck_exprt::convert_system_function(
979
1005
980
1006
return std::move (expr);
981
1007
}
1008
+ else if (identifier == " $isunknown" )
1009
+ {
1010
+ if (arguments.size () != 1 )
1011
+ {
1012
+ throw errort ().with_location (expr.source_location ())
1013
+ << " $isunknown takes one argument" ;
1014
+ }
1015
+
1016
+ expr.type () = bool_typet ();
1017
+
1018
+ return std::move (expr);
1019
+ }
982
1020
else if (identifier == " $past" )
983
1021
{
984
1022
if (arguments.size () == 0 || arguments.size () >= 4 )
@@ -1784,6 +1822,17 @@ exprt verilog_typecheck_exprt::elaborate_constant_system_function_call(
1784
1822
DATA_INVARIANT (arguments.size () == 1 , " $typename takes one argument" );
1785
1823
return typename_string (arguments[0 ]);
1786
1824
}
1825
+ else if (identifier == " $isunknown" )
1826
+ {
1827
+ DATA_INVARIANT (arguments.size () == 1 , " $isunknown takes one argument" );
1828
+
1829
+ auto op = elaborate_constant_expression (arguments[0 ]);
1830
+
1831
+ if (!op.is_constant ())
1832
+ return std::move (expr); // give up
1833
+ else
1834
+ return isunknown (to_constant_expr (op));
1835
+ }
1787
1836
else
1788
1837
return std::move (expr); // don't know it, won't elaborate
1789
1838
}
0 commit comments