From ae16eacec97d98639a026aa8bf8323e073fc305a Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 9 Oct 2007 20:46:17 -0700 Subject: [PATCH] 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 --- PExpr.h | 2 +- elab_expr.cc | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/PExpr.h b/PExpr.h index ba4ec4d24..1beb01f6b 100644 --- a/PExpr.h +++ b/PExpr.h @@ -666,7 +666,7 @@ class PECallFunction : public PExpr { 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, unsigned width, const NetExpr* rise, diff --git a/elab_expr.cc b/elab_expr.cc index df84cbcd4..0970bd2c8 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -372,7 +372,7 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope, * size_tf functions, make assumptions about widths based on some * 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 @@ -405,6 +405,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const PExpr*expr = parms_[0]; NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); sub->cast_signed(false); + + if (expr_wid > sub->expr_width()) + sub = pad_to_width(sub, expr_wid); + return sub; } @@ -536,7 +540,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, int expr_wid, bool) const { 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_); if (def == 0) { @@ -570,7 +574,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) { PExpr*tmp = parms_[idx]; 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 { missing_parms += 1;