Fix associative add tree to get result width correct.

When evaluating A+1+2 in eval_tree, the (1+2) needs to have the correct
result width, or the elaborated expression with will be lost.
This commit is contained in:
Stephen Williams 2008-10-03 19:52:26 -07:00
parent 5fd3be570e
commit 18de6980ff
2 changed files with 12 additions and 3 deletions

View File

@ -133,6 +133,8 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
verinum lval = lc->value(); verinum lval = lc->value();
verinum rval = rc->value(); verinum rval = rc->value();
ivl_assert(*this, se->expr_width() == this->expr_width());
verinum val; verinum val;
if (op_ == se->op_) { if (op_ == se->op_) {
/* (a + lval) + rval --> a + (rval+lval) */ /* (a + lval) + rval --> a + (rval+lval) */
@ -144,6 +146,13 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
val = rval - lval; val = rval - lval;
} }
val = pad_to_width(val, expr_width());
if (val.len() > expr_width()) {
verinum tmp (val, expr_width());
tmp.has_sign(val.has_sign());
val = tmp;
}
NetEConst*tmp = new NetEConst(val); NetEConst*tmp = new NetEConst(val);
left_ = se->left_->dup_expr(); left_ = se->left_->dup_expr();
delete se; delete se;

View File

@ -99,8 +99,8 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
return 0; return 0;
} }
assert(expr_width() >= lsig->vector_width()); ivl_assert(*this, expr_width() >= lsig->vector_width());
assert(expr_width() >= rsig->vector_width()); ivl_assert(*this, expr_width() >= rsig->vector_width());
unsigned width; unsigned width;
if (expr_type() == IVL_VT_REAL) { if (expr_type() == IVL_VT_REAL) {
@ -752,7 +752,7 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope)
perm_string path = scope->local_symbol(); perm_string path = scope->local_symbol();
unsigned width=expr_width(); unsigned width=expr_width();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width-1,0); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true); osig->local_flag(true);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign()); osig->set_signed(has_sign());