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 (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()))
rp = pad_to_width(rp, expr_wid);
rp = pad_to_width(rp, expr_wid, *this);
}
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
of the output. */
if (expr_wid > 0) {
lp = pad_to_width(lp, expr_wid);
rp = pad_to_width(rp, expr_wid);
lp = pad_to_width(lp, expr_wid, *this);
rp = pad_to_width(rp, expr_wid, *this);
}
NetEBDiv*tmp = new NetEBDiv(op_, lp, rp);
@ -509,7 +509,7 @@ NetExpr* PEBinary::elaborate_expr_base_lshift_(Design*des,
cerr << get_fileline() << ": debug: "
<< "Left shift expression by constant "
<< 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);
}
@ -517,7 +517,7 @@ NetExpr* PEBinary::elaborate_expr_base_lshift_(Design*des,
// Left side is not constant, so handle it the
// default way.
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);
}
@ -582,9 +582,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
tmp->set_line(*this);
tmp = new NetESelect(lp, tmp, 1);
tmp->cast_signed(true);
tmp->set_line(*this);
tmp = pad_to_width(tmp, use_wid);
tmp->set_line(*this);
tmp = pad_to_width(tmp, use_wid, *this);
return tmp;
} else if (shift >= 0) {
@ -607,8 +605,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
tmp = new NetESelect(lp, tmp, tmp_wid);
tmp->set_line(*this);
tmp->cast_signed(lp->has_sign() && op_=='R');
tmp = pad_to_width(tmp, use_wid);
tmp->set_line(*this);
tmp = pad_to_width(tmp, use_wid, *this);
return tmp;
} else if ((0-shift) >= use_wid) {
@ -626,7 +623,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
// Falback, handle the general case.
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->set_line(*this);
return tmp;
@ -641,9 +638,9 @@ NetExpr* PEBinary::elaborate_expr_base_mult_(Design*des,
// multiplication to come out right.
if (expr_wid > 0) {
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)
rp = pad_to_width(rp, expr_wid);
rp = pad_to_width(rp, expr_wid, *this);
}
// 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
// desired 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);
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
// are signed, then this padding will do sign extension.
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()))
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(rp, use_wid_r);
@ -1090,7 +1087,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
sub->cast_signed(false);
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;
}
@ -2800,7 +2797,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
}
ivl_assert(*this, use_wid > 0);
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
@ -2818,7 +2815,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
}
ivl_assert(*this, use_wid > 0);
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
@ -2851,8 +2848,8 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
/* Whatever the width we choose for the ternary operator, we
need to make sure the operands match. */
tru = pad_to_width(tru, use_wid);
fal = pad_to_width(fal, use_wid);
tru = pad_to_width(tru, use_wid, *this);
fal = pad_to_width(fal, use_wid, *this);
NetETernary*res = new NetETernary(con, tru, fal);
res->set_line(*this);
@ -2975,7 +2972,7 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
} else {
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->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())
operand = pad_to_width(operand, expr_wid);
operand = pad_to_width(operand, expr_wid, *this);
NetEUBits*tmp = new NetEUBits(op_, operand);
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 "
<< 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);
@ -165,9 +165,10 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
of the l-value. */
if (lval->vector_width() > rval->vector_width()) {
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
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
@ -861,7 +862,7 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, port_wid);
tmp->local_flag(true);
tmp->set_line(*sig);
tmp->set_line(*this);
// Handle the special case of a bi-directional part
// 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 {
NetNet*osig;
if (as_signed) {
osig = pad_to_width_signed(des, tmp, swidth);
osig = pad_to_width_signed(des, tmp, swidth, *this);
} else {
osig = pad_to_width(des, tmp, swidth);
osig = pad_to_width(des, tmp, swidth, *this);
}
connect(osig->pin(0), sig->pin(0));
}
@ -915,9 +916,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
if (pwidth > swidth) {
delete tmp;
if (as_signed) {
tmp = pad_to_width_signed(des, sig, pwidth);
tmp = pad_to_width_signed(des, sig, pwidth, *this);
} else {
tmp = pad_to_width(des, sig, pwidth);
tmp = pad_to_width(des, sig, pwidth, *this);
}
} else {
NetPartSelect*node = new NetPartSelect(sig, 0, pwidth,
@ -1192,7 +1193,7 @@ v NOTE that this also handles the case that the
}
delete tmp_expr;
sig->set_line(*this);
if (!sig->get_lineno()) sig->set_line(*this);
if (need_bufz_for_input_port(prts)) {
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);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
if (wid > rv->expr_width()) {
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);
if (wid > rv->expr_width()) {
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
}
ivl_assert(*this, rv->expr_width() >= wid);
}
@ -2053,7 +2054,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
} else {
unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
}
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);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
NetAssign*pr = new NetAssign(lv, rv);
block->append(pr);
}
@ -2599,7 +2600,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
continue;
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. */
NetAssign*ass = new NetAssign(lv, rv);
@ -2655,7 +2656,7 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
return 0;
rexp->set_width(lwid);
rexp = pad_to_width(rexp, lwid);
rexp = pad_to_width(rexp, lwid, *this);
dev = new NetCAssign(lval, rexp);
@ -3253,7 +3254,7 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
return 0;
rexp->set_width(lwid, true);
rexp = pad_to_width(rexp, lwid);
rexp = pad_to_width(rexp, lwid, *this);
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. */
etmp = elab_and_eval(des, scope, expr1_, 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) {
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) {
unsigned wid = count_lval_width(lv);
etmp->set_width(wid);
etmp = pad_to_width(etmp, wid);
etmp = pad_to_width(etmp, wid, *this);
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);
} else {
lsig = pad_to_width(des, lsig, expr_width());
rsig = pad_to_width(des, rsig, expr_width());
lsig = pad_to_width(des, lsig, expr_width(), *this);
rsig = pad_to_width(des, rsig, expr_width(), *this);
assert(lsig->vector_width() == rsig->vector_width());
width=lsig->vector_width();
@ -167,8 +167,8 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope)
unsigned width = expr_width();
if (rsig->vector_width() > width) width = rsig->vector_width();
lsig = pad_to_width(des, lsig, width);
rsig = pad_to_width(des, rsig, width);
lsig = pad_to_width(des, lsig, width, *this);
rsig = pad_to_width(des, rsig, width, *this);
assert(lsig->vector_width() == rsig->vector_width());
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 (lsig->get_signed())
lsig = pad_to_width_signed(des, lsig, width);
lsig = pad_to_width_signed(des, lsig, width, *this);
else
lsig = pad_to_width(des, lsig, width);
lsig = pad_to_width(des, lsig, width, *this);
if (rsig->get_signed())
rsig = pad_to_width_signed(des, rsig, width);
rsig = pad_to_width_signed(des, rsig, width, *this);
else
rsig = pad_to_width(des, rsig, width);
rsig = pad_to_width(des, rsig, width, *this);
}
NetNet*osig = new NetNet(scope, scope->local_symbol(),
@ -768,10 +768,13 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope)
osig->local_flag(true);
osig->data_type(expr_type());
osig->set_signed(has_sign());
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
connect(osig->pin(0), con->pin(0));
osig->set_line(*this);
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
des->add_node(con);
con->set_line(*this);
connect(osig->pin(0), con->pin(0));
return osig;
}
@ -1154,8 +1157,8 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope)
osig->local_flag(true);
/* Make sure both value operands are the right width. */
tsig = crop_to_width(des, pad_to_width(des, tsig, width), width);
fsig = crop_to_width(des, pad_to_width(des, fsig, 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, *this), width);
assert(width == tsig->vector_width());
assert(width == fsig->vector_width());
@ -1302,7 +1305,7 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope)
NetFuncDef*def = func_->func_def();
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
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));
}

View File

@ -63,10 +63,12 @@ inline NetScope* symbol_search(const LineInfo*li,
* not transforming the expression at all, if it is already wide
* enough.
*/
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info);
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

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
* 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
* 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"
@ -32,7 +29,7 @@
* not transforming the expression at all, if it is already wide
* 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())
return expr;
@ -42,12 +39,13 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
verinum oval = pad_to_width(tmp->value(), wid);
tmp = new NetEConst(oval);
tmp->set_line(info);
delete expr;
return tmp;
}
NetESelect*tmp = new NetESelect(expr, 0, wid);
tmp->set_line(*expr);
tmp->set_line(info);
tmp->cast_signed(expr->has_sign());
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
* 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();
@ -80,6 +78,7 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, wid - net->vector_width());
tmp->data_type( net->data_type() );
tmp->set_line(info);
tmp->local_flag(true);
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(),
NetNet::WIRE, wid);
tmp->data_type( net->data_type() );
tmp->set_line(*net);
tmp->set_line(info);
tmp->local_flag(true);
connect(cc->pin(0), tmp->pin(0));
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();
@ -104,11 +104,11 @@ NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid)
NetSignExtend*se
= new NetSignExtend(scope, scope->local_symbol(), wid);
se->set_line(*net);
se->set_line(info);
des->add_node(se);
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid);
tmp->set_line(*net);
tmp->set_line(info);
tmp->local_flag(true);
tmp->data_type(net->data_type());
tmp->set_signed(true);
@ -139,48 +139,3 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid)
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 (left_->expr_width() < use_width) {
NetExpr*tmp = pad_to_width(left_, use_width);
NetExpr*tmp = pad_to_width(left_, use_width, *this);
assert(tmp);
left_ = tmp;
}
if (right_->expr_width() < w) {
NetExpr*tmp = pad_to_width(right_, use_width);
NetExpr*tmp = pad_to_width(right_, use_width, *this);
assert(tmp);
right_ = tmp;
}
@ -211,13 +211,13 @@ bool NetEBShift::set_width(unsigned w, bool)
case 'l':
left_->set_width(w);
if (left_->expr_width() < w)
left_ = pad_to_width(left_, w);
left_ = pad_to_width(left_, w, *this);
break;
case 'r':
case 'R':
if (left_->expr_width() < w)
left_ = pad_to_width(left_, w);
left_ = pad_to_width(left_, w, *this);
break;
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 larger. */
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())
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());
return flag;