Merge pull request #471 from antmicro/kr/fix_param_const_simplify
systemverilog-plugin: fix calculate parameter value that requires extended simplify
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index a3484d6..e52d75d 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -137,6 +137,8 @@
node->children.clear();
}
+static void simplify(AST::AstNode *current_node, AST::AstNode *parent_node);
+
static void sanitize_symbol_name(std::string &name)
{
if (!name.empty()) {
@@ -274,17 +276,21 @@
if (ranges[i]->children.size() == 1) {
ranges[i]->children.push_back(ranges[i]->children[0]->clone());
}
+ simplify(ranges[i], wire_node);
while (ranges[i]->simplify(true, false, false, 1, -1, false, false)) {
}
// this workaround case, where yosys doesn't follow id2ast and simplifies it to resolve constant
if (ranges[i]->children[0]->id2ast) {
+ simplify(ranges[i]->children[0]->id2ast, ranges[i]->children[0]);
while (ranges[i]->children[0]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
}
}
if (ranges[i]->children[1]->id2ast) {
+ simplify(ranges[i]->children[1]->id2ast, ranges[i]->children[1]);
while (ranges[i]->children[1]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
}
}
+ simplify(ranges[i], wire_node);
while (ranges[i]->simplify(true, false, false, 1, -1, false, false)) {
}
log_assert(ranges[i]->children[0]->type == AST::AST_CONSTANT);
@@ -1901,7 +1907,31 @@
});
}
// first apply custom simplification step if needed
- simplify(parameter, nullptr);
+ simplify(parameter, module_node);
+ // workaround for yosys sometimes not simplifying parameters children
+ // parameters can have 2 children:
+ // first child should be parameter value
+ // second child should be parameter range (optional)
+ log_assert(!parameter->children.empty());
+ simplify(parameter->children[0], parameter);
+ while (parameter->children[0]->simplify(true, false, false, 1, -1, false, false)) {
+ }
+ // follow id2ast as yosys doesn't do it by default
+ if (parameter->children[0]->id2ast) {
+ simplify(parameter->children[0]->id2ast, parameter);
+ while (parameter->children[0]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
+ }
+ }
+ if (parameter->children.size() > 1) {
+ simplify(parameter->children[1], parameter);
+ while (parameter->children[1]->simplify(true, false, false, 1, -1, false, false)) {
+ }
+ if (parameter->children[1]->id2ast) {
+ simplify(parameter->children[1]->id2ast, parameter);
+ while (parameter->children[1]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
+ }
+ }
+ }
// then simplify parameter to AST_CONSTANT or AST_REALVALUE
while (parameter->simplify(true, false, false, 1, -1, false, false)) {
}