From 076182c34e34b5e59eb5d89d5001f7547102bb4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 25 Jun 2014 10:05:36 +0200 Subject: [PATCH] Fixed handling of mixed real/int ternary expressions --- frontends/ast/simplify.cc | 16 ++++++++++++++++ tests/simple/realexpr.v | 9 ++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 0b0e46f2c..db7f5ca34 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -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); diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 2adffe2dd..5b756e6be 100644 --- a/tests/simple/realexpr.v +++ b/tests/simple/realexpr.v @@ -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 -- 2.30.2