diff --git a/elab_sig.cc b/elab_sig.cc index d5edf1a00..f78f4aae4 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -92,10 +92,10 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const && (sig->port_type() == NetNet::PINPUT) && (sig->type() == NetNet::REG)) { - cerr << cur->get_fileline() << ": error: " - << cur->basename() << " in " + cerr << cur->get_fileline() << ": error: Port " + << cur->basename() << " of module " << scope->module_name() - << " declared as input and as a reg type." << endl; + << " is declared as input and as a reg type." << endl; des->errors += 1; } @@ -104,10 +104,22 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const && (sig->port_type() == NetNet::PINOUT) && (sig->type() == NetNet::REG)) { - cerr << cur->get_fileline() << ": error: " - << cur->basename() << " in " + cerr << cur->get_fileline() << ": error: Port " + << cur->basename() << " of module " << scope->module_name() - << " declared as inout and as a reg type." << endl; + << " is declared as inout and as a reg type." << endl; + des->errors += 1; + } + + if (sig && (sig->scope() == scope) + && (scope->type() == NetScope::MODULE) + && (sig->port_type() == NetNet::PINOUT) + && (sig->data_type() == IVL_VT_REAL)) { + + cerr << cur->get_fileline() << ": error: Port " + << cur->basename() << " of module " + << scope->module_name() + << " is declared as a real inout port." << endl; des->errors += 1; } diff --git a/elaborate.cc b/elaborate.cc index fcfd8ce49..76ac4e1e9 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1311,6 +1311,30 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const continue; } + // We do not support automatic bits to real conversion + // for inout ports. + if ((sig->data_type() == IVL_VT_REAL ) && + !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; + des->errors += 1; + continue; + } + + // We do not support real inout ports at all. + 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; + des->errors += 1; + continue; + } + } else { @@ -1333,6 +1357,69 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const continue; } + // If we have a real port driving a bit/vector signal + // then we convert the real value using the appropriate + // width cast. Since a real is only one bit the whole + // thing needs to go to each instance when arrayed. + if ((sig->data_type() != IVL_VT_REAL ) && + !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) { + if (sig->vector_width() % instance.size() != 0) { + cerr << pins[idx]->get_fileline() << ": error: " + "When automatically converting a real " + "port of an arrayed instance to a bit " + "signal" << endl; + cerr << pins[idx]->get_fileline() << ": : " + "the signal width (" + << sig->vector_width() << ") must be an " + "integer multiple of the instance count (" + << instance.size() << ")." << endl; + des->errors += 1; + continue; + } + prts_vector_width = sig->vector_width(); + for (unsigned idx = 0; idx < prts.size(); idx += 1) { + prts[idx]->port_type(NetNet::NOT_A_PORT); + prts[idx] = cast_to_int(des, scope, prts[idx], + prts_vector_width / + instance.size()); + prts[idx]->port_type(NetNet::POUTPUT); + } + } + + // If we have a bit/vector port driving a single real + // signal then we convert the value to a real. + if ((sig->data_type() == IVL_VT_REAL ) && + !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) { + prts_vector_width -= prts[0]->vector_width() - 1; + prts[0]->port_type(NetNet::NOT_A_PORT); + prts[0] = cast_to_real(des, scope, prts[0]); + prts[0]->port_type(NetNet::POUTPUT); + // No support for multiple real drivers. + if (instance.size() != 1) { + cerr << pins[idx]->get_fileline() << ": error: " + << "Cannot connect an arrayed instance of " + "module " << rmod->mod_name() << " to " + "real signal " << sig->name() << "." + << endl; + des->errors += 1; + continue; + } + } + + // A real to real connection is not allowed for arrayed + // instances. You cannot have multiple real drivers. + if ((sig->data_type() == IVL_VT_REAL ) && + !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL ) && + 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 " + "real signal (" << sig->name() << ")." << endl; + des->errors += 1; + continue; + } + } assert(sig);