In the context of range declarations, use elab_and_eval instead

of the less robust eval_const methods.
This commit is contained in:
steve 2001-02-10 20:29:39 +00:00
parent 1f4232187c
commit f5d0211864
7 changed files with 178 additions and 51 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.90 2001/01/14 23:04:55 steve Exp $"
#ident "$Id: Makefile.in,v 1.91 2001/02/10 20:29:39 steve Exp $"
#
#
SHELL = /bin/sh
@ -98,7 +98,7 @@ O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_rconst.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
mangle.o netlist.o net_assign.o \
mangle.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \
net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \

View File

@ -17,12 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_expr.cc,v 1.35 2001/02/09 05:44:23 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.36 2001/02/10 20:29:39 steve Exp $"
#endif
# include "pform.h"
# include "netlist.h"
# include "netmisc.h"
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
{
@ -174,14 +175,23 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
NetESFunc*fun = new NetESFunc(name_, wid, nparms);
/* Now run through the expected parameters. If we find that
there are missing parameters, print an error message. */
there are missing parameters, print an error message.
While we're at it, try to evaluate the function parameter
expression as much as possible, and use the reduced
expression if one is created. */
unsigned missing_parms = 0;
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
PExpr*expr = parms_[idx];
if (expr) {
NetExpr*tmp = expr->elaborate_expr(des, scope);
fun->parm(idx, tmp);
NetExpr*tmp1 = expr->elaborate_expr(des, scope);
if (NetExpr*tmp2 = tmp1->eval_tree()) {
delete tmp1;
fun->parm(idx, tmp2);
} else {
fun->parm(idx, tmp1);
}
} else {
missing_parms += 1;
@ -283,17 +293,21 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
if (repeat_) {
verinum*vrep = repeat_->eval_const(des, scope->name());
if (vrep == 0) {
NetExpr*tmp = elab_and_eval(des, scope, repeat_);
assert(tmp);
NetEConst*rep = dynamic_cast<NetEConst*>(tmp);
if (rep == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
cerr << get_line() << ": : The expression is: "
<< *tmp << endl;
des->errors += 1;
return 0;
}
repeat = vrep->as_ulong();
delete vrep;
repeat = rep->value().as_ulong();
}
/* Make the empty concat expression. */
@ -597,6 +611,10 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/*
* $Log: elab_expr.cc,v $
* Revision 1.36 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.35 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_sig.cc,v 1.10 2001/01/13 22:20:08 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.11 2001/02/10 20:29:39 steve Exp $"
#endif
# include "Module.h"
@ -26,6 +26,7 @@
# include "PTask.h"
# include "PWire.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
/*
@ -320,27 +321,35 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
here. I will resolve the values later. */
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
verinum*mval = msb_[idx]->eval_const(des,path);
if (mval == 0) {
NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*msb_[idx] << "''." << endl;
des->errors += 1;
return;
}
verinum*lval = lsb_[idx]->eval_const(des, path);
if (lval == 0) {
cerr << lsb_[idx]->get_line() << ": error: "
mnum[idx] = tmp->value().as_long();
delete texpr;
texpr = elab_and_eval(des, scope, lsb_[idx]);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*lsb_[idx] << "''." << endl;
des->errors += 1;
return;
}
mnum[idx] = mval->as_long();
lnum[idx] = lval->as_long();
delete mval;
delete lval;
lnum[idx] = tmp->value().as_long();
delete texpr;
}
/* Make sure all the values for msb and lsb match by
@ -404,6 +413,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/*
* $Log: elab_sig.cc,v $
* Revision 1.11 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_tree.cc,v 1.23 2001/02/09 05:44:23 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.24 2001/02/10 20:29:39 steve Exp $"
#endif
# include "netlist.h"
@ -249,6 +249,92 @@ NetEConst* NetEBComp::eval_leeq_()
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_gt_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
verinum lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
}
/* Detect the case where the left side is greater than the
largest value the right side can possibly have. */
assert(right_->expr_width() > 0);
verinum rv (verinum::V1, right_->expr_width());
if (lv > rv) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
rv = r->value();
if (! rv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
}
if (lv.has_sign() && rv.has_sign() && (lv.as_long() > rv.as_long())) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
if (lv.as_ulong() > rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_gteq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
verinum lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
}
/* Detect the case where the left side is greater than the
largest value the right side can possibly have. */
assert(right_->expr_width() > 0);
verinum rv (verinum::V1, right_->expr_width());
if (lv >= rv) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
rv = r->value();
if (! rv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
}
if (lv.has_sign() && rv.has_sign() && (lv.as_long() >= rv.as_long())) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
if (lv.as_ulong() >= rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_neeq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
@ -393,6 +479,9 @@ NetEConst* NetEBComp::eval_tree()
case 'e': // Equality (==)
return eval_eqeq_();
case 'G': // >=
return eval_gteq_();
case 'L': // <=
return eval_leeq_();
@ -405,6 +494,9 @@ NetEConst* NetEBComp::eval_tree()
case '<': // Less than
return eval_less_();
case '>': // Greater then
return eval_gt_();
default:
return 0;
}
@ -890,6 +982,10 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.24 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.23 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.196 2001/02/09 05:44:23 steve Exp $"
#ident "$Id: netlist.h,v 1.197 2001/02/10 20:29:39 steve Exp $"
#endif
/*
@ -2184,6 +2184,8 @@ class NetEBComp : public NetEBinary {
NetEConst*eval_eqeq_();
NetEConst*eval_less_();
NetEConst*eval_leeq_();
NetEConst*eval_gt_();
NetEConst*eval_gteq_();
NetEConst*eval_neeq_();
NetEConst*eval_eqeqeq_();
NetEConst*eval_neeqeq_();
@ -2853,6 +2855,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.197 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.196 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netmisc.h,v 1.10 2000/11/20 00:58:40 steve Exp $"
#ident "$Id: netmisc.h,v 1.11 2001/02/10 20:29:39 steve Exp $"
#endif
# include "netlist.h"
@ -54,9 +54,20 @@ extern verinum::V driven_value(const Link&lnk);
*/
extern unsigned count_lval_width(const class NetAssign_*first);
/*
* This function elaborates an expression, and tries to evaluate it
* right away. It is useful for those places where the user is
* supposed to supply a constant expression.
*/
class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
/*
* $Log: netmisc.h,v $
* Revision 1.11 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.10 2000/11/20 00:58:40 steve
* Add support for supply nets (PR#17)
*
@ -69,32 +80,5 @@ extern unsigned count_lval_width(const class NetAssign_*first);
*
* Revision 1.7 2000/05/14 17:55:04 steve
* Support initialization of FF Q value.
*
* Revision 1.6 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* Change vvm constants to use the driver_t to drive
* a constant value. This works better if there are
* multiple drivers on a signal.
*
* Revision 1.5 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations.
*
* Revision 1.4 2000/03/16 19:03:03 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*
* Revision 1.3 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 2000/02/16 03:58:27 steve
* Fix up width matching in structural bitwise operators.
*
* Revision 1.1 1999/09/29 00:42:51 steve
* Allow expanding of additive operators.
*
*/
#endif

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: verinum.h,v 1.17 2001/02/09 05:44:23 steve Exp $"
#ident "$Id: verinum.h,v 1.18 2001/02/10 20:29:39 steve Exp $"
#endif
# include <string>
@ -117,10 +117,20 @@ extern verinum operator * (const verinum&left, const verinum&right);
extern verinum operator / (const verinum&left, const verinum&right);
extern verinum operator % (const verinum&left, const verinum&right);
inline verinum::V operator > (const verinum&left, const verinum&right)
{ return right < left; }
inline verinum::V operator >= (const verinum&left, const verinum&right)
{ return right <= left; }
extern verinum v_not(const verinum&left);
/*
* $Log: verinum.h,v $
* Revision 1.18 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.17 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*