Skip to content

Commit 833dfc4

Browse files
committed
Verilog: $isunknown
This adds a lowering and constant-folding for $isunknown.
1 parent 5906108 commit 833dfc4

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# EBMC 5.7
22

33
* Verilog: `elsif preprocessor directive
4+
* Verilog: $isunknown
45
* LTL/SVA to Buechi with --buechi
56

67
# EBMC 5.6
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

@@ -33,6 +34,18 @@ countones(const constant_exprt &expr, const namespacet &ns)
3334
return to_constant_expr(simplified);
3435
}
3536

37+
/// constant folding for $isunknown
38+
static constant_exprt
39+
isunknown(const constant_exprt &expr, const namespacet &ns)
40+
{
41+
auto bval = ::bval(expr);
42+
CHECK_RETURN(bval.is_constant());
43+
if(numeric_cast_v<mp_integer>(to_constant_expr(bval)) == 0)
44+
return false_exprt{};
45+
else
46+
return true_exprt{};
47+
}
48+
3649
static exprt verilog_simplifier_rec(exprt expr, const namespacet &ns)
3750
{
3851
// Remember the Verilog type.
@@ -129,6 +142,21 @@ static exprt verilog_simplifier_rec(exprt expr, const namespacet &ns)
129142
ops.push_back(replication.op());
130143
expr = concatenation_exprt{ops, expr.type()};
131144
}
145+
else if(expr.id() == ID_function_call)
146+
{
147+
auto &call = to_function_call_expr(expr);
148+
if(call.function().id() == ID_symbol)
149+
{
150+
auto identifier = to_symbol_expr(call.function()).get_identifier();
151+
if(identifier == "$isunknown")
152+
{
153+
DATA_INVARIANT(
154+
call.arguments().size() == 1, "$isunknown gets one argument");
155+
if(call.arguments()[0].is_constant())
156+
expr = isunknown(to_constant_expr(call.arguments()[0]), ns);
157+
}
158+
}
159+
}
132160

133161
// We fall back to the simplifier to approximate
134162
// 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)

0 commit comments

Comments
 (0)