Skip to content

Commit 0ebb18f

Browse files
committed
SystemVerilog: --initial-zero
The SystemVerilog standard specifies that variables are to be zero initialized before simulation begins. Some synthesis tools generate logic to achieve this, whereas others do not. This adds the option --initial-zero to match the synthesis semantics when appropriate.
1 parent e281a3d commit 0ebb18f

15 files changed

+151
-5
lines changed

CHANGELOG

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

3+
* Verilog: --initial-zero changes the default value from nondet to zero
34
* Verilog: `elsif preprocessor directive
45
* Verilog: fix for named generate blocks
56
* Verilog: $onehot and $onehot0 are now elaboration-time constant
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
initial-zero1.sv
3+
--top main --initial-zero --bound 3
4+
^\[main\.p1\] main\.t == 0: PROVED up to bound 3$
5+
^\[main\.p2\] ##1 main\.t == 5: PROVED up to bound 3$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module main(input clk);
2+
3+
reg [7:0] t;
4+
5+
always_ff @(posedge clk) t = 5;
6+
7+
initial p1: assert property (t == 0);
8+
initial p2: assert property (##1 t == 5);
9+
10+
chandle ch;
11+
initial p3: assert property (ch == null);
12+
13+
endmodule

src/ebmc/ebmc_parse_options.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ void ebmc_parse_optionst::help()
438438
" {y--systemverilog} \t force SystemVerilog instead of Verilog\n"
439439
" {y--reset} {uexpr} \t set up module reset\n"
440440
" {y--ignore-initial} \t disregard initial blocks\n"
441+
" {y--initial-zero} \t initialize variables with zero\n"
441442
"\n"
442443
"Debugging options:\n"
443444
" {y--preprocess} \t output the preprocessed source file\n"

src/ebmc/ebmc_parse_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ebmc_parse_optionst:public parse_options_baset
3535
"(outfile):(xml-ui)(verbosity):(gui)"
3636
"(json-modules):(json-properties):(json-result):"
3737
"(neural-liveness)(neural-engine):"
38-
"(reset):(ignore-initial)"
38+
"(reset):(ignore-initial)(initial-zero)"
3939
"(version)(verilog-rtl)(verilog-netlist)"
4040
"(compute-interpolant)(interpolation)(interpolation-vmcai)"
4141
"(ic3)(property):(constr)(h)(new-mode)(aiger)"

src/ebmc/transition_system.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ static bool parse(
178178
if(cmdline.isset("ignore-initial"))
179179
options.set_option("ignore-initial", true);
180180

181+
// do --initial-zero
182+
if(cmdline.isset("initial-zero"))
183+
options.set_option("initial-zero", true);
184+
181185
language.set_language_options(options, message_handler);
182186

183187
message.status() << "Parsing " << filename << messaget::eom;

src/verilog/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SRC = aval_bval_encoding.cpp \
77
verilog_elaborate_type.cpp \
88
verilog_expr.cpp \
99
verilog_generate.cpp \
10+
verilog_initializer.cpp \
1011
verilog_interfaces.cpp \
1112
verilog_interpreter.cpp \
1213
verilog_language.cpp \

src/verilog/verilog_expr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,12 @@ class verilog_initialt:public verilog_statementt
10801080
operands().resize(1);
10811081
}
10821082

1083+
explicit verilog_initialt(verilog_statementt _statement)
1084+
: verilog_statementt(ID_initial)
1085+
{
1086+
add_to_operands(std::move(_statement));
1087+
}
1088+
10831089
verilog_statementt &statement()
10841090
{
10851091
return static_cast<verilog_statementt &>(op0());

src/verilog/verilog_initializer.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*******************************************************************\
2+
3+
Module: Verilog Initializer
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "verilog_initializer.h"
10+
11+
#include <util/arith_tools.h>
12+
#include <util/std_expr.h>
13+
14+
std::optional<exprt> verilog_default_initializer(const typet &type)
15+
{
16+
if(type.id() == ID_signedbv || type.id() == ID_unsignedbv)
17+
return from_integer(0, type);
18+
else if(type.id() == ID_bool)
19+
return false_exprt{};
20+
else if(type.id() == ID_array)
21+
{
22+
auto &array_type = to_array_type(type);
23+
auto default_element_opt =
24+
verilog_default_initializer(array_type.element_type());
25+
if(!default_element_opt.has_value())
26+
return {};
27+
else
28+
return array_of_exprt{*default_element_opt, array_type};
29+
}
30+
else if(type.id() == ID_struct)
31+
{
32+
auto &struct_type = to_struct_type(type);
33+
exprt::operandst member_values;
34+
for(auto &component : struct_type.components())
35+
{
36+
auto member_value_opt = verilog_default_initializer(component.type());
37+
if(!member_value_opt.has_value())
38+
return {};
39+
member_values.push_back(*member_value_opt);
40+
}
41+
return struct_exprt{std::move(member_values), struct_type};
42+
}
43+
else if(type.id() == ID_verilog_chandle)
44+
{
45+
return constant_exprt{ID_NULL, type};
46+
}
47+
else
48+
return {};
49+
}

src/verilog/verilog_initializer.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*******************************************************************\
2+
3+
Module: Verilog Initializer
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_VERILOG_INITIALIZER_H
10+
#define CPROVER_VERILOG_INITIALIZER_H
11+
12+
#include <optional>
13+
14+
class exprt;
15+
class typet;
16+
17+
/// The default initial value, 1800-2017 Table 6-7
18+
std::optional<exprt> verilog_default_initializer(const typet &);
19+
20+
#endif

0 commit comments

Comments
 (0)