Elaborate of PGAssign always passes calculated width.

the PGAssign elaborate method used the test_width to get the width
of the r-value expression. This should be completely sufficient to
get the width of the expression, so always use a defined width to
elaborate the expression.
This commit is contained in:
Stephen Williams 2008-09-20 19:23:54 -07:00
parent dc313436c1
commit 6e12c1f236
4 changed files with 55 additions and 15 deletions

15
PExpr.h
View File

@ -283,12 +283,13 @@ class PEIdent : public PExpr {
index_component_t::ctype_t) const;
private:
NetExpr*elaborate_expr_param(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb,
int expr_wid) const;
NetExpr*elaborate_expr_param_part_(Design*des,
NetScope*scope,
const NetExpr*par,
@ -488,6 +489,8 @@ class PEBShift : public PEBinary {
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval, bool&flag) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
};
/*

View File

@ -82,6 +82,8 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope,
min = lval;
break;
case 'l':
ivl_assert(*this, 0); // Should be handled bin PEBShift
default:
if (wid_left > min)
min = wid_left;
@ -577,9 +579,37 @@ unsigned PEBShift::test_width(Design*des, NetScope*scope,
if (wid_left < lval)
wid_left = lval;
if (unsized_flag && wid_left < integer_width) {
wid_left = integer_width;
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Test width of unsized left shift"
<< " is padded to compiler integer width=" << wid_left
<< endl;
}
return wid_left;
}
NetExpr*PEBShift::elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool sys_task_arg) const
{
assert(left_);
assert(right_);
NetExpr*lp = left_->elaborate_expr(des, scope, expr_wid, false);
NetExpr*rp = right_->elaborate_expr(des, scope, -1, false);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetExpr*tmp = elaborate_eval_expr_base_(des, lp, rp, expr_wid);
return tmp;
}
unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const
@ -1294,7 +1324,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// If the identifier name is a parameter name, then return
// a reference to the parameter expression.
if (par != 0)
return elaborate_expr_param(des, scope, par, found_in, ex1, ex2);
return elaborate_expr_param_(des, scope, par, found_in, ex1, ex2, expr_wid);
// If the identifier names a signal (a register or wire)
@ -1576,12 +1606,13 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
* parameter expression has already been located for us (as the par
* argument) so we just need to process the sub-expression.
*/
NetExpr* PEIdent::elaborate_expr_param(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found_in,
const NetExpr*par_msb,
const NetExpr*par_lsb) const
NetExpr* PEIdent::elaborate_expr_param_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found_in,
const NetExpr*par_msb,
const NetExpr*par_lsb,
int expr_wid) const
{
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
@ -1737,6 +1768,9 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
NetEConstParam*ptmp
= new NetEConstParam(found_in, name, ctmp->value());
if (expr_wid > 0)
ptmp->set_width((unsigned)expr_wid);
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Elaborate parameter <" << name

View File

@ -110,7 +110,10 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
<< ", unsized_flag=" << (unsized_flag?"true":"false") << endl;
}
int expr_wid = unsized_flag? -2 : (int) use_width;
int expr_wid = lval->vector_width();
if (use_width > (unsigned)expr_wid)
expr_wid = (int)use_width;
NetExpr*rval_expr = elab_and_eval(des, scope, pin(1),
expr_wid, lval->vector_width());

View File

@ -1632,7 +1632,7 @@ class NetEConstParam : public NetEConst {
perm_string name() const;
const NetScope*scope() const;
virtual bool set_width(unsigned w, bool last_chance);
virtual bool set_width(unsigned w, bool last_chance =false);
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;