Added support for $clog2 system function
authorClifford Wolf <clifford@clifford.at>
Wed, 4 Dec 2013 20:19:54 +0000 (21:19 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 4 Dec 2013 20:19:54 +0000 (21:19 +0100)
frontends/ast/simplify.cc

index ae2f0caaec1f6ff14ebd9152398ab65981862360..94b588f257a26e5e61448237ce4dfd589841acb8 100644 (file)
@@ -1052,11 +1052,27 @@ skip_dynamic_range_lvalue_expansion:;
        // replace function and task calls with the code from the function or task
        if ((type == AST_FCALL || type == AST_TCALL) && !str.empty())
        {
-               if (type == AST_FCALL) {
-                       if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) {
-                               current_ast_mod->dumpAst(stderr, "> ");
-                               log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
+               if (type == AST_FCALL)
+               {
+                       if (str == "\\$clog2")
+                       {
+                               AstNode *buf = children[0]->clone();
+                               while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
+                               if (!buf->type == AST_CONSTANT)
+                                       log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
+
+                               RTLIL::Const arg_value = buf->bitsAsConst();
+                               uint32_t result = 0;
+                               for (size_t i = 0; i < arg_value.bits.size(); i++)
+                                       if (arg_value.bits.at(i) == RTLIL::State::S1)
+                                               result = i;
+
+                               newNode = mkconst_int(result, false);
+                               goto apply_newNode;
                        }
+
+                       if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
+                               log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
                }
                if (type == AST_TCALL) {
                        if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)