primitive ports can bind bi name.
This commit is contained in:
parent
413932e406
commit
c6453a0854
7
PGate.h
7
PGate.h
|
|
@ -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
16
PUdp.cc
|
|
@ -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
7
PUdp.h
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
119
elaborate.cc
119
elaborate.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue