Limit the calculated widths of constants.
This commit is contained in:
parent
29b4d5a46e
commit
d9efe3312e
10
elaborate.cc
10
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.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.
|
||||
*
|
||||
|
|
|
|||
44
eval_tree.cc
44
eval_tree.cc
|
|
@ -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
|
||||
|
|
|
|||
40
netlist.h
40
netlist.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
14
netmisc.h
14
netmisc.h
|
|
@ -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)
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue