Added init= attribute for fpga-style reset values
authorClifford Wolf <clifford@clifford.at>
Wed, 20 Nov 2013 00:49:37 +0000 (01:49 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 20 Nov 2013 00:49:37 +0000 (01:49 +0100)
README
frontends/verilog/parser.y

diff --git a/README b/README
index 9825bca45a4798782e33e4dd0549dfc38b544c65..eb60bc3fb1a2c9f2561541c9454dccb6c315c79b 100644 (file)
--- a/README
+++ b/README
@@ -258,6 +258,10 @@ Verilog Attributes and non-standard features
   never be removed by the optimizer. This is used for example for cells that
   have hidden connections that are not part of the netlist, such as IO pads.
 
+- The "init" attribute on wires is set by the frontend when a register is
+  initialized "FPGA-style" with 'reg foo = val'. It can be used during synthesis
+  to add the necessary reset logic.
+
 - In addition to the (* ... *) attribute syntax, yosys supports
   the non-standard {* ... *} attribute syntax to set default attributes
   for everything that comes after the {* ... *} statement. (Reset
index 1dcc0d6ccac839442161382a7f9a701098d3b3d8..24c84514f1b618911883851ea576739a50622f87 100644 (file)
@@ -246,8 +246,22 @@ module_args:
 optional_comma:
        ',' | /* empty */;
 
+module_arg_opt_assignment:
+       '=' expr {
+               if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
+                       if (!ast_stack.back()->children.back()->is_reg) {
+                               AstNode *wire = new AstNode(AST_IDENTIFIER);
+                               wire->str = ast_stack.back()->children.back()->str;
+                               ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2));
+                       } else
+                               ast_stack.back()->children.back()->attributes["\\init"] = $2;
+               } else
+                       frontend_verilog_yyerror("Syntax error.");
+       } |
+       /* empty */;
+
 module_arg:
-       TOK_ID range {
+       TOK_ID {
                if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
                        AstNode *node = ast_stack.back()->children.back()->clone();
                        node->str = *$1;
@@ -258,10 +272,8 @@ module_arg:
                                frontend_verilog_yyerror("Duplicate module port `%s'.", $1->c_str());
                        port_stubs[*$1] = ++port_counter;
                }
-               if ($2 != NULL)
-                       delete $2;
                delete $1;
-       } |
+       } module_arg_opt_assignment |
        attr wire_type range TOK_ID {
                AstNode *node = $2;
                node->str = *$4;
@@ -275,7 +287,7 @@ module_arg:
                ast_stack.back()->children.push_back(node);
                append_attr(node, $1);
                delete $4;
-       };
+       } module_arg_opt_assignment;
 
 wire_type:
        {
@@ -501,7 +513,8 @@ wire_name_and_opt_assign:
                        AstNode *wire = new AstNode(AST_IDENTIFIER);
                        wire->str = ast_stack.back()->children.back()->str;
                        ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $3));
-               }
+               } else
+                       ast_stack.back()->children.back()->attributes["\\init"] = $3;
        };
 
 wire_name: