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 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 /* If the expression is a const, then replace it with a new
const. This is a more efficient result. */ const. This is a more efficient result. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) { if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
@ -1338,10 +1345,6 @@ NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const
return tmp; 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); NetESelect*tmp = new NetESelect(expr, 0, wid);
tmp->cast_signed(signed_flag_); tmp->cast_signed(signed_flag_);
tmp->set_line(*this); tmp->set_line(*this);
@ -1385,6 +1388,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
return 0; 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]; PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, expr_width_, flags); 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; expr_width_ = integer_width;
mode = UNSIZED; mode = UNSIZED;
} else if (mode < LOSSLESS) { } 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_; return expr_width_;
} }

View File

@ -1998,7 +1998,7 @@ class NetEConst : public NetExpr {
/* This method allows the constant value to be converted /* This method allows the constant value to be converted
to an unsized value. This is used after evaluating a to an unsized value. This is used after evaluating a
unsized constant expression. */ unsized constant expression. */
virtual void trim(); void trim();
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) 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. // determine the exact width required to hold the result.
// But leave literal numbers exactly as the user supplied // But leave literal numbers exactly as the user supplied
// them. // them.
if ((mode >= PExpr::LOSSLESS) && !dynamic_cast<PENumber*>(pe)) if ((mode >= PExpr::LOSSLESS) && !dynamic_cast<PENumber*>(pe) && tmp->expr_width()>32)
ce->trim(); ce->trim();
} }