Argument to $unsigned is self-determined.

The argument to $unsigned is self-determined no matter what the
context the $unsigned itself is in. This is important only where
the result can be negative but the result width is context-determined.
Do ocntext fitting manually to prevent the context fitting it and
affecting the expression argument.

Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
Stephen Williams 2007-10-09 20:46:17 -07:00
parent c7edace243
commit ae16eacec9
2 changed files with 15 additions and 4 deletions

View File

@ -666,7 +666,7 @@ class PECallFunction : public PExpr {
bool check_call_matches_definition_(Design*des, NetScope*dscope) const; bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope, NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width, unsigned width,
const NetExpr* rise, const NetExpr* rise,

View File

@ -372,7 +372,7 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
* size_tf functions, make assumptions about widths based on some * size_tf functions, make assumptions about widths based on some
* known function names. * known function names.
*/ */
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const
{ {
/* Catch the special case that the system function is the /* Catch the special case that the system function is the
@ -405,6 +405,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
PExpr*expr = parms_[0]; PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); NetExpr*sub = expr->elaborate_expr(des, scope, -1, true);
sub->cast_signed(false); sub->cast_signed(false);
if (expr_wid > sub->expr_width())
sub = pad_to_width(sub, expr_wid);
return sub; return sub;
} }
@ -536,7 +540,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool) const int expr_wid, bool) const
{ {
if (peek_tail_name(path_)[0] == '$') if (peek_tail_name(path_)[0] == '$')
return elaborate_sfunc_(des, scope); return elaborate_sfunc_(des, scope, expr_wid);
NetFuncDef*def = des->find_function(scope, path_); NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) { if (def == 0) {
@ -570,7 +574,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
PExpr*tmp = parms_[idx]; PExpr*tmp = parms_[idx];
if (tmp) { if (tmp) {
parms[idx] = elab_and_eval(des, scope, tmp, -1); int argwid = def->port(idx)->vector_width();
parms[idx] = elab_and_eval(des, scope, tmp, argwid);
if (debug_elaborate)
cerr << get_line() << ": debug:"
<< " function " << path_
<< " arg " << (idx+1)
<< " argwid=" << argwid
<< ": " << *parms[idx] << endl;
} else { } else {
missing_parms += 1; missing_parms += 1;