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.
This commit is contained in:
steve 2006-06-02 04:48:49 +00:00
parent 53ae1f29c9
commit 71faebd6df
13 changed files with 241 additions and 130 deletions

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # include "config.h"
@ -65,7 +65,7 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr) 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()) { if (NetExpr*tmp = dex->eval_tree()) {
delete dex; delete dex;
dex = tmp; dex = tmp;
@ -163,6 +163,11 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
/* /*
* $Log: PDelays.cc,v $ * $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 * Revision 1.13 2006/01/03 05:22:14 steve
* Handle complex net node delays. * Handle complex net node delays.
* *

35
PExpr.h
View File

@ -19,7 +19,7 @@
* 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 #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 #endif
# include <string> # include <string>
@ -51,11 +51,13 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
// Procedural elaboration of the expression. Set the // Procedural elaboration of the expression. The expr_width is
// bare_memory_ok flag if the result is allowed to be a // the width of the context of the expression (i.e. the
// NetEMemory without an index. // 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, 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 // Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of // assignments. This elaboration follows the restrictions of
@ -137,7 +139,7 @@ class PEConcat : public PExpr {
Link::strength_t drive0, Link::strength_t drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, 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 NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
@ -200,7 +202,7 @@ class PEFNumber : public PExpr {
virtual bool is_constant(Module*) const; virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, 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 NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope, virtual NetNet* elaborate_net(Design*des, NetScope*scope,
@ -246,7 +248,7 @@ class PEIdent : public PExpr {
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, 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 NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method // 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 drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, 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 NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
@ -388,7 +390,7 @@ class PEString : public PExpr {
Link::strength_t drive0, Link::strength_t drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, 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; virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* eval_const(const Design*, NetScope*) const; verinum* eval_const(const Design*, NetScope*) const;
@ -413,7 +415,7 @@ class PEUnary : public PExpr {
Link::strength_t drive0, Link::strength_t drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, 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 NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const 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 drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*, 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 NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const 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 drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*, 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 NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const 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 drive0,
Link::strength_t drive1) const; Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg =false) const; int expr_wid, bool sys_task_arg) const;
private: private:
hname_t path_; hname_t path_;
@ -558,6 +560,11 @@ class PECallFunction : public PExpr {
/* /*
* $Log: PExpr.h,v $ * $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 * Revision 1.81 2006/04/28 04:28:35 steve
* Allow concatenations as arguments to inout ports. * Allow concatenations as arguments to inout ports.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # include "config.h"
@ -28,7 +28,7 @@
# include "netmisc.h" # include "netmisc.h"
# include "util.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" cerr << get_line() << ": internal error: I do not know how to elaborate"
<< " expression. " << endl; << " 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 * and right sides, and creating one of a variety of different NetExpr
* types. * 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(left_);
assert(right_); assert(right_);
NetExpr*lp = left_->elaborate_expr(des, scope); NetExpr*lp = left_->elaborate_expr(des, scope, expr_wid, false);
NetExpr*rp = right_->elaborate_expr(des, scope); NetExpr*rp = right_->elaborate_expr(des, scope, expr_wid, false);
if ((lp == 0) || (rp == 0)) { if ((lp == 0) || (rp == 0)) {
delete lp; delete lp;
delete rp; delete rp;
@ -195,7 +196,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
} }
PExpr*expr = parms_[0]; 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); sub->cast_signed(true);
return sub; return sub;
} }
@ -209,7 +210,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
} }
PExpr*expr = parms_[0]; 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); sub->cast_signed(false);
return sub; return sub;
} }
@ -232,7 +233,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
<< " Use $bits() instead." << endl; << " Use $bits() instead." << endl;
PExpr*expr = parms_[0]; 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)); verinum val (sub->expr_width(), 8*sizeof(unsigned));
delete sub; delete sub;
@ -255,7 +256,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
} }
PExpr*expr = parms_[0]; 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); verinum val (sub->has_sign()? verinum::V1 : verinum::V0, 1);
delete sub; delete sub;
@ -303,7 +304,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < nparms ; idx += 1) { for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
PExpr*expr = parms_[idx]; PExpr*expr = parms_[idx];
if (expr) { 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()) { if (NetExpr*tmp2 = tmp1->eval_tree()) {
delete tmp1; delete tmp1;
fun->parm(idx, tmp2); fun->parm(idx, tmp2);
@ -329,7 +330,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
return fun; 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] == '$') if (path_.peek_name(0)[0] == '$')
return elaborate_sfunc_(des, scope); 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) { for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
PExpr*tmp = parms_[idx]; PExpr*tmp = parms_[idx];
if (tmp) { if (tmp) {
parms[idx] = tmp->elaborate_expr(des, scope); parms[idx] = tmp->elaborate_expr(des, scope, -1, false);
} else { } else {
missing_parms += 1; 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; NetExpr* repeat = 0;
/* If there is a repeat expression, then evaluate the constant /* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */ value and set the repeat count. */
if (repeat_) { if (repeat_) {
NetExpr*tmp = elab_and_eval(des, scope, repeat_); NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
assert(tmp); assert(tmp);
NetEConst*rep = dynamic_cast<NetEConst*>(tmp); NetEConst*rep = dynamic_cast<NetEConst*>(tmp);
@ -444,7 +447,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
} }
assert(parms_[idx]); 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; if (ex == 0) continue;
ex->set_line(*parms_[idx]); ex->set_line(*parms_[idx]);
@ -465,7 +468,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
return tmp; 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_); NetECReal*tmp = new NetECReal(*value_);
tmp->set_line(*this); 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. * The signal name may be escaped, but that affects nothing here.
*/ */
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg) const int expr_wid, bool sys_task_arg) const
{ {
assert(scope); assert(scope);
@ -555,7 +558,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
PExpr*addr = idx_[0]; PExpr*addr = idx_[0];
assert(addr); assert(addr);
NetExpr*i = addr->elaborate_expr(des, scope); NetExpr*i = addr->elaborate_expr(des, scope, -1, false);
if (i == 0) { if (i == 0) {
cerr << get_line() << ": error: Unable to elaborate " cerr << get_line() << ": error: Unable to elaborate "
"index expression `" << *addr << "'" << endl; "index expression `" << *addr << "'" << endl;
@ -575,8 +578,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
if (sel_ == SEL_PART) { if (sel_ == SEL_PART) {
NetExpr*le = elab_and_eval(des, scope, lsb_); NetExpr*le = elab_and_eval(des, scope, lsb_, -1);
NetExpr*me = elab_and_eval(des, scope, msb_); NetExpr*me = elab_and_eval(des, scope, msb_, -1);
NetEConst*lec = dynamic_cast<NetEConst*>(le); NetEConst*lec = dynamic_cast<NetEConst*>(le);
NetEConst*mec = dynamic_cast<NetEConst*>(me); NetEConst*mec = dynamic_cast<NetEConst*>(me);
@ -601,7 +604,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
assert(sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO); 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<NetEConst*> (wid_ex); NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
if (wid_ec == 0) { if (wid_ec == 0) {
cerr << lsb_->get_line() << ": error: " cerr << lsb_->get_line() << ": error: "
@ -613,7 +616,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
unsigned wid = wid_ec->value().as_ulong(); 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) { if (idx_ex == 0) {
return 0; return 0;
} }
@ -771,7 +774,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
/* Get and evaluate the width of the index /* Get and evaluate the width of the index
select. This must be constant. */ 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<NetEConst*> (wid_ex); NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
if (wid_ec == 0) { if (wid_ec == 0) {
cerr << lsb_->get_line() << ": error: " cerr << lsb_->get_line() << ": error: "
@ -783,7 +786,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
unsigned wid = wid_ec->value().as_ulong(); 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) { if (idx_ex == 0) {
return 0; return 0;
} }
@ -806,7 +809,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
/* Handle the case where a parameter has a bit /* Handle the case where a parameter has a bit
select attached to it. Generate a NetESelect select attached to it. Generate a NetESelect
object to select the bit as desired. */ 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<NetEConst*>(mtmp)) { if (! dynamic_cast<NetEConst*>(mtmp)) {
NetExpr*re = mtmp->eval_tree(); NetExpr*re = mtmp->eval_tree();
if (re) { if (re) {
@ -985,9 +988,9 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
NetESignal*sig = new NetESignal(net); NetESignal*sig = new NetESignal(net);
sig->set_line(*this); 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<NetEConst*> (wid_e); NetEConst*wid_c = dynamic_cast<NetEConst*> (wid_e);
if (wid_c == 0) { if (wid_c == 0) {
cerr << get_line() << ": error: Width of indexed part select " 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); NetESignal*sig = new NetESignal(net);
sig->set_line(*this); 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<NetEConst*> (wid_e); NetEConst*wid_c = dynamic_cast<NetEConst*> (wid_e);
if (wid_c == 0) { if (wid_c == 0) {
cerr << get_line() << ": error: Width of indexed part select " 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 // complicated task because we need to generate
// expressions to convert calculated bit select // expressions to convert calculated bit select
// values to canonical values that are used internally. // 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()) { if (net->msb() < net->lsb()) {
ex = make_sub_expr(net->lsb(), ex); ex = make_sub_expr(net->lsb(), ex);
@ -1181,7 +1184,8 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
return node; 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_); assert(value_);
NetEConst*tmp = new NetEConst(*value_); NetEConst*tmp = new NetEConst(*value_);
@ -1189,7 +1193,8 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const
return tmp; 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()); NetEConst*tmp = new NetEConst(value());
tmp->set_line(*this); 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 * parsed so I can presume that they exist, and call elaboration
* methods. If any elaboration fails, then give up and return 0. * 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(expr_);
assert(tru_); assert(tru_);
assert(fal_); assert(fal_);
NetExpr*con = expr_->elaborate_expr(des, scope); NetExpr*con = expr_->elaborate_expr(des, scope, -1, false);
if (con == 0) if (con == 0)
return 0; return 0;
NetExpr*tru = tru_->elaborate_expr(des, scope); NetExpr*tru = tru_->elaborate_expr(des, scope, expr_wid, false);
if (tru == 0) { if (tru == 0) {
delete con; delete con;
return 0; return 0;
} }
NetExpr*fal = fal_->elaborate_expr(des, scope); NetExpr*fal = fal_->elaborate_expr(des, scope, expr_wid, false);
if (fal == 0) { if (fal == 0) {
delete con; delete con;
delete tru; delete tru;
@ -1251,9 +1257,10 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, bool) const
return res; 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; if (ip == 0) return 0;
/* Should we evaluate expressions ahead of time, /* Should we evaluate expressions ahead of time,
@ -1269,16 +1276,22 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
case '-': case '-':
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) { if (NetEConst*ipc = dynamic_cast<NetEConst*>(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 /* When taking the - of a number, turn it into a
signed expression and extend it one bit to signed expression and extend it one bit to
accommodate a possible sign bit. */ accommodate a possible sign bit. */
verinum val = ipc->value();
verinum zero (verinum::V0, val.len()+1, val.has_len()); verinum zero (verinum::V0, val.len()+1, val.has_len());
val = zero - val; verinum nval = zero - val;
if (ipc->value().has_len())
val = verinum(val, ipc->value().len()); if (val.has_len())
val.has_sign(true); nval = verinum(nval, val.len());
tmp = new NetEConst(val); nval.has_sign(true);
tmp = new NetEConst(nval);
tmp->set_line(*this);
delete ip; delete ip;
} else if (NetECReal*ipc = dynamic_cast<NetECReal*>(ip)) { } else if (NetECReal*ipc = dynamic_cast<NetECReal*>(ip)) {
@ -1359,6 +1372,11 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
/* /*
* $Log: elab_expr.cc,v $ * $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 * Revision 1.104 2006/06/01 03:54:51 steve
* Fix broken subtraction of small constants. * Fix broken subtraction of small constants.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # include "config.h"
@ -216,7 +216,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
assert(idx_.size() == 1); assert(idx_.size() == 1);
verinum*v = idx_[0]->eval_const(des, scope); verinum*v = idx_[0]->eval_const(des, scope);
if (v == 0) { if (v == 0) {
NetExpr*m = idx_[0]->elaborate_expr(des, scope); NetExpr*m = idx_[0]->elaborate_expr(des, scope, -1, false);
assert(m); assert(m);
msb = 0; msb = 0;
lsb = 0; lsb = 0;
@ -310,7 +310,7 @@ NetAssign_* PEIdent::elaborate_lval_net_part_(Design*des,
two bit select expressions, and both must be two bit select expressions, and both must be
constant. Evaluate them and pass the results back to constant. Evaluate them and pass the results back to
the caller. */ 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<NetEConst*>(lsb_ex); NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
if (lsb_c == 0) { if (lsb_c == 0) {
cerr << lsb_->get_line() << ": error: " cerr << lsb_->get_line() << ": error: "
@ -322,7 +322,7 @@ NetAssign_* PEIdent::elaborate_lval_net_part_(Design*des,
return 0; 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<NetEConst*>(msb_ex); NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
if (msb_c == 0) { if (msb_c == 0) {
cerr << msb_->get_line() << ": error: " 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) /* Calculate the width expression (in the lsb_ position)
first. If the expression is not constant, error but guess 1 first. If the expression is not constant, error but guess 1
so we can keep going and find more errors. */ 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<NetEConst*>(wid_ex); NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
if (wid_c == 0) { 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; unsigned wid = wid_c? wid_c->value().as_ulong() : 1;
delete wid_ex; 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. */ /* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb()) if (reg->msb() < reg->lsb())
@ -468,7 +468,7 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
assert(idx_.size() == 1); assert(idx_.size() == 1);
/* Elaborate the address expression. */ /* 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) if (ix == 0)
return 0; return 0;
@ -485,8 +485,8 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
assert(msb_ && lsb_); assert(msb_ && lsb_);
if (sel_ == SEL_PART) { if (sel_ == SEL_PART) {
NetExpr*le = elab_and_eval(des, scope, lsb_); NetExpr*le = elab_and_eval(des, scope, lsb_, -1);
NetExpr*me = elab_and_eval(des, scope, msb_); NetExpr*me = elab_and_eval(des, scope, msb_, -1);
NetEConst*lec = dynamic_cast<NetEConst*>(le); NetEConst*lec = dynamic_cast<NetEConst*>(le);
NetEConst*mec = dynamic_cast<NetEConst*>(me); NetEConst*mec = dynamic_cast<NetEConst*>(me);
@ -509,7 +509,7 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
assert(sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO); 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<NetEConst*> (wid_ex); NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
if (wid_ec == 0) { if (wid_ec == 0) {
cerr << lsb_->get_line() << ": error: " 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(); 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) { if (base_ex == 0) {
return 0; return 0;
} }
@ -544,6 +544,11 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
/* /*
* $Log: elab_lval.cc,v $ * $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 * Revision 1.35 2006/04/16 00:54:04 steve
* Cleanup lval part select handling. * Cleanup lval part select handling.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # 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 (so that the eval_tree method can reduce constant
expressions, including parameters) then turn those results expressions, including parameters) then turn those results
into synthesized nets. */ into synthesized nets. */
NetExpr*lexp = elab_and_eval(des, scope, left_); NetExpr*lexp = elab_and_eval(des, scope, left_, lwidth);
if (lexp == 0) { if (lexp == 0) {
cerr << get_line() << ": error: Cannot elaborate "; cerr << get_line() << ": error: Cannot elaborate ";
left_->dump(cerr); left_->dump(cerr);
@ -482,7 +482,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
return 0; return 0;
} }
NetExpr*rexp = elab_and_eval(des, scope, right_); NetExpr*rexp = elab_and_eval(des, scope, right_, lwidth);
if (rexp == 0) { if (rexp == 0) {
cerr << get_line() << ": error: Cannot elaborate "; cerr << get_line() << ": error: Cannot elaborate ";
right_->dump(cerr); 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 constant. This is used to generate the width of the
concatenation. */ concatenation. */
if (repeat_) { if (repeat_) {
NetExpr*etmp = elab_and_eval(des, scope, repeat_); NetExpr*etmp = elab_and_eval(des, scope, repeat_, -1);
assert(etmp); assert(etmp);
NetEConst*erep = dynamic_cast<NetEConst*>(etmp); NetEConst*erep = dynamic_cast<NetEConst*>(etmp);
@ -1479,7 +1479,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
NetNet*sel; NetNet*sel;
if (sig->msb() < sig->lsb()) { 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); sel_expr = make_sub_expr(sig->lsb(), sel_expr);
if (NetExpr*tmp = sel_expr->eval_tree()) { if (NetExpr*tmp = sel_expr->eval_tree()) {
delete sel_expr; delete sel_expr;
@ -1489,7 +1489,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
sel = sel_expr->synthesize(des); sel = sel_expr->synthesize(des);
} else if (sig->lsb() != 0) { } 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()); sel_expr = make_add_expr(sel_expr, - sig->lsb());
if (NetExpr*tmp = sel_expr->eval_tree()) { if (NetExpr*tmp = sel_expr->eval_tree()) {
delete sel_expr; 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; const bool must_be_self_determined_save = must_be_self_determined_flag;
must_be_self_determined_flag = false; 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 /* If an offset is needed, subtract it from the address to get
an expression for the canonical address. */ an expression for the canonical address. */
@ -1925,7 +1925,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
assert(lsb_); assert(lsb_);
assert(idx_.empty()); 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<NetEConst*>(tmp_ex); NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp); assert(tmp);
@ -1933,7 +1933,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
midx = sig->sb_to_idx(midx_val); midx = sig->sb_to_idx(midx_val);
delete tmp_ex; delete tmp_ex;
tmp_ex = elab_and_eval(des, scope, lsb_); tmp_ex = elab_and_eval(des, scope, lsb_, -1);
tmp = dynamic_cast<NetEConst*>(tmp_ex); tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp); assert(tmp);
@ -1959,7 +1959,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
assert(lsb_); assert(lsb_);
assert(idx_.empty()); 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<NetEConst*>(tmp_ex); NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp); assert(tmp);
@ -1967,7 +1967,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
midx = sig->sb_to_idx(midx_val); midx = sig->sb_to_idx(midx_val);
delete tmp_ex; delete tmp_ex;
tmp_ex = elab_and_eval(des, scope, lsb_); tmp_ex = elab_and_eval(des, scope, lsb_, -1);
tmp = dynamic_cast<NetEConst*>(tmp_ex); tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp); assert(tmp);
@ -2779,6 +2779,11 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $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 * Revision 1.185 2006/05/19 04:44:55 steve
* Get self-determined unary - width right. * Get self-determined unary - width right.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # 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 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 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 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 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 $ * $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 * Revision 1.23 2006/02/02 02:43:58 steve
* Allow part selects of memory words in l-values. * Allow part selects of memory words in l-values.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # 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 // The initial value for the genvar does not need (nor can it
// use) the genvar itself, so we can evaluate this expression // use) the genvar itself, so we can evaluate this expression
// the same way any other paramter value is evaluated. // 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<NetEConst*> (init_ex); NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) { if (init == 0) {
cerr << get_line() << ": error: Cannot evaluate genvar" 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 = loop_index;
container->genvar_tmp_val = 0; 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<NetEConst*>(test_ex); NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
assert(test); assert(test);
while (test->value().as_long()) { while (test->value().as_long()) {
@ -379,7 +379,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
scope_list_.push_back(scope); scope_list_.push_back(scope);
// Calculate the step for the loop variable. // 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<NetEConst*>(step_ex); NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
assert(step); assert(step);
if (debug_elaborate) if (debug_elaborate)
@ -390,7 +390,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
container->genvar_tmp_val = genvar; container->genvar_tmp_val = genvar;
delete step; delete step;
delete test_ex; 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<NetEConst*>(test_ex); test = dynamic_cast<NetEConst*>(test_ex);
assert(test); assert(test);
} }
@ -448,8 +448,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
return; return;
} }
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_) : 0; NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_) : 0; NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
NetEConst*msb = dynamic_cast<NetEConst*> (mse); NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse); NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
@ -748,6 +748,11 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/* /*
* $Log: elab_scope.cc,v $ * $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 * Revision 1.40 2006/04/12 05:05:03 steve
* Use elab_and_eval to evaluate genvar expressions. * Use elab_and_eval to evaluate genvar expressions.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # include "config.h"
@ -318,10 +318,10 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
case PTF_REG: case PTF_REG:
if (return_type_.range) { if (return_type_.range) {
NetExpr*me = elab_and_eval(des, scope, NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0]); (*return_type_.range)[0], -1);
assert(me); assert(me);
NetExpr*le = elab_and_eval(des, scope, NetExpr*le = elab_and_eval(des, scope,
(*return_type_.range)[1]); (*return_type_.range)[1], -1);
assert(le); assert(le);
long mnum = 0, lnum = 0; long mnum = 0, lnum = 0;
@ -548,7 +548,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
} }
NetEConst*tmp; NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]); NetExpr*texpr = elab_and_eval(des, scope, msb_[idx], -1);
tmp = dynamic_cast<NetEConst*>(texpr); tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) { if (tmp == 0) {
@ -562,7 +562,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
mnum[idx] = tmp->value().as_long(); mnum[idx] = tmp->value().as_long();
delete texpr; delete texpr;
texpr = elab_and_eval(des, scope, lsb_[idx]); texpr = elab_and_eval(des, scope, lsb_[idx], -1);
tmp = dynamic_cast<NetEConst*>(texpr); tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) { if (tmp == 0) {
cerr << msb_[idx]->get_line() << ": error: " cerr << msb_[idx]->get_line() << ": error: "
@ -623,8 +623,8 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if (lidx_ || ridx_) { if (lidx_ || ridx_) {
assert(lidx_ && ridx_); assert(lidx_ && ridx_);
NetExpr*lexp = elab_and_eval(des, scope, lidx_); NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
NetExpr*rexp = elab_and_eval(des, scope, ridx_); NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
if ((lexp == 0) || (rexp == 0)) { if ((lexp == 0) || (rexp == 0)) {
cerr << get_line() << ": internal error: There is " 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 $ * $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 * Revision 1.41 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates. * Add support for generate loops w/ wires and gates.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # 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 gates, then I am expected to make more then one
gate. Figure out how many are desired. */ gate. Figure out how many are desired. */
if (msb_) { if (msb_) {
NetExpr*msb_exp = elab_and_eval(des, scope, msb_); NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_); NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp); NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp); NetEConst*lsb_con = dynamic_cast<NetEConst*>(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) 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 /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time 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. */ /* Elaborate the r-value expression, then try to evaluate it. */
assert(rval()); 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; if (rv == 0) return 0;
assert(rv); assert(rv);
@ -1530,7 +1530,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
assert(rval()); assert(rval());
/* Elaborate and precalculate the r-value. */ /* 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) if (rv == 0)
return 0; return 0;
@ -1638,7 +1638,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
NetExpr*expr = elab_and_eval(des, scope, expr_); NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
if (expr == 0) { if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate this case" cerr << get_line() << ": error: Unable to elaborate this case"
" expression." << endl; " expression." << endl;
@ -1690,7 +1690,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
NetExpr*gu = 0; NetExpr*gu = 0;
NetProc*st = 0; NetProc*st = 0;
assert(cur->expr[e]); 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) if (cur->stat)
st = cur->stat->elaborate(des, scope); st = cur->stat->elaborate(des, scope);
@ -1708,7 +1708,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
assert(scope); assert(scope);
// Elaborate and try to evaluate the conditional expression. // 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) { if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate" cerr << get_line() << ": error: Unable to elaborate"
" condition expression." << endl; " 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) { for (unsigned idx = 0 ; idx < parm_count ; idx += 1) {
PExpr*ex = parm(idx); 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 /* Attempt to pre-evaluate the parameters. It may be
possible to at least partially reduce the 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); NetAssign_*lv = new NetAssign_(port);
unsigned wid = count_lval_width(lv); 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->set_width(wid);
rv = pad_to_width(rv, wid); rv = pad_to_width(rv, wid);
NetAssign*pr = new NetAssign(lv, rv); NetAssign*pr = new NetAssign(lv, rv);
@ -2009,12 +2009,12 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
if (lval == 0) if (lval == 0)
return 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) if (rexp == 0)
return 0; return 0;
unsigned lwid = count_lval_width(lval);
rexp->set_width(lwid); rexp->set_width(lwid);
rexp = pad_to_width(rexp, 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 /* Elaborate wait expression. Don't eval yet, we will do that
shortly, after we apply a reduction or. */ 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) { if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate" cerr << get_line() << ": error: Unable to elaborate"
" wait condition expression." << endl; " wait condition expression." << endl;
@ -2537,12 +2537,12 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
if (lval == 0) if (lval == 0)
return 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) if (rexp == 0)
return 0; return 0;
unsigned lwid = count_lval_width(lval);
rexp->set_width(lwid, true); rexp->set_width(lwid, true);
rexp = pad_to_width(rexp, lwid); 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 /* Make the r-value of the initial assignment, and size it
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_); etmp = elab_and_eval(des, scope, expr1_, lv->lwidth());
etmp->set_width(lv->lwidth()); etmp->set_width(lv->lwidth());
etmp = pad_to_width(etmp, 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 /* Make the rvalue of the increment expression, and size it
for the lvalue. */ for the lvalue. */
etmp = expr2_->elaborate_expr(des, scope); etmp = expr2_->elaborate_expr(des, scope, lv->lwidth(), false);
etmp->set_width(lv->lwidth()); etmp->set_width(lv->lwidth());
NetAssign*step = new NetAssign(lv, etmp); NetAssign*step = new NetAssign(lv, etmp);
step->set_line(*this); 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, /* Elaborate the condition expression. Try to evaluate it too,
in case it is a constant. This is an interesting case in case it is a constant. This is an interesting case
worthy of a warning. */ worthy of a warning. */
NetExpr*ce = elab_and_eval(des, scope, cond_); NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
if (ce == 0) { if (ce == 0) {
delete top; delete top;
return 0; return 0;
@ -2735,7 +2735,7 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
NetExpr*expr = elab_and_eval(des, scope, expr_); NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
if (expr == 0) { if (expr == 0) {
cerr << get_line() << ": Unable to elaborate" cerr << get_line() << ": Unable to elaborate"
" repeat expression." << endl; " repeat expression." << endl;
@ -2856,7 +2856,7 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
*/ */
NetProc* PWhile::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)); statement_->elaborate(des, scope));
return loop; return loop;
} }
@ -3133,6 +3133,11 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $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 * Revision 1.339 2006/05/01 20:47:59 steve
* More explicit datatype setup. * More explicit datatype setup.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # include "config.h"
@ -123,9 +123,10 @@ NetExpr* make_sub_expr(long val, NetExpr*expr)
return res; 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) if (tmp == 0)
return 0; return 0;
@ -140,6 +141,11 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
/* /*
* $Log: netmisc.cc,v $ * $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 * Revision 1.11 2005/04/08 04:50:31 steve
* Don not give to make_add express an unwanted width. * Don not give to make_add express an unwanted width.
* *

View File

@ -19,7 +19,7 @@
* 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 #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 #endif
# include "netlist.h" # 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. * it can. If the expression cannot be elaborated, return 0.
*/ */
class PExpr; 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 $ * $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 * Revision 1.24 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges. * Handle bit select of parameter with ranges.
* *

View File

@ -17,7 +17,7 @@
* 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 #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 #endif
# include "config.h" # include "config.h"
@ -317,6 +317,30 @@ bool verinum::is_zero() const
return true; 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 * This function returns a version of the verinum that has only as
* many bits as are needed to accurately represent the value. It takes * 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 $ * $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 * Revision 1.45 2006/06/01 03:54:51 steve
* Fix broken subtraction of small constants. * Fix broken subtraction of small constants.
* *

View File

@ -19,7 +19,7 @@
* 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 #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 #endif
# include <string> # include <string>
@ -105,6 +105,11 @@ class verinum {
bool string_flag_; 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 /* Return a verinum that is minimal. That is, it has only the length
needed to accurately represent the contained value, signed or not. */ needed to accurately represent the contained value, signed or not. */
extern verinum trim_vnum(const verinum&); extern verinum trim_vnum(const verinum&);
@ -152,6 +157,11 @@ extern verinum v_not(const verinum&left);
/* /*
* $Log: verinum.h,v $ * $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 * Revision 1.29 2006/06/01 03:54:51 steve
* Fix broken subtraction of small constants. * Fix broken subtraction of small constants.
* *