Skip to content

Commit c6d15d0

Browse files
committed
Verilog: set type of implicit nets
1800 2017 6.10 allows implicit declarations of nets. The type of these nets is to be derived from the LHS of the assignment or the type of the port connection. The warning when a net is declared implicitly is dropped by default; it can be reactivated with --warn-implicit-nets.
1 parent a363d90 commit c6d15d0

19 files changed

+155
-48
lines changed

Diff for: 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$

Diff for: regression/verilog/nets/implicit2.desc

+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.

Diff for: 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$

Diff for: regression/verilog/nets/implicit4.desc

+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.

Diff for: regression/verilog/nets/implicit5.desc

+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.

Diff for: regression/verilog/nets/implicit6.desc

+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+
--

Diff for: 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

Diff for: regression/verilog/nets/implicit7.desc

+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.

Diff for: 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

Diff for: 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),

Diff for: 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'))

Diff for: 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);

Diff for: 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
};

Diff for: 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;

Diff for: 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())

Diff for: 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
}

Diff for: 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(

Diff for: 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)