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)) {
     }