Remove last bits of relax_width methods, and use test_width
to calculate the width of an r-value expression that may contain unsized numbers.
This commit is contained in:
parent
ed5d3188b3
commit
c339dc4bbc
52
PExpr.h
52
PExpr.h
|
|
@ -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: PExpr.h,v 1.84 2006/10/30 05:44:49 steve Exp $"
|
#ident "$Id: PExpr.h,v 1.85 2006/11/04 06:19:24 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -72,7 +72,9 @@ class PExpr : public LineInfo {
|
||||||
// unsized and therefore expandable. This happens if a
|
// unsized and therefore expandable. This happens if a
|
||||||
// sub-expression is an unsized literal. Some expressions make
|
// sub-expression is an unsized literal. Some expressions make
|
||||||
// special use of that.
|
// special use of that.
|
||||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval,
|
||||||
|
bool&unsized_flag) const;
|
||||||
|
|
||||||
// Procedural elaboration of the expression. The expr_width is
|
// Procedural elaboration of the expression. The expr_width is
|
||||||
// the width of the context of the expression (i.e. the
|
// the width of the context of the expression (i.e. the
|
||||||
|
|
@ -151,8 +153,6 @@ class PEConcat : public PExpr {
|
||||||
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
|
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||||
bool implicit_net_ok =false) const;
|
bool implicit_net_ok =false) const;
|
||||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||||
|
|
@ -202,8 +202,6 @@ class PEEvent : public PExpr {
|
||||||
|
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
edge_t type_;
|
edge_t type_;
|
||||||
PExpr *expr_;
|
PExpr *expr_;
|
||||||
|
|
@ -220,8 +218,6 @@ class PEFNumber : public PExpr {
|
||||||
|
|
||||||
const verireal& value() const;
|
const verireal& value() const;
|
||||||
|
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
/* The eval_const method as applied to a floating point number
|
/* The eval_const method as applied to a floating point number
|
||||||
gets the *integer* value of the number. This accounts for
|
gets the *integer* value of the number. This accounts for
|
||||||
any rounding that is needed to get the value. */
|
any rounding that is needed to get the value. */
|
||||||
|
|
@ -255,9 +251,9 @@ class PEIdent : public PExpr {
|
||||||
~PEIdent();
|
~PEIdent();
|
||||||
|
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval,
|
||||||
//virtual int test_width(bool) const;
|
bool&unsized_flag) const;
|
||||||
|
|
||||||
// Identifiers are allowed (with restrictions) is assign l-values.
|
// Identifiers are allowed (with restrictions) is assign l-values.
|
||||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||||
|
|
@ -292,6 +288,11 @@ class PEIdent : public PExpr {
|
||||||
|
|
||||||
const hname_t& path() const;
|
const hname_t& path() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Common functions to calculate parts of part/bit selects.
|
||||||
|
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
|
||||||
|
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetAssign_*elaborate_lval_net_part_(Design*, NetScope*, NetNet*) const;
|
NetAssign_*elaborate_lval_net_part_(Design*, NetScope*, NetNet*) const;
|
||||||
NetAssign_*elaborate_lval_net_idx_up_(Design*, NetScope*, NetNet*) const;
|
NetAssign_*elaborate_lval_net_idx_up_(Design*, NetScope*, NetNet*) const;
|
||||||
|
|
@ -376,7 +377,9 @@ class PENumber : public PExpr {
|
||||||
const verinum& value() const;
|
const verinum& value() const;
|
||||||
|
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval,
|
||||||
|
bool&unsized_flag) const;
|
||||||
|
|
||||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned lwidth,
|
unsigned lwidth,
|
||||||
|
|
@ -416,7 +419,6 @@ class PEString : public PExpr {
|
||||||
|
|
||||||
string value() const;
|
string value() const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned width,
|
unsigned width,
|
||||||
|
|
@ -443,7 +445,6 @@ class PEUnary : public PExpr {
|
||||||
~PEUnary();
|
~PEUnary();
|
||||||
|
|
||||||
virtual void dump(ostream&out) const;
|
virtual void dump(ostream&out) const;
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned width,
|
unsigned width,
|
||||||
|
|
@ -471,11 +472,12 @@ class PEBinary : public PExpr {
|
||||||
~PEBinary();
|
~PEBinary();
|
||||||
|
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
virtual void dump(ostream&out) const;
|
virtual void dump(ostream&out) const;
|
||||||
|
|
||||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval,
|
||||||
|
bool&unsized_flag) const;
|
||||||
|
|
||||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned width,
|
unsigned width,
|
||||||
|
|
@ -494,8 +496,8 @@ class PEBinary : public PExpr {
|
||||||
PExpr*left_;
|
PExpr*left_;
|
||||||
PExpr*right_;
|
PExpr*right_;
|
||||||
|
|
||||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
|
||||||
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
||||||
|
|
@ -550,7 +552,9 @@ class PEBComp : public PEBinary {
|
||||||
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
||||||
~PEBComp();
|
~PEBComp();
|
||||||
|
|
||||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&flag) const;
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval,
|
||||||
|
bool&flag) const;
|
||||||
|
|
||||||
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
|
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
|
||||||
int expr_width, bool sys_task_arg) const;
|
int expr_width, bool sys_task_arg) const;
|
||||||
|
|
@ -562,7 +566,8 @@ class PEBShift : public PEBinary {
|
||||||
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
||||||
~PEBShift();
|
~PEBShift();
|
||||||
|
|
||||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&flag) const;
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval, bool&flag) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -576,7 +581,6 @@ class PETernary : public PExpr {
|
||||||
~PETernary();
|
~PETernary();
|
||||||
|
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
virtual void dump(ostream&out) const;
|
virtual void dump(ostream&out) const;
|
||||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||||
|
|
@ -609,7 +613,6 @@ class PECallFunction : public PExpr {
|
||||||
~PECallFunction();
|
~PECallFunction();
|
||||||
|
|
||||||
virtual void dump(ostream &) const;
|
virtual void dump(ostream &) const;
|
||||||
//virtual int test_width(bool) const;
|
|
||||||
|
|
||||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned width,
|
unsigned width,
|
||||||
|
|
@ -639,6 +642,11 @@ class PECallFunction : public PExpr {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.h,v $
|
* $Log: PExpr.h,v $
|
||||||
|
* Revision 1.85 2006/11/04 06:19:24 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.84 2006/10/30 05:44:49 steve
|
* Revision 1.84 2006/10/30 05:44:49 steve
|
||||||
* Expression widths with unsized literals are pseudo-infinite width.
|
* Expression widths with unsized literals are pseudo-infinite width.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
244
elab_expr.cc
244
elab_expr.cc
|
|
@ -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: elab_expr.cc,v 1.114 2006/10/30 05:44:49 steve Exp $"
|
#ident "$Id: elab_expr.cc,v 1.115 2006/11/04 06:19:24 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -32,7 +32,8 @@
|
||||||
* The default behavor for the test_width method is to just return the
|
* The default behavor for the test_width method is to just return the
|
||||||
* minimum width that is passed in.
|
* minimum width that is passed in.
|
||||||
*/
|
*/
|
||||||
unsigned PExpr::test_width(unsigned min, unsigned lval, bool&) const
|
unsigned PExpr::test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval, bool&) const
|
||||||
{
|
{
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_line() << ": debug: test_width defaults to "
|
cerr << get_line() << ": debug: test_width defaults to "
|
||||||
|
|
@ -51,12 +52,13 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, int, bool) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PEBinary::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
unsigned PEBinary::test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval, bool&unsized_flag) const
|
||||||
{
|
{
|
||||||
bool flag_left = false;
|
bool flag_left = false;
|
||||||
bool flag_right = false;
|
bool flag_right = false;
|
||||||
unsigned wid_left = left_->test_width(min, lval, flag_left);
|
unsigned wid_left = left_->test_width(des,scope, min, lval, flag_left);
|
||||||
unsigned wid_right = right_->test_width(min, lval, flag_right);
|
unsigned wid_right = right_->test_width(des,scope, min, lval, flag_right);
|
||||||
|
|
||||||
if (flag_left || flag_right)
|
if (flag_left || flag_right)
|
||||||
unsized_flag = true;
|
unsized_flag = true;
|
||||||
|
|
@ -106,13 +108,14 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBinary*tmp = elaborate_eval_expr_base_(des, lp, rp);
|
NetEBinary*tmp = elaborate_eval_expr_base_(des, lp, rp, expr_wid);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des,
|
NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des,
|
||||||
NetExpr*lp,
|
NetExpr*lp,
|
||||||
NetExpr*rp) const
|
NetExpr*rp,
|
||||||
|
int expr_wid) const
|
||||||
{
|
{
|
||||||
/* If either expression can be evaluated ahead of time, then
|
/* If either expression can be evaluated ahead of time, then
|
||||||
do so. This can prove helpful later. */
|
do so. This can prove helpful later. */
|
||||||
|
|
@ -130,7 +133,7 @@ NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return elaborate_expr_base_(des, lp, rp);
|
return elaborate_expr_base_(des, lp, rp, expr_wid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -139,7 +142,8 @@ NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des,
|
||||||
* the correct NetEBinary object and connect the parameters.
|
* the correct NetEBinary object and connect the parameters.
|
||||||
*/
|
*/
|
||||||
NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
NetExpr*lp, NetExpr*rp) const
|
NetExpr*lp, NetExpr*rp,
|
||||||
|
int expr_wid) const
|
||||||
{
|
{
|
||||||
bool flag;
|
bool flag;
|
||||||
|
|
||||||
|
|
@ -204,6 +208,9 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
tmp = new NetEBAdd(op_, lp, rp);
|
tmp = new NetEBAdd(op_, lp, rp);
|
||||||
|
if (expr_wid > 0 && (tmp->expr_type() == IVL_VT_BOOL
|
||||||
|
|| tmp->expr_type() == IVL_VT_LOGIC))
|
||||||
|
tmp->set_width(expr_wid);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -245,7 +252,7 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PEBComp::test_width(unsigned, unsigned, bool&) const
|
unsigned PEBComp::test_width(Design*, NetScope*,unsigned, unsigned, bool&) const
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -256,8 +263,26 @@ NetEBinary* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
||||||
assert(left_);
|
assert(left_);
|
||||||
assert(right_);
|
assert(right_);
|
||||||
|
|
||||||
|
bool unsized_flag = false;
|
||||||
|
unsigned left_width = left_->test_width(des, scope, 0, 0, unsized_flag);
|
||||||
|
bool save_flag = unsized_flag;
|
||||||
|
unsigned right_width = right_->test_width(des, scope, 0, 0, unsized_flag);
|
||||||
|
|
||||||
|
if (save_flag != unsized_flag)
|
||||||
|
left_width = left_->test_width(des, scope, 0, 0, unsized_flag);
|
||||||
|
|
||||||
/* Width of operands is self-determined. */
|
/* Width of operands is self-determined. */
|
||||||
int use_wid = -1;
|
int use_wid = left_width;
|
||||||
|
if (right_width > left_width)
|
||||||
|
use_wid = right_width;
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_line() << ": debug: "
|
||||||
|
<< "Comparison expression operands are "
|
||||||
|
<< left_width << " bits and "
|
||||||
|
<< right_width << " bits. Resorting to "
|
||||||
|
<< use_wid << " bits." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr*lp = left_->elaborate_expr(des, scope, use_wid, false);
|
NetExpr*lp = left_->elaborate_expr(des, scope, use_wid, false);
|
||||||
NetExpr*rp = right_->elaborate_expr(des, scope, use_wid, false);
|
NetExpr*rp = right_->elaborate_expr(des, scope, use_wid, false);
|
||||||
|
|
@ -267,20 +292,13 @@ NetEBinary* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we find that one of the operands are indefinitely wide,
|
return elaborate_eval_expr_base_(des, lp, rp, use_wid);
|
||||||
then go ahead and relax the width of the operand to
|
|
||||||
eliminate loss. */
|
|
||||||
if (! lp->has_width())
|
|
||||||
rp->relax_width();
|
|
||||||
if (! rp->has_width())
|
|
||||||
lp->relax_width();
|
|
||||||
|
|
||||||
return elaborate_eval_expr_base_(des, lp, rp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PEBShift::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
unsigned PEBShift::test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval, bool&unsized_flag) const
|
||||||
{
|
{
|
||||||
unsigned wid_left = left_->test_width(min, 0, unsized_flag);
|
unsigned wid_left = left_->test_width(des,scope,min, 0, unsized_flag);
|
||||||
|
|
||||||
// The right expression is self-determined and has no impact
|
// The right expression is self-determined and has no impact
|
||||||
// on the expression size that is generated.
|
// on the expression size that is generated.
|
||||||
|
|
@ -591,9 +609,118 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, int, bool) const
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
unsigned PEIdent::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
* Given that the msb_ and lsb_ are part select expressions, this
|
||||||
|
* function calculates their values. Note that this method does *not*
|
||||||
|
* convert the values to canonical form.
|
||||||
|
*/
|
||||||
|
bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
||||||
|
long&msb, long&lsb) const
|
||||||
{
|
{
|
||||||
|
assert(lsb_ != 0);
|
||||||
|
assert(msb_ != 0);
|
||||||
|
|
||||||
|
/* This handles part selects. In this case, there are
|
||||||
|
two bit select expressions, and both must be
|
||||||
|
constant. Evaluate them and pass the results back to
|
||||||
|
the caller. */
|
||||||
|
NetExpr*lsb_ex = elab_and_eval(des, scope, lsb_, -1);
|
||||||
|
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
|
||||||
|
if (lsb_c == 0) {
|
||||||
|
cerr << lsb_->get_line() << ": error: "
|
||||||
|
"Part select expressions must be constant."
|
||||||
|
<< endl;
|
||||||
|
cerr << lsb_->get_line() << ": : This lsb expression "
|
||||||
|
"violates the rule: " << *lsb_ << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr*msb_ex = elab_and_eval(des, scope, msb_, -1);
|
||||||
|
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
|
||||||
|
if (msb_c == 0) {
|
||||||
|
cerr << msb_->get_line() << ": error: "
|
||||||
|
"Part select expressions must be constant."
|
||||||
|
<< endl;
|
||||||
|
cerr << msb_->get_line() << ": : This msb expression "
|
||||||
|
"violates the rule: " << *msb_ << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
msb = msb_c->value().as_long();
|
||||||
|
lsb = lsb_c->value().as_long();
|
||||||
|
|
||||||
|
delete msb_ex;
|
||||||
|
delete lsb_ex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
|
||||||
|
unsigned long&wid) const
|
||||||
|
{
|
||||||
|
assert(lsb_);
|
||||||
|
bool flag = true;
|
||||||
|
|
||||||
|
/* Calculate the width expression (in the lsb_ position)
|
||||||
|
first. If the expression is not constant, error but guess 1
|
||||||
|
so we can keep going and find more errors. */
|
||||||
|
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1);
|
||||||
|
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
||||||
|
|
||||||
|
if (wid_c == 0) {
|
||||||
|
cerr << get_line() << ": error: Indexed part width must be "
|
||||||
|
<< "constant. Expression in question is..." << endl;
|
||||||
|
cerr << get_line() << ": : " << *wid_ex << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wid = wid_c? wid_c->value().as_ulong() : 1;
|
||||||
|
delete wid_ex;
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
||||||
|
unsigned min, unsigned lval,
|
||||||
|
bool&unsized_flag) const
|
||||||
|
{
|
||||||
|
NetNet* net = 0;
|
||||||
|
NetMemory* mem = 0;
|
||||||
|
const NetExpr*par = 0;
|
||||||
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
|
const NetExpr*ex1, *ex2;
|
||||||
|
|
||||||
|
NetScope*found_in = symbol_search(des, scope, path_,
|
||||||
|
net, mem, par, eve,
|
||||||
|
ex1, ex2);
|
||||||
|
|
||||||
|
if (net != 0) {
|
||||||
|
unsigned use_width = net->vector_width();
|
||||||
|
switch (sel_) {
|
||||||
|
case SEL_NONE:
|
||||||
|
break;
|
||||||
|
case SEL_PART:
|
||||||
|
{ long msb, lsb;
|
||||||
|
bool flag = calculate_parts_(des, scope, msb, lsb);
|
||||||
|
use_width = 1 + ((msb>lsb)? (msb-lsb) : (lsb-msb));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_IDX_UP:
|
||||||
|
case SEL_IDX_DO:
|
||||||
|
{ unsigned long tmp = 0;
|
||||||
|
calculate_up_do_width_(des, scope, tmp);
|
||||||
|
use_width = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
return use_width;
|
||||||
|
}
|
||||||
|
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1055,37 +1182,23 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
||||||
NetNet*net, NetScope*found_in)const
|
NetNet*net, NetScope*found_in)const
|
||||||
{
|
{
|
||||||
assert(lsb_ != 0);
|
long msv, lsv;
|
||||||
assert(msb_ != 0);
|
|
||||||
assert(idx_.empty());
|
assert(idx_.empty());
|
||||||
|
bool flag = calculate_parts_(des, scope, msv, lsv);
|
||||||
verinum*lsn = lsb_->eval_const(des, scope);
|
if (!flag)
|
||||||
verinum*msn = msb_->eval_const(des, scope);
|
|
||||||
if ((lsn == 0) || (msn == 0)) {
|
|
||||||
cerr << get_line() << ": error: "
|
|
||||||
"Part select expressions must be "
|
|
||||||
"constant expressions." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
assert(lsn);
|
|
||||||
assert(msn);
|
|
||||||
|
|
||||||
/* The indices of part selects are signed integers, so allow
|
/* The indices of part selects are signed integers, so allow
|
||||||
negative values. However, the width that they represent is
|
negative values. However, the width that they represent is
|
||||||
unsigned. Remember that any order is possible,
|
unsigned. Remember that any order is possible,
|
||||||
i.e., [1:0], [-4:6], etc. */
|
i.e., [1:0], [-4:6], etc. */
|
||||||
|
|
||||||
long lsv = lsn->as_long();
|
|
||||||
long msv = msn->as_long();
|
|
||||||
unsigned long wid = 1 + ((msv>lsv)? (msv-lsv) : (lsv-msv));
|
unsigned long wid = 1 + ((msv>lsv)? (msv-lsv) : (lsv-msv));
|
||||||
if (wid > net->vector_width()) {
|
if (wid > net->vector_width()) {
|
||||||
cerr << get_line() << ": error: part select ["
|
cerr << get_line() << ": error: part select ["
|
||||||
<< msv << ":" << lsv << "] out of range." << endl;
|
<< msv << ":" << lsv << "] out of range." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
delete lsn;
|
//delete lsn;
|
||||||
delete msn;
|
//delete msn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert(wid <= net->vector_width());
|
assert(wid <= net->vector_width());
|
||||||
|
|
@ -1094,8 +1207,8 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
||||||
cerr << get_line() << ": error: part select ["
|
cerr << get_line() << ": error: part select ["
|
||||||
<< msv << ":" << lsv << "] out of order." << endl;
|
<< msv << ":" << lsv << "] out of order." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
delete lsn;
|
//delete lsn;
|
||||||
delete msn;
|
//delete msn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1104,8 +1217,8 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
||||||
cerr << get_line() << ": error: part select ["
|
cerr << get_line() << ": error: part select ["
|
||||||
<< msv << ":" << lsv << "] out of range." << endl;
|
<< msv << ":" << lsv << "] out of range." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
delete lsn;
|
//delete lsn;
|
||||||
delete msn;
|
//delete msn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1140,19 +1253,9 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
||||||
|
|
||||||
NetExpr*wid_e = elab_and_eval(des, scope, lsb_, -1);
|
unsigned long wid = 0;
|
||||||
NetEConst*wid_c = dynamic_cast<NetEConst*> (wid_e);
|
calculate_up_do_width_(des, scope, wid);
|
||||||
if (wid_c == 0) {
|
|
||||||
cerr << get_line() << ": error: Width of indexed part select "
|
|
||||||
<< "must be constant." << endl;
|
|
||||||
cerr << get_line() << ": : Width expression is: "
|
|
||||||
<< *wid_e << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(wid_c != 0);
|
|
||||||
unsigned long wid = wid_c->value().as_ulong();
|
|
||||||
|
|
||||||
// Handle the special case that the base is constant as
|
// Handle the special case that the base is constant as
|
||||||
// well. In this case it can be converted to a conventional
|
// well. In this case it can be converted to a conventional
|
||||||
|
|
@ -1193,19 +1296,8 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
||||||
|
|
||||||
NetExpr*wid_e = elab_and_eval(des, scope, lsb_, -1);
|
unsigned long wid = 0;
|
||||||
NetEConst*wid_c = dynamic_cast<NetEConst*> (wid_e);
|
calculate_up_do_width_(des, scope, wid);
|
||||||
if (wid_c == 0) {
|
|
||||||
cerr << get_line() << ": error: Width of indexed part select "
|
|
||||||
<< "must be constant." << endl;
|
|
||||||
cerr << get_line() << ": : Width expression is: "
|
|
||||||
<< *wid_e << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(wid_c != 0);
|
|
||||||
long wid = wid_c->value().as_long();
|
|
||||||
|
|
||||||
// Handle the special case that the base is constant as
|
// Handle the special case that the base is constant as
|
||||||
// well. In this case it can be converted to a conventional
|
// well. In this case it can be converted to a conventional
|
||||||
|
|
@ -1335,7 +1427,8 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PENumber::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
unsigned PENumber::test_width(Design*, NetScope*,
|
||||||
|
unsigned min, unsigned lval, bool&unsized_flag) const
|
||||||
{
|
{
|
||||||
unsigned use_wid = value_->len();
|
unsigned use_wid = value_->len();
|
||||||
if (min > use_wid)
|
if (min > use_wid)
|
||||||
|
|
@ -1545,6 +1638,11 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_expr.cc,v $
|
* $Log: elab_expr.cc,v $
|
||||||
|
* Revision 1.115 2006/11/04 06:19:24 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.114 2006/10/30 05:44:49 steve
|
* Revision 1.114 2006/10/30 05:44:49 steve
|
||||||
* Expression widths with unsized literals are pseudo-infinite width.
|
* Expression widths with unsized literals are pseudo-infinite width.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
61
elab_lval.cc
61
elab_lval.cc
|
|
@ -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: elab_lval.cc,v 1.36 2006/06/02 04:48:50 steve Exp $"
|
#ident "$Id: elab_lval.cc,v 1.37 2006/11/04 06:19:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -304,41 +304,10 @@ NetAssign_* PEIdent::elaborate_lval_net_part_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
NetNet*reg) const
|
NetNet*reg) const
|
||||||
{
|
{
|
||||||
assert(msb_ && lsb_);
|
long msb, lsb;
|
||||||
|
bool flag = calculate_parts_(des, scope, msb, lsb);
|
||||||
/* This handles part selects. In this case, there are
|
if (!flag)
|
||||||
two bit select expressions, and both must be
|
|
||||||
constant. Evaluate them and pass the results back to
|
|
||||||
the caller. */
|
|
||||||
NetExpr*lsb_ex = elab_and_eval(des, scope, lsb_, -1);
|
|
||||||
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
|
|
||||||
if (lsb_c == 0) {
|
|
||||||
cerr << lsb_->get_line() << ": error: "
|
|
||||||
"Part select expressions must be constant."
|
|
||||||
<< endl;
|
|
||||||
cerr << lsb_->get_line() << ": : This lsb expression "
|
|
||||||
"violates the rule: " << *lsb_ << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
NetExpr*msb_ex = elab_and_eval(des, scope, msb_, -1);
|
|
||||||
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
|
|
||||||
if (msb_c == 0) {
|
|
||||||
cerr << msb_->get_line() << ": error: "
|
|
||||||
"Part select expressions must be constant."
|
|
||||||
<< endl;
|
|
||||||
cerr << msb_->get_line() << ": : This msb expression "
|
|
||||||
"violates the rule: " << *msb_ << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
long msb = msb_c->value().as_long();
|
|
||||||
long lsb = lsb_c->value().as_long();
|
|
||||||
|
|
||||||
delete msb_ex;
|
|
||||||
delete lsb_ex;
|
|
||||||
|
|
||||||
NetAssign_*lv = 0;
|
NetAssign_*lv = 0;
|
||||||
|
|
||||||
|
|
@ -402,21 +371,8 @@ NetAssign_* PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the width expression (in the lsb_ position)
|
unsigned long wid;
|
||||||
first. If the expression is not constant, error but guess 1
|
calculate_up_do_width_(des, scope, wid);
|
||||||
so we can keep going and find more errors. */
|
|
||||||
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1);
|
|
||||||
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
|
||||||
|
|
||||||
if (wid_c == 0) {
|
|
||||||
cerr << get_line() << ": error: Indexed part width must be "
|
|
||||||
<< "constant. Expression in question is..." << endl;
|
|
||||||
cerr << get_line() << ": : " << *wid_ex << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wid = wid_c? wid_c->value().as_ulong() : 1;
|
|
||||||
delete wid_ex;
|
|
||||||
|
|
||||||
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
|
||||||
|
|
||||||
|
|
@ -544,6 +500,11 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_lval.cc,v $
|
* $Log: elab_lval.cc,v $
|
||||||
|
* Revision 1.37 2006/11/04 06:19:25 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.36 2006/06/02 04:48:50 steve
|
* Revision 1.36 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
|
||||||
|
|
|
||||||
|
|
@ -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: elab_pexpr.cc,v 1.24 2006/06/02 04:48:50 steve Exp $"
|
#ident "$Id: elab_pexpr.cc,v 1.25 2006/11/04 06:19:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -53,7 +53,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
|
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -1);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,6 +236,11 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_pexpr.cc,v $
|
* $Log: elab_pexpr.cc,v $
|
||||||
|
* Revision 1.25 2006/11/04 06:19:25 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.24 2006/06/02 04:48:50 steve
|
* Revision 1.24 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
|
||||||
|
|
|
||||||
21
elaborate.cc
21
elaborate.cc
|
|
@ -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.348 2006/10/30 05:44:49 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.349 2006/11/04 06:19:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1428,7 +1428,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
something else based on self-determined widths inside. */
|
something else based on self-determined widths inside. */
|
||||||
unsigned use_width = lv->lwidth();
|
unsigned use_width = lv->lwidth();
|
||||||
bool unsized_flag = false;
|
bool unsized_flag = false;
|
||||||
use_width = rval()->test_width(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. */
|
||||||
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width);
|
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width);
|
||||||
|
|
@ -2619,11 +2619,17 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
assert(sig);
|
assert(sig);
|
||||||
NetAssign_*lv = new NetAssign_(sig);
|
NetAssign_*lv = new NetAssign_(sig);
|
||||||
|
|
||||||
|
/* Calculate the width of the initialization as if this were
|
||||||
|
any other assignment statement. */
|
||||||
|
unsigned use_width = lv->lwidth();
|
||||||
|
bool unsized_flag = false;
|
||||||
|
use_width = expr1_->test_width(des, scope, use_width, use_width, unsized_flag);
|
||||||
|
|
||||||
/* Make the r-value of the initial assignment, and size it
|
/* Make the r-value of the initial assignment, and size it
|
||||||
properly. Then use it to build the assignment statement. */
|
properly. Then use it to build the assignment statement. */
|
||||||
etmp = elab_and_eval(des, scope, expr1_, lv->lwidth());
|
etmp = elab_and_eval(des, scope, expr1_, use_width);
|
||||||
etmp->set_width(lv->lwidth());
|
etmp->set_width(use_width);
|
||||||
etmp = pad_to_width(etmp, lv->lwidth());
|
etmp = pad_to_width(etmp, use_width);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_line() << ": debug: FOR initial assign: "
|
cerr << get_line() << ": debug: FOR initial assign: "
|
||||||
|
|
@ -3320,6 +3326,11 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.349 2006/11/04 06:19:25 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.348 2006/10/30 05:44:49 steve
|
* Revision 1.348 2006/10/30 05:44:49 steve
|
||||||
* Expression widths with unsized literals are pseudo-infinite width.
|
* Expression widths with unsized literals are pseudo-infinite width.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
14
netlist.h
14
netlist.h
|
|
@ -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.364 2006/10/30 05:44:49 steve Exp $"
|
#ident "$Id: netlist.h,v 1.365 2006/11/04 06:19:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1134,12 +1134,6 @@ class NetExpr : public LineInfo {
|
||||||
// width to the l-value width, if possible.
|
// width to the l-value width, if possible.
|
||||||
virtual bool set_width(unsigned wid, bool last_chance =false);
|
virtual bool set_width(unsigned wid, bool last_chance =false);
|
||||||
|
|
||||||
// This is similar to set_width, but allows the expression to
|
|
||||||
// set the width for itself, it a way that eliminates
|
|
||||||
// loss. This is used by elaboration in expressions where the
|
|
||||||
// expression width is determined to be "indefinitely large".
|
|
||||||
virtual void relax_width(void);
|
|
||||||
|
|
||||||
// This method returns true if the expression is
|
// This method returns true if the expression is
|
||||||
// signed. Unsigned expressions return false.
|
// signed. Unsigned expressions return false.
|
||||||
bool has_sign() const;
|
bool has_sign() const;
|
||||||
|
|
@ -2682,7 +2676,6 @@ class NetEBAdd : public NetEBinary {
|
||||||
virtual ivl_variable_type_t expr_type() const;
|
virtual ivl_variable_type_t expr_type() const;
|
||||||
|
|
||||||
virtual bool set_width(unsigned w, bool last_chance);
|
virtual bool set_width(unsigned w, bool last_chance);
|
||||||
virtual void relax_width(void);
|
|
||||||
virtual NetEBAdd* dup_expr() const;
|
virtual NetEBAdd* dup_expr() const;
|
||||||
virtual NetEConst* eval_tree();
|
virtual NetEConst* eval_tree();
|
||||||
virtual NetNet* synthesize(Design*);
|
virtual NetNet* synthesize(Design*);
|
||||||
|
|
@ -3574,6 +3567,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.365 2006/11/04 06:19:25 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.364 2006/10/30 05:44:49 steve
|
* Revision 1.364 2006/10/30 05:44:49 steve
|
||||||
* Expression widths with unsized literals are pseudo-infinite width.
|
* Expression widths with unsized literals are pseudo-infinite width.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
33
set_width.cc
33
set_width.cc
|
|
@ -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: set_width.cc,v 1.40 2006/10/30 05:44:49 steve Exp $"
|
#ident "$Id: set_width.cc,v 1.41 2006/11/04 06:19:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -46,14 +46,6 @@ bool NetExpr::set_width(unsigned w, bool)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The default relax_width method does nothing, and leaves the
|
|
||||||
* previously elaborated width.
|
|
||||||
*/
|
|
||||||
void NetExpr::relax_width(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NetEBinary::set_width(unsigned w, bool)
|
bool NetEBinary::set_width(unsigned w, bool)
|
||||||
{
|
{
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
|
|
@ -117,24 +109,6 @@ bool NetEBAdd::set_width(unsigned w, bool)
|
||||||
return wid == w;
|
return wid == w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetEBAdd::relax_width(void)
|
|
||||||
{
|
|
||||||
unsigned wid = left_->expr_width();
|
|
||||||
if (right_->expr_width() > wid)
|
|
||||||
wid = right_->expr_width();
|
|
||||||
|
|
||||||
// Allow space for the carry.
|
|
||||||
wid += 1;
|
|
||||||
|
|
||||||
if (debug_elaborate)
|
|
||||||
cerr << get_line() << ": debug: "
|
|
||||||
<< "Relax addition width to " << wid << endl;
|
|
||||||
|
|
||||||
left_->set_width(wid);
|
|
||||||
right_->set_width(wid);
|
|
||||||
expr_width(wid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The bitwise logical operators have operands the same size as the
|
* The bitwise logical operators have operands the same size as the
|
||||||
* result. Anything else is a mess. I first try to get the operands to
|
* result. Anything else is a mess. I first try to get the operands to
|
||||||
|
|
@ -467,6 +441,11 @@ bool NetEUReduce::set_width(unsigned w, bool)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: set_width.cc,v $
|
* $Log: set_width.cc,v $
|
||||||
|
* Revision 1.41 2006/11/04 06:19:25 steve
|
||||||
|
* Remove last bits of relax_width methods, and use test_width
|
||||||
|
* to calculate the width of an r-value expression that may
|
||||||
|
* contain unsized numbers.
|
||||||
|
*
|
||||||
* Revision 1.40 2006/10/30 05:44:49 steve
|
* Revision 1.40 2006/10/30 05:44:49 steve
|
||||||
* Expression widths with unsized literals are pseudo-infinite width.
|
* Expression widths with unsized literals are pseudo-infinite width.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue