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
*/
#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
# include "config.h"
@ -1442,8 +1442,9 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
bool unsized_flag = false;
use_width = rval()->test_width(des, scope, use_width, use_width, unsized_flag);
/* Now elaborate to the expected width. */
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width);
/* Now elaborate to the expected width. Pass the lwidth to
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;
assert(rv);
@ -3400,6 +3401,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $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
* Handle processes within generate loops.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -27,7 +27,7 @@
# include "netlist.h"
NetExpr* NetExpr::eval_tree()
NetExpr* NetExpr::eval_tree(int prune_to_width)
{
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_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
@ -115,7 +115,7 @@ NetEConst* NetEBAdd::eval_tree()
return 0;
}
NetEConst* NetEBBits::eval_tree()
NetEConst* NetEBBits::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@ -690,7 +690,7 @@ NetEConst* NetEBComp::eval_neeqeq_()
return res;
}
NetEConst* NetEBComp::eval_tree()
NetEConst* NetEBComp::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@ -728,7 +728,7 @@ NetEConst* NetEBComp::eval_tree()
* The NetEBDiv operator includes the / and % operators. First evaluate
* the sub-expressions, then perform the required operation.
*/
NetExpr* NetEBDiv::eval_tree()
NetExpr* NetEBDiv::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@ -798,7 +798,7 @@ NetExpr* NetEBDiv::eval_tree()
return 0;
}
NetEConst* NetEBLogic::eval_tree()
NetEConst* NetEBLogic::eval_tree(int prune_to_width)
{
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
@ -917,7 +917,7 @@ NetExpr* NetEBMult::eval_tree_real_()
return res;
}
NetExpr* NetEBMult::eval_tree()
NetExpr* NetEBMult::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@ -990,7 +990,7 @@ NetExpr* NetEBPow::eval_tree_real_()
return res;
}
NetExpr* NetEBPow::eval_tree()
NetExpr* NetEBPow::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@ -1015,7 +1015,7 @@ NetExpr* NetEBPow::eval_tree()
* Evaluate the shift operator if possible. For this to work, both
* operands must be constant.
*/
NetEConst* NetEBShift::eval_tree()
NetEConst* NetEBShift::eval_tree(int prune_to_width)
{
eval_sub_tree_();
NetEConst*re = dynamic_cast<NetEConst*>(right_);
@ -1042,7 +1042,7 @@ NetEConst* NetEBShift::eval_tree()
cerr << get_line() << ": debug: "
<< "Evaluate " << lv << "<<" << op() << ">> "
<< 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()) {
@ -1056,6 +1056,9 @@ NetEConst* NetEBShift::eval_tree()
wid = lv.len() + shift;
}
if (prune_to_width > 0 && wid > prune_to_width)
wid = prune_to_width;
assert(wid);
verinum nv (verinum::V0, wid, lv.has_len());
@ -1096,7 +1099,7 @@ NetEConst* NetEBShift::eval_tree()
return res;
}
NetEConst* NetEConcat::eval_tree()
NetEConst* NetEConcat::eval_tree(int prune_to_width)
{
unsigned repeat_val = repeat();
unsigned local_errors = 0;
@ -1190,7 +1193,7 @@ NetEConst* NetEConcat::eval_tree()
return res;
}
NetExpr* NetEParam::eval_tree()
NetExpr* NetEParam::eval_tree(int prune_to_width)
{
if (des_ == 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_);
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
* false expressions.
*/
NetExpr* NetETernary::eval_tree()
NetExpr* NetETernary::eval_tree(int prune_to_width)
{
NetExpr*tmp;
@ -1507,7 +1510,7 @@ void NetEUnary::eval_expr_()
expr_ = oper;
}
NetEConst* NetEUnary::eval_tree()
NetEConst* NetEUnary::eval_tree(int prune_to_width)
{
eval_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_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
@ -1652,6 +1655,9 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $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
* Major rework of array handling. Memories are replaced with the
* 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
*/
#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
/*
@ -1116,7 +1116,10 @@ class NetExpr : public LineInfo {
// equivalent expression that is reduced as far as compile
// time knows how. Essentially, this is designed to fold
// 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
// 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 NetEBAdd* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
};
@ -2654,7 +2657,7 @@ class NetEBDiv : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
};
@ -2680,7 +2683,7 @@ class NetEBBits : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBBits* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
};
@ -2711,7 +2714,7 @@ class NetEBComp : public NetEBinary {
virtual bool has_width() const;
virtual ivl_variable_type_t expr_type() const;
virtual NetEBComp* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
@ -2741,7 +2744,7 @@ class NetEBLogic : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBLogic* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
private:
@ -2761,7 +2764,7 @@ class NetEBMult : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
private:
@ -2783,7 +2786,7 @@ class NetEBPow : public NetEBinary {
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBPow* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
private:
@ -2814,7 +2817,7 @@ class NetEBShift : public NetEBinary {
virtual bool has_width() const;
virtual NetEBShift* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*);
@ -2849,7 +2852,7 @@ class NetEConcat : public NetExpr {
virtual bool has_width() const;
virtual bool set_width(unsigned w, bool last_chance =false);
virtual NetEConcat* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet*synthesize(Design*);
virtual void expr_scan(struct expr_scan_t*) 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 has_width() 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 void dump(ostream&) const;
@ -2920,7 +2923,7 @@ class NetESelect : public NetExpr {
virtual bool set_width(unsigned w, bool last_chance =false);
virtual bool has_width() 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 NetNet*synthesize(Design*des);
virtual void dump(ostream&) const;
@ -3030,7 +3033,7 @@ class NetETernary : public NetExpr {
const NetExpr*false_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 NexusSet* nex_input();
@ -3071,7 +3074,7 @@ class NetEUnary : public NetExpr {
virtual bool set_width(unsigned w, bool last_chance);
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 NexusSet* nex_input();
@ -3093,7 +3096,7 @@ class NetEUBits : public NetEUnary {
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;
};
@ -3106,7 +3109,7 @@ class NetEUReduce : public NetEUnary {
virtual bool set_width(unsigned w, bool last_chance);
virtual NetNet* synthesize(Design*);
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;
};
@ -3492,6 +3495,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $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
* 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
*/
#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
# include "config.h"
@ -124,13 +124,13 @@ NetExpr* make_sub_expr(long val, NetExpr*expr)
}
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);
if (tmp == 0)
return 0;
if (NetExpr*tmp2 = tmp->eval_tree()) {
if (NetExpr*tmp2 = tmp->eval_tree(prune_width)) {
delete tmp;
tmp = tmp2;
}
@ -141,6 +141,9 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope,
/*
* $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
* Make elaborate_expr methods aware of the width that the context
* 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
*/
#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
# 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.
*
* 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;
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 $
* 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
* Spelling fixes (larry doolittle)
*