Skip to content

Commit

Permalink
Improve error reporting for unnamed module ports.
Browse files Browse the repository at this point in the history
Implicit ports may be unnamed, either because the port expression
is not a simple/escaped identifier, or because there is no port
expression. To handle these cases, error messages should report
the port position as well as the port name.
  • Loading branch information
martinwhitaker committed Jul 10, 2015
1 parent 97c6339 commit e6be9de
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 35 deletions.
8 changes: 5 additions & 3 deletions Module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,15 @@ perm_string Module::get_port_name(unsigned idx) const
{

assert(idx < ports.size());
if (ports[idx] == 0) {
if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
/* It is possible to have undeclared ports. These
are ports that are skipped in the declaration,
for example like so: module foo(x ,, y); The
port between x and y is unnamed and thus
inaccessible to binding by name. */
return perm_string::literal("");
inaccessible to binding by name. Port references
that aren't simple or escaped identifiers are
also inaccessible to binding by name. */
return perm_string::literal("unnamed");
}
return ports[idx]->name;
}
Expand Down
65 changes: 33 additions & 32 deletions elaborate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1287,15 +1287,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
for (unsigned idx = 0 ; idx < pins.size() ; idx += 1) {
bool unconnected_port = false;

perm_string port_name = rmod->get_port_name(idx);

// Skip unconnected module ports. This happens when a
// null parameter is passed in.

if (pins[idx] == 0) {

if (pins_fromwc[idx]) {
cerr << get_fileline() << ": error: Wildcard named port " <<
"connection (.*) did not find a matching identifier " <<
"for port '" << rmod->ports[idx]->name << "'." << endl;
cerr << get_fileline() << ": error: Wildcard named "
"port connection (.*) did not find a matching "
"identifier for port " << (idx+1) << " ("
<< port_name << ")." << endl;
des->errors += 1;
return;
}
Expand Down Expand Up @@ -1330,22 +1333,22 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
break;
}

// Print a waring for an unconnected input.
// Print a warning for an unconnected input.
if (warn_portbinding) {
cerr << get_fileline() << ": warning: "
<< "Instantiating module "
<< rmod->mod_name()
<< " with dangling input port '"
<< rmod->ports[idx]->name;
<< " with dangling input port "
<< (idx+1) << " (" << port_name;
switch (rmod->uc_drive) {
case Module::UCD_PULL0:
cerr << "' (pulled low)." << endl;
cerr << ") pulled low." << endl;
break;
case Module::UCD_PULL1:
cerr << "' (pulled high)." << endl;
cerr << ") pulled high." << endl;
break;
case Module::UCD_NONE:
cerr << "' (floating)." << endl;
cerr << ") floating." << endl;
break;
}
}
Expand All @@ -1361,8 +1364,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const

if (debug_elaborate) {
cerr << get_fileline() << ": debug: " << get_name()
<< ": Port " << (idx+1) << " has " << prts.size()
<< " sub-ports." << endl;
<< ": Port " << (idx+1) << " (" << port_name
<< ") has " << prts.size() << " sub-ports." << endl;
}

// Count the internal vector bits of the port.
Expand Down Expand Up @@ -1394,7 +1397,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
prt_vector_width += port_width;
ptype = PortType::merged(netnet->port_type(), ptype);
}
inst_scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
inst_scope->add_module_port_info(idx, port_name, ptype, prt_vector_width );
}

// If I find that the port is unconnected inside the
Expand Down Expand Up @@ -1454,8 +1457,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx], -1);
if (tmp_expr == 0) {
cerr << pins[idx]->get_fileline()
<< ": internal error: Port expression "
<< "too complicated for elaboration." << endl;
<< ": error: Failed to elaborate port expression."
<< endl;
des->errors += 1;
continue;
}

Expand Down Expand Up @@ -1541,8 +1545,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
cerr << pins[idx]->get_fileline() << ": error: "
<< "Inout port expression must support "
<< "continuous assignment." << endl;
cerr << pins[idx]->get_fileline() << ": : "
<< "Port " << rmod->ports[idx]->name << " of "
cerr << pins[idx]->get_fileline() << ": : Port "
<< (idx+1) << " (" << port_name << ") of "
<< rmod->mod_name() << " is connected to "
<< *pins[idx] << endl;
des->errors += 1;
Expand All @@ -1555,9 +1559,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
!prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "Cannot automatically connect bit based "
"inout port " << rmod->ports[idx]->name
<< " of module " << rmod->mod_name() << " to real "
"signal " << sig->name() << "." << endl;
"inout port " << (idx+1) << " (" << port_name
<< ") of module " << rmod->mod_name()
<< " to real signal " << sig->name() << "." << endl;
des->errors += 1;
continue;
}
Expand All @@ -1566,9 +1570,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "No support for connecting real inout ports ("
"port "
<< rmod->ports[idx]->name << " of module "
<< rmod->mod_name() << ")." << endl;
"port " << (idx+1) << " (" << port_name
<< ") of module " << rmod->mod_name() << ")." << endl;
des->errors += 1;
continue;
}
Expand Down Expand Up @@ -1611,8 +1614,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
cerr << pins[idx]->get_fileline() << ": error: "
<< "Output port expression must support "
<< "continuous assignment." << endl;
cerr << pins[idx]->get_fileline() << ": : "
<< "Port " << rmod->ports[idx]->name << " of "
cerr << pins[idx]->get_fileline() << ": : Port "
<< (idx+1) << " (" << port_name << ") of "
<< rmod->mod_name() << " is connected to "
<< *pins[idx] << endl;
des->errors += 1;
Expand Down Expand Up @@ -1687,8 +1690,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
instance.size() != 1) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "An arrayed instance of " << rmod->mod_name()
<< " cannot have a real port ("
<< rmod->ports[idx]->name << ") connected to a "
<< " cannot have a real port (port " << (idx+1)
<< " : " << port_name << ") connected to a "
"real signal (" << sig->name() << ")." << endl;
des->errors += 1;
continue;
Expand Down Expand Up @@ -1721,20 +1724,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const

if (debug_elaborate) {
cerr << get_fileline() << ": debug: " << get_name()
<< ": Port " << (idx+1) << " has vector width of "
<< prts_vector_width << "." << endl;
<< ": Port " << (idx+1) << " (" << port_name
<< ") has vector width of " << prts_vector_width
<< "." << endl;
}

// Check that the parts have matching pin counts. If
// not, they are different widths. Note that idx is 0
// based, but users count parameter positions from 1.
if ((instance.size() == 1)
&& (prts_vector_width != sig->vector_width())) {
const char *tmp3 = rmod->ports[idx]->name.str();
bool as_signed = false;

if (tmp3 == 0) tmp3 = "???";

switch (prts[0]->port_type()) {
case NetNet::POUTPUT:
as_signed = prts[0]->get_signed();
Expand All @@ -1754,7 +1755,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}

cerr << get_fileline() << ": warning: Port " << (idx+1)
<< " (" << tmp3 << ") of "
<< " (" << port_name << ") of "
<< type_ << " expects " << prts_vector_width <<
" bits, got " << sig->vector_width() << "." << endl;

Expand Down

0 comments on commit e6be9de

Please sign in to comment.