diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-07-09 23:41:28 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-07-09 23:41:43 +0200 |
commit | 5dab327b30cb1d864297b22a15f0fce4b374a841 (patch) | |
tree | 6d4bcc104fab5ecd4dd51bae0459ea0144063c27 /frontends | |
parent | 618b2ac994360de4ffc9299aecb104a5bf5ba721 (diff) | |
download | yosys-5dab327b30cb1d864297b22a15f0fce4b374a841.tar.gz yosys-5dab327b30cb1d864297b22a15f0fce4b374a841.tar.bz2 yosys-5dab327b30cb1d864297b22a15f0fce4b374a841.zip |
More fixes in ast expression sign/width handling
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/genrtlil.cc | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 39f6e90ef..830778227 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -530,7 +530,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_TO_UNSIGNED: - children.at(0)->detectSignWidthWorker(width_hint, sign_hint); + children.at(0)->detectSignWidthWorker(width_hint, dummy_sign_hint); sign_hint = false; break; @@ -593,8 +593,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) case AST_LOGIC_AND: case AST_LOGIC_OR: case AST_LOGIC_NOT: - for (auto child : children) - child->detectSignWidthWorker(width_hint, sign_hint); + width_hint = std::max(width_hint, 1); + sign_hint = false; break; case AST_TERNARY: @@ -835,7 +835,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // just pass thru the signal. the parent will evaluated the is_signed property and inperpret the SigSpec accordingly case AST_TO_SIGNED: case AST_TO_UNSIGNED: { - RTLIL::SigSpec sig = children[0]->genRTLIL(width_hint, sign_hint); + RTLIL::SigSpec sig = children[0]->genRTLIL(); is_signed = type == AST_TO_SIGNED; return sig; } @@ -889,6 +889,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (0) { case AST_BIT_XOR: type_name = "$xor"; } if (0) { case AST_BIT_XNOR: type_name = "$xnor"; } { + if (width_hint < 0) + detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); int width = std::max(left.width, right.width); @@ -965,12 +967,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (width > width_hint && width_hint > 0) width = width_hint; if (width < width_hint) { - if (type == AST_ADD || type == AST_SUB) { + if (type == AST_ADD || type == AST_SUB) width++; - if (width < width_hint && children[0]->is_signed != children[1]->is_signed) - width++; - } - if (type == AST_SUB && !children[0]->is_signed && !children[1]->is_signed) + if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed)) width = width_hint; if (type == AST_MUL) width = std::min(left.width + right.width, width_hint); |