Skip to content

Commit

Permalink
Verilog: set type of implicit nets
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kroening committed Oct 4, 2024
1 parent 8bbc75e commit 13db991
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 33 deletions.
3 changes: 1 addition & 2 deletions regression/verilog/nets/implicit2.desc
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
KNOWNBUG
CORE
implicit2.sv
--bound 0
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
--
The width of the implicit net is set incorrectly.
3 changes: 1 addition & 2 deletions regression/verilog/nets/implicit4.desc
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
KNOWNBUG
CORE
implicit4.sv
--bound 0
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
--
The width of the implicit net is set incorrectly.
6 changes: 3 additions & 3 deletions regression/verilog/nets/implicit5.desc
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
KNOWNBUG
CORE
implicit5.sv
--bound 0
^EXIT=0$
^file .* line 4: unknown identifier A$
^EXIT=2$
^SIGNAL=0$
--
^warning: ignoring
--
This case should be errored.
40 changes: 34 additions & 6 deletions src/verilog/verilog_typecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,17 @@ void verilog_typecheckt::typecheck_port_connection(
}
else
{
convert_expr(op);

// IEEE 1800 2017 6.10 allows implicit declarations of nets when
// used in a port connection.
if(op.id() == ID_symbol)
{
op = convert_symbol(to_symbol_expr(op), port.type());
}
else
{
convert_expr(op);
}

if(symbol.is_output)
check_lhs(op, A_CONTINUOUS);
else
Expand Down Expand Up @@ -229,7 +238,17 @@ void verilog_typecheckt::typecheck_builtin_port_connections(

for(auto &connection : inst.connections())
{
convert_expr(connection);
// IEEE 1800 2017 6.10 allows implicit declarations of nets when
// used in a port connection.
if(connection.id() == ID_symbol)
{
connection = convert_symbol(to_symbol_expr(connection), type);
}
else
{
convert_expr(connection);
}

propagate_type(connection, type);
}
}
Expand Down Expand Up @@ -821,8 +840,16 @@ void verilog_typecheckt::convert_continuous_assign(
exprt &lhs = to_binary_expr(*it).lhs();
exprt &rhs = to_binary_expr(*it).rhs();

convert_expr(lhs);
// IEEE 1800 2017 6.10 allows implicit declarations of nets when
// used as the LHS of a continuous assignment. The type is derived
// from the RHS, and hence, we convert that first.
convert_expr(rhs);

if(lhs.id() == ID_symbol)
lhs = convert_symbol(to_symbol_expr(lhs), rhs.type());
else
convert_expr(lhs);

propagate_type(rhs, lhs.type());

check_lhs(lhs, A_CONTINUOUS);
Expand Down Expand Up @@ -1761,7 +1788,8 @@ Function: verilog_typecheckt::implicit_wire

bool verilog_typecheckt::implicit_wire(
const irep_idt &identifier,
const symbolt *&symbol_ptr)
const symbolt *&symbol_ptr,
const typet &net_type)
{
std::string full_identifier=
id2string(module_identifier)+"."+id2string(identifier);
Expand All @@ -1773,7 +1801,7 @@ bool verilog_typecheckt::implicit_wire(
symbol.value.make_nil();
symbol.base_name=identifier;
symbol.name=full_identifier;
symbol.type=bool_typet(); // TODO: other types?
symbol.type = net_type;
symbol.pretty_name=strip_verilog_prefix(full_identifier);

symbolt *new_symbol;
Expand Down
6 changes: 4 additions & 2 deletions src/verilog/verilog_typecheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,10 @@ class verilog_typecheckt:
virtual void convert_statements(verilog_module_exprt &);

// to be overridden
bool implicit_wire(const irep_idt &identifier,
const symbolt *&symbol) override;
bool implicit_wire(
const irep_idt &identifier,
const symbolt *&,
const typet &) override;

// generate constructs
void elaborate_generate_assign(
Expand Down
32 changes: 19 additions & 13 deletions src/verilog/verilog_typecheck_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ exprt verilog_typecheck_exprt::convert_nullary_expr(nullary_exprt expr)
}
else if(expr.id()==ID_symbol)
{
return convert_symbol(to_symbol_expr(std::move(expr)));
return convert_symbol(to_symbol_expr(std::move(expr)), {});
}
else if(expr.id()==ID_verilog_star_event)
{
Expand Down Expand Up @@ -936,7 +936,9 @@ Function: verilog_typecheck_exprt::convert_symbol
\*******************************************************************/

exprt verilog_typecheck_exprt::convert_symbol(symbol_exprt expr)
exprt verilog_typecheck_exprt::convert_symbol(
symbol_exprt expr,
const std::optional<typet> &implicit_net_type)
{
const irep_idt &identifier = expr.get_identifier();

Expand Down Expand Up @@ -1023,19 +1025,23 @@ exprt verilog_typecheck_exprt::convert_symbol(symbol_exprt expr)
return std::move(expr);
}
}
else if(!implicit_wire(identifier, symbol))
{
// this should become an error
warning().source_location=expr.source_location();
warning() << "implicit wire " << symbol->display_name() << eom;
expr.type()=symbol->type;
expr.set_identifier(symbol->name);
return std::move(expr);
}
else
{
throw errort().with_location(expr.source_location())
<< "unknown identifier " << identifier;
if(implicit_net_type.has_value())
{
implicit_wire(identifier, symbol, implicit_net_type.value());

warning().source_location = expr.source_location();
warning() << "implicit wire " << symbol->display_name() << eom;
expr.type() = symbol->type;
expr.set_identifier(symbol->name);
return std::move(expr);
}
else
{
throw errort().with_location(expr.source_location())
<< "unknown identifier " << identifier;
}
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/verilog/verilog_typecheck_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,12 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
PRECONDITION(false);
}

virtual bool implicit_wire(const irep_idt &identifier,
const symbolt *&symbol) {
virtual bool
implicit_wire(const irep_idt &identifier, const symbolt *&, const typet &)
{
return true;
}

void typecheck() override
{
}
Expand All @@ -155,10 +156,11 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
UNREACHABLE;
}

private:
protected:
[[nodiscard]] exprt convert_expr_rec(exprt expr);
[[nodiscard]] exprt convert_constant(constant_exprt);
[[nodiscard]] exprt convert_symbol(symbol_exprt);
[[nodiscard]] exprt
convert_symbol(symbol_exprt, const std::optional<typet> &implicit_net_type);
[[nodiscard]] exprt
convert_hierarchical_identifier(class hierarchical_identifier_exprt);
[[nodiscard]] exprt convert_nullary_expr(nullary_exprt);
Expand Down

0 comments on commit 13db991

Please sign in to comment.