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:
parent
c7edace243
commit
ae16eacec9
2
PExpr.h
2
PExpr.h
|
|
@ -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,
|
||||||
|
|
|
||||||
17
elab_expr.cc
17
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
|
* 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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue