diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-11-07 09:58:15 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-11-07 10:02:11 +0100 |
commit | f050c405190c50d2c1aed22644a9a207445e6592 (patch) | |
tree | 359ea7c98170c004095e7773e659ce4d74631255 /frontends/ast/simplify.cc | |
parent | 160adccca2cc8f81c2937cab03280603aaafb391 (diff) | |
download | yosys-f050c405190c50d2c1aed22644a9a207445e6592.tar.gz yosys-f050c405190c50d2c1aed22644a9a207445e6592.tar.bz2 yosys-f050c405190c50d2c1aed22644a9a207445e6592.zip |
Various fixes for correct parameter support
Diffstat (limited to 'frontends/ast/simplify.cc')
-rw-r--r-- | frontends/ast/simplify.cc | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 81812a40f..d34960481 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -197,6 +197,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, child_0_is_self_determined = true; break; + case AST_PARAMETER: + case AST_LOCALPARAM: + children[0]->detectSignWidth(width_hint, sign_hint); + if (children.size() > 1) { + assert(children[1]->type == AST_RANGE); + while (children[1]->simplify(false, false, false, stage, -1, false) == true) { } + if (!children[1]->range_valid) + log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); + width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1); + } + break; + case AST_TO_SIGNED: case AST_TO_UNSIGNED: case AST_CONCAT: @@ -419,6 +431,19 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } + // trim/extend parameters + if ((type == AST_PARAMETER || type == AST_LOCALPARAM) && children[0]->type == AST_CONSTANT && children.size() > 1) { + if (!children[1]->range_valid) + log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); + int width = children[1]->range_left - children[1]->range_right + 1; + if (width != int(children[0]->bits.size())) { + RTLIL::SigSpec sig(children[0]->bits); + sig.extend(width, children[0]->is_signed); + delete children[0]; + children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed); + } + } + // annotate identifiers using scope resolution and create auto-wires as needed if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { |