From d2ff77d56c0972b87eeb726c3d8108b4ffd3de5f Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 1 Mar 2014 08:38:23 -0800 Subject: [PATCH] More standard handling of unsized numbers as system task arguments. --- elab_expr.cc | 30 +++++++++++++++++++++++++----- netlist.h | 2 +- netmisc.cc | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 6d37cc515..57ef9ecc0 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1326,6 +1326,13 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope, NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const { + if (debug_elaborate) { + cerr << get_fileline() << ": PECallFunction::cast_to_width_: " + << "cast to " << wid + << " bits " << (signed_flag_?"signed":"unsigned") + << " from expr_width()=" << expr->expr_width() << endl; + } + /* If the expression is a const, then replace it with a new const. This is a more efficient result. */ if (NetEConst*tmp = dynamic_cast(expr)) { @@ -1338,10 +1345,6 @@ NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const return tmp; } - if (debug_elaborate) - cerr << get_fileline() << ": debug: cast to " << wid - << " bits " << (signed_flag_?"signed":"unsigned") << endl; - NetESelect*tmp = new NetESelect(expr, 0, wid); tmp->cast_signed(signed_flag_); tmp->set_line(*this); @@ -1385,6 +1388,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, return 0; } + if (debug_elaborate) { + cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: " + << name << " expression is the argument cast to expr_wid=" << expr_wid << endl; + } PExpr*expr = parms_[0]; NetExpr*sub = expr->elaborate_expr(des, scope, expr_width_, flags); @@ -4916,10 +4923,23 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode) expr_width_ = integer_width; mode = UNSIZED; } else if (mode < LOSSLESS) { - mode = LOSSLESS; + if (expr_width_ < integer_width) { + expr_width_ = integer_width; + if (mode < UNSIZED) + mode = UNSIZED; + } else { + mode = LOSSLESS; + } } } + if (debug_elaborate) { + cerr << get_fileline() << ": PENumber::test_width: " + << "Value=" << *value_ + << ", width=" << expr_width_ + << ", output mode=" << width_mode_name(mode) << endl; + } + return expr_width_; } diff --git a/netlist.h b/netlist.h index 6cefc4c15..81b62b5d4 100644 --- a/netlist.h +++ b/netlist.h @@ -1998,7 +1998,7 @@ class NetEConst : public NetExpr { /* This method allows the constant value to be converted to an unsized value. This is used after evaluating a unsized constant expression. */ - virtual void trim(); + void trim(); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; diff --git a/netmisc.cc b/netmisc.cc index 6bb07a8f0..a7184696e 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -910,7 +910,7 @@ NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name, // determine the exact width required to hold the result. // But leave literal numbers exactly as the user supplied // them. - if ((mode >= PExpr::LOSSLESS) && !dynamic_cast(pe)) + if ((mode >= PExpr::LOSSLESS) && !dynamic_cast(pe) && tmp->expr_width()>32) ce->trim(); }