Skip to content

Commit 626cf79

Browse files
authored
Merge pull request #750 from diffblue/implicit-nets-type
Verilog: set type of implicit nets
2 parents a363d90 + c6d15d0 commit 626cf79

19 files changed

+155
-48
lines changed

regression/verilog/nets/implicit1.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
implicit1.sv
3-
--bound 0
3+
--bound 0 --warn-implicit-nets
44
^file .* line 4: implicit wire main\.O$
55
^file .* line 4: implicit wire main\.A$
66
^file .* line 4: implicit wire main\.B$
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
implicit2.sv
3-
--bound 0
3+
--bound 0 --warn-implicit-nets
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The width of the implicit net is set incorrectly.

regression/verilog/nets/implicit3.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
implicit3.sv
3-
--bound 0
3+
--bound 0 --warn-implicit-nets
44
^file .* line 6: implicit wire main\.O$
55
^EXIT=0$
66
^SIGNAL=0$
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
implicit4.sv
3-
--bound 0
3+
--bound 0 --warn-implicit-nets
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The width of the implicit net is set incorrectly.
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
implicit5.sv
3-
--bound 0
4-
^EXIT=0$
3+
--bound 0 --warn-implicit-nets
4+
^file .* line 4: unknown identifier A$
5+
^EXIT=2$
56
^SIGNAL=0$
67
--
78
^warning: ignoring
89
--
9-
This case should be errored.
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
implicit6.sv
3+
--bound 0 --warn-implicit-nets
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--

regression/verilog/nets/implicit6.sv

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module main;
2+
3+
parameter P = 2;
4+
5+
// implicit nets are allowed in the port connection list of a module
6+
and [P:0] (O, A, B);
7+
8+
assert final ($bits(O) == P+1);
9+
10+
endmodule
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
KNOWNBUG
2+
implicit7.sv
3+
--bound 0 --warn-implicit-nets
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--
9+
The implicit net is not known yet when evaluating parameters.

regression/verilog/nets/implicit7.sv

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module main;
2+
3+
parameter P = 10;
4+
5+
// implicit nets are allowed in the port connection list of a module
6+
sub #(P) my_sub(x);
7+
8+
// The type of the implict net could be used to define another parameter
9+
parameter Q = $bits(x);
10+
11+
assert final (Q == P + 1);
12+
13+
endmodule
14+
15+
module sub #(parameter P = 1)(input [P:0] some_input);
16+
endmodule

src/ebmc/ebmc_parse_options.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class ebmc_parse_optionst:public parse_options_baset
4747
"(random-traces)(trace-steps):(random-seed):(traces):"
4848
"(random-trace)(random-waveform)"
4949
"(liveness-to-safety)"
50-
"I:D:(preprocess)(systemverilog)(vl2smv-extensions)",
50+
"I:D:(preprocess)(systemverilog)(vl2smv-extensions)"
51+
"(warn-implicit-nets)",
5152
argc,
5253
argv,
5354
std::string("EBMC ") + EBMC_VERSION),

src/ebmc/transition_system.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ int preprocess(const cmdlinet &cmdline, message_handlert &message_handler)
112112
optionst options;
113113
options.set_option("force-systemverilog", cmdline.isset("systemverilog"));
114114
options.set_option("vl2smv-extensions", cmdline.isset("vl2smv-extensions"));
115+
options.set_option("warn-implicit-nets", cmdline.isset("warn-implicit-nets"));
115116

116117
// do -D
117118
if(cmdline.isset('D'))
@@ -163,6 +164,7 @@ static bool parse(
163164
optionst options;
164165
options.set_option("force-systemverilog", cmdline.isset("systemverilog"));
165166
options.set_option("vl2smv-extensions", cmdline.isset("vl2smv-extensions"));
167+
options.set_option("warn-implicit-nets", cmdline.isset("warn-implicit-nets"));
166168

167169
// do -D
168170
if(cmdline.isset('D'))

src/verilog/verilog_language.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void verilog_languaget::set_language_options(
3737
force_systemverilog = options.get_bool_option("force-systemverilog");
3838
vl2smv_extensions = options.get_bool_option("vl2smv-extensions");
3939
initial_defines = options.get_list_option("defines");
40+
warn_implicit_nets = options.get_bool_option("warn-implicit-nets");
4041
}
4142

4243
/*******************************************************************\
@@ -180,7 +181,8 @@ bool verilog_languaget::typecheck(
180181
{
181182
if(module=="") return false;
182183

183-
if(verilog_typecheck(parse_tree, symbol_table, module, message_handler))
184+
if(verilog_typecheck(
185+
parse_tree, symbol_table, module, warn_implicit_nets, message_handler))
184186
return true;
185187

186188
messaget message(message_handler);

src/verilog/verilog_language.h

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class verilog_languaget:public languaget
9393
protected:
9494
bool force_systemverilog = false;
9595
bool vl2smv_extensions = false;
96+
bool warn_implicit_nets = false;
9697
std::list<std::string> initial_defines;
9798
verilog_parse_treet parse_tree;
9899
};

src/verilog/verilog_parameterize_module.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ irep_idt verilog_typecheckt::parameterize_module(
289289
// recursive call
290290

291291
verilog_typecheckt verilog_typecheck(
292-
standard, *new_symbol, symbol_table, get_message_handler());
292+
standard, false, *new_symbol, symbol_table, get_message_handler());
293293

294294
if(verilog_typecheck.typecheck_main())
295295
throw 0;

src/verilog/verilog_synthesis.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ exprt verilog_synthesist::expand_function_call(
663663
{
664664
// Attempt to constant fold.
665665
verilog_typecheck_exprt verilog_typecheck_expr(
666-
standard, ns, get_message_handler());
666+
standard, false, ns, get_message_handler());
667667
auto result =
668668
verilog_typecheck_expr.elaborate_constant_system_function_call(call);
669669
if(!result.is_constant())

src/verilog/verilog_typecheck.cpp

+43-8
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,17 @@ void verilog_typecheckt::typecheck_port_connection(
5656
}
5757
else
5858
{
59-
convert_expr(op);
60-
59+
// IEEE 1800 2017 6.10 allows implicit declarations of nets when
60+
// used in a port connection.
61+
if(op.id() == ID_symbol)
62+
{
63+
op = convert_symbol(to_symbol_expr(op), port.type());
64+
}
65+
else
66+
{
67+
convert_expr(op);
68+
}
69+
6170
if(symbol.is_output)
6271
check_lhs(op, A_CONTINUOUS);
6372
else
@@ -229,7 +238,17 @@ void verilog_typecheckt::typecheck_builtin_port_connections(
229238

230239
for(auto &connection : inst.connections())
231240
{
232-
convert_expr(connection);
241+
// IEEE 1800 2017 6.10 allows implicit declarations of nets when
242+
// used in a port connection.
243+
if(connection.id() == ID_symbol)
244+
{
245+
connection = convert_symbol(to_symbol_expr(connection), type);
246+
}
247+
else
248+
{
249+
convert_expr(connection);
250+
}
251+
233252
propagate_type(connection, type);
234253
}
235254
}
@@ -821,8 +840,16 @@ void verilog_typecheckt::convert_continuous_assign(
821840
exprt &lhs = to_binary_expr(*it).lhs();
822841
exprt &rhs = to_binary_expr(*it).rhs();
823842

824-
convert_expr(lhs);
843+
// IEEE 1800 2017 6.10 allows implicit declarations of nets when
844+
// used as the LHS of a continuous assignment. The type is derived
845+
// from the RHS, and hence, we convert that first.
825846
convert_expr(rhs);
847+
848+
if(lhs.id() == ID_symbol)
849+
lhs = convert_symbol(to_symbol_expr(lhs), rhs.type());
850+
else
851+
convert_expr(lhs);
852+
826853
propagate_type(rhs, lhs.type());
827854

828855
check_lhs(lhs, A_CONTINUOUS);
@@ -1761,7 +1788,8 @@ Function: verilog_typecheckt::implicit_wire
17611788

17621789
bool verilog_typecheckt::implicit_wire(
17631790
const irep_idt &identifier,
1764-
const symbolt *&symbol_ptr)
1791+
const symbolt *&symbol_ptr,
1792+
const typet &net_type)
17651793
{
17661794
std::string full_identifier=
17671795
id2string(module_identifier)+"."+id2string(identifier);
@@ -1773,7 +1801,7 @@ bool verilog_typecheckt::implicit_wire(
17731801
symbol.value.make_nil();
17741802
symbol.base_name=identifier;
17751803
symbol.name=full_identifier;
1776-
symbol.type=bool_typet(); // TODO: other types?
1804+
symbol.type = net_type;
17771805
symbol.pretty_name=strip_verilog_prefix(full_identifier);
17781806

17791807
symbolt *new_symbol;
@@ -1836,6 +1864,7 @@ bool verilog_typecheck(
18361864
const verilog_parse_treet &parse_tree,
18371865
symbol_table_baset &symbol_table,
18381866
const std::string &module,
1867+
bool warn_implicit_nets,
18391868
message_handlert &message_handler)
18401869
{
18411870
verilog_parse_treet::module_mapt::const_iterator it=
@@ -1851,7 +1880,11 @@ bool verilog_typecheck(
18511880
}
18521881

18531882
return verilog_typecheck(
1854-
symbol_table, *it->second, parse_tree.standard, message_handler);
1883+
symbol_table,
1884+
*it->second,
1885+
parse_tree.standard,
1886+
warn_implicit_nets,
1887+
message_handler);
18551888
}
18561889

18571890
/*******************************************************************\
@@ -1870,6 +1903,7 @@ bool verilog_typecheck(
18701903
symbol_table_baset &symbol_table,
18711904
const verilog_module_sourcet &verilog_module_source,
18721905
verilog_standardt standard,
1906+
bool warn_implicit_nets,
18731907
message_handlert &message_handler)
18741908
{
18751909
// create symbol
@@ -1898,6 +1932,7 @@ bool verilog_typecheck(
18981932
}
18991933

19001934
verilog_typecheckt verilog_typecheck(
1901-
standard, *new_symbol, symbol_table, message_handler);
1935+
standard, warn_implicit_nets, *new_symbol, symbol_table, message_handler);
1936+
19021937
return verilog_typecheck.typecheck_main();
19031938
}

src/verilog/verilog_typecheck.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ bool verilog_typecheck(
2323
const verilog_parse_treet &parse_tree,
2424
symbol_table_baset &,
2525
const std::string &module,
26+
bool warn_implicit_nets,
2627
message_handlert &message_handler);
2728

2829
bool verilog_typecheck(
2930
symbol_table_baset &,
3031
const verilog_module_sourcet &verilog_module_source,
3132
verilog_standardt,
33+
bool warn_implicit_nets,
3234
message_handlert &message_handler);
3335

3436
bool verilog_typecheck(
@@ -57,10 +59,15 @@ class verilog_typecheckt:
5759
public:
5860
verilog_typecheckt(
5961
verilog_standardt _standard,
62+
bool warn_implicit_nets,
6063
symbolt &_module_symbol,
6164
symbol_table_baset &_symbol_table,
6265
message_handlert &_message_handler)
63-
: verilog_typecheck_exprt(_standard, ns, _message_handler),
66+
: verilog_typecheck_exprt(
67+
_standard,
68+
warn_implicit_nets,
69+
ns,
70+
_message_handler),
6471
verilog_symbol_tablet(_symbol_table),
6572
ns(_symbol_table),
6673
module_symbol(_module_symbol),
@@ -204,8 +211,10 @@ class verilog_typecheckt:
204211
virtual void convert_statements(verilog_module_exprt &);
205212

206213
// to be overridden
207-
bool implicit_wire(const irep_idt &identifier,
208-
const symbolt *&symbol) override;
214+
bool implicit_wire(
215+
const irep_idt &identifier,
216+
const symbolt *&,
217+
const typet &) override;
209218

210219
// generate constructs
211220
void elaborate_generate_assign(

src/verilog/verilog_typecheck_expr.cpp

+22-14
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ exprt verilog_typecheck_exprt::convert_nullary_expr(nullary_exprt expr)
893893
}
894894
else if(expr.id()==ID_symbol)
895895
{
896-
return convert_symbol(to_symbol_expr(std::move(expr)));
896+
return convert_symbol(to_symbol_expr(std::move(expr)), {});
897897
}
898898
else if(expr.id()==ID_verilog_star_event)
899899
{
@@ -931,7 +931,9 @@ Function: verilog_typecheck_exprt::convert_symbol
931931
932932
\*******************************************************************/
933933

934-
exprt verilog_typecheck_exprt::convert_symbol(symbol_exprt expr)
934+
exprt verilog_typecheck_exprt::convert_symbol(
935+
symbol_exprt expr,
936+
const std::optional<typet> &implicit_net_type)
935937
{
936938
const irep_idt &identifier = expr.get_identifier();
937939

@@ -1018,19 +1020,25 @@ exprt verilog_typecheck_exprt::convert_symbol(symbol_exprt expr)
10181020
return std::move(expr);
10191021
}
10201022
}
1021-
else if(!implicit_wire(identifier, symbol))
1022-
{
1023-
// this should become an error
1024-
warning().source_location=expr.source_location();
1025-
warning() << "implicit wire " << symbol->display_name() << eom;
1026-
expr.type()=symbol->type;
1027-
expr.set_identifier(symbol->name);
1028-
return std::move(expr);
1029-
}
10301023
else
10311024
{
1032-
throw errort().with_location(expr.source_location())
1033-
<< "unknown identifier " << identifier;
1025+
if(implicit_net_type.has_value())
1026+
{
1027+
implicit_wire(identifier, symbol, implicit_net_type.value());
1028+
if(warn_implicit_nets)
1029+
{
1030+
warning().source_location = expr.source_location();
1031+
warning() << "implicit wire " << symbol->display_name() << eom;
1032+
}
1033+
expr.type() = symbol->type;
1034+
expr.set_identifier(symbol->name);
1035+
return std::move(expr);
1036+
}
1037+
else
1038+
{
1039+
throw errort().with_location(expr.source_location())
1040+
<< "unknown identifier " << identifier;
1041+
}
10341042
}
10351043
}
10361044

@@ -3259,7 +3267,7 @@ bool verilog_typecheck(
32593267
message_handler.get_message_count(messaget::M_ERROR);
32603268

32613269
verilog_typecheck_exprt verilog_typecheck_expr(
3262-
standard, ns, module_identifier, message_handler);
3270+
standard, true, ns, module_identifier, message_handler);
32633271

32643272
try
32653273
{

0 commit comments

Comments
 (0)