diff --git a/eval_tree.cc b/eval_tree.cc index 69a336555..ccf1eb1bf 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_tree.cc,v 1.74 2007/03/08 05:30:02 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.75 2007/04/07 04:46:18 steve Exp $" #endif # include "config.h" @@ -26,6 +26,7 @@ # include # include "netlist.h" +# include "ivl_assert.h" NetExpr* NetExpr::eval_tree(int prune_to_width) { @@ -51,9 +52,61 @@ void NetEBinary::eval_sub_tree_() } } -NetEConst* NetEBAdd::eval_tree(int prune_to_width) +bool NetEBinary::get_real_arguments_(verireal&lval, verireal&rval) +{ + switch (left_->expr_type()) { + case IVL_VT_REAL: { + NetECReal*lc = dynamic_cast (left_); + if (lc == 0) return false; + lval = lc->value(); + break; + } + + case IVL_VT_BOOL: + case IVL_VT_LOGIC: { + NetEConst*lc = dynamic_cast(left_); + if (lc == 0) return false; + verinum tmp = lc->value(); + lval = verireal(tmp.as_long()); + break; + } + + default: + assert(0); + } + + switch (right_->expr_type()) { + case IVL_VT_REAL: { + NetECReal*rc = dynamic_cast (right_); + if (rc == 0) return 0; + rval = rc->value(); + break; + } + + case IVL_VT_BOOL: + case IVL_VT_LOGIC: { + NetEConst*rc = dynamic_cast(right_); + if (rc == 0) return 0; + verinum tmp = rc->value(); + rval = verireal(tmp.as_long()); + break; + } + + default: + assert(0); + } + + + return true; +} + +NetExpr* NetEBAdd::eval_tree(int prune_to_width) { eval_sub_tree_(); + + if (left_->expr_type() == IVL_VT_REAL || right_->expr_type()==IVL_VT_REAL) + return eval_tree_real_(); + NetEConst*lc = dynamic_cast(left_); NetEConst*rc = dynamic_cast(right_); @@ -115,6 +168,31 @@ NetEConst* NetEBAdd::eval_tree(int prune_to_width) return 0; } +NetECReal* NetEBAdd::eval_tree_real_() +{ + verireal lval; + verireal rval; + bool flag = get_real_arguments_(lval, rval); + if (!flag) return 0; + + verireal res_val; + + switch (op()) { + case '+': + res_val = lval + rval; + break; + case '-': + res_val = lval - rval; + break; + default: + ivl_assert(*this, 0); + } + + NetECReal*res = new NetECReal( res_val ); + res->set_line(*this); + return res; +} + NetEConst* NetEBBits::eval_tree(int prune_to_width) { eval_sub_tree_(); @@ -864,52 +942,14 @@ NetEConst* NetEBLogic::eval_tree(int prune_to_width) return new NetEConst(verinum(res, 1)); } + NetExpr* NetEBMult::eval_tree_real_() { verireal lval; verireal rval; - switch (left_->expr_type()) { - case IVL_VT_REAL: { - NetECReal*lc = dynamic_cast (left_); - if (lc == 0) return 0; - lval = lc->value(); - break; - } - - case IVL_VT_BOOL: - case IVL_VT_LOGIC: { - NetEConst*lc = dynamic_cast(left_); - if (lc == 0) return 0; - verinum tmp = lc->value(); - lval = verireal(tmp.as_long()); - break; - } - - default: - assert(0); - } - - switch (right_->expr_type()) { - case IVL_VT_REAL: { - NetECReal*rc = dynamic_cast (right_); - if (rc == 0) return 0; - rval = rc->value(); - break; - } - - case IVL_VT_BOOL: - case IVL_VT_LOGIC: { - NetEConst*rc = dynamic_cast(right_); - if (rc == 0) return 0; - verinum tmp = rc->value(); - rval = verireal(tmp.as_long()); - break; - } - - default: - assert(0); - } + bool flag = get_real_arguments_(lval, rval); + if (! flag) return 0; NetECReal*res = new NetECReal(lval * rval); @@ -942,48 +982,8 @@ NetExpr* NetEBPow::eval_tree_real_() verireal lval; verireal rval; - switch (left_->expr_type()) { - case IVL_VT_REAL: { - NetECReal*lc = dynamic_cast (left_); - if (lc == 0) return 0; - lval = lc->value(); - break; - } - - case IVL_VT_BOOL: - case IVL_VT_LOGIC: { - NetEConst*lc = dynamic_cast(left_); - if (lc == 0) return 0; - verinum tmp = lc->value(); - lval = verireal(tmp.as_long()); - break; - } - - default: - assert(0); - } - - switch (right_->expr_type()) { - case IVL_VT_REAL: { - NetECReal*rc = dynamic_cast (right_); - if (rc == 0) return 0; - rval = rc->value(); - break; - } - - case IVL_VT_BOOL: - case IVL_VT_LOGIC: { - NetEConst*rc = dynamic_cast(right_); - if (rc == 0) return 0; - verinum tmp = rc->value(); - rval = verireal(tmp.as_long()); - break; - } - - default: - assert(0); - } - + bool flag = get_real_arguments_(lval, rval); + if (! flag) return 0; NetECReal*res = new NetECReal( pow(lval,rval) ); res->set_line(*this); @@ -1655,6 +1655,9 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width) /* * $Log: eval_tree.cc,v $ + * Revision 1.75 2007/04/07 04:46:18 steve + * Handle evaluate of addition of real valued constants. + * * Revision 1.74 2007/03/08 05:30:02 steve * Limit the calculated widths of constants. * diff --git a/netlist.h b/netlist.h index 1e8d5c601..d64d87aa2 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.h,v 1.375 2007/04/02 01:12:34 steve Exp $" +#ident "$Id: netlist.h,v 1.376 2007/04/07 04:46:18 steve Exp $" #endif /* @@ -2622,6 +2622,7 @@ class NetEBinary : public NetExpr { NetExpr* right_; void eval_sub_tree_(); + bool get_real_arguments_(verireal&lv, verireal&rv); }; /* @@ -2641,8 +2642,11 @@ class NetEBAdd : public NetEBinary { virtual bool set_width(unsigned w, bool last_chance); virtual NetEBAdd* dup_expr() const; - virtual NetEConst* eval_tree(int prune_to_width = -1); + virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetNet* synthesize(Design*); + + private: + NetECReal* eval_tree_real_(); }; /* @@ -3498,6 +3502,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.376 2007/04/07 04:46:18 steve + * Handle evaluate of addition of real valued constants. + * * Revision 1.375 2007/04/02 01:12:34 steve * Seperate arrayness from word count * diff --git a/verireal.cc b/verireal.cc index e88c8bd25..fd0292ea6 100644 --- a/verireal.cc +++ b/verireal.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verireal.cc,v 1.18 2006/10/03 05:06:00 steve Exp $" +#ident "$Id: verireal.cc,v 1.19 2007/04/07 04:46:18 steve Exp $" #endif # include "config.h" @@ -104,6 +104,20 @@ double verireal::as_double() const return value_; } +verireal operator+ (const verireal&l, const verireal&r) +{ + verireal res; + res.value_ = l.value_ + r.value_; + return res; +} + +verireal operator- (const verireal&l, const verireal&r) +{ + verireal res; + res.value_ = l.value_ - r.value_; + return res; +} + verireal operator* (const verireal&l, const verireal&r) { verireal res; @@ -161,6 +175,9 @@ ostream& operator<< (ostream&out, const verireal&v) /* * $Log: verireal.cc,v $ + * Revision 1.19 2007/04/07 04:46:18 steve + * Handle evaluate of addition of real valued constants. + * * Revision 1.18 2006/10/03 05:06:00 steve * Support real valued specify delays, properly scaled. * diff --git a/verireal.h b/verireal.h index 159b4492f..51fccb086 100644 --- a/verireal.h +++ b/verireal.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verireal.h,v 1.15 2007/02/02 04:33:01 steve Exp $" +#ident "$Id: verireal.h,v 1.16 2007/04/07 04:46:19 steve Exp $" #endif # include "config.h" @@ -43,6 +43,8 @@ class verinum; class verireal { friend ostream& operator<< (ostream&, const verireal&); + friend verireal operator+ (const verireal&, const verireal&); + friend verireal operator- (const verireal&, const verireal&); friend verireal operator* (const verireal&, const verireal&); friend verireal operator/ (const verireal&, const verireal&); friend verireal operator/ (const verireal&, const verinum&); @@ -85,6 +87,9 @@ extern verireal operator- (const verireal&); /* * $Log: verireal.h,v $ + * Revision 1.16 2007/04/07 04:46:19 steve + * Handle evaluate of addition of real valued constants. + * * Revision 1.15 2007/02/02 04:33:01 steve * Use inttypes.h instead of stdint.h for portability. *