Skip to content

Commit d1783b8

Browse files
committed
Verilog: $isunknown
This adds a lowering and constant-folding for $isunknown.
1 parent 8f220ab commit d1783b8

File tree

6 files changed

+72
-0
lines changed

6 files changed

+72
-0
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Verilog: `elsif preprocessor directive
44
* Verilog: fix for named generate blocks
55
* Verilog: $onehot and $onehot0 are now elaboration-time constant
6+
* Verilog: $isunknown
67
* SystemVerilog: fix for #-# and #=# for empty matches
78
* SystemVerilog: fix for |-> and |=> for empty matches
89
* LTL/SVA to Buechi with --buechi
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
isunknown1.sv
3+
--module main
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module main;
2+
3+
p0: assert final ($isunknown(123)==0);
4+
p1: assert final ($isunknown('z)==1);
5+
p2: assert final ($isunknown('x)==1);
6+
p3: assert final ($isunknown('b01x0)==1);
7+
p4: assert final ($isunknown(3'bzzz)==1);
8+
9+
// $isunknown yields an elaboration-time constant
10+
parameter Q1 = $isunknown(3'b10z);
11+
parameter P1 = $isunknown(3'b101);
12+
13+
endmodule

src/verilog/verilog_simplifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515

1616
#include <ebmc/ebmc_error.h>
1717

18+
#include "aval_bval_encoding.h"
1819
#include "verilog_expr.h"
1920
#include "verilog_types.h"
2021

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Author: Daniel Kroening, [email protected]
2020
#include <util/std_expr.h>
2121
#include <util/string2int.h>
2222

23+
#include "aval_bval_encoding.h"
2324
#include "convert_literals.h"
2425
#include "expr2verilog.h"
2526
#include "verilog_bits.h"
@@ -488,6 +489,31 @@ exprt verilog_typecheck_exprt::convert_expr_function_call(
488489

489490
/*******************************************************************\
490491
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 = simplify_expr(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+
491517
Function: verilog_typecheck_exprt::bits
492518
493519
Inputs:
@@ -979,6 +1005,18 @@ exprt verilog_typecheck_exprt::convert_system_function(
9791005

9801006
return std::move(expr);
9811007
}
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+
}
9821020
else if(identifier == "$past")
9831021
{
9841022
if(arguments.size() == 0 || arguments.size() >= 4)
@@ -1784,6 +1822,17 @@ exprt verilog_typecheck_exprt::elaborate_constant_system_function_call(
17841822
DATA_INVARIANT(arguments.size() == 1, "$typename takes one argument");
17851823
return typename_string(arguments[0]);
17861824
}
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+
}
17871836
else
17881837
return std::move(expr); // don't know it, won't elaborate
17891838
}

src/verilog/verilog_typecheck_expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
215215
exprt bits(const exprt &);
216216
std::optional<mp_integer> bits_rec(const typet &) const;
217217
constant_exprt countones(const constant_exprt &);
218+
constant_exprt isunknown(const constant_exprt &);
218219
constant_exprt left(const exprt &);
219220
constant_exprt right(const exprt &);
220221
constant_exprt low(const exprt &);

0 commit comments

Comments
 (0)