From c339dc4bbc8b54e97063871f72d4d4cd0d77e5f9 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 4 Nov 2006 06:19:24 +0000 Subject: [PATCH] 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. --- PExpr.h | 52 ++++++----- elab_expr.cc | 244 +++++++++++++++++++++++++++++++++++--------------- elab_lval.cc | 61 +++---------- elab_pexpr.cc | 9 +- elaborate.cc | 21 +++-- netlist.h | 14 ++- set_width.cc | 33 ++----- 7 files changed, 247 insertions(+), 187 deletions(-) diff --git a/PExpr.h b/PExpr.h index e8bb9b516..625db825d 100644 --- a/PExpr.h +++ b/PExpr.h @@ -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 @@ -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. * diff --git a/elab_expr.cc b/elab_expr.cc index 41567ab6a..9eda46210 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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(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(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(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 (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 (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. * diff --git a/elab_lval.cc b/elab_lval.cc index 27a75c21d..936793354 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -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(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(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(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 diff --git a/elab_pexpr.cc b/elab_pexpr.cc index 98c5858b9..7a21085cd 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -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 diff --git a/elaborate.cc b/elaborate.cc index de982cb2b..46e9aee15 100644 --- a/elaborate.cc +++ b/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.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(listroots) /* * $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. * diff --git a/netlist.h b/netlist.h index 0e2e28e15..7a0b37e3e 100644 --- a/netlist.h +++ b/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.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. * diff --git a/set_width.cc b/set_width.cc index b89b5e18f..db36518c5 100644 --- a/set_width.cc +++ b/set_width.cc @@ -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. *