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:
parent
2eb01605b1
commit
e0001de3ba
24
elab_sig.cc
24
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
87
elaborate.cc
87
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue