Trim results of unsized constant add to prevent width expansion

When constant values are added to get another constant value, and the
expression is not otherwise a fixed size, then trim the result to
prevent unbounded expansion of unsized expression with.

In the process, find and fix a bug in the vtrim function that caused
an assert if trimming were not possible for an unsigned value.
This commit is contained in:
Stephen Williams 2008-04-15 19:18:03 -07:00
parent bfb33230aa
commit dffe1be819
2 changed files with 19 additions and 5 deletions

View File

@ -95,12 +95,14 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
return 0;
}
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluate expr=" << *this
<< " --- prune=" << prune_to_width
<< " has_width=" << (has_width()? "true" : "false") << endl;
}
/* Result might have known width. */
if (has_width()) {
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluate expr=" << *this
<< " --- prune=" << prune_to_width << endl;
}
unsigned lwid = lc->expr_width();
unsigned rwid = rc->expr_width();
unsigned wid = (rwid > lwid) ? rwid : lwid;
@ -108,6 +110,10 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
wid += 1;
verinum val2=verinum(val,wid);
val=val2;
} else {
/* No fixed width, so trim the bits losslessly. */
verinum val2 = trim_vnum(val);
val = val2;
}
return new NetEConst(val);

View File

@ -505,12 +505,20 @@ verinum trim_vnum(const verinum&that)
unsigned top = that.len()-1;
while ((top > 0) && (that.get(top) == verinum::V0))
top -= 1;
/* Now top is the index of the highest non-zero bit. If
that turns out to the highest bit in the vector, then
tere is no trimming possible. */
if (top+1 == that.len())
return that;
/* Make tlen wide enough to include the highest non-zero
bit, plus one extra 0 bit. */
tlen = top+2;
/* This can only happen when the verinum is all zeros,
so make it a single bit wide. */
if (that.get(top) == verinum::V0) tlen -= 1;
}
verinum tmp (verinum::V0, tlen, false);