diff --git a/eval_tree.cc b/eval_tree.cc index e531b7dfd..f1ff325b6 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 */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: eval_tree.cc,v 1.11 2000/07/07 04:53:54 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.12 2000/09/27 18:28:37 steve Exp $" #endif # include "netlist.h" @@ -147,7 +147,16 @@ NetEConst* NetEBLogic::eval_tree() NetEConst* NetEBMult::eval_tree() { eval_sub_tree_(); - return 0; + + NetEConst*lc = dynamic_cast(left_); + if (lc == 0) return 0; + NetEConst*rc = dynamic_cast(right_); + if (rc == 0) return 0; + + verinum lval = lc->value(); + verinum rval = rc->value(); + + return new NetEConst(lval * rval); } /* @@ -317,6 +326,9 @@ NetEConst* NetEUnary::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.12 2000/09/27 18:28:37 steve + * multiply in parameter expressions. + * * Revision 1.11 2000/07/07 04:53:54 steve * Add support for non-constant delays in delay statements, * Support evaluating ! in constant expressions, and diff --git a/verinum.cc b/verinum.cc index 2ab7b754f..2a350f715 100644 --- a/verinum.cc +++ b/verinum.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: verinum.cc,v 1.18 2000/09/07 22:37:10 steve Exp $" +#ident "$Id: verinum.cc,v 1.19 2000/09/27 18:28:37 steve Exp $" #endif # include "verinum.h" @@ -481,8 +481,49 @@ verinum operator - (const verinum&left, const verinum&r) return val; } +/* + * This multiplies two verinum numbers together into a verinum + * result. The resulting number is as large as the sum of the sizes of + * the operand. + * + * The algorithm used is sucessive shift and add operations, + * implemented as the nested loops. + * + * If either value is not completely defined, then the result is not + * defined either. + */ +verinum operator * (const verinum&left, const verinum&right) +{ + if (! (left.is_defined() && right.is_defined())) { + verinum result (verinum::Vx, left.len() + right.len()); + result.has_sign(left.has_sign() || right.has_sign()); + return result; + } + + verinum result(verinum::V0, left.len() + right.len()); + + for (unsigned rdx = 0 ; rdx < right.len() ; rdx += 1) { + + if (right.get(rdx) == verinum::V0) + continue; + + verinum::V carry = verinum::V0; + for (unsigned ldx = 0 ; ldx < left.len() ; ldx += 1) { + result.set(ldx+rdx, add_with_carry(left[ldx], + result[rdx+ldx], + carry)); + } + } + + result.has_sign(left.has_sign() || right.has_sign()); + return result; +} + /* * $Log: verinum.cc,v $ + * Revision 1.19 2000/09/27 18:28:37 steve + * multiply in parameter expressions. + * * Revision 1.18 2000/09/07 22:37:10 steve * The + operator now preserves signedness. * diff --git a/verinum.h b/verinum.h index 93e181781..26a941e04 100644 --- a/verinum.h +++ b/verinum.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: verinum.h,v 1.11 2000/02/23 04:43:43 steve Exp $" +#ident "$Id: verinum.h,v 1.12 2000/09/27 18:28:37 steve Exp $" #endif # include @@ -101,11 +101,16 @@ extern verinum::V operator == (const verinum&left, const verinum&right); extern verinum::V operator <= (const verinum&left, const verinum&right); extern verinum operator + (const verinum&left, const verinum&right); extern verinum operator - (const verinum&left, const verinum&right); +extern verinum operator * (const verinum&left, const verinum&right); +extern verinum operator / (const verinum&left, const verinum&right); extern verinum v_not(const verinum&left); /* * $Log: verinum.h,v $ + * Revision 1.12 2000/09/27 18:28:37 steve + * multiply in parameter expressions. + * * Revision 1.11 2000/02/23 04:43:43 steve * Some compilers do not accept the not symbol. *