Fixed handling of mixed real/int ternary expressions
authorClifford Wolf <clifford@clifford.at>
Wed, 25 Jun 2014 08:05:36 +0000 (10:05 +0200)
committerClifford Wolf <clifford@clifford.at>
Wed, 25 Jun 2014 08:05:36 +0000 (10:05 +0200)
frontends/ast/simplify.cc
tests/simple/realexpr.v

index 0b0e46f2c77da4433badf971225fd9715a1a5550..db7f5ca3448f68a71f236142975d11d5e1b2fd8b 100644 (file)
@@ -247,6 +247,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
        bool detect_width_simple = false;
        bool child_0_is_self_determined = false;
        bool child_1_is_self_determined = false;
+       bool child_2_is_self_determined = false;
        bool children_are_self_determined = false;
        bool reset_width_after_children = false;
 
@@ -367,6 +368,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                detectSignWidth(width_hint, sign_hint);
        }
 
+       if (type == AST_TERNARY) {
+               int width_hint_left, width_hint_right;
+               bool sign_hint_left, sign_hint_right;
+               bool found_real_left, found_real_right;
+               children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
+               children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
+               if (found_real_left || found_real_right) {
+                       child_1_is_self_determined = true;
+                       child_2_is_self_determined = true;
+               }
+       }
+
        // simplify all children first
        // (iterate by index as e.g. auto wires can add new children in the process)
        for (size_t i = 0; i < children.size(); i++) {
@@ -402,6 +415,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                                width_hint_here = -1, sign_hint_here = false;
                        if (i == 1 && child_1_is_self_determined)
                                width_hint_here = -1, sign_hint_here = false;
+                       if (i == 2 && child_2_is_self_determined)
+                               width_hint_here = -1, sign_hint_here = false;
                        if (children_are_self_determined)
                                width_hint_here = -1, sign_hint_here = false;
                        did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here);
@@ -1620,6 +1635,7 @@ skip_dynamic_range_lvalue_expansion:;
                                                not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real);
                                                if (other_real) {
                                                        newNode = new AstNode(AST_REALVALUE);
+                                                       choice->detectSignWidth(width_hint, sign_hint);
                                                        newNode->realvalue = choice->asReal(sign_hint);
                                                } else {
                                                        RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
index 2adffe2dd2f09771c161769d6730d26ba5d7450b..5b756e6be9036acab8da3227d74a405ed9797afd 100644 (file)
@@ -13,9 +13,12 @@ module demo_001(y1, y2, y3, y4);
        assign y4 = p4 + 0.2;
 endmodule
 
-module demo_002(y1);
-       output [3:0] y1;
+module demo_002(y0, y1, y2, y3);
+       output [63:0] y0, y1, y2, y3;
 
-       assign y1 = 1'bx >= (-1 * -1.17);
+       assign y0 = 1'bx >= (-1 * -1.17);
+       assign y1 = 1 ?  1 ?  -1 : 'd0 : 0.0;
+       assign y2 = 1 ? -1 :   1 ? 'd0 : 0.0;
+       assign y3 = 1 ? -1 : 'd0;
 endmodule