Add test_width methods for PETernary and PEString.

This commit is contained in:
steve 2006-11-10 04:54:26 +00:00
parent c339dc4bbc
commit 34b5a31ff4
3 changed files with 63 additions and 3 deletions

13
PExpr.h
View File

@ -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.85 2006/11/04 06:19:24 steve Exp $"
#ident "$Id: PExpr.h,v 1.86 2006/11/10 04:54:26 steve Exp $"
#endif
# include <string>
@ -420,6 +420,10 @@ class PEString : public PExpr {
string value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
@ -583,6 +587,10 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
@ -642,6 +650,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.86 2006/11/10 04:54:26 steve
* Add test_width methods for PETernary and PEString.
*
* Revision 1.85 2006/11/04 06:19:24 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may

View File

@ -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.115 2006/11/04 06:19:24 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.116 2006/11/10 04:54:26 steve Exp $"
#endif
# include "config.h"
@ -1459,6 +1459,17 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*,
return tmp;
}
unsigned PEString::test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const
{
unsigned use_wid = text_? 8*strlen(text_) : 0;
if (min > use_wid)
use_wid = min;
return use_wid;
}
NetEConst* PEString::elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const
{
@ -1467,6 +1478,15 @@ NetEConst* PEString::elaborate_expr(Design*des, NetScope*,
return tmp;
}
unsigned PETernary::test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&flag) const
{
unsigned tru_wid = tru_->test_width(des, scope, min, lval, flag);
unsigned fal_wid = fal_->test_width(des, scope, min, lval, flag);
return max(tru_wid,fal_wid);
}
static bool test_ternary_operand_compat(ivl_variable_type_t l,
ivl_variable_type_t r)
{
@ -1492,6 +1512,18 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope,
assert(tru_);
assert(fal_);
if (expr_wid < 0) {
bool flag = false;
unsigned tru_wid = tru_->test_width(des, scope, 0, 0, flag);
unsigned fal_wid = fal_->test_width(des, scope, 0, 0, flag);
expr_wid = max(tru_wid, fal_wid);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Self-sized ternary chooses wid="<< expr_wid
<< " from " <<tru_wid
<< " and " << fal_wid << endl;
}
NetExpr*con = expr_->elaborate_expr(des, scope, -1, false);
if (con == 0)
return 0;
@ -1518,6 +1550,11 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
/* Whatever the width we choose for the ternary operator, we
need to make sure the operands match. */
tru = pad_to_width(tru, expr_wid);
fal = pad_to_width(fal, expr_wid);
NetETernary*res = new NetETernary(con, tru, fal);
res->set_line(*this);
return res;
@ -1638,6 +1675,9 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
/*
* $Log: elab_expr.cc,v $
* Revision 1.116 2006/11/10 04:54:26 steve
* Add test_width methods for PETernary and PEString.
*
* Revision 1.115 2006/11/04 06:19:24 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.cc,v 1.249 2006/09/23 04:57:19 steve Exp $"
#ident "$Id: netlist.cc,v 1.250 2006/11/10 04:54:26 steve Exp $"
#endif
# include "config.h"
@ -2180,6 +2180,12 @@ ivl_variable_type_t NetESignal::expr_type() const
return net_->data_type();
}
/*
* Make a ternary operator from all the sub-expressions. The condition
* expression is self-determined, but the true and false expressions
* should have the same width. NOTE: This matching of the widths really
* has to be done in elaboration.
*/
NetETernary::NetETernary(NetExpr*c, NetExpr*t, NetExpr*f)
: cond_(c), true_val_(t), false_val_(f)
{
@ -2336,6 +2342,9 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.250 2006/11/10 04:54:26 steve
* Add test_width methods for PETernary and PEString.
*
* Revision 1.249 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*