diff --git a/PDelays.cc b/PDelays.cc index 65669d172..d0627dec1 100644 --- a/PDelays.cc +++ b/PDelays.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PDelays.cc,v 1.13 2006/01/03 05:22:14 steve Exp $" +#ident "$Id: PDelays.cc,v 1.14 2006/06/02 04:48:49 steve Exp $" #endif # include "config.h" @@ -65,7 +65,7 @@ void PDelays::set_delays(const svector*del, bool df) static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr) { - NetExpr*dex = expr->elaborate_expr(des, scope); + NetExpr*dex = expr->elaborate_expr(des, scope, -1, false); if (NetExpr*tmp = dex->eval_tree()) { delete dex; dex = tmp; @@ -163,6 +163,11 @@ void PDelays::eval_delays(Design*des, NetScope*scope, /* * $Log: PDelays.cc,v $ + * Revision 1.14 2006/06/02 04:48:49 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.13 2006/01/03 05:22:14 steve * Handle complex net node delays. * diff --git a/PExpr.h b/PExpr.h index d777dec74..dfc3fe297 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.h,v 1.81 2006/04/28 04:28:35 steve Exp $" +#ident "$Id: PExpr.h,v 1.82 2006/06/02 04:48:49 steve Exp $" #endif # include @@ -51,11 +51,13 @@ class PExpr : public LineInfo { virtual void dump(ostream&) const; - // Procedural elaboration of the expression. Set the - // bare_memory_ok flag if the result is allowed to be a - // NetEMemory without an index. + // Procedural elaboration of the expression. The expr_width is + // the width of the context of the expression (i.e. the + // l-value width of an assignment) or -1 if the expression is + // self-determinted. The sys_task_arg flag is true if + // expressions are allowed to be incomplete. virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; // Elaborate expressions that are the r-value of parameter // assignments. This elaboration follows the restrictions of @@ -137,7 +139,7 @@ class PEConcat : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const; virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope, @@ -200,7 +202,7 @@ class PEFNumber : public PExpr { virtual bool is_constant(Module*) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, @@ -246,7 +248,7 @@ class PEIdent : public PExpr { Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; // Elaborate the PEIdent as a port to a module. This method @@ -350,7 +352,7 @@ class PENumber : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope, @@ -388,7 +390,7 @@ class PEString : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool) const; virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const; verinum* eval_const(const Design*, NetScope*) const; @@ -413,7 +415,7 @@ class PEUnary : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; virtual verinum* eval_const(const Design*des, NetScope*sc) const; @@ -441,7 +443,7 @@ class PEBinary : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetEBinary*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; virtual verinum* eval_const(const Design*des, NetScope*sc) const; @@ -515,7 +517,7 @@ class PETernary : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetETernary*elaborate_expr(Design*des, NetScope*, - bool sys_task_arg =false) const; + int expr_width, bool sys_task_arg) const; virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const; virtual verinum* eval_const(const Design*des, NetScope*sc) const; @@ -545,7 +547,7 @@ class PECallFunction : public PExpr { Link::strength_t drive0, Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, - bool sys_task_arg =false) const; + int expr_wid, bool sys_task_arg) const; private: hname_t path_; @@ -558,6 +560,11 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.82 2006/06/02 04:48:49 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.81 2006/04/28 04:28:35 steve * Allow concatenations as arguments to inout ports. * diff --git a/elab_expr.cc b/elab_expr.cc index 2fab79ade..4bea1b72f 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_expr.cc,v 1.104 2006/06/01 03:54:51 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.105 2006/06/02 04:48:49 steve Exp $" #endif # include "config.h" @@ -28,7 +28,7 @@ # include "netmisc.h" # include "util.h" -NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const +NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, int, bool) const { cerr << get_line() << ": internal error: I do not know how to elaborate" << " expression. " << endl; @@ -43,13 +43,14 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const * and right sides, and creating one of a variety of different NetExpr * types. */ -NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const +NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, + int expr_wid, bool) const { assert(left_); assert(right_); - NetExpr*lp = left_->elaborate_expr(des, scope); - NetExpr*rp = right_->elaborate_expr(des, scope); + NetExpr*lp = left_->elaborate_expr(des, scope, expr_wid, false); + NetExpr*rp = right_->elaborate_expr(des, scope, expr_wid, false); if ((lp == 0) || (rp == 0)) { delete lp; delete rp; @@ -195,7 +196,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const } PExpr*expr = parms_[0]; - NetExpr*sub = expr->elaborate_expr(des, scope, true); + NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); sub->cast_signed(true); return sub; } @@ -209,7 +210,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const } PExpr*expr = parms_[0]; - NetExpr*sub = expr->elaborate_expr(des, scope, true); + NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); sub->cast_signed(false); return sub; } @@ -232,7 +233,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const << " Use $bits() instead." << endl; PExpr*expr = parms_[0]; - NetExpr*sub = expr->elaborate_expr(des, scope, true); + NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); verinum val (sub->expr_width(), 8*sizeof(unsigned)); delete sub; @@ -255,7 +256,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const } PExpr*expr = parms_[0]; - NetExpr*sub = expr->elaborate_expr(des, scope, true); + NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); verinum val (sub->has_sign()? verinum::V1 : verinum::V0, 1); delete sub; @@ -303,7 +304,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const for (unsigned idx = 0 ; idx < nparms ; idx += 1) { PExpr*expr = parms_[idx]; if (expr) { - NetExpr*tmp1 = expr->elaborate_expr(des, scope, true); + NetExpr*tmp1 = expr->elaborate_expr(des, scope, -1, true); if (NetExpr*tmp2 = tmp1->eval_tree()) { delete tmp1; fun->parm(idx, tmp2); @@ -329,7 +330,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const return fun; } -NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const +NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, + int expr_wid, bool) const { if (path_.peek_name(0)[0] == '$') return elaborate_sfunc_(des, scope); @@ -366,7 +368,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) { PExpr*tmp = parms_[idx]; if (tmp) { - parms[idx] = tmp->elaborate_expr(des, scope); + parms[idx] = tmp->elaborate_expr(des, scope, -1, false); } else { missing_parms += 1; @@ -405,14 +407,15 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const } -NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const +NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, + int expr_wid, bool) const { NetExpr* repeat = 0; /* If there is a repeat expression, then evaluate the constant value and set the repeat count. */ if (repeat_) { - NetExpr*tmp = elab_and_eval(des, scope, repeat_); + NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1); assert(tmp); NetEConst*rep = dynamic_cast(tmp); @@ -444,7 +447,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const } assert(parms_[idx]); - NetExpr*ex = elab_and_eval(des, scope, parms_[idx]); + NetExpr*ex = elab_and_eval(des, scope, parms_[idx], -1); if (ex == 0) continue; ex->set_line(*parms_[idx]); @@ -465,7 +468,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const return tmp; } -NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, bool) const +NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, int, bool) const { NetECReal*tmp = new NetECReal(*value_); tmp->set_line(*this); @@ -484,7 +487,7 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, bool) const * The signal name may be escaped, but that affects nothing here. */ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, - bool sys_task_arg) const + int expr_wid, bool sys_task_arg) const { assert(scope); @@ -555,7 +558,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, PExpr*addr = idx_[0]; assert(addr); - NetExpr*i = addr->elaborate_expr(des, scope); + NetExpr*i = addr->elaborate_expr(des, scope, -1, false); if (i == 0) { cerr << get_line() << ": error: Unable to elaborate " "index expression `" << *addr << "'" << endl; @@ -575,8 +578,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, if (sel_ == SEL_PART) { - NetExpr*le = elab_and_eval(des, scope, lsb_); - NetExpr*me = elab_and_eval(des, scope, msb_); + NetExpr*le = elab_and_eval(des, scope, lsb_, -1); + NetExpr*me = elab_and_eval(des, scope, msb_, -1); NetEConst*lec = dynamic_cast(le); NetEConst*mec = dynamic_cast(me); @@ -601,7 +604,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, assert(sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO); - NetExpr*wid_ex = elab_and_eval(des, scope, lsb_); + NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1); NetEConst*wid_ec = dynamic_cast (wid_ex); if (wid_ec == 0) { cerr << lsb_->get_line() << ": error: " @@ -613,7 +616,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, unsigned wid = wid_ec->value().as_ulong(); - NetExpr*idx_ex = elab_and_eval(des, scope, msb_); + NetExpr*idx_ex = elab_and_eval(des, scope, msb_, -1); if (idx_ex == 0) { return 0; } @@ -771,7 +774,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, /* Get and evaluate the width of the index select. This must be constant. */ - NetExpr*wid_ex = elab_and_eval(des, scope, lsb_); + NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1); NetEConst*wid_ec = dynamic_cast (wid_ex); if (wid_ec == 0) { cerr << lsb_->get_line() << ": error: " @@ -783,7 +786,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, unsigned wid = wid_ec->value().as_ulong(); - NetExpr*idx_ex = elab_and_eval(des, scope, msb_); + NetExpr*idx_ex = elab_and_eval(des, scope, msb_, -1); if (idx_ex == 0) { return 0; } @@ -806,7 +809,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des, /* Handle the case where a parameter has a bit select attached to it. Generate a NetESelect object to select the bit as desired. */ - NetExpr*mtmp = idx_[0]->elaborate_expr(des, scope); + NetExpr*mtmp = idx_[0]->elaborate_expr(des, scope, -1,false); if (! dynamic_cast(mtmp)) { NetExpr*re = mtmp->eval_tree(); if (re) { @@ -985,9 +988,9 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope, NetESignal*sig = new NetESignal(net); sig->set_line(*this); - NetExpr*base = elab_and_eval(des, scope, msb_); + NetExpr*base = elab_and_eval(des, scope, msb_, -1); - NetExpr*wid_e = elab_and_eval(des, scope, lsb_); + NetExpr*wid_e = elab_and_eval(des, scope, lsb_, -1); NetEConst*wid_c = dynamic_cast (wid_e); if (wid_c == 0) { cerr << get_line() << ": error: Width of indexed part select " @@ -1038,9 +1041,9 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope, NetESignal*sig = new NetESignal(net); sig->set_line(*this); - NetExpr*base = elab_and_eval(des, scope, msb_); + NetExpr*base = elab_and_eval(des, scope, msb_, -1); - NetExpr*wid_e = elab_and_eval(des, scope, lsb_); + NetExpr*wid_e = elab_and_eval(des, scope, lsb_, -1); NetEConst*wid_c = dynamic_cast (wid_e); if (wid_c == 0) { cerr << get_line() << ": error: Width of indexed part select " @@ -1136,7 +1139,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope, // complicated task because we need to generate // expressions to convert calculated bit select // values to canonical values that are used internally. - NetExpr*ex = idx_[0]->elaborate_expr(des, scope); + NetExpr*ex = idx_[0]->elaborate_expr(des, scope, -1, false); if (net->msb() < net->lsb()) { ex = make_sub_expr(net->lsb(), ex); @@ -1181,7 +1184,8 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope, return node; } -NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const +NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, + int expr_width, bool) const { assert(value_); NetEConst*tmp = new NetEConst(*value_); @@ -1189,7 +1193,8 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const return tmp; } -NetEConst* PEString::elaborate_expr(Design*des, NetScope*, bool) const +NetEConst* PEString::elaborate_expr(Design*des, NetScope*, + int expr_width, bool) const { NetEConst*tmp = new NetEConst(value()); tmp->set_line(*this); @@ -1214,23 +1219,24 @@ static bool test_ternary_operand_compat(ivl_variable_type_t l, * parsed so I can presume that they exist, and call elaboration * methods. If any elaboration fails, then give up and return 0. */ -NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, bool) const +NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, + int expr_wid, bool) const { assert(expr_); assert(tru_); assert(fal_); - NetExpr*con = expr_->elaborate_expr(des, scope); + NetExpr*con = expr_->elaborate_expr(des, scope, -1, false); if (con == 0) return 0; - NetExpr*tru = tru_->elaborate_expr(des, scope); + NetExpr*tru = tru_->elaborate_expr(des, scope, expr_wid, false); if (tru == 0) { delete con; return 0; } - NetExpr*fal = fal_->elaborate_expr(des, scope); + NetExpr*fal = fal_->elaborate_expr(des, scope, expr_wid, false); if (fal == 0) { delete con; delete tru; @@ -1251,9 +1257,10 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, bool) const return res; } -NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const +NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, + int expr_wid, bool) const { - NetExpr*ip = expr_->elaborate_expr(des, scope); + NetExpr*ip = expr_->elaborate_expr(des, scope, expr_wid, false); if (ip == 0) return 0; /* Should we evaluate expressions ahead of time, @@ -1269,16 +1276,22 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const case '-': if (NetEConst*ipc = dynamic_cast(ip)) { + + verinum val = ipc->value(); + if (expr_wid > 0) + val = pad_to_width(val, expr_wid); + /* When taking the - of a number, turn it into a signed expression and extend it one bit to accommodate a possible sign bit. */ - verinum val = ipc->value(); verinum zero (verinum::V0, val.len()+1, val.has_len()); - val = zero - val; - if (ipc->value().has_len()) - val = verinum(val, ipc->value().len()); - val.has_sign(true); - tmp = new NetEConst(val); + verinum nval = zero - val; + + if (val.has_len()) + nval = verinum(nval, val.len()); + nval.has_sign(true); + tmp = new NetEConst(nval); + tmp->set_line(*this); delete ip; } else if (NetECReal*ipc = dynamic_cast(ip)) { @@ -1359,6 +1372,11 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const /* * $Log: elab_expr.cc,v $ + * Revision 1.105 2006/06/02 04:48:49 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.104 2006/06/01 03:54:51 steve * Fix broken subtraction of small constants. * diff --git a/elab_lval.cc b/elab_lval.cc index e335eeb80..27a75c21d 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_lval.cc,v 1.35 2006/04/16 00:54:04 steve Exp $" +#ident "$Id: elab_lval.cc,v 1.36 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -216,7 +216,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, assert(idx_.size() == 1); verinum*v = idx_[0]->eval_const(des, scope); if (v == 0) { - NetExpr*m = idx_[0]->elaborate_expr(des, scope); + NetExpr*m = idx_[0]->elaborate_expr(des, scope, -1, false); assert(m); msb = 0; lsb = 0; @@ -310,7 +310,7 @@ NetAssign_* PEIdent::elaborate_lval_net_part_(Design*des, two bit select expressions, and both must be constant. Evaluate them and pass the results back to the caller. */ - NetExpr*lsb_ex = elab_and_eval(des, scope, lsb_); + NetExpr*lsb_ex = elab_and_eval(des, scope, lsb_, -1); NetEConst*lsb_c = dynamic_cast(lsb_ex); if (lsb_c == 0) { cerr << lsb_->get_line() << ": error: " @@ -322,7 +322,7 @@ NetAssign_* PEIdent::elaborate_lval_net_part_(Design*des, return 0; } - NetExpr*msb_ex = elab_and_eval(des, scope, msb_); + NetExpr*msb_ex = elab_and_eval(des, scope, msb_, -1); NetEConst*msb_c = dynamic_cast(msb_ex); if (msb_c == 0) { cerr << msb_->get_line() << ": error: " @@ -405,7 +405,7 @@ NetAssign_* PEIdent::elaborate_lval_net_idx_up_(Design*des, /* Calculate the width expression (in the lsb_ position) first. If the expression is not constant, error but guess 1 so we can keep going and find more errors. */ - NetExpr*wid_ex = elab_and_eval(des, scope, lsb_); + NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1); NetEConst*wid_c = dynamic_cast(wid_ex); if (wid_c == 0) { @@ -418,7 +418,7 @@ NetAssign_* PEIdent::elaborate_lval_net_idx_up_(Design*des, unsigned wid = wid_c? wid_c->value().as_ulong() : 1; delete wid_ex; - NetExpr*base = elab_and_eval(des, scope, msb_); + NetExpr*base = elab_and_eval(des, scope, msb_, -1); /* Correct the mux for the range of the vector. */ if (reg->msb() < reg->lsb()) @@ -468,7 +468,7 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope, assert(idx_.size() == 1); /* Elaborate the address expression. */ - NetExpr*ix = elab_and_eval(des, scope, idx_[0]); + NetExpr*ix = elab_and_eval(des, scope, idx_[0], -1); if (ix == 0) return 0; @@ -485,8 +485,8 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope, assert(msb_ && lsb_); if (sel_ == SEL_PART) { - NetExpr*le = elab_and_eval(des, scope, lsb_); - NetExpr*me = elab_and_eval(des, scope, msb_); + NetExpr*le = elab_and_eval(des, scope, lsb_, -1); + NetExpr*me = elab_and_eval(des, scope, msb_, -1); NetEConst*lec = dynamic_cast(le); NetEConst*mec = dynamic_cast(me); @@ -509,7 +509,7 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope, assert(sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO); - NetExpr*wid_ex = elab_and_eval(des, scope, lsb_); + NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1); NetEConst*wid_ec = dynamic_cast (wid_ex); if (wid_ec == 0) { cerr << lsb_->get_line() << ": error: " @@ -521,7 +521,7 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope, unsigned wid = wid_ec->value().as_ulong(); - NetExpr*base_ex = elab_and_eval(des, scope, msb_); + NetExpr*base_ex = elab_and_eval(des, scope, msb_, -1); if (base_ex == 0) { return 0; } @@ -544,6 +544,11 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const /* * $Log: elab_lval.cc,v $ + * Revision 1.36 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.35 2006/04/16 00:54:04 steve * Cleanup lval part select handling. * diff --git a/elab_net.cc b/elab_net.cc index 6ad7d4bf5..b71fa0d7d 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_net.cc,v 1.185 2006/05/19 04:44:55 steve Exp $" +#ident "$Id: elab_net.cc,v 1.186 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -474,7 +474,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, (so that the eval_tree method can reduce constant expressions, including parameters) then turn those results into synthesized nets. */ - NetExpr*lexp = elab_and_eval(des, scope, left_); + NetExpr*lexp = elab_and_eval(des, scope, left_, lwidth); if (lexp == 0) { cerr << get_line() << ": error: Cannot elaborate "; left_->dump(cerr); @@ -482,7 +482,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, return 0; } - NetExpr*rexp = elab_and_eval(des, scope, right_); + NetExpr*rexp = elab_and_eval(des, scope, right_, lwidth); if (rexp == 0) { cerr << get_line() << ": error: Cannot elaborate "; right_->dump(cerr); @@ -1341,7 +1341,7 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, constant. This is used to generate the width of the concatenation. */ if (repeat_) { - NetExpr*etmp = elab_and_eval(des, scope, repeat_); + NetExpr*etmp = elab_and_eval(des, scope, repeat_, -1); assert(etmp); NetEConst*erep = dynamic_cast(etmp); @@ -1479,7 +1479,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, NetNet*sel; if (sig->msb() < sig->lsb()) { - NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope); + NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope, -1, false); sel_expr = make_sub_expr(sig->lsb(), sel_expr); if (NetExpr*tmp = sel_expr->eval_tree()) { delete sel_expr; @@ -1489,7 +1489,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, sel = sel_expr->synthesize(des); } else if (sig->lsb() != 0) { - NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope); + NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope, -1,false); sel_expr = make_add_expr(sel_expr, - sig->lsb()); if (NetExpr*tmp = sel_expr->eval_tree()) { delete sel_expr; @@ -1696,7 +1696,7 @@ NetNet* PEIdent::elaborate_net_ram_(Design*des, NetScope*scope, const bool must_be_self_determined_save = must_be_self_determined_flag; must_be_self_determined_flag = false; - NetExpr*adr_expr = elab_and_eval(des, scope, idx_[0]); + NetExpr*adr_expr = elab_and_eval(des, scope, idx_[0], -1); /* If an offset is needed, subtract it from the address to get an expression for the canonical address. */ @@ -1925,7 +1925,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, assert(lsb_); assert(idx_.empty()); - NetExpr*tmp_ex = elab_and_eval(des, scope, msb_); + NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1); NetEConst*tmp = dynamic_cast(tmp_ex); assert(tmp); @@ -1933,7 +1933,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, midx = sig->sb_to_idx(midx_val); delete tmp_ex; - tmp_ex = elab_and_eval(des, scope, lsb_); + tmp_ex = elab_and_eval(des, scope, lsb_, -1); tmp = dynamic_cast(tmp_ex); assert(tmp); @@ -1959,7 +1959,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, assert(lsb_); assert(idx_.empty()); - NetExpr*tmp_ex = elab_and_eval(des, scope, msb_); + NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1); NetEConst*tmp = dynamic_cast(tmp_ex); assert(tmp); @@ -1967,7 +1967,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, midx = sig->sb_to_idx(midx_val); delete tmp_ex; - tmp_ex = elab_and_eval(des, scope, lsb_); + tmp_ex = elab_and_eval(des, scope, lsb_, -1); tmp = dynamic_cast(tmp_ex); assert(tmp); @@ -2779,6 +2779,11 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.186 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.185 2006/05/19 04:44:55 steve * Get self-determined unary - width right. * diff --git a/elab_pexpr.cc b/elab_pexpr.cc index 8d80a3376..98c5858b9 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_pexpr.cc,v 1.23 2006/02/02 02:43:58 steve Exp $" +#ident "$Id: elab_pexpr.cc,v 1.24 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -119,7 +119,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const { - return elaborate_expr(des, scope); + return elaborate_expr(des, scope, -1, false); } /* @@ -181,13 +181,13 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const */ NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const { - return elaborate_expr(des, sc); + return elaborate_expr(des, sc, -1, false); } NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const { - return elaborate_expr(des, scope); + return elaborate_expr(des, scope, -1, false); } NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const @@ -236,6 +236,11 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const /* * $Log: elab_pexpr.cc,v $ + * Revision 1.24 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.23 2006/02/02 02:43:58 steve * Allow part selects of memory words in l-values. * diff --git a/elab_scope.cc b/elab_scope.cc index 8b3d2c8b7..c06bc0d13 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_scope.cc,v 1.40 2006/04/12 05:05:03 steve Exp $" +#ident "$Id: elab_scope.cc,v 1.41 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -325,7 +325,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) // The initial value for the genvar does not need (nor can it // use) the genvar itself, so we can evaluate this expression // the same way any other paramter value is evaluated. - NetExpr*init_ex = elab_and_eval(des, container, loop_init); + NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1); NetEConst*init = dynamic_cast (init_ex); if (init == 0) { cerr << get_line() << ": error: Cannot evaluate genvar" @@ -342,7 +342,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) container->genvar_tmp = loop_index; container->genvar_tmp_val = 0; - NetExpr*test_ex = elab_and_eval(des, container, loop_test); + NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1); NetEConst*test = dynamic_cast(test_ex); assert(test); while (test->value().as_long()) { @@ -379,7 +379,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) scope_list_.push_back(scope); // Calculate the step for the loop variable. - NetExpr*step_ex = elab_and_eval(des, container, loop_step); + NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1); NetEConst*step = dynamic_cast(step_ex); assert(step); if (debug_elaborate) @@ -390,7 +390,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) container->genvar_tmp_val = genvar; delete step; delete test_ex; - test_ex = elab_and_eval(des, container, loop_test); + test_ex = elab_and_eval(des, container, loop_test, -1); test = dynamic_cast(test_ex); assert(test); } @@ -448,8 +448,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const return; } - NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_) : 0; - NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_) : 0; + NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0; + NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0; NetEConst*msb = dynamic_cast (mse); NetEConst*lsb = dynamic_cast (lse); @@ -748,6 +748,11 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const /* * $Log: elab_scope.cc,v $ + * Revision 1.41 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.40 2006/04/12 05:05:03 steve * Use elab_and_eval to evaluate genvar expressions. * diff --git a/elab_sig.cc b/elab_sig.cc index 38463355f..8d17fec29 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_sig.cc,v 1.41 2006/04/10 00:37:42 steve Exp $" +#ident "$Id: elab_sig.cc,v 1.42 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -318,10 +318,10 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const case PTF_REG: if (return_type_.range) { NetExpr*me = elab_and_eval(des, scope, - (*return_type_.range)[0]); + (*return_type_.range)[0], -1); assert(me); NetExpr*le = elab_and_eval(des, scope, - (*return_type_.range)[1]); + (*return_type_.range)[1], -1); assert(le); long mnum = 0, lnum = 0; @@ -548,7 +548,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const } NetEConst*tmp; - NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]); + NetExpr*texpr = elab_and_eval(des, scope, msb_[idx], -1); tmp = dynamic_cast(texpr); if (tmp == 0) { @@ -562,7 +562,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const mnum[idx] = tmp->value().as_long(); delete texpr; - texpr = elab_and_eval(des, scope, lsb_[idx]); + texpr = elab_and_eval(des, scope, lsb_[idx], -1); tmp = dynamic_cast(texpr); if (tmp == 0) { cerr << msb_[idx]->get_line() << ": error: " @@ -623,8 +623,8 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const if (lidx_ || ridx_) { assert(lidx_ && ridx_); - NetExpr*lexp = elab_and_eval(des, scope, lidx_); - NetExpr*rexp = elab_and_eval(des, scope, ridx_); + NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1); + NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1); if ((lexp == 0) || (rexp == 0)) { cerr << get_line() << ": internal error: There is " @@ -720,6 +720,11 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const /* * $Log: elab_sig.cc,v $ + * Revision 1.42 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.41 2006/04/10 00:37:42 steve * Add support for generate loops w/ wires and gates. * diff --git a/elaborate.cc b/elaborate.cc index 509b22892..610dc4f28 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elaborate.cc,v 1.339 2006/05/01 20:47:59 steve Exp $" +#ident "$Id: elaborate.cc,v 1.340 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -308,8 +308,8 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const gates, then I am expected to make more then one gate. Figure out how many are desired. */ if (msb_) { - NetExpr*msb_exp = elab_and_eval(des, scope, msb_); - NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_); + NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1); + NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1); NetEConst*msb_con = dynamic_cast(msb_exp); NetEConst*lsb_con = dynamic_cast(lsb_exp); @@ -1333,7 +1333,7 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const */ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope) { - NetExpr*dex = elab_and_eval(des, scope, expr); + NetExpr*dex = elab_and_eval(des, scope, expr, -1); /* If the delay expression is a real constant or vector constant, then evaluate it, scale it to the local time @@ -1410,7 +1410,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const /* Elaborate the r-value expression, then try to evaluate it. */ assert(rval()); - NetExpr*rv = elab_and_eval(des, scope, rval()); + NetExpr*rv = elab_and_eval(des, scope, rval(), lv->lwidth()); if (rv == 0) return 0; assert(rv); @@ -1530,7 +1530,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const assert(rval()); /* Elaborate and precalculate the r-value. */ - NetExpr*rv = elab_and_eval(des, scope, rval()); + NetExpr*rv = elab_and_eval(des, scope, rval(), count_lval_width(lv)); if (rv == 0) return 0; @@ -1638,7 +1638,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const { assert(scope); - NetExpr*expr = elab_and_eval(des, scope, expr_); + NetExpr*expr = elab_and_eval(des, scope, expr_, -1); if (expr == 0) { cerr << get_line() << ": error: Unable to elaborate this case" " expression." << endl; @@ -1690,7 +1690,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const NetExpr*gu = 0; NetProc*st = 0; assert(cur->expr[e]); - gu = elab_and_eval(des, scope, cur->expr[e]); + gu = elab_and_eval(des, scope, cur->expr[e], -1); if (cur->stat) st = cur->stat->elaborate(des, scope); @@ -1708,7 +1708,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const assert(scope); // Elaborate and try to evaluate the conditional expression. - NetExpr*expr = elab_and_eval(des, scope, expr_); + NetExpr*expr = elab_and_eval(des, scope, expr_, -1); if (expr == 0) { cerr << get_line() << ": error: Unable to elaborate" " condition expression." << endl; @@ -1815,7 +1815,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { PExpr*ex = parm(idx); - eparms[idx] = ex? ex->elaborate_expr(des, scope, true) : 0; + eparms[idx] = ex? ex->elaborate_expr(des, scope, -1, true) : 0; /* Attempt to pre-evaluate the parameters. It may be possible to at least partially reduce the @@ -1929,7 +1929,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const NetAssign_*lv = new NetAssign_(port); unsigned wid = count_lval_width(lv); - NetExpr*rv = elab_and_eval(des, scope, parms_[idx]); + NetExpr*rv = elab_and_eval(des, scope, parms_[idx], wid); rv->set_width(wid); rv = pad_to_width(rv, wid); NetAssign*pr = new NetAssign(lv, rv); @@ -2009,12 +2009,12 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const if (lval == 0) return 0; - NetExpr*rexp = elab_and_eval(des, scope, expr_); + unsigned lwid = count_lval_width(lval); + + NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid); if (rexp == 0) return 0; - unsigned lwid = count_lval_width(lval); - rexp->set_width(lwid); rexp = pad_to_width(rexp, lwid); @@ -2357,7 +2357,7 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope, /* Elaborate wait expression. Don't eval yet, we will do that shortly, after we apply a reduction or. */ - NetExpr*expr = pe->elaborate_expr(des, scope); + NetExpr*expr = pe->elaborate_expr(des, scope, -1, false); if (expr == 0) { cerr << get_line() << ": error: Unable to elaborate" " wait condition expression." << endl; @@ -2537,12 +2537,12 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const if (lval == 0) return 0; - NetExpr*rexp = elab_and_eval(des, scope, expr_); + unsigned lwid = count_lval_width(lval); + + NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid); if (rexp == 0) return 0; - unsigned lwid = count_lval_width(lval); - rexp->set_width(lwid, true); rexp = pad_to_width(rexp, lwid); @@ -2600,7 +2600,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const /* Make the r-value of the initial assignment, and size it properly. Then use it to build the assignment statement. */ - etmp = elab_and_eval(des, scope, expr1_); + etmp = elab_and_eval(des, scope, expr1_, lv->lwidth()); etmp->set_width(lv->lwidth()); etmp = pad_to_width(etmp, lv->lwidth()); @@ -2643,7 +2643,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const /* Make the rvalue of the increment expression, and size it for the lvalue. */ - etmp = expr2_->elaborate_expr(des, scope); + etmp = expr2_->elaborate_expr(des, scope, lv->lwidth(), false); etmp->set_width(lv->lwidth()); NetAssign*step = new NetAssign(lv, etmp); step->set_line(*this); @@ -2654,7 +2654,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const /* Elaborate the condition expression. Try to evaluate it too, in case it is a constant. This is an interesting case worthy of a warning. */ - NetExpr*ce = elab_and_eval(des, scope, cond_); + NetExpr*ce = elab_and_eval(des, scope, cond_, -1); if (ce == 0) { delete top; return 0; @@ -2735,7 +2735,7 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const { assert(scope); - NetExpr*expr = elab_and_eval(des, scope, expr_); + NetExpr*expr = elab_and_eval(des, scope, expr_, -1); if (expr == 0) { cerr << get_line() << ": Unable to elaborate" " repeat expression." << endl; @@ -2856,7 +2856,7 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const */ NetProc* PWhile::elaborate(Design*des, NetScope*scope) const { - NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_), + NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_, -1), statement_->elaborate(des, scope)); return loop; } @@ -3133,6 +3133,11 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.340 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.339 2006/05/01 20:47:59 steve * More explicit datatype setup. * diff --git a/netmisc.cc b/netmisc.cc index 36acd2648..df99fa5d7 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netmisc.cc,v 1.11 2005/04/08 04:50:31 steve Exp $" +#ident "$Id: netmisc.cc,v 1.12 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -123,9 +123,10 @@ NetExpr* make_sub_expr(long val, NetExpr*expr) return res; } -NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe) +NetExpr* elab_and_eval(Design*des, NetScope*scope, + const PExpr*pe, int expr_wid) { - NetExpr*tmp = pe->elaborate_expr(des, scope); + NetExpr*tmp = pe->elaborate_expr(des, scope, expr_wid, false); if (tmp == 0) return 0; @@ -140,6 +141,11 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe) /* * $Log: netmisc.cc,v $ + * Revision 1.12 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.11 2005/04/08 04:50:31 steve * Don not give to make_add express an unwanted width. * diff --git a/netmisc.h b/netmisc.h index a07580d41..5f2075a57 100644 --- a/netmisc.h +++ b/netmisc.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netmisc.h,v 1.24 2005/11/27 05:56:20 steve Exp $" +#ident "$Id: netmisc.h,v 1.25 2006/06/02 04:48:50 steve Exp $" #endif # include "netlist.h" @@ -114,10 +114,16 @@ extern unsigned count_lval_width(const class NetAssign_*first); * it can. If the expression cannot be elaborated, return 0. */ class PExpr; -extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe); +extern NetExpr* elab_and_eval(Design*des, NetScope*scope, + const PExpr*pe, int expr_wid); /* * $Log: netmisc.h,v $ + * Revision 1.25 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.24 2005/11/27 05:56:20 steve * Handle bit select of parameter with ranges. * diff --git a/verinum.cc b/verinum.cc index 680d084d3..0136e1af2 100644 --- a/verinum.cc +++ b/verinum.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verinum.cc,v 1.45 2006/06/01 03:54:51 steve Exp $" +#ident "$Id: verinum.cc,v 1.46 2006/06/02 04:48:50 steve Exp $" #endif # include "config.h" @@ -317,6 +317,30 @@ bool verinum::is_zero() const return true; } +verinum pad_to_width(const verinum&that, unsigned width) +{ + if (that.len() >= width) + return that; + + if (that.len() == 0) { + verinum val (verinum::V0, width, that.has_len()); + val.has_sign(that.has_sign()); + return val; + } + + verinum::V pad = that[that.len()-1]; + if (pad==verinum::V1 && !that.has_sign()) + pad = verinum::V0; + + verinum val(pad, width, that.has_len()); + + for (unsigned idx = 0 ; idx < that.len() ; idx += 1) + val.set(idx, that[idx]); + + val.has_sign(that.has_sign()); + return val; +} + /* * This function returns a version of the verinum that has only as * many bits as are needed to accurately represent the value. It takes @@ -983,6 +1007,11 @@ verinum::V operator ^ (verinum::V l, verinum::V r) /* * $Log: verinum.cc,v $ + * Revision 1.46 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.45 2006/06/01 03:54:51 steve * Fix broken subtraction of small constants. * diff --git a/verinum.h b/verinum.h index a8de922fa..8f4890c1f 100644 --- a/verinum.h +++ b/verinum.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verinum.h,v 1.29 2006/06/01 03:54:51 steve Exp $" +#ident "$Id: verinum.h,v 1.30 2006/06/02 04:48:50 steve Exp $" #endif # include @@ -105,6 +105,11 @@ class verinum { bool string_flag_; }; +/* Return a verinum that has the same value as the input, but is at + least as wide as the requested width. This may involve sign + extension, if the value is signed. */ +extern verinum pad_to_width(const verinum&, unsigned width); + /* Return a verinum that is minimal. That is, it has only the length needed to accurately represent the contained value, signed or not. */ extern verinum trim_vnum(const verinum&); @@ -152,6 +157,11 @@ extern verinum v_not(const verinum&left); /* * $Log: verinum.h,v $ + * Revision 1.30 2006/06/02 04:48:50 steve + * Make elaborate_expr methods aware of the width that the context + * requires of it. In the process, fix sizing of the width of unary + * minus is context determined sizes. + * * Revision 1.29 2006/06/01 03:54:51 steve * Fix broken subtraction of small constants. *