From cfd8cbf850dfc547f90b3950b532259457ea80e4 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 9 Nov 2002 19:20:48 +0000 Subject: [PATCH] Port expressions for output ports are lnets, not nets. --- PExpr.cc | 7 +++- PExpr.h | 14 +++++-- elab_net.cc | 89 ++++++++++++++++++++++++++++++++++++++---- elaborate.cc | 107 +++++++++++++++------------------------------------ 4 files changed, 127 insertions(+), 90 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index e335ea4c1..8b4f74112 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include "config.h" @@ -46,7 +46,7 @@ bool PExpr::is_constant(Module*) const 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: " << *this << endl; @@ -256,6 +256,9 @@ bool PEUnary::is_constant(Module*m) const /* * $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 * Support parameters with defined ranges. * diff --git a/PExpr.h b/PExpr.h index 7a63116a1..7fa6d1aab 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include @@ -80,7 +80,8 @@ class PExpr : public LineInfo { // This method elaborates the expression as gates, but // 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 // assignments can be elaborated with this method. @@ -126,7 +127,8 @@ class PEConcat : public PExpr { // continuous assignments. 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, unsigned width, unsigned long rise, @@ -216,7 +218,8 @@ class PEIdent : public PExpr { virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const; // 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. virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const; @@ -501,6 +504,9 @@ class PECallFunction : public PExpr { /* * $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 * conditional ident string using autoconfig. * diff --git a/elab_net.cc b/elab_net.cc index e8767d2a2..dffa4a5e8 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #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 # include "config.h" @@ -1437,11 +1437,70 @@ NetNet* PEIdent::elaborate_net_ram_(Design*des, NetScope*scope, 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); + + svectornets (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 * 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(); @@ -1455,11 +1514,24 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const return 0; } - cerr << get_line() << ": error: Net " << path_ - << " is not defined in this context." << endl; - cerr << get_line() << ": : Do you mean this? wire " - << path_ << " = ;" << endl; - 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_ + << " is not defined in this context." << endl; + cerr << get_line() << ": : Do you mean this? wire " + << path_ << " = ;" << endl; + return 0; + } } assert(sig); @@ -2207,6 +2279,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $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 * Add support for binary NOR operator. * diff --git a/elaborate.cc b/elaborate.cc index b76de0021..6d562c87a 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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.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 # include "config.h" @@ -612,33 +612,38 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const // port. sig is the thing outside the module that // connects to the port. - NetNet*sig = (*pins)[idx]->elaborate_net(des, scope, - prts_pin_count, - 0, 0, 0); - if (sig == 0) { - cerr << "internal error: Expression too complicated " - "for elaboration." << endl; - continue; + 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, + 0, 0, 0); + if (sig == 0) { + cerr << "internal error: Expression too complicated " + "for elaboration." << endl; + continue; + } } assert(sig); - // Check that a reg is not passed as an output or inout - // port of the module. sig is the elaborated signal in - // 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) +#ifndef NDEBUG + if ((prts.count() >= 1) && (prts[0]->port_type() != NetNet::PINPUT)) { - cerr << get_line() << ": error: reg/variable " - << sig->name() << " cannot connect to " - << "output port " << (idx+1) << " of " - << my_scope->name() << "." << endl; - des->errors += 1; - continue; + assert(sig->type() != NetNet::REG); } - +#endif // Check that the parts have matching pin counts. If // 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; } -/* - * 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); - - svectornets (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 { @@ -2522,6 +2472,9 @@ Design* elaborate(listroots) /* * $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 * Evaluate nonblocking assign r-values. *