Add support for bit <-> real conversion for output ports.

This patch adds support for converting bit based ports to real signals.
You can only do this for single instances. Arrayed instance would
create multiple instances driving the same real signal.

Any real port can be connected to a bit based signal. The only limitation
is that the signal width must be an integer multiple of the instance
count since all the real conversions must have the same width.

Also add an error message for an arrayed instance with real to real
output connections. Again multiple drivers.

This patch also adds errors for inout real and bit based inout ports
driving a real signal. There is no logical way to deal with the full
capabilities of inout and real ports/signals. So for now they are not
allowed.
This commit is contained in:
Cary R 2010-04-25 14:15:35 -07:00 committed by Stephen Williams
parent 2eb01605b1
commit e0001de3ba
2 changed files with 105 additions and 6 deletions

View File

@ -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;
}

View File

@ -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);