Port expressions for output ports are lnets, not nets.

This commit is contained in:
steve 2002-11-09 19:20:48 +00:00
parent 013b18b3dc
commit cfd8cbf850
4 changed files with 127 additions and 90 deletions

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: PExpr.cc,v 1.31 2002/08/19 02:39:16 steve Exp $" #ident "$Id: PExpr.cc,v 1.32 2002/11/09 19:20:48 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -46,7 +46,7 @@ bool PExpr::is_constant(Module*) const
return false; return false;
} }
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
{ {
cerr << get_line() << ": error: expression not valid in assign l-value: " cerr << get_line() << ": error: expression not valid in assign l-value: "
<< *this << endl; << *this << endl;
@ -256,6 +256,9 @@ bool PEUnary::is_constant(Module*m) const
/* /*
* $Log: PExpr.cc,v $ * $Log: PExpr.cc,v $
* Revision 1.32 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.31 2002/08/19 02:39:16 steve * Revision 1.31 2002/08/19 02:39:16 steve
* Support parameters with defined ranges. * Support parameters with defined ranges.
* *

14
PExpr.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: PExpr.h,v 1.62 2002/08/12 01:34:58 steve Exp $" #ident "$Id: PExpr.h,v 1.63 2002/11/09 19:20:48 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -80,7 +80,8 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but // This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments. // restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// Expressions that can be in the l-value of procedural // Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method. // assignments can be elaborated with this method.
@ -126,7 +127,8 @@ class PEConcat : public PExpr {
// continuous assignments. // continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope, virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width, unsigned width,
unsigned long rise, unsigned long rise,
@ -216,7 +218,8 @@ class PEIdent : public PExpr {
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values. // Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// Identifiers are also allowed as procedural assignment l-values. // Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const; virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
@ -501,6 +504,9 @@ class PECallFunction : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $Log: PExpr.h,v $
* Revision 1.63 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.62 2002/08/12 01:34:58 steve * Revision 1.62 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig. * conditional ident string using autoconfig.
* *

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: elab_net.cc,v 1.101 2002/09/18 04:29:55 steve Exp $" #ident "$Id: elab_net.cc,v 1.102 2002/11/09 19:20:48 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1437,11 +1437,70 @@ NetNet* PEIdent::elaborate_net_ram_(Design*des, NetScope*scope,
return osig; return osig;
} }
/*
* The concatenation is also OK an an l-value. This method elaborates
* it as a structural l-value.
*/
NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok) const
{
assert(scope);
svector<NetNet*>nets (parms_.count());
unsigned pins = 0;
unsigned errors = 0;
if (repeat_) {
cerr << get_line() << ": sorry: I do not know how to"
" elaborate repeat concatenation nets." << endl;
return 0;
}
/* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope,
implicit_net_ok);
if (nets[idx] == 0)
errors += 1;
else
pins += nets[idx]->pin_count();
}
/* If any of the sub expressions failed to elaborate, then
delete all those that did and abort myself. */
if (errors) {
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (nets[idx]) delete nets[idx];
}
des->errors += 1;
return 0;
}
/* Make the temporary signal that connects to all the
operands, and connect it up. Scan the operands of the
concat operator from least significant to most significant,
which is opposite from how they are given in the list. */
NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()),
NetNet::IMPLICIT, pins);
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
for (unsigned pin = 0 ; pin < cur->pin_count() ; pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
}
}
osig->local_flag(true);
return osig;
}
/* /*
* Identifiers in continuous assignment l-values are limited to wires * Identifiers in continuous assignment l-values are limited to wires
* and that ilk. Detect registers and memories here and report errors. * and that ilk. Detect registers and memories here and report errors.
*/ */
NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok) const
{ {
string path = scope->name(); string path = scope->name();
@ -1455,12 +1514,25 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
return 0; return 0;
} }
if (implicit_net_ok && !error_implicit) {
sig = new NetNet(scope, scope->name()+"."+path_.peek_name(0),
NetNet::IMPLICIT, 1);
if (warn_implicit) {
cerr << get_line() << ": warning: implicit "
"definition of wire " << scope->name()
<< "." << path_.peek_name(0) << "." << endl;
}
} else {
cerr << get_line() << ": error: Net " << path_ cerr << get_line() << ": error: Net " << path_
<< " is not defined in this context." << endl; << " is not defined in this context." << endl;
cerr << get_line() << ": : Do you mean this? wire " cerr << get_line() << ": : Do you mean this? wire "
<< path_ << " = <expr>;" << endl; << path_ << " = <expr>;" << endl;
return 0; return 0;
} }
}
assert(sig); assert(sig);
@ -2207,6 +2279,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $Log: elab_net.cc,v $
* Revision 1.102 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.101 2002/09/18 04:29:55 steve * Revision 1.101 2002/09/18 04:29:55 steve
* Add support for binary NOR operator. * Add support for binary NOR operator.
* *

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.263 2002/08/28 18:54:36 steve Exp $" #ident "$Id: elaborate.cc,v 1.264 2002/11/09 19:20:48 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -612,7 +612,21 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// port. sig is the thing outside the module that // port. sig is the thing outside the module that
// connects to the port. // connects to the port.
NetNet*sig = (*pins)[idx]->elaborate_net(des, scope, NetNet*sig;
if ((prts.count() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) {
sig = (*pins)[idx]->elaborate_lnet(des, scope, true);
if (sig == 0) {
cerr << (*pins)[idx]->get_line() << ": error: "
<< "Output port expression must support "
<< "continuous assignment." << endl;
des->errors += 1;
continue;
}
} else {
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) {
@ -620,25 +634,16 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
"for elaboration." << endl; "for elaboration." << endl;
continue; continue;
} }
}
assert(sig); assert(sig);
// Check that a reg is not passed as an output or inout #ifndef NDEBUG
// port of the module. sig is the elaborated signal in if ((prts.count() >= 1)
// the outside that is to be passed, and prts is a
// concatenation of signals on the input that receive a
// reg value.
if ((sig->type() == NetNet::REG)
&& (prts.count() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) { && (prts[0]->port_type() != NetNet::PINPUT)) {
cerr << get_line() << ": error: reg/variable " assert(sig->type() != NetNet::REG);
<< sig->name() << " cannot connect to "
<< "output port " << (idx+1) << " of "
<< my_scope->name() << "." << endl;
des->errors += 1;
continue;
} }
#endif
// Check that the parts have matching pin counts. If // Check that the parts have matching pin counts. If
// not, they are different widths. Note that idx is 0 // not, they are different widths. Note that idx is 0
@ -838,61 +843,6 @@ void PGModule::elaborate_scope(Design*des, NetScope*sc) const
des->errors += 1; des->errors += 1;
} }
/*
* The concatenation is also OK an an l-value. This method elaborates
* it as a structural l-value.
*/
NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const
{
assert(scope);
svector<NetNet*>nets (parms_.count());
unsigned pins = 0;
unsigned errors = 0;
if (repeat_) {
cerr << get_line() << ": sorry: I do not know how to"
" elaborate repeat concatenation nets." << endl;
return 0;
}
/* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
if (nets[idx] == 0)
errors += 1;
else
pins += nets[idx]->pin_count();
}
/* If any of the sub expressions failed to elaborate, then
delete all those that did and abort myself. */
if (errors) {
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (nets[idx]) delete nets[idx];
}
des->errors += 1;
return 0;
}
/* Make the temporary signal that connects to all the
operands, and connect it up. Scan the operands of the
concat operator from least significant to most significant,
which is opposite from how they are given in the list. */
NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()),
NetNet::IMPLICIT, pins);
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
for (unsigned pin = 0 ; pin < cur->pin_count() ; pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
}
}
osig->local_flag(true);
return osig;
}
NetProc* Statement::elaborate(Design*des, NetScope*) const NetProc* Statement::elaborate(Design*des, NetScope*) const
{ {
@ -2522,6 +2472,9 @@ Design* elaborate(list<const char*>roots)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.264 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.263 2002/08/28 18:54:36 steve * Revision 1.263 2002/08/28 18:54:36 steve
* Evaluate nonblocking assign r-values. * Evaluate nonblocking assign r-values.
* *