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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
# include "svector.h" # include "svector.h"
@ -88,7 +88,7 @@ class PGate : public LineInfo {
virtual bool elaborate_sig(Design*des, NetScope*scope) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const;
protected: 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_pins(ostream&out) const;
void dump_delays(ostream&out) const; void dump_delays(ostream&out) const;
@ -227,6 +227,9 @@ class PGModule : public PGate {
/* /*
* $Log: PGate.h,v $ * $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 * Revision 1.27 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
# include "PUdp.h" # 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 $ * $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 * Revision 1.2 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
# include <map> # include <map>
@ -56,6 +56,8 @@ class PUdp {
explicit PUdp(perm_string n, unsigned nports); explicit PUdp(perm_string n, unsigned nports);
svector<string>ports; svector<string>ports;
unsigned find_port(const char*name);
bool sequential; bool sequential;
svector<string>tinput; svector<string>tinput;
@ -78,6 +80,9 @@ class PUdp {
/* /*
* $Log: PUdp.h,v $ * $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 * Revision 1.11 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items. * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
# include "config.h" # 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()); NetScope*my_scope = scope->child(get_name());
assert(my_scope); 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 // Detect binding by name. If I am binding by name, then make
// up a pins array that reflects the positions of the named // 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. // place, then get the binding from the base class.
if (pins_) { if (pins_) {
unsigned nexp = rmod->port_count(); unsigned nexp = rmod->port_count();
svector<PExpr*>*exp = new svector<PExpr*>(nexp);
// Scan the bindings, matching them with port names. // Scan the bindings, matching them with port names.
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) { 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 // If I already bound something to this port, then
// the (*exp) array will already have a pointer // the (*exp) array will already have a pointer
// value where I want to place this expression. // value where I want to place this expression.
if ((*exp)[pidx]) { if (pins[pidx]) {
cerr << get_line() << ": error: port ``" << cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' already bound." << pins_[idx].name << "'' already bound." <<
endl; 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 // OK, do the binding by placing the expression in
// the right place. // the right place.
(*exp)[pidx] = pins_[idx].parm; pins[pidx] = pins_[idx].parm;
} }
pins = exp;
} else if (pin_count() == 0) { } 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 connect-by-name list, so we'll allow it and assume
that is the case. */ that is the case. */
svector<PExpr*>*tmp = new svector<PExpr*>(rmod->port_count());
for (unsigned idx = 0 ; idx < rmod->port_count() ; idx += 1) for (unsigned idx = 0 ; idx < rmod->port_count() ; idx += 1)
(*tmp)[idx] = 0; pins[idx] = 0;
pins = tmp;
} else { } else {
@ -605,12 +605,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// to a concatenation, or connected to an internally // to a concatenation, or connected to an internally
// unconnected port. // 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 // Skip unconnected module ports. This happens when a
// null parameter is passed in. // null parameter is passed in.
if ((*pins)[idx] == 0) { if (pins[idx] == 0) {
// While we're here, look to see if this // While we're here, look to see if this
// unconnected (from the outside) port is an // 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) if ((prts.count() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) { && (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) { if (sig == 0) {
cerr << (*pins)[idx]->get_line() << ": error: " cerr << pins[idx]->get_line() << ": error: "
<< "Output port expression must support " << "Output port expression must support "
<< "continuous assignment." << endl; << "continuous assignment." << endl;
cerr << (*pins)[idx]->get_line() << ": : " cerr << pins[idx]->get_line() << ": : "
<< "Port of " << rmod->mod_name() << "Port of " << rmod->mod_name()
<< " is " << rmod->ports[idx]->name << endl; << " is " << rmod->ports[idx]->name << endl;
des->errors += 1; des->errors += 1;
@ -687,11 +687,11 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
} }
} else { } else {
sig = (*pins)[idx]->elaborate_net(des, scope, sig = pins[idx]->elaborate_net(des, scope,
prts_pin_count, prts_pin_count,
0, 0, 0); 0, 0, 0);
if (sig == 0) { if (sig == 0) {
cerr << (*pins)[idx]->get_line() cerr << pins[idx]->get_line()
<< ": internal error: Port expression " << ": internal error: Port expression "
<< "too complicated for elaboration." << endl; << "too complicated for elaboration." << endl;
continue; continue;
@ -808,15 +808,87 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
delete[]attrib_list; 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 /* Handle the output port of the primitive special. It is an
output port (the only output port) so must be passed an output port (the only output port) so must be passed an
l-value net. */ l-value net. */
if (pin(0) == 0) { if (pins[0] == 0) {
cerr << get_line() << ": warning: output port unconnected." cerr << get_line() << ": warning: output port unconnected."
<< endl; << endl;
} else { } else {
NetNet*sig = pin(0)->elaborate_lnet(des, scope, true); NetNet*sig = pins[0]->elaborate_lnet(des, scope, true);
if (sig == 0) { if (sig == 0) {
cerr << get_line() << ": error: " cerr << get_line() << ": error: "
<< "Output port expression is not valid." << endl; << "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 expressions and connecting them to the pin in question. All
of this is independent of the nature of the UDP. */ of this is independent of the nature of the UDP. */
for (unsigned idx = 1 ; idx < net->pin_count() ; idx += 1) { for (unsigned idx = 1 ; idx < net->pin_count() ; idx += 1) {
if (pin(idx) == 0) if (pins[idx] == 0)
continue; 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) { if (sig == 0) {
cerr << "internal error: Expression too complicated " cerr << "internal error: Expression too complicated "
"for elaboration:" << *pin(idx) << endl; "for elaboration:" << pins[idx] << endl;
continue; continue;
} }
@ -2607,6 +2679,9 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $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 * Revision 1.299 2004/03/08 00:10:29 steve
* Verilog2001 new style port declartions for primitives. * Verilog2001 new style port declartions for primitives.
* *