primitive ports can bind bi name.

This commit is contained in:
steve 2004-03-08 00:47:44 +00:00
parent 413932e406
commit c6453a0854
4 changed files with 123 additions and 26 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.27 2004/02/20 18:53:33 steve Exp $"
#ident "$Id: PGate.h,v 1.28 2004/03/08 00:47:44 steve Exp $"
#endif
# include "svector.h"
@ -88,7 +88,7 @@ class PGate : public LineInfo {
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
protected:
const svector<PExpr*>* get_pins() const { return pins_; }
const svector<PExpr*>& get_pins() const { return *pins_; }
void dump_pins(ostream&out) const;
void dump_delays(ostream&out) const;
@ -227,6 +227,9 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.28 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.27 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*

16
PUdp.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.cc,v 1.2 2004/02/18 17:11:54 steve Exp $"
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
#endif
# include "PUdp.h"
@ -27,8 +27,22 @@ PUdp::PUdp(perm_string n, unsigned nports)
{
}
unsigned PUdp::find_port(const char*name)
{
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
if (ports[idx] == name)
return idx;
}
return ports.count();
}
/*
* $Log: PUdp.cc,v $
* Revision 1.3 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.2 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*

7
PUdp.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.h,v 1.11 2004/02/18 17:11:54 steve Exp $"
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
#endif
# include <map>
@ -56,6 +56,8 @@ class PUdp {
explicit PUdp(perm_string n, unsigned nports);
svector<string>ports;
unsigned find_port(const char*name);
bool sequential;
svector<string>tinput;
@ -78,6 +80,9 @@ class PUdp {
/*
* $Log: PUdp.h,v $
* Revision 1.12 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.11 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.299 2004/03/08 00:10:29 steve Exp $"
#ident "$Id: elaborate.cc,v 1.300 2004/03/08 00:47:44 steve Exp $"
#endif
# include "config.h"
@ -509,7 +509,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
NetScope*my_scope = scope->child(get_name());
assert(my_scope);
const svector<PExpr*>*pins;
// This is the array of pin expressions, shuffled to match the
// order of the declaration. If the source instantiation uses
// bind by order, this is the same as the source
// list. Otherwise, the source list is rearranged by name
// binding into this list.
svector<PExpr*>pins (rmod->port_count());
// Detect binding by name. If I am binding by name, then make
// up a pins array that reflects the positions of the named
@ -517,7 +522,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// place, then get the binding from the base class.
if (pins_) {
unsigned nexp = rmod->port_count();
svector<PExpr*>*exp = new svector<PExpr*>(nexp);
// Scan the bindings, matching them with port names.
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
@ -540,7 +544,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// If I already bound something to this port, then
// the (*exp) array will already have a pointer
// value where I want to place this expression.
if ((*exp)[pidx]) {
if (pins[pidx]) {
cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' already bound." <<
endl;
@ -550,10 +554,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// OK, do the binding by placing the expression in
// the right place.
(*exp)[pidx] = pins_[idx].parm;
pins[pidx] = pins_[idx].parm;
}
pins = exp;
} else if (pin_count() == 0) {
@ -562,11 +565,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
connect-by-name list, so we'll allow it and assume
that is the case. */
svector<PExpr*>*tmp = new svector<PExpr*>(rmod->port_count());
for (unsigned idx = 0 ; idx < rmod->port_count() ; idx += 1)
(*tmp)[idx] = 0;
pins = tmp;
pins[idx] = 0;
} else {
@ -605,12 +605,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// to a concatenation, or connected to an internally
// unconnected port.
for (unsigned idx = 0 ; idx < pins->count() ; idx += 1) {
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1) {
// Skip unconnected module ports. This happens when a
// null parameter is passed in.
if ((*pins)[idx] == 0) {
if (pins[idx] == 0) {
// While we're here, look to see if this
// unconnected (from the outside) port is an
@ -674,12 +674,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if ((prts.count() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) {
sig = (*pins)[idx]->elaborate_lnet(des, scope, true);
sig = pins[idx]->elaborate_lnet(des, scope, true);
if (sig == 0) {
cerr << (*pins)[idx]->get_line() << ": error: "
cerr << pins[idx]->get_line() << ": error: "
<< "Output port expression must support "
<< "continuous assignment." << endl;
cerr << (*pins)[idx]->get_line() << ": : "
cerr << pins[idx]->get_line() << ": : "
<< "Port of " << rmod->mod_name()
<< " is " << rmod->ports[idx]->name << endl;
des->errors += 1;
@ -687,11 +687,11 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
} else {
sig = (*pins)[idx]->elaborate_net(des, scope,
sig = pins[idx]->elaborate_net(des, scope,
prts_pin_count,
0, 0, 0);
if (sig == 0) {
cerr << (*pins)[idx]->get_line()
cerr << pins[idx]->get_line()
<< ": internal error: Port expression "
<< "too complicated for elaboration." << endl;
continue;
@ -808,15 +808,87 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
delete[]attrib_list;
// This is the array of pin expressions, shuffled to match the
// order of the declaration. If the source instantiation uses
// bind by order, this is the same as the source
// list. Otherwise, the source list is rearranged by name
// binding into this list.
svector<PExpr*>pins;
// Detect binding by name. If I am binding by name, then make
// up a pins array that reflects the positions of the named
// ports. If this is simply positional binding in the first
// place, then get the binding from the base class.
if (pins_) {
unsigned nexp = udp->ports.count();
pins = svector<PExpr*>(nexp);
// Scan the bindings, matching them with port names.
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
// Given a binding, look at the module port names
// for the position that matches the binding name.
unsigned pidx = udp->find_port(pins_[idx].name);
// If the port name doesn't exist, the find_port
// method will return the port count. Detect that
// as an error.
if (pidx == nexp) {
cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' is not a port of "
<< get_name() << "." << endl;
des->errors += 1;
continue;
}
// If I already bound something to this port, then
// the (*exp) array will already have a pointer
// value where I want to place this expression.
if (pins[pidx]) {
cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' already bound." <<
endl;
des->errors += 1;
continue;
}
// OK, do the binding by placing the expression in
// the right place.
pins[pidx] = pins_[idx].parm;
}
} else {
/* Otherwise, this is a positional list of port
connections. In this case, the port count must be
right. Check that is is, the get the pin list. */
if (pin_count() != udp->ports.count()) {
cerr << get_line() << ": error: Wrong number "
"of ports. Expecting " << udp->ports.count() <<
", got " << pin_count() << "."
<< endl;
des->errors += 1;
return;
}
// No named bindings, just use the positional list I
// already have.
assert(pin_count() == udp->ports.count());
pins = get_pins();
}
/* Handle the output port of the primitive special. It is an
output port (the only output port) so must be passed an
l-value net. */
if (pin(0) == 0) {
if (pins[0] == 0) {
cerr << get_line() << ": warning: output port unconnected."
<< endl;
} else {
NetNet*sig = pin(0)->elaborate_lnet(des, scope, true);
NetNet*sig = pins[0]->elaborate_lnet(des, scope, true);
if (sig == 0) {
cerr << get_line() << ": error: "
<< "Output port expression is not valid." << endl;
@ -833,13 +905,13 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
expressions and connecting them to the pin in question. All
of this is independent of the nature of the UDP. */
for (unsigned idx = 1 ; idx < net->pin_count() ; idx += 1) {
if (pin(idx) == 0)
if (pins[idx] == 0)
continue;
NetNet*sig = pin(idx)->elaborate_net(des, scope, 1, 0, 0, 0);
NetNet*sig = pins[idx]->elaborate_net(des, scope, 1, 0, 0, 0);
if (sig == 0) {
cerr << "internal error: Expression too complicated "
"for elaboration:" << *pin(idx) << endl;
"for elaboration:" << pins[idx] << endl;
continue;
}
@ -2607,6 +2679,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.300 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.299 2004/03/08 00:10:29 steve
* Verilog2001 new style port declartions for primitives.
*