summaryrefslogtreecommitdiff
path: root/frontends/ast
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-11-07 14:08:53 +0100
committerClifford Wolf <clifford@clifford.at>2013-11-07 14:08:53 +0100
commit83a8b8b5caa9f0c3455715f78ff4f3bedab437f5 (patch)
treedf761157f0e72f1b8a37752c7700ce0dabbff0a5 /frontends/ast
parent90300cbacc756b7ebacd41faf28d57180c20bb8c (diff)
Fixed const folding in corner cases with parameters
Diffstat (limited to 'frontends/ast')
-rw-r--r--frontends/ast/genrtlil.cc11
-rw-r--r--frontends/ast/simplify.cc30
2 files changed, 27 insertions, 14 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 58f1b54b..e901a3b5 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -593,10 +593,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
if (id_ast->type == AST_AUTOWIRE)
this_width = 1;
else {
- current_ast_mod->dumpAst(stdout, "");
- printf("---\n");
- dumpAst(stdout, "");
- fflush(stdout);
+ // current_ast_mod->dumpAst(stdout, "");
+ // printf("---\n");
+ // dumpAst(stdout, "");
+ // fflush(stdout);
log_error("Failed to detect with of signal access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum);
}
} else {
@@ -900,6 +900,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
current_module->wires[str] = wire;
}
else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) {
+ if (id2ast->children[0]->type != AST_CONSTANT)
+ log_error("Parameter %s does not evaluate to constant value at %s:%d!\n",
+ str.c_str(), filename.c_str(), linenum);
chunk = RTLIL::Const(id2ast->children[0]->bits);
goto use_const_chunk;
}
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 1bdd6862..132a59f2 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -199,6 +199,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
case AST_PARAMETER:
case AST_LOCALPARAM:
+ while (children[0]->simplify(false, false, false, stage, -1, false) == true) { }
children[0]->detectSignWidth(width_hint, sign_hint);
if (children.size() > 1) {
assert(children[1]->type == AST_RANGE);
@@ -309,6 +310,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
bool sign_hint_here = sign_hint;
if (i == 0 && type == AST_REPLICATE)
const_fold_here = true;
+ if (type == AST_PARAMETER || type == AST_LOCALPARAM)
+ const_fold_here = true;
if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
in_lvalue_here = true;
if (type == AST_BLOCK) {
@@ -375,7 +378,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
// resolve constant prefixes
if (type == AST_PREFIX) {
if (children[0]->type != AST_CONSTANT) {
- dumpAst(NULL, "> ");
+ // dumpAst(NULL, "> ");
log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum);
}
assert(children[1]->type == AST_IDENTIFIER);
@@ -593,8 +596,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
AstNode *buf = children[0]->clone();
while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
if (buf->type != AST_CONSTANT) {
- for (auto f : log_files)
- dumpAst(f, "verilog-ast> ");
+ // for (auto f : log_files)
+ // dumpAst(f, "verilog-ast> ");
log_error("Condition for generate if at %s:%d is not constant!\n", filename.c_str(), linenum);
}
if (buf->integer != 0) {
@@ -954,16 +957,16 @@ skip_dynamic_range_lvalue_expansion:;
{
case AST_IDENTIFIER:
if (current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) {
- if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
- if (current_scope[str]->children[0]->type == AST_CONSTANT) {
+ if (current_scope[str]->children[0]->type == AST_CONSTANT) {
+ if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
std::vector<RTLIL::State> data;
for (int i = children[0]->range_right; i <= children[0]->range_left; i++)
data.push_back(current_scope[str]->children[0]->bits[i]);
newNode = mkconst_bits(data, false);
- }
- } else
- if (children.size() == 0)
- newNode = current_scope[str]->children[0]->clone();
+ } else
+ if (children.size() == 0)
+ newNode = current_scope[str]->children[0]->clone();
+ }
}
else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
newNode = mkconst_int(0, sign_hint, width_hint);
@@ -1067,7 +1070,14 @@ skip_dynamic_range_lvalue_expansion:;
goto not_const;
tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
}
- newNode = mkconst_bits(tmp_bits, is_signed);
+ newNode = mkconst_bits(tmp_bits, false);
+ break;
+ case AST_REPLICATE:
+ if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT)
+ goto not_const;
+ for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
+ tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
+ newNode = mkconst_bits(tmp_bits, false);
break;
default:
not_const: