Skip to content

Commit a99de09

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

File tree

6 files changed

+62
-0
lines changed

6 files changed

+62
-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: 28 additions & 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

@@ -53,6 +54,18 @@ static constant_exprt onehot0(const constant_exprt &expr, const namespacet &ns)
5354
return false_exprt();
5455
}
5556

57+
/// constant folding for $isunknown
58+
static constant_exprt
59+
isunknown(const constant_exprt &expr, const namespacet &ns)
60+
{
61+
auto bval = ::bval(expr);
62+
CHECK_RETURN(bval.is_constant());
63+
if(numeric_cast_v<mp_integer>(to_constant_expr(bval)) == 0)
64+
return false_exprt{};
65+
else
66+
return true_exprt{};
67+
}
68+
5669
static exprt verilog_simplifier_rec(exprt expr, const namespacet &ns)
5770
{
5871
// Remember the Verilog type.
@@ -161,6 +174,21 @@ static exprt verilog_simplifier_rec(exprt expr, const namespacet &ns)
161174
if(op.is_constant())
162175
expr = onehot0(to_constant_expr(op), ns);
163176
}
177+
else if(expr.id() == ID_function_call)
178+
{
179+
auto &call = to_function_call_expr(expr);
180+
if(call.function().id() == ID_symbol)
181+
{
182+
auto identifier = to_symbol_expr(call.function()).get_identifier();
183+
if(identifier == "$isunknown")
184+
{
185+
DATA_INVARIANT(
186+
call.arguments().size() == 1, "$isunknown gets one argument");
187+
if(call.arguments()[0].is_constant())
188+
expr = isunknown(to_constant_expr(call.arguments()[0]), ns);
189+
}
190+
}
191+
}
164192

165193
// We fall back to the simplifier to approximate
166194
// the standard's definition of 'constant expression'.

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,18 @@ exprt verilog_typecheck_exprt::convert_system_function(
979979

980980
return std::move(expr);
981981
}
982+
else if(identifier == "$isunknown")
983+
{
984+
if(arguments.size() != 1)
985+
{
986+
throw errort().with_location(expr.source_location())
987+
<< "$isunknown takes one argument";
988+
}
989+
990+
expr.type() = bool_typet();
991+
992+
return std::move(expr);
993+
}
982994
else if(identifier == "$past")
983995
{
984996
if(arguments.size() == 0 || arguments.size() >= 4)

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)