|
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