In the context of range declarations, use elab_and_eval instead
of the less robust eval_const methods.
This commit is contained in:
parent
1f4232187c
commit
f5d0211864
|
|
@ -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 \
|
||||
|
|
|
|||
34
elab_expr.cc
34
elab_expr.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
33
elab_sig.cc
33
elab_sig.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
98
eval_tree.cc
98
eval_tree.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
40
netmisc.h
40
netmisc.h
|
|
@ -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
|
||||
|
|
|
|||
12
verinum.h
12
verinum.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue