diff --git a/eval_tree.cc b/eval_tree.cc index c0c9c5019..47d7d211f 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -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); diff --git a/verinum.cc b/verinum.cc index 0f9907389..44e114731 100644 --- a/verinum.cc +++ b/verinum.cc @@ -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);