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:
parent
dc313436c1
commit
6e12c1f236
15
PExpr.h
15
PExpr.h
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
48
elab_expr.cc
48
elab_expr.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue