Add "noblackbox" attribute
authorClifford Wolf <clifford@clifford.at>
Sun, 21 Apr 2019 09:40:09 +0000 (11:40 +0200)
committerClifford Wolf <clifford@clifford.at>
Sun, 21 Apr 2019 09:40:09 +0000 (11:40 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
README.md
frontends/ast/ast.cc

index 7f90cb3c21d563a21306bd0bcb172d20f1d58ad3..fd45b54704f877f8b36146b39b7624123580ddfe 100644 (file)
--- a/README.md
+++ b/README.md
@@ -310,7 +310,12 @@ Verilog Attributes and non-standard features
   that have the same ports as the real thing but do not contain information
   on the internal configuration. This modules are only used by the synthesis
   passes to identify input and output ports of cells. The Verilog backend
-  also does not output blackbox modules on default.
+  also does not output blackbox modules on default. ``read_verilog``, unless
+  called with ``-noblackbox`` will automatically set the blackbox attribute
+  on any empty module it reads.
+
+- The ``noblackbox`` attribute set on an empty module prevents ``read_verilog``
+  from automatically setting the blackbox attribute on the module.
 
 - The ``whitebox`` attribute on modules triggers the same behavior as
   ``blackbox``, but is for whitebox modules, i.e. library modules that
index e4f18a2acbe23a8f9df50b3b032a70d4cdcb7a2a..9f88b08c1243d5fb82f6c777c4285c99df70c161 100644 (file)
@@ -942,6 +942,20 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
 
        if (!defer)
        {
+               bool blackbox_module = flag_lib;
+
+               if (!blackbox_module && !flag_noblackbox) {
+                       blackbox_module = true;
+                       for (auto child : ast->children) {
+                               if (child->type == AST_WIRE && (child->is_input || child->is_output))
+                                       continue;
+                               if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
+                                       continue;
+                               blackbox_module = false;
+                               break;
+                       }
+               }
+
                while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { }
 
                if (flag_dump_ast2) {
@@ -976,35 +990,31 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
                        }
                }
 
-               bool blackbox_module = flag_lib;
-
                if (!blackbox_module && ast->attributes.count("\\blackbox")) {
                        AstNode *n = ast->attributes.at("\\blackbox");
                        if (n->type != AST_CONSTANT)
-                               log_file_error(ast->filename, ast->linenum, "Blackbox attribute with non-constant value!\n");
+                               log_file_error(ast->filename, ast->linenum, "Got blackbox attribute with non-constant value!\n");
                        blackbox_module = n->asBool();
                }
 
-               if (!blackbox_module && !flag_noblackbox)
-               {
-                       for (auto child : ast->children) {
-                               if (child->type == AST_WIRE && (child->is_input || child->is_output))
-                                       continue;
-                               if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
-                                       continue;
-                               goto noblackbox;
-                       }
-                       blackbox_module = 1;
-               }
-
-       noblackbox:
                if (blackbox_module && ast->attributes.count("\\whitebox")) {
                        AstNode *n = ast->attributes.at("\\whitebox");
                        if (n->type != AST_CONSTANT)
-                               log_file_error(ast->filename, ast->linenum, "Whitebox attribute with non-constant value!\n");
+                               log_file_error(ast->filename, ast->linenum, "Got whitebox attribute with non-constant value!\n");
                        blackbox_module = !n->asBool();
                }
 
+               if (ast->attributes.count("\\noblackbox")) {
+                       if (blackbox_module) {
+                               AstNode *n = ast->attributes.at("\\noblackbox");
+                               if (n->type != AST_CONSTANT)
+                                       log_file_error(ast->filename, ast->linenum, "Got noblackbox attribute with non-constant value!\n");
+                               blackbox_module = !n->asBool();
+                       }
+                       delete ast->attributes.at("\\noblackbox");
+                       ast->attributes.erase("\\noblackbox");
+               }
+
                if (blackbox_module)
                {
                        if (ast->attributes.count("\\whitebox")) {