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:
steve 2006-11-04 06:19:24 +00:00
parent ed5d3188b3
commit c339dc4bbc
7 changed files with 247 additions and 187 deletions

52
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include <string>
@ -72,7 +72,9 @@ class PExpr : public LineInfo {
// unsized and therefore expandable. This happens if a
// sub-expression is an unsized literal. Some expressions make
// 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
// 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 void dump(ostream&) const;
//virtual int test_width(bool) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) 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 int test_width(bool) const;
private:
edge_t type_;
PExpr *expr_;
@ -220,8 +218,6 @@ class PEFNumber : public PExpr {
const verireal& value() const;
//virtual int test_width(bool) const;
/* The eval_const method as applied to a floating point number
gets the *integer* value of the number. This accounts for
any rounding that is needed to get the value. */
@ -255,9 +251,9 @@ class PEIdent : public PExpr {
~PEIdent();
virtual void dump(ostream&) const;
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
//virtual int test_width(bool) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
@ -292,6 +288,11 @@ class PEIdent : public PExpr {
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:
NetAssign_*elaborate_lval_net_part_(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;
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,
unsigned lwidth,
@ -416,7 +419,6 @@ class PEString : public PExpr {
string value() const;
virtual void dump(ostream&) const;
//virtual int test_width(bool) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
@ -443,7 +445,6 @@ class PEUnary : public PExpr {
~PEUnary();
virtual void dump(ostream&out) const;
//virtual int test_width(bool) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
@ -471,11 +472,12 @@ class PEBinary : public PExpr {
~PEBinary();
virtual bool is_constant(Module*) const;
//virtual int test_width(bool) 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,
unsigned width,
@ -494,8 +496,8 @@ class PEBinary : public PExpr {
PExpr*left_;
PExpr*right_;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
NetEBinary*elaborate_eval_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, int use_wid) const;
private:
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
@ -550,7 +552,9 @@ class PEBComp : public PEBinary {
explicit PEBComp(char op, PExpr*l, PExpr*r);
~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,
int expr_width, bool sys_task_arg) const;
@ -562,7 +566,8 @@ class PEBShift : public PEBinary {
explicit PEBShift(char op, PExpr*l, PExpr*r);
~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();
virtual bool is_constant(Module*) const;
//virtual int test_width(bool) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
@ -609,7 +613,6 @@ class PECallFunction : public PExpr {
~PECallFunction();
virtual void dump(ostream &) const;
//virtual int test_width(bool) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
@ -639,6 +642,11 @@ class PECallFunction : public PExpr {
/*
* $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
* Expression widths with unsized literals are pseudo-infinite width.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -32,7 +32,8 @@
* The default behavor for the test_width method is to just return the
* 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) {
cerr << get_line() << ": debug: test_width defaults to "
@ -51,12 +52,13 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, int, bool) const
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_right = false;
unsigned wid_left = left_->test_width(min, lval, flag_left);
unsigned wid_right = right_->test_width(min, lval, flag_right);
unsigned wid_left = left_->test_width(des,scope, min, lval, flag_left);
unsigned wid_right = right_->test_width(des,scope, min, lval, flag_right);
if (flag_left || flag_right)
unsized_flag = true;
@ -106,13 +108,14 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
NetEBinary*tmp = elaborate_eval_expr_base_(des, lp, rp);
NetEBinary*tmp = elaborate_eval_expr_base_(des, lp, rp, expr_wid);
return tmp;
}
NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des,
NetExpr*lp,
NetExpr*rp) const
NetExpr*rp,
int expr_wid) const
{
/* If either expression can be evaluated ahead of time, then
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.
*/
NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
NetExpr*lp, NetExpr*rp) const
NetExpr*lp, NetExpr*rp,
int expr_wid) const
{
bool flag;
@ -204,6 +208,9 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
case '+':
case '-':
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);
break;
@ -245,7 +252,7 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
return tmp;
}
unsigned PEBComp::test_width(unsigned, unsigned, bool&) const
unsigned PEBComp::test_width(Design*, NetScope*,unsigned, unsigned, bool&) const
{
return 1;
}
@ -256,8 +263,26 @@ NetEBinary* PEBComp::elaborate_expr(Design*des, NetScope*scope,
assert(left_);
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. */
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*rp = right_->elaborate_expr(des, scope, use_wid, false);
@ -267,20 +292,13 @@ NetEBinary* PEBComp::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
/* If we find that one of the operands are indefinitely wide,
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);
return elaborate_eval_expr_base_(des, lp, rp, use_wid);
}
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
// on the expression size that is generated.
@ -591,9 +609,118 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, int, bool) const
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;
}
@ -1055,37 +1182,23 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
NetNet*net, NetScope*found_in)const
{
assert(lsb_ != 0);
assert(msb_ != 0);
long msv, lsv;
assert(idx_.empty());
verinum*lsn = lsb_->eval_const(des, scope);
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;
bool flag = calculate_parts_(des, scope, msv, lsv);
if (!flag)
return 0;
}
assert(lsn);
assert(msn);
/* The indices of part selects are signed integers, so allow
negative values. However, the width that they represent is
unsigned. Remember that any order is possible,
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));
if (wid > net->vector_width()) {
cerr << get_line() << ": error: part select ["
<< msv << ":" << lsv << "] out of range." << endl;
des->errors += 1;
delete lsn;
delete msn;
//delete lsn;
//delete msn;
return 0;
}
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 ["
<< msv << ":" << lsv << "] out of order." << endl;
des->errors += 1;
delete lsn;
delete msn;
//delete lsn;
//delete msn;
return 0;
}
@ -1104,8 +1217,8 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
cerr << get_line() << ": error: part select ["
<< msv << ":" << lsv << "] out of range." << endl;
des->errors += 1;
delete lsn;
delete msn;
//delete lsn;
//delete msn;
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*wid_e = elab_and_eval(des, scope, lsb_, -1);
NetEConst*wid_c = dynamic_cast<NetEConst*> (wid_e);
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;
}
unsigned long wid = 0;
calculate_up_do_width_(des, scope, wid);
assert(wid_c != 0);
unsigned long wid = wid_c->value().as_ulong();
// Handle the special case that the base is constant as
// 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*wid_e = elab_and_eval(des, scope, lsb_, -1);
NetEConst*wid_c = dynamic_cast<NetEConst*> (wid_e);
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();
unsigned long wid = 0;
calculate_up_do_width_(des, scope, wid);
// Handle the special case that the base is constant as
// 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;
}
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();
if (min > use_wid)
@ -1545,6 +1638,11 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
/*
* $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
* Expression widths with unsized literals are pseudo-infinite width.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -304,41 +304,10 @@ NetAssign_* PEIdent::elaborate_lval_net_part_(Design*des,
NetScope*scope,
NetNet*reg) const
{
assert(msb_ && lsb_);
/* 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;
long msb, lsb;
bool flag = calculate_parts_(des, scope, msb, lsb);
if (!flag)
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;
@ -402,21 +371,8 @@ NetAssign_* PEIdent::elaborate_lval_net_idx_up_(Design*des,
return 0;
}
/* 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;
}
unsigned wid = wid_c? wid_c->value().as_ulong() : 1;
delete wid_ex;
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
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 $
* 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
* 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

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -53,7 +53,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
return 0;
}
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -1);
return tmp;
}
@ -236,6 +236,11 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $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
* 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

@ -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.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
# include "config.h"
@ -1428,7 +1428,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
something else based on self-determined widths inside. */
unsigned use_width = lv->lwidth();
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. */
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width);
@ -2619,11 +2619,17 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
assert(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
properly. Then use it to build the assignment statement. */
etmp = elab_and_eval(des, scope, expr1_, lv->lwidth());
etmp->set_width(lv->lwidth());
etmp = pad_to_width(etmp, lv->lwidth());
etmp = elab_and_eval(des, scope, expr1_, use_width);
etmp->set_width(use_width);
etmp = pad_to_width(etmp, use_width);
if (debug_elaborate) {
cerr << get_line() << ": debug: FOR initial assign: "
@ -3320,6 +3326,11 @@ Design* elaborate(list<perm_string>roots)
/*
* $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
* Expression widths with unsized literals are pseudo-infinite width.
*

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.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
/*
@ -1134,12 +1134,6 @@ class NetExpr : public LineInfo {
// width to the l-value width, if possible.
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
// signed. Unsigned expressions return false.
bool has_sign() const;
@ -2682,7 +2676,6 @@ class NetEBAdd : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance);
virtual void relax_width(void);
virtual NetEBAdd* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*);
@ -3574,6 +3567,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $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
* Expression widths with unsized literals are pseudo-infinite width.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@ -46,14 +46,6 @@ bool NetExpr::set_width(unsigned w, bool)
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 flag = true;
@ -117,24 +109,6 @@ bool NetEBAdd::set_width(unsigned w, bool)
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
* 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 $
* 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
* Expression widths with unsized literals are pseudo-infinite width.
*