From 6e12c1f236dcf9a02f10cb58aa99d3d61db05cea Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 20 Sep 2008 19:23:54 -0700 Subject: [PATCH] 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. --- PExpr.h | 15 +++++++++------ elab_expr.cc | 48 +++++++++++++++++++++++++++++++++++++++++------- elaborate.cc | 5 ++++- netlist.h | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/PExpr.h b/PExpr.h index 828acb83b..cfc21e3cd 100644 --- a/PExpr.h +++ b/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; }; /* diff --git a/elab_expr.cc b/elab_expr.cc index 306275c78..654c4d4df 100644 --- a/elab_expr.cc +++ b/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 diff --git a/elaborate.cc b/elaborate.cc index bd8aa89f3..81a5e4304 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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()); diff --git a/netlist.h b/netlist.h index fc2d120f7..52fd0154d 100644 --- a/netlist.h +++ b/netlist.h @@ -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;