More standard handling of unsized numbers as system task arguments.

This commit is contained in:
Stephen Williams 2014-03-01 08:38:23 -08:00
parent 91b7c6ab55
commit d2ff77d56c
3 changed files with 27 additions and 7 deletions

View File

@ -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<NetEConst*>(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_;
}

View File

@ -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;

View File

@ -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<PENumber*>(pe))
if ((mode >= PExpr::LOSSLESS) && !dynamic_cast<PENumber*>(pe) && tmp->expr_width()>32)
ce->trim();
}