Skip to content

Commit 91db9b4

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 aac75f1 commit 91db9b4

14 files changed

+148
-5
lines changed
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
@@ -417,6 +417,7 @@ void ebmc_parse_optionst::help()
417417
" {y--systemverilog} \t force SystemVerilog instead of Verilog\n"
418418
" {y--reset} {uexpr} \t set up module reset\n"
419419
" {y--ignore-initial} \t disregard initial blocks\n"
420+
" {y--initial-zero} \t initialize variables with zero\n"
420421
"\n"
421422
"Debugging options:\n"
422423
" {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
@@ -1073,6 +1073,12 @@ class verilog_initialt:public verilog_statementt
10731073
operands().resize(1);
10741074
}
10751075

1076+
explicit verilog_initialt(verilog_statementt _statement)
1077+
: verilog_statementt(ID_initial)
1078+
{
1079+
add_to_operands(std::move(_statement));
1080+
}
1081+
10761082
verilog_statementt &statement()
10771083
{
10781084
return static_cast<verilog_statementt &>(op0());

src/verilog/verilog_initializer.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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_zero_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 zero_element_opt = verilog_zero_initializer(array_type.element_type());
24+
if(!zero_element_opt.has_value())
25+
return {};
26+
else
27+
return array_of_exprt{*zero_element_opt, array_type};
28+
}
29+
else if(type.id() == ID_struct)
30+
{
31+
auto &struct_type = to_struct_type(type);
32+
exprt::operandst member_values;
33+
for(auto &component : struct_type.components())
34+
{
35+
auto member_value_opt = verilog_zero_initializer(component.type());
36+
if(!member_value_opt.has_value())
37+
return {};
38+
member_values.push_back(*member_value_opt);
39+
}
40+
return struct_exprt{std::move(member_values), struct_type};
41+
}
42+
else if(type.id() == ID_verilog_chandle)
43+
{
44+
return constant_exprt{ID_NULL, type};
45+
}
46+
else
47+
return {};
48+
}

src/verilog/verilog_initializer.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
std::optional<exprt> verilog_zero_initializer(const typet &);
18+
19+
#endif

src/verilog/verilog_language.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void verilog_languaget::set_language_options(
4040
initial_defines = options.get_list_option("defines");
4141
warn_implicit_nets = options.get_bool_option("warn-implicit-nets");
4242
ignore_initial = options.get_bool_option("ignore-initial");
43+
initial_zero = options.get_bool_option("initial-zero");
4344
}
4445

4546
/*******************************************************************\
@@ -196,6 +197,7 @@ bool verilog_languaget::typecheck(
196197
module,
197198
parse_tree.standard,
198199
ignore_initial,
200+
initial_zero,
199201
message_handler))
200202
{
201203
return true;

0 commit comments

Comments
 (0)