From 34b5a31ff46447dac019bcdde206bfeef4666432 Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 10 Nov 2006 04:54:26 +0000 Subject: [PATCH] Add test_width methods for PETernary and PEString. --- PExpr.h | 13 ++++++++++++- elab_expr.cc | 42 +++++++++++++++++++++++++++++++++++++++++- netlist.cc | 11 ++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/PExpr.h b/PExpr.h index 625db825d..8b3fb080c 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.h,v 1.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 @@ -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 diff --git a/elab_expr.cc b/elab_expr.cc index 9eda46210..fa67d03b1 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_expr.cc,v 1.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 " <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 diff --git a/netlist.cc b/netlist.cc index 73fff0753..5ada350b5 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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. *