Pads and local signal file/line should be related to creation location.

When padding a signal or when creating a local signal the file and
line information should be related to where the new object was
created not the signal value it is being created from.

This patch modifies the NetE* pad_to_width() routines to take a
LineInfo object to set the location to the correct value.

It fixes some set_line() calls to use the correct location.

It fixes ports to not set the file/line information if it is
already defined. Doing this was causing the definition of
signals to become the instantiation instead of the real
module declaration.
This commit is contained in:
Cary R 2008-11-18 17:17:19 -08:00 committed by Stephen Williams
parent 1630c41d5f
commit 3c4b9692a6
6 changed files with 80 additions and 120 deletions

View File

@ -377,9 +377,9 @@ NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des,
if (expr_wid > 0) { if (expr_wid > 0) {
if (type_is_vectorable(lp->expr_type())) if (type_is_vectorable(lp->expr_type()))
lp = pad_to_width(lp, expr_wid); lp = pad_to_width(lp, expr_wid, *this);
if (type_is_vectorable(rp->expr_type())) if (type_is_vectorable(rp->expr_type()))
rp = pad_to_width(rp, expr_wid); rp = pad_to_width(rp, expr_wid, *this);
} }
NetEBBits*tmp = new NetEBBits(op_, lp, rp); NetEBBits*tmp = new NetEBBits(op_, lp, rp);
@ -410,8 +410,8 @@ NetExpr* PEBinary::elaborate_expr_base_div_(Design*des,
padded. The divide expression operands must be the width padded. The divide expression operands must be the width
of the output. */ of the output. */
if (expr_wid > 0) { if (expr_wid > 0) {
lp = pad_to_width(lp, expr_wid); lp = pad_to_width(lp, expr_wid, *this);
rp = pad_to_width(rp, expr_wid); rp = pad_to_width(rp, expr_wid, *this);
} }
NetEBDiv*tmp = new NetEBDiv(op_, lp, rp); NetEBDiv*tmp = new NetEBDiv(op_, lp, rp);
@ -509,7 +509,7 @@ NetExpr* PEBinary::elaborate_expr_base_lshift_(Design*des,
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Left shift expression by constant " << "Left shift expression by constant "
<< shift << " bits. (use_wid=" << use_wid << ")" << endl; << shift << " bits. (use_wid=" << use_wid << ")" << endl;
lp = pad_to_width(lp, use_wid); lp = pad_to_width(lp, use_wid, *this);
tmp = new NetEBShift(op_, lp, rp); tmp = new NetEBShift(op_, lp, rp);
} }
@ -517,7 +517,7 @@ NetExpr* PEBinary::elaborate_expr_base_lshift_(Design*des,
// Left side is not constant, so handle it the // Left side is not constant, so handle it the
// default way. // default way.
if (expr_wid >= 0) if (expr_wid >= 0)
lp = pad_to_width(lp, expr_wid); lp = pad_to_width(lp, expr_wid, *this);
tmp = new NetEBShift(op_, lp, rp); tmp = new NetEBShift(op_, lp, rp);
} }
@ -582,9 +582,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
tmp->set_line(*this); tmp->set_line(*this);
tmp = new NetESelect(lp, tmp, 1); tmp = new NetESelect(lp, tmp, 1);
tmp->cast_signed(true); tmp->cast_signed(true);
tmp->set_line(*this); tmp = pad_to_width(tmp, use_wid, *this);
tmp = pad_to_width(tmp, use_wid);
tmp->set_line(*this);
return tmp; return tmp;
} else if (shift >= 0) { } else if (shift >= 0) {
@ -607,8 +605,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
tmp = new NetESelect(lp, tmp, tmp_wid); tmp = new NetESelect(lp, tmp, tmp_wid);
tmp->set_line(*this); tmp->set_line(*this);
tmp->cast_signed(lp->has_sign() && op_=='R'); tmp->cast_signed(lp->has_sign() && op_=='R');
tmp = pad_to_width(tmp, use_wid); tmp = pad_to_width(tmp, use_wid, *this);
tmp->set_line(*this);
return tmp; return tmp;
} else if ((0-shift) >= use_wid) { } else if ((0-shift) >= use_wid) {
@ -626,7 +623,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
// Falback, handle the general case. // Falback, handle the general case.
if (expr_wid > 0) if (expr_wid > 0)
lp = pad_to_width(lp, expr_wid); lp = pad_to_width(lp, expr_wid, *this);
tmp = new NetEBShift(op_, lp, rp); tmp = new NetEBShift(op_, lp, rp);
tmp->set_line(*this); tmp->set_line(*this);
return tmp; return tmp;
@ -641,9 +638,9 @@ NetExpr* PEBinary::elaborate_expr_base_mult_(Design*des,
// multiplication to come out right. // multiplication to come out right.
if (expr_wid > 0) { if (expr_wid > 0) {
if (lp->has_sign() && lp->expr_type() != IVL_VT_REAL) if (lp->has_sign() && lp->expr_type() != IVL_VT_REAL)
lp = pad_to_width(lp, expr_wid); lp = pad_to_width(lp, expr_wid, *this);
if (rp->has_sign() && rp->expr_type() != IVL_VT_REAL) if (rp->has_sign() && rp->expr_type() != IVL_VT_REAL)
rp = pad_to_width(rp, expr_wid); rp = pad_to_width(rp, expr_wid, *this);
} }
// Keep constants on the right side. // Keep constants on the right side.
@ -683,7 +680,7 @@ NetExpr* PEBinary::elaborate_expr_base_mult_(Design*des,
// pad one of the arguments enough that the sum is the // pad one of the arguments enough that the sum is the
// desired width. // desired width.
if (expr_wid > (long)(lp->expr_width() + rp->expr_width())) if (expr_wid > (long)(lp->expr_width() + rp->expr_width()))
lp = pad_to_width(lp, expr_wid - rp->expr_width()); lp = pad_to_width(lp, expr_wid - rp->expr_width(), *this);
NetEBMult*tmp = new NetEBMult(op_, lp, rp); NetEBMult*tmp = new NetEBMult(op_, lp, rp);
tmp->set_line(*this); tmp->set_line(*this);
@ -781,9 +778,9 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
// pad the width here. This matters because if the arguments // pad the width here. This matters because if the arguments
// are signed, then this padding will do sign extension. // are signed, then this padding will do sign extension.
if (type_is_vectorable(lp->expr_type())) if (type_is_vectorable(lp->expr_type()))
lp = pad_to_width(lp, use_wid_l); lp = pad_to_width(lp, use_wid_l, *this);
if (type_is_vectorable(rp->expr_type())) if (type_is_vectorable(rp->expr_type()))
rp = pad_to_width(rp, use_wid_r); rp = pad_to_width(rp, use_wid_r, *this);
eval_expr(lp, use_wid_l); eval_expr(lp, use_wid_l);
eval_expr(rp, use_wid_r); eval_expr(rp, use_wid_r);
@ -1090,7 +1087,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
sub->cast_signed(false); sub->cast_signed(false);
if (expr_wid > 0 && (unsigned)expr_wid > sub->expr_width()) if (expr_wid > 0 && (unsigned)expr_wid > sub->expr_width())
sub = pad_to_width(sub, expr_wid); sub = pad_to_width(sub, expr_wid, *this);
return sub; return sub;
} }
@ -2800,7 +2797,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
} }
ivl_assert(*this, use_wid > 0); ivl_assert(*this, use_wid > 0);
NetExpr*tru = elab_and_eval(des, scope, tru_, use_wid); NetExpr*tru = elab_and_eval(des, scope, tru_, use_wid);
return pad_to_width(tru, use_wid); return pad_to_width(tru, use_wid, *this);
} }
// Condition is constant FALSE, so we only need the // Condition is constant FALSE, so we only need the
@ -2818,7 +2815,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
} }
ivl_assert(*this, use_wid > 0); ivl_assert(*this, use_wid > 0);
NetExpr*fal = elab_and_eval(des, scope, fal_, use_wid); NetExpr*fal = elab_and_eval(des, scope, fal_, use_wid);
return pad_to_width(fal, use_wid); return pad_to_width(fal, use_wid, *this);
} }
// X and Z conditions need to blend both results, so we // X and Z conditions need to blend both results, so we
@ -2851,8 +2848,8 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
/* Whatever the width we choose for the ternary operator, we /* Whatever the width we choose for the ternary operator, we
need to make sure the operands match. */ need to make sure the operands match. */
tru = pad_to_width(tru, use_wid); tru = pad_to_width(tru, use_wid, *this);
fal = pad_to_width(fal, use_wid); fal = pad_to_width(fal, use_wid, *this);
NetETernary*res = new NetETernary(con, tru, fal); NetETernary*res = new NetETernary(con, tru, fal);
res->set_line(*this); res->set_line(*this);
@ -2975,7 +2972,7 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
} else { } else {
if (expr_wid > 0) if (expr_wid > 0)
ip = pad_to_width(ip, expr_wid); ip = pad_to_width(ip, expr_wid, *this);
tmp = new NetEUnary(op_, ip); tmp = new NetEUnary(op_, ip);
tmp->set_line(*this); tmp->set_line(*this);
} }
@ -3063,7 +3060,7 @@ NetExpr* PEUnary::elaborate_expr_bits_(NetExpr*operand, int expr_wid) const
} }
if (expr_wid > (int)operand->expr_width()) if (expr_wid > (int)operand->expr_width())
operand = pad_to_width(operand, expr_wid); operand = pad_to_width(operand, expr_wid, *this);
NetEUBits*tmp = new NetEUBits(op_, operand); NetEUBits*tmp = new NetEUBits(op_, operand);
tmp->set_line(*this); tmp->set_line(*this);

View File

@ -119,7 +119,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
<< " expression is to small for l-value width " << " expression is to small for l-value width "
<< lval->vector_width() << "." << endl; << lval->vector_width() << "." << endl;
} }
rval_expr = pad_to_width(rval_expr, lval->vector_width()); rval_expr = pad_to_width(rval_expr, lval->vector_width(), *this);
} }
NetNet*rval = rval_expr->synthesize(des, scope); NetNet*rval = rval_expr->synthesize(des, scope);
@ -165,9 +165,10 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
of the l-value. */ of the l-value. */
if (lval->vector_width() > rval->vector_width()) { if (lval->vector_width() > rval->vector_width()) {
if (rval->get_signed()) if (rval->get_signed())
rval = pad_to_width_signed(des, rval, lval->vector_width()); rval = pad_to_width_signed(des, rval, lval->vector_width(),
*this);
else else
rval = pad_to_width(des, rval, lval->vector_width()); rval = pad_to_width(des, rval, lval->vector_width(), *this);
} }
/* If, on the other hand, the r-value insists on being /* If, on the other hand, the r-value insists on being
@ -861,7 +862,7 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, port_wid); NetNet::WIRE, port_wid);
tmp->local_flag(true); tmp->local_flag(true);
tmp->set_line(*sig); tmp->set_line(*this);
// Handle the special case of a bi-directional part // Handle the special case of a bi-directional part
// select. Create a NetTran(VP) instead of a uni-directional // select. Create a NetTran(VP) instead of a uni-directional
@ -903,9 +904,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
} else { } else {
NetNet*osig; NetNet*osig;
if (as_signed) { if (as_signed) {
osig = pad_to_width_signed(des, tmp, swidth); osig = pad_to_width_signed(des, tmp, swidth, *this);
} else { } else {
osig = pad_to_width(des, tmp, swidth); osig = pad_to_width(des, tmp, swidth, *this);
} }
connect(osig->pin(0), sig->pin(0)); connect(osig->pin(0), sig->pin(0));
} }
@ -915,9 +916,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
if (pwidth > swidth) { if (pwidth > swidth) {
delete tmp; delete tmp;
if (as_signed) { if (as_signed) {
tmp = pad_to_width_signed(des, sig, pwidth); tmp = pad_to_width_signed(des, sig, pwidth, *this);
} else { } else {
tmp = pad_to_width(des, sig, pwidth); tmp = pad_to_width(des, sig, pwidth, *this);
} }
} else { } else {
NetPartSelect*node = new NetPartSelect(sig, 0, pwidth, NetPartSelect*node = new NetPartSelect(sig, 0, pwidth,
@ -1192,7 +1193,7 @@ v NOTE that this also handles the case that the
} }
delete tmp_expr; delete tmp_expr;
sig->set_line(*this); if (!sig->get_lineno()) sig->set_line(*this);
if (need_bufz_for_input_port(prts)) { if (need_bufz_for_input_port(prts)) {
NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(), NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(),
@ -1890,7 +1891,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
unsigned wid = count_lval_width(lv); unsigned wid = count_lval_width(lv);
rv->set_width(wid); rv->set_width(wid);
rv = pad_to_width(rv, wid); rv = pad_to_width(rv, wid, *this);
if (wid > rv->expr_width()) { if (wid > rv->expr_width()) {
cerr << get_fileline() << ": error: Unable to match " cerr << get_fileline() << ": error: Unable to match "
@ -1999,7 +2000,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
unsigned wid = count_lval_width(lv); unsigned wid = count_lval_width(lv);
if (wid > rv->expr_width()) { if (wid > rv->expr_width()) {
rv->set_width(wid); rv->set_width(wid);
rv = pad_to_width(rv, wid); rv = pad_to_width(rv, wid, *this);
} }
ivl_assert(*this, rv->expr_width() >= wid); ivl_assert(*this, rv->expr_width() >= wid);
} }
@ -2053,7 +2054,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
} else { } else {
unsigned wid = count_lval_width(lv); unsigned wid = count_lval_width(lv);
rv->set_width(wid); rv->set_width(wid);
rv = pad_to_width(rv, wid); rv = pad_to_width(rv, wid, *this);
} }
NetExpr*delay = 0; NetExpr*delay = 0;
@ -2546,7 +2547,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
NetExpr*rv = elab_and_eval(des, scope, parms_[idx], wid); NetExpr*rv = elab_and_eval(des, scope, parms_[idx], wid);
rv->set_width(wid); rv->set_width(wid);
rv = pad_to_width(rv, wid); rv = pad_to_width(rv, wid, *this);
NetAssign*pr = new NetAssign(lv, rv); NetAssign*pr = new NetAssign(lv, rv);
block->append(pr); block->append(pr);
} }
@ -2599,7 +2600,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
continue; continue;
NetESignal*sig = new NetESignal(port); NetESignal*sig = new NetESignal(port);
NetExpr*rv = pad_to_width(sig, count_lval_width(lv)); NetExpr*rv = pad_to_width(sig, count_lval_width(lv), *this);
/* Generate the assignment statement. */ /* Generate the assignment statement. */
NetAssign*ass = new NetAssign(lv, rv); NetAssign*ass = new NetAssign(lv, rv);
@ -2655,7 +2656,7 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
return 0; return 0;
rexp->set_width(lwid); rexp->set_width(lwid);
rexp = pad_to_width(rexp, lwid); rexp = pad_to_width(rexp, lwid, *this);
dev = new NetCAssign(lval, rexp); dev = new NetCAssign(lval, rexp);
@ -3253,7 +3254,7 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
return 0; return 0;
rexp->set_width(lwid, true); rexp->set_width(lwid, true);
rexp = pad_to_width(rexp, lwid); rexp = pad_to_width(rexp, lwid, *this);
dev = new NetForce(lval, rexp); dev = new NetForce(lval, rexp);
@ -3318,7 +3319,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
properly. Then use it to build the assignment statement. */ properly. Then use it to build the assignment statement. */
etmp = elab_and_eval(des, scope, expr1_, use_width); etmp = elab_and_eval(des, scope, expr1_, use_width);
etmp->set_width(use_width); etmp->set_width(use_width);
etmp = pad_to_width(etmp, use_width); etmp = pad_to_width(etmp, use_width, *this);
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: FOR initial assign: " cerr << get_fileline() << ": debug: FOR initial assign: "
@ -3331,7 +3332,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
if (etmp->expr_type() != IVL_VT_REAL) { if (etmp->expr_type() != IVL_VT_REAL) {
unsigned wid = count_lval_width(lv); unsigned wid = count_lval_width(lv);
etmp->set_width(wid); etmp->set_width(wid);
etmp = pad_to_width(etmp, wid); etmp = pad_to_width(etmp, wid, *this);
assert(etmp->expr_width() >= wid); assert(etmp->expr_width() >= wid);
} }

View File

@ -111,8 +111,8 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
rsig = cast_to_real(des, scope, rsig); rsig = cast_to_real(des, scope, rsig);
} else { } else {
lsig = pad_to_width(des, lsig, expr_width()); lsig = pad_to_width(des, lsig, expr_width(), *this);
rsig = pad_to_width(des, rsig, expr_width()); rsig = pad_to_width(des, rsig, expr_width(), *this);
assert(lsig->vector_width() == rsig->vector_width()); assert(lsig->vector_width() == rsig->vector_width());
width=lsig->vector_width(); width=lsig->vector_width();
@ -167,8 +167,8 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope)
unsigned width = expr_width(); unsigned width = expr_width();
if (rsig->vector_width() > width) width = rsig->vector_width(); if (rsig->vector_width() > width) width = rsig->vector_width();
lsig = pad_to_width(des, lsig, width); lsig = pad_to_width(des, lsig, width, *this);
rsig = pad_to_width(des, rsig, width); rsig = pad_to_width(des, rsig, width, *this);
assert(lsig->vector_width() == rsig->vector_width()); assert(lsig->vector_width() == rsig->vector_width());
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet*osig = new NetNet(scope, scope->local_symbol(),
@ -230,13 +230,13 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope)
if (rsig->vector_width() > width) width = rsig->vector_width(); if (rsig->vector_width() > width) width = rsig->vector_width();
if (lsig->get_signed()) if (lsig->get_signed())
lsig = pad_to_width_signed(des, lsig, width); lsig = pad_to_width_signed(des, lsig, width, *this);
else else
lsig = pad_to_width(des, lsig, width); lsig = pad_to_width(des, lsig, width, *this);
if (rsig->get_signed()) if (rsig->get_signed())
rsig = pad_to_width_signed(des, rsig, width); rsig = pad_to_width_signed(des, rsig, width, *this);
else else
rsig = pad_to_width(des, rsig, width); rsig = pad_to_width(des, rsig, width, *this);
} }
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet*osig = new NetNet(scope, scope->local_symbol(),
@ -768,10 +768,13 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope)
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());
NetConst*con = new NetConst(scope, scope->local_symbol(), value()); osig->set_line(*this);
connect(osig->pin(0), con->pin(0));
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
des->add_node(con); des->add_node(con);
con->set_line(*this);
connect(osig->pin(0), con->pin(0));
return osig; return osig;
} }
@ -1154,8 +1157,8 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope)
osig->local_flag(true); osig->local_flag(true);
/* Make sure both value operands are the right width. */ /* Make sure both value operands are the right width. */
tsig = crop_to_width(des, pad_to_width(des, tsig, width), width); tsig = crop_to_width(des, pad_to_width(des, tsig, width, *this), width);
fsig = crop_to_width(des, pad_to_width(des, fsig, width), width); fsig = crop_to_width(des, pad_to_width(des, fsig, width, *this), width);
assert(width == tsig->vector_width()); assert(width == tsig->vector_width());
assert(width == fsig->vector_width()); assert(width == fsig->vector_width());
@ -1302,7 +1305,7 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope)
NetFuncDef*def = func_->func_def(); NetFuncDef*def = func_->func_def();
for (unsigned idx = 0; idx < eparms.count(); idx += 1) { for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
NetNet*tmp = pad_to_width(des, eparms[idx], NetNet*tmp = pad_to_width(des, eparms[idx],
def->port(idx)->vector_width()); def->port(idx)->vector_width(), *this);
connect(net->pin(idx+1), tmp->pin(0)); connect(net->pin(idx+1), tmp->pin(0));
} }

View File

@ -63,10 +63,12 @@ inline NetScope* symbol_search(const LineInfo*li,
* not transforming the expression at all, if it is already wide * not transforming the expression at all, if it is already wide
* enough. * enough.
*/ */
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid); extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info);
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w); extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w,
const LineInfo&info);
extern NetNet*pad_to_width_signed(Design*des, NetNet*n, unsigned w); extern NetNet*pad_to_width_signed(Design*des, NetNet*n, unsigned w,
const LineInfo&info);
/* /*
* Generate the nodes necessary to cast an expression (a net) to a * Generate the nodes necessary to cast an expression (a net) to a

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: pad_to_width.cc,v 1.20 2005/12/22 15:43:47 steve Exp $"
#endif
# include "config.h" # include "config.h"
@ -32,7 +29,7 @@
* not transforming the expression at all, if it is already wide * not transforming the expression at all, if it is already wide
* enough. * enough.
*/ */
NetExpr*pad_to_width(NetExpr*expr, unsigned wid) NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info)
{ {
if (wid <= expr->expr_width()) if (wid <= expr->expr_width())
return expr; return expr;
@ -42,12 +39,13 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) { if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
verinum oval = pad_to_width(tmp->value(), wid); verinum oval = pad_to_width(tmp->value(), wid);
tmp = new NetEConst(oval); tmp = new NetEConst(oval);
tmp->set_line(info);
delete expr; delete expr;
return tmp; return tmp;
} }
NetESelect*tmp = new NetESelect(expr, 0, wid); NetESelect*tmp = new NetESelect(expr, 0, wid);
tmp->set_line(*expr); tmp->set_line(info);
tmp->cast_signed(expr->has_sign()); tmp->cast_signed(expr->has_sign());
return tmp; return tmp;
} }
@ -57,7 +55,7 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
* NetConst of constant zeros. Use a NetConcat node to do the * NetConst of constant zeros. Use a NetConcat node to do the
* concatenation. * concatenation.
*/ */
NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid) NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid, const LineInfo&info)
{ {
NetScope*scope = net->scope(); NetScope*scope = net->scope();
@ -80,6 +78,7 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, wid - net->vector_width()); NetNet::WIRE, wid - net->vector_width());
tmp->data_type( net->data_type() ); tmp->data_type( net->data_type() );
tmp->set_line(info);
tmp->local_flag(true); tmp->local_flag(true);
connect(cc->pin(2), tmp->pin(0)); connect(cc->pin(2), tmp->pin(0));
@ -88,14 +87,15 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
tmp = new NetNet(scope, scope->local_symbol(), tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, wid); NetNet::WIRE, wid);
tmp->data_type( net->data_type() ); tmp->data_type( net->data_type() );
tmp->set_line(*net); tmp->set_line(info);
tmp->local_flag(true); tmp->local_flag(true);
connect(cc->pin(0), tmp->pin(0)); connect(cc->pin(0), tmp->pin(0));
return tmp; return tmp;
} }
NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid) NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid,
const LineInfo&info)
{ {
NetScope*scope = net->scope(); NetScope*scope = net->scope();
@ -104,11 +104,11 @@ NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid)
NetSignExtend*se NetSignExtend*se
= new NetSignExtend(scope, scope->local_symbol(), wid); = new NetSignExtend(scope, scope->local_symbol(), wid);
se->set_line(*net); se->set_line(info);
des->add_node(se); des->add_node(se);
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
tmp->set_line(*net); tmp->set_line(info);
tmp->local_flag(true); tmp->local_flag(true);
tmp->data_type(net->data_type()); tmp->data_type(net->data_type());
tmp->set_signed(true); tmp->set_signed(true);
@ -139,48 +139,3 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid)
return tmp; return tmp;
} }
/*
* $Log: pad_to_width.cc,v $
* Revision 1.20 2005/12/22 15:43:47 steve
* pad_to_width handles signed expressions.
*
* Revision 1.19 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.18 2005/05/24 01:44:28 steve
* Do sign extension of structuran nets.
*
* Revision 1.17 2005/04/24 23:44:02 steve
* Update DFF support to new data flow.
*
* Revision 1.16 2005/01/12 03:17:37 steve
* Properly pad vector widths in pgassign.
*
* Revision 1.15 2004/02/18 17:11:57 steve
* Use perm_strings for named langiage items.
*
* Revision 1.14 2003/03/06 00:28:42 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.13 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.12 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.11 2002/08/12 01:35:00 steve
* conditional ident string using autoconfig.
*
* Revision 1.10 2002/05/25 16:43:22 steve
* Better padding of constants.
*
* Revision 1.9 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.8 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*/

View File

@ -130,13 +130,13 @@ bool NetEBBits::set_width(unsigned w, bool)
/* If the operands end up too small, then pad them to suit. */ /* If the operands end up too small, then pad them to suit. */
if (left_->expr_width() < use_width) { if (left_->expr_width() < use_width) {
NetExpr*tmp = pad_to_width(left_, use_width); NetExpr*tmp = pad_to_width(left_, use_width, *this);
assert(tmp); assert(tmp);
left_ = tmp; left_ = tmp;
} }
if (right_->expr_width() < w) { if (right_->expr_width() < w) {
NetExpr*tmp = pad_to_width(right_, use_width); NetExpr*tmp = pad_to_width(right_, use_width, *this);
assert(tmp); assert(tmp);
right_ = tmp; right_ = tmp;
} }
@ -211,13 +211,13 @@ bool NetEBShift::set_width(unsigned w, bool)
case 'l': case 'l':
left_->set_width(w); left_->set_width(w);
if (left_->expr_width() < w) if (left_->expr_width() < w)
left_ = pad_to_width(left_, w); left_ = pad_to_width(left_, w, *this);
break; break;
case 'r': case 'r':
case 'R': case 'R':
if (left_->expr_width() < w) if (left_->expr_width() < w)
left_ = pad_to_width(left_, w); left_ = pad_to_width(left_, w, *this);
break; break;
default: default:
@ -407,9 +407,11 @@ bool NetETernary::set_width(unsigned w, bool last_chance)
the user requests, at least pad the smaller width to suit the user requests, at least pad the smaller width to suit
the larger. */ the larger. */
if (true_val_->expr_width() < false_val_->expr_width()) if (true_val_->expr_width() < false_val_->expr_width())
true_val_ = pad_to_width(true_val_, false_val_->expr_width()); true_val_ = pad_to_width(true_val_, false_val_->expr_width(),
*this);
if (false_val_->expr_width() < true_val_->expr_width()) if (false_val_->expr_width() < true_val_->expr_width())
false_val_ = pad_to_width(false_val_, true_val_->expr_width()); false_val_ = pad_to_width(false_val_, true_val_->expr_width(),
*this);
expr_width(true_val_->expr_width()); expr_width(true_val_->expr_width());
return flag; return flag;