Pad input and output ports correctly.
This patch pads inputs and output ports correctly when the port and the port expression have different widths. It does not fix inout ports. It also sets the file and line number information in the unsigned pad_to_width() routine.
This commit is contained in:
parent
bd504ea14e
commit
5fd3be570e
2
PGate.h
2
PGate.h
|
|
@ -247,7 +247,7 @@ class PGModule : public PGate {
|
||||||
|
|
||||||
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
|
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
|
||||||
NetNet*sig, unsigned port_wid,
|
NetNet*sig, unsigned port_wid,
|
||||||
NetNet::PortType dir) const;
|
NetNet::PortType dir, bool as_signed) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
60
elaborate.cc
60
elaborate.cc
|
|
@ -853,7 +853,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
||||||
NetNet*sig, unsigned port_wid,
|
NetNet*sig, unsigned port_wid,
|
||||||
NetNet::PortType dir) const
|
NetNet::PortType dir, bool as_signed) const
|
||||||
{
|
{
|
||||||
ivl_assert(*this, dir != NetNet::NOT_A_PORT);
|
ivl_assert(*this, dir != NetNet::NOT_A_PORT);
|
||||||
ivl_assert(*this, dir != NetNet::PIMPLICIT);
|
ivl_assert(*this, dir != NetNet::PIMPLICIT);
|
||||||
|
|
@ -870,6 +870,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
||||||
unsigned wida = sig->vector_width();
|
unsigned wida = sig->vector_width();
|
||||||
unsigned widb = tmp->vector_width();
|
unsigned widb = tmp->vector_width();
|
||||||
bool part_b = widb < wida;
|
bool part_b = widb < wida;
|
||||||
|
// This needs to pad the value!
|
||||||
|
// Also delete the inout specific warning when this is fixed.
|
||||||
|
// It is located just before this routine is called.
|
||||||
NetTran*node = new NetTran(scope, scope->local_symbol(),
|
NetTran*node = new NetTran(scope, scope->local_symbol(),
|
||||||
part_b? wida : widb,
|
part_b? wida : widb,
|
||||||
part_b? widb : wida,
|
part_b? widb : wida,
|
||||||
|
|
@ -888,30 +891,39 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPartSelect*node = 0;
|
unsigned pwidth = tmp->vector_width();
|
||||||
|
unsigned swidth = sig->vector_width();
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case NetNet::POUTPUT:
|
case NetNet::POUTPUT:
|
||||||
if (tmp->vector_width() > sig->vector_width()) {
|
if (pwidth > swidth) {
|
||||||
node = new NetPartSelect(tmp, 0, sig->vector_width(),
|
NetPartSelect*node = new NetPartSelect(tmp, 0, swidth,
|
||||||
NetPartSelect::VP);
|
NetPartSelect::VP);
|
||||||
connect(node->pin(0), sig->pin(0));
|
connect(node->pin(0), sig->pin(0));
|
||||||
|
des->add_node(node);
|
||||||
} else {
|
} else {
|
||||||
node = new NetPartSelect(sig, 0, tmp->vector_width(),
|
NetNet*osig;
|
||||||
NetPartSelect::PV);
|
if (as_signed) {
|
||||||
connect(node->pin(0), tmp->pin(0));
|
osig = pad_to_width_signed(des, tmp, swidth);
|
||||||
|
} else {
|
||||||
|
osig = pad_to_width(des, tmp, swidth);
|
||||||
|
}
|
||||||
|
connect(osig->pin(0), sig->pin(0));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NetNet::PINPUT:
|
case NetNet::PINPUT:
|
||||||
if (tmp->vector_width() > sig->vector_width()) {
|
if (pwidth > swidth) {
|
||||||
node = new NetPartSelect(tmp, 0, sig->vector_width(),
|
delete tmp;
|
||||||
NetPartSelect::PV);
|
if (as_signed) {
|
||||||
connect(node->pin(0), sig->pin(0));
|
tmp = pad_to_width_signed(des, sig, pwidth);
|
||||||
} else {
|
} else {
|
||||||
node = new NetPartSelect(sig, 0, tmp->vector_width(),
|
tmp = pad_to_width(des, sig, pwidth);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NetPartSelect*node = new NetPartSelect(sig, 0, pwidth,
|
||||||
NetPartSelect::VP);
|
NetPartSelect::VP);
|
||||||
connect(node->pin(0), tmp->pin(0));
|
connect(node->pin(0), tmp->pin(0));
|
||||||
|
des->add_node(node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -923,8 +935,6 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, 0);
|
ivl_assert(*this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
des->add_node(node);
|
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1291,22 +1301,36 @@ v NOTE that this also handles the case that the
|
||||||
<< type_ << " expects " << prts_vector_width <<
|
<< type_ << " expects " << prts_vector_width <<
|
||||||
" bits, got " << sig->vector_width() << "." << endl;
|
" bits, got " << sig->vector_width() << "." << endl;
|
||||||
|
|
||||||
|
// Delete this when inout ports pad correctly.
|
||||||
|
if (prts[0]->port_type() == NetNet::PINOUT) {
|
||||||
if (prts_vector_width > sig->vector_width()) {
|
if (prts_vector_width > sig->vector_width()) {
|
||||||
cerr << get_fileline() << ": : Leaving "
|
cerr << get_fileline() << ": : Leaving "
|
||||||
<< (prts_vector_width-sig->vector_width())
|
<< (prts_vector_width-sig->vector_width())
|
||||||
<< " high bits of the port unconnected."
|
<< " high bits of the port unconnected."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cerr << get_fileline() << ": : Leaving "
|
cerr << get_fileline() << ": : Leaving "
|
||||||
<< (sig->vector_width()-prts_vector_width)
|
<< (sig->vector_width()-prts_vector_width)
|
||||||
<< " high bits of the expression dangling."
|
<< " high bits of the expression dangling."
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
// Keep the if, but delete the "} else" when fixed.
|
||||||
|
} else if (prts_vector_width > sig->vector_width()) {
|
||||||
|
cerr << get_fileline() << ": : Padding "
|
||||||
|
<< (prts_vector_width-sig->vector_width())
|
||||||
|
<< " high bits of the port."
|
||||||
|
<< endl;
|
||||||
|
} else {
|
||||||
|
cerr << get_fileline() << ": : Padding "
|
||||||
|
<< (sig->vector_width()-prts_vector_width)
|
||||||
|
<< " high bits of the expression."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
sig = resize_net_to_port_(des, scope, sig, prts_vector_width,
|
sig = resize_net_to_port_(des, scope, sig, prts_vector_width,
|
||||||
prts[0]->port_type());
|
prts[0]->port_type(),
|
||||||
|
prts[0]->get_signed() &&
|
||||||
|
sig->get_signed());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect the sig expression that is the context of the
|
// Connect the sig expression that is the context of the
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
|
||||||
tmp = new NetNet(scope, scope->local_symbol(),
|
tmp = new NetNet(scope, scope->local_symbol(),
|
||||||
NetNet::WIRE, wid);
|
NetNet::WIRE, wid);
|
||||||
tmp->data_type( net->data_type() );
|
tmp->data_type( net->data_type() );
|
||||||
|
tmp->set_line(*net);
|
||||||
tmp->local_flag(true);
|
tmp->local_flag(true);
|
||||||
connect(cc->pin(0), tmp->pin(0));
|
connect(cc->pin(0), tmp->pin(0));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue