Limit the calculated widths of constants.

This commit is contained in:
steve 2007-03-08 05:30:02 +00:00
parent 29b4d5a46e
commit d9efe3312e
5 changed files with 72 additions and 45 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: elaborate.cc,v 1.363 2007/03/05 05:59:10 steve Exp $" #ident "$Id: elaborate.cc,v 1.364 2007/03/08 05:30:02 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1442,8 +1442,9 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
bool unsized_flag = false; bool unsized_flag = false;
use_width = rval()->test_width(des, scope, use_width, use_width, unsized_flag); use_width = rval()->test_width(des, scope, use_width, use_width, unsized_flag);
/* Now elaborate to the expected width. */ /* Now elaborate to the expected width. Pass the lwidth to
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width); prune any constant result to fit with the lvalue at hand. */
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width, lv->lwidth());
if (rv == 0) return 0; if (rv == 0) return 0;
assert(rv); assert(rv);
@ -3400,6 +3401,9 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.364 2007/03/08 05:30:02 steve
* Limit the calculated widths of constants.
*
* Revision 1.363 2007/03/05 05:59:10 steve * Revision 1.363 2007/03/05 05:59:10 steve
* Handle processes within generate loops. * Handle processes within generate loops.
* *

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: eval_tree.cc,v 1.73 2007/01/16 05:44:15 steve Exp $" #ident "$Id: eval_tree.cc,v 1.74 2007/03/08 05:30:02 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -27,7 +27,7 @@
# include "netlist.h" # include "netlist.h"
NetExpr* NetExpr::eval_tree() NetExpr* NetExpr::eval_tree(int prune_to_width)
{ {
return 0; return 0;
} }
@ -51,7 +51,7 @@ void NetEBinary::eval_sub_tree_()
} }
} }
NetEConst* NetEBAdd::eval_tree() NetEConst* NetEBAdd::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_); NetEConst*lc = dynamic_cast<NetEConst*>(left_);
@ -115,7 +115,7 @@ NetEConst* NetEBAdd::eval_tree()
return 0; return 0;
} }
NetEConst* NetEBBits::eval_tree() NetEConst* NetEBBits::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
@ -690,7 +690,7 @@ NetEConst* NetEBComp::eval_neeqeq_()
return res; return res;
} }
NetEConst* NetEBComp::eval_tree() NetEConst* NetEBComp::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
@ -728,7 +728,7 @@ NetEConst* NetEBComp::eval_tree()
* The NetEBDiv operator includes the / and % operators. First evaluate * The NetEBDiv operator includes the / and % operators. First evaluate
* the sub-expressions, then perform the required operation. * the sub-expressions, then perform the required operation.
*/ */
NetExpr* NetEBDiv::eval_tree() NetExpr* NetEBDiv::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
@ -798,7 +798,7 @@ NetExpr* NetEBDiv::eval_tree()
return 0; return 0;
} }
NetEConst* NetEBLogic::eval_tree() NetEConst* NetEBLogic::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_); NetEConst*lc = dynamic_cast<NetEConst*>(left_);
@ -917,7 +917,7 @@ NetExpr* NetEBMult::eval_tree_real_()
return res; return res;
} }
NetExpr* NetEBMult::eval_tree() NetExpr* NetEBMult::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
@ -990,7 +990,7 @@ NetExpr* NetEBPow::eval_tree_real_()
return res; return res;
} }
NetExpr* NetEBPow::eval_tree() NetExpr* NetEBPow::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
@ -1015,7 +1015,7 @@ NetExpr* NetEBPow::eval_tree()
* Evaluate the shift operator if possible. For this to work, both * Evaluate the shift operator if possible. For this to work, both
* operands must be constant. * operands must be constant.
*/ */
NetEConst* NetEBShift::eval_tree() NetEConst* NetEBShift::eval_tree(int prune_to_width)
{ {
eval_sub_tree_(); eval_sub_tree_();
NetEConst*re = dynamic_cast<NetEConst*>(right_); NetEConst*re = dynamic_cast<NetEConst*>(right_);
@ -1042,7 +1042,7 @@ NetEConst* NetEBShift::eval_tree()
cerr << get_line() << ": debug: " cerr << get_line() << ": debug: "
<< "Evaluate " << lv << "<<" << op() << ">> " << "Evaluate " << lv << "<<" << op() << ">> "
<< rv << ", wid=" << wid << ", shift=" << shift << rv << ", wid=" << wid << ", shift=" << shift
<< ", lv.las_len()=" << lv.has_len() << endl; << ", lv.has_len()=" << lv.has_len() << endl;
} }
if ((wid == 0) || ! lv.has_len()) { if ((wid == 0) || ! lv.has_len()) {
@ -1056,6 +1056,9 @@ NetEConst* NetEBShift::eval_tree()
wid = lv.len() + shift; wid = lv.len() + shift;
} }
if (prune_to_width > 0 && wid > prune_to_width)
wid = prune_to_width;
assert(wid); assert(wid);
verinum nv (verinum::V0, wid, lv.has_len()); verinum nv (verinum::V0, wid, lv.has_len());
@ -1096,7 +1099,7 @@ NetEConst* NetEBShift::eval_tree()
return res; return res;
} }
NetEConst* NetEConcat::eval_tree() NetEConst* NetEConcat::eval_tree(int prune_to_width)
{ {
unsigned repeat_val = repeat(); unsigned repeat_val = repeat();
unsigned local_errors = 0; unsigned local_errors = 0;
@ -1190,7 +1193,7 @@ NetEConst* NetEConcat::eval_tree()
return res; return res;
} }
NetExpr* NetEParam::eval_tree() NetExpr* NetEParam::eval_tree(int prune_to_width)
{ {
if (des_ == 0) { if (des_ == 0) {
assert(scope_ == 0); assert(scope_ == 0);
@ -1297,7 +1300,7 @@ NetExpr* NetEParam::eval_tree()
} }
} }
NetEConst* NetESelect::eval_tree() NetEConst* NetESelect::eval_tree(int prune_to_width)
{ {
NetEConst*expr = dynamic_cast<NetEConst*>(expr_); NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
if (expr == 0) { if (expr == 0) {
@ -1370,7 +1373,7 @@ NetEConst* NetESelect::eval_tree()
* evaluates to x or z, then merge the constant bits of the true and * evaluates to x or z, then merge the constant bits of the true and
* false expressions. * false expressions.
*/ */
NetExpr* NetETernary::eval_tree() NetExpr* NetETernary::eval_tree(int prune_to_width)
{ {
NetExpr*tmp; NetExpr*tmp;
@ -1507,7 +1510,7 @@ void NetEUnary::eval_expr_()
expr_ = oper; expr_ = oper;
} }
NetEConst* NetEUnary::eval_tree() NetEConst* NetEUnary::eval_tree(int prune_to_width)
{ {
eval_expr_(); eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_); NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
@ -1564,12 +1567,12 @@ NetEConst* NetEUnary::eval_tree()
} }
NetEConst* NetEUBits::eval_tree() NetEConst* NetEUBits::eval_tree(int prune_to_width)
{ {
return NetEUnary::eval_tree(); return NetEUnary::eval_tree(prune_to_width);
} }
NetEConst* NetEUReduce::eval_tree() NetEConst* NetEUReduce::eval_tree(int prune_to_width)
{ {
eval_expr_(); eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_); NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
@ -1652,6 +1655,9 @@ NetEConst* NetEUReduce::eval_tree()
/* /*
* $Log: eval_tree.cc,v $ * $Log: eval_tree.cc,v $
* Revision 1.74 2007/03/08 05:30:02 steve
* Limit the calculated widths of constants.
*
* Revision 1.73 2007/01/16 05:44:15 steve * Revision 1.73 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the * Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory * more general concept of arrays. The NetMemory and NetEMemory

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: netlist.h,v 1.371 2007/03/02 06:13:22 steve Exp $" #ident "$Id: netlist.h,v 1.372 2007/03/08 05:30:03 steve Exp $"
#endif #endif
/* /*
@ -1116,7 +1116,10 @@ class NetExpr : public LineInfo {
// equivalent expression that is reduced as far as compile // equivalent expression that is reduced as far as compile
// time knows how. Essentially, this is designed to fold // time knows how. Essentially, this is designed to fold
// constants. // constants.
virtual NetExpr*eval_tree(); //
// The prune_to_width is the maximum width that the result
// should be. If it is -1, then do not prune the result.
virtual NetExpr*eval_tree(int prune_to_width = -1);
// Make a duplicate of myself, and subexpressions if I have // Make a duplicate of myself, and subexpressions if I have
// any. This is a deep copy operation. // any. This is a deep copy operation.
@ -2635,7 +2638,7 @@ class NetEBAdd : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBAdd* dup_expr() const; virtual NetEBAdd* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
}; };
@ -2654,7 +2657,7 @@ class NetEBDiv : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBDiv* dup_expr() const; virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree(); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
}; };
@ -2680,7 +2683,7 @@ class NetEBBits : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBBits* dup_expr() const; virtual NetEBBits* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
}; };
@ -2711,7 +2714,7 @@ class NetEBComp : public NetEBinary {
virtual bool has_width() const; virtual bool has_width() const;
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
virtual NetEBComp* dup_expr() const; virtual NetEBComp* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
@ -2741,7 +2744,7 @@ class NetEBLogic : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBLogic* dup_expr() const; virtual NetEBLogic* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
private: private:
@ -2761,7 +2764,7 @@ class NetEBMult : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBMult* dup_expr() const; virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree(); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
private: private:
@ -2783,7 +2786,7 @@ class NetEBPow : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBPow* dup_expr() const; virtual NetEBPow* dup_expr() const;
virtual NetExpr* eval_tree(); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
private: private:
@ -2814,7 +2817,7 @@ class NetEBShift : public NetEBinary {
virtual bool has_width() const; virtual bool has_width() const;
virtual NetEBShift* dup_expr() const; virtual NetEBShift* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
@ -2849,7 +2852,7 @@ class NetEConcat : public NetExpr {
virtual bool has_width() const; virtual bool has_width() const;
virtual bool set_width(unsigned w, bool last_chance =false); virtual bool set_width(unsigned w, bool last_chance =false);
virtual NetEConcat* dup_expr() const; virtual NetEConcat* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet*synthesize(Design*); virtual NetNet*synthesize(Design*);
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -2881,7 +2884,7 @@ class NetEParam : public NetExpr {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual bool has_width() const; virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual NetExpr* eval_tree(); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetEParam* dup_expr() const; virtual NetEParam* dup_expr() const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -2920,7 +2923,7 @@ class NetESelect : public NetExpr {
virtual bool set_width(unsigned w, bool last_chance =false); virtual bool set_width(unsigned w, bool last_chance =false);
virtual bool has_width() const; virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetESelect* dup_expr() const; virtual NetESelect* dup_expr() const;
virtual NetNet*synthesize(Design*des); virtual NetNet*synthesize(Design*des);
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -3030,7 +3033,7 @@ class NetETernary : public NetExpr {
const NetExpr*false_expr() const; const NetExpr*false_expr() const;
virtual NetETernary* dup_expr() const; virtual NetETernary* dup_expr() const;
virtual NetExpr* eval_tree(); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(); virtual NexusSet* nex_input();
@ -3071,7 +3074,7 @@ class NetEUnary : public NetExpr {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetEUnary* dup_expr() const; virtual NetEUnary* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(); virtual NexusSet* nex_input();
@ -3093,7 +3096,7 @@ class NetEUBits : public NetEUnary {
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
}; };
@ -3106,7 +3109,7 @@ class NetEUReduce : public NetEUnary {
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual NetNet* synthesize(Design*); virtual NetNet* synthesize(Design*);
virtual NetEUReduce* dup_expr() const; virtual NetEUReduce* dup_expr() const;
virtual NetEConst* eval_tree(); virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
}; };
@ -3492,6 +3495,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.372 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
* Revision 1.371 2007/03/02 06:13:22 steve * Revision 1.371 2007/03/02 06:13:22 steve
* Add support for edge sensitive spec paths. * Add support for edge sensitive spec paths.
* *

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: netmisc.cc,v 1.12 2006/06/02 04:48:50 steve Exp $" #ident "$Id: netmisc.cc,v 1.13 2007/03/08 05:30:03 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -124,13 +124,13 @@ NetExpr* make_sub_expr(long val, NetExpr*expr)
} }
NetExpr* elab_and_eval(Design*des, NetScope*scope, NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid) const PExpr*pe, int expr_wid, int prune_width)
{ {
NetExpr*tmp = pe->elaborate_expr(des, scope, expr_wid, false); NetExpr*tmp = pe->elaborate_expr(des, scope, expr_wid, false);
if (tmp == 0) if (tmp == 0)
return 0; return 0;
if (NetExpr*tmp2 = tmp->eval_tree()) { if (NetExpr*tmp2 = tmp->eval_tree(prune_width)) {
delete tmp; delete tmp;
tmp = tmp2; tmp = tmp2;
} }
@ -141,6 +141,9 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope,
/* /*
* $Log: netmisc.cc,v $ * $Log: netmisc.cc,v $
* Revision 1.13 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
* Revision 1.12 2006/06/02 04:48:50 steve * Revision 1.12 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context * Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary * requires of it. In the process, fix sizing of the width of unary

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: netmisc.h,v 1.28 2007/02/26 19:49:49 steve Exp $" #ident "$Id: netmisc.h,v 1.29 2007/03/08 05:30:03 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -112,14 +112,22 @@ extern unsigned count_lval_width(const class NetAssign_*first);
* it can. If the expression cannot be elaborated, return 0. * it can. If the expression cannot be elaborated, return 0.
* *
* The expr_width is the width of the context where the expression is * The expr_width is the width of the context where the expression is
* being elaborated, or -1 if the expression is self-determinted width. * being elaborated, or -1 if the expression is self-determined width.
*
* Also, the prune_width is the maximum width of the result, and it
* passed to the eval_tree method of the expression to limit constant
* results if possible.
*/ */
class PExpr; class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope, extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid); const PExpr*pe, int expr_wid,
int prune_width =-1);
/* /*
* $Log: netmisc.h,v $ * $Log: netmisc.h,v $
* Revision 1.29 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
* Revision 1.28 2007/02/26 19:49:49 steve * Revision 1.28 2007/02/26 19:49:49 steve
* Spelling fixes (larry doolittle) * Spelling fixes (larry doolittle)
* *