From 4892e93a093726bf986ad2d261cf53593354c0c8 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 15 Nov 2008 21:42:02 -0800 Subject: [PATCH] Fix special case that one of the arguments of a compare is a real expression. If one of the arguments of a comparison expression has a real value, then the expression with is 1 no matter the width of the other argument. This means that the arguments may have different widths in this special case. Patch is from pr2251119, suggested by Martin Whitaker. --- elab_expr.cc | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 5240f2b42..e4c998ff5 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -749,20 +749,26 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope, left_width = left_->test_width(des, scope, 0, 0, left_type, unsized_flag); /* Width of operands is self-determined. */ - int use_wid = left_width; - if (right_width > left_width) - use_wid = right_width; + + int use_wid_l = left_width; + if (type_is_vectorable(left_type) && (right_width > left_width)) + use_wid_l = right_width; + + int use_wid_r = right_width; + if (type_is_vectorable(right_type) && (left_width > right_width)) + use_wid_r = left_width; if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Comparison expression operands are " << left_width << " bits and " << right_width << " bits. Resorting to " - << use_wid << " bits." << endl; + << use_wid_l << " bits and " + << use_wid_r << " bits." << endl; } - NetExpr*lp = left_->elaborate_expr(des, scope, use_wid, false); - NetExpr*rp = right_->elaborate_expr(des, scope, use_wid, false); + NetExpr*lp = left_->elaborate_expr(des, scope, use_wid_l, false); + NetExpr*rp = right_->elaborate_expr(des, scope, use_wid_r, false); if ((lp == 0) || (rp == 0)) { delete lp; delete rp; @@ -775,12 +781,12 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope, // pad the width here. This matters because if the arguments // are signed, then this padding will do sign extension. if (type_is_vectorable(lp->expr_type())) - lp = pad_to_width(lp, use_wid); + lp = pad_to_width(lp, use_wid_l); if (type_is_vectorable(rp->expr_type())) - rp = pad_to_width(rp, use_wid); + rp = pad_to_width(rp, use_wid_r); - eval_expr(lp, use_wid); - eval_expr(rp, use_wid); + eval_expr(lp, use_wid_l); + eval_expr(rp, use_wid_r); // Handle some operand-specific special cases... switch (op_) {