diff --git a/eval.cc b/eval.cc index 58fca4a9a..39f103317 100644 --- a/eval.cc +++ b/eval.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.cc,v 1.18 2001/01/14 23:04:56 steve Exp $" +#ident "$Id: eval.cc,v 1.19 2001/01/27 05:41:48 steve Exp $" #endif # include "PExpr.h" @@ -173,9 +173,18 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const case '+': return val; - case '-': - *val = v_not(*val) + verinum(verinum::V1, 1); - return val; + case '-': { + /* We need to expand the value a bit if we are + taking the 2's complement so that we are + guaranteed to not overflow. */ + verinum tmp (0UL, val->len()+1); + for (unsigned idx = 0 ; idx < val->len() ; idx += 1) + tmp.set(idx, val->get(idx)); + + *val = v_not(tmp) + verinum(verinum::V1, 1); + val->has_sign(true); + return val; + } } delete val; @@ -185,6 +194,9 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const /* * $Log: eval.cc,v $ + * Revision 1.19 2001/01/27 05:41:48 steve + * Fix sign extension of evaluated constants. (PR#91) + * * Revision 1.18 2001/01/14 23:04:56 steve * Generalize the evaluation of floating point delays, and * get it working with delay assignment statements. diff --git a/set_width.cc b/set_width.cc index 23e93b52f..5a7a44a9c 100644 --- a/set_width.cc +++ b/set_width.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: set_width.cc,v 1.14 2000/06/18 03:29:52 steve Exp $" +#ident "$Id: set_width.cc,v 1.15 2001/01/27 05:41:48 steve Exp $" #endif /* @@ -201,9 +201,15 @@ bool NetEConcat::set_width(unsigned w) bool NetEConst::set_width(unsigned w) { if (w > value_.len()) { + verinum::V pad = verinum::V0; + if (value_.has_sign()) + pad = value_.get(value_.len()-1); + verinum tmp (verinum::V0, w); for (unsigned idx = 0 ; idx < value_.len() ; idx += 1) tmp.set(idx, value_[idx]); + for (unsigned idx = value_.len() ; idx < w ; idx += 1) + tmp.set(idx, pad); value_ = tmp; @@ -307,6 +313,9 @@ bool NetEUnary::set_width(unsigned w) /* * $Log: set_width.cc,v $ + * Revision 1.15 2001/01/27 05:41:48 steve + * Fix sign extension of evaluated constants. (PR#91) + * * Revision 1.14 2000/06/18 03:29:52 steve * Handle width expansion of shift operators. *