diff --git a/elab_expr.cc b/elab_expr.cc index 6c32fc4c9..21e302b06 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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); diff --git a/elaborate.cc b/elaborate.cc index 8c5b47c9e..bd67391b0 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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); } diff --git a/expr_synth.cc b/expr_synth.cc index ff829aacf..fcd690eaa 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -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)); } diff --git a/netmisc.h b/netmisc.h index 29333b063..c51ba02f7 100644 --- a/netmisc.h +++ b/netmisc.h @@ -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 diff --git a/pad_to_width.cc b/pad_to_width.cc index 373d9457e..a63c75b15 100644 --- a/pad_to_width.cc +++ b/pad_to_width.cc @@ -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(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) - */ - diff --git a/set_width.cc b/set_width.cc index 24a6f8df0..ed209c754 100644 --- a/set_width.cc +++ b/set_width.cc @@ -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;