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:
parent
53ae1f29c9
commit
71faebd6df
|
|
@ -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<PExpr*>*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.
|
||||
*
|
||||
|
|
|
|||
35
PExpr.h
35
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 <string>
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
106
elab_expr.cc
106
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<NetEConst*>(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<NetEConst*>(le);
|
||||
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);
|
||||
|
||||
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);
|
||||
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<NetEConst*> (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<NetEConst*>(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<NetEConst*> (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<NetEConst*> (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<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
|
||||
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<NetECReal*>(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.
|
||||
*
|
||||
|
|
|
|||
27
elab_lval.cc
27
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<NetEConst*>(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<NetEConst*>(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<NetEConst*>(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<NetEConst*>(le);
|
||||
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);
|
||||
|
||||
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);
|
||||
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.
|
||||
*
|
||||
|
|
|
|||
27
elab_net.cc
27
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<NetEConst*>(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<NetEConst*>(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<NetEConst*>(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<NetEConst*>(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<NetEConst*>(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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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<NetEConst*> (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<NetEConst*>(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<NetEConst*>(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<NetEConst*>(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<NetEConst*> (mse);
|
||||
NetEConst*lsb = dynamic_cast<NetEConst*> (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.
|
||||
*
|
||||
|
|
|
|||
19
elab_sig.cc
19
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<NetEConst*>(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<NetEConst*>(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.
|
||||
*
|
||||
|
|
|
|||
51
elaborate.cc
51
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<NetEConst*>(msb_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)
|
||||
{
|
||||
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(list<perm_string>roots)
|
|||
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
|
|
|
|||
12
netmisc.cc
12
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.
|
||||
*
|
||||
|
|
|
|||
10
netmisc.h
10
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.
|
||||
*
|
||||
|
|
|
|||
31
verinum.cc
31
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.
|
||||
*
|
||||
|
|
|
|||
12
verinum.h
12
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 <string>
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue