From e340532ce5d60129fbfb2e1b0a3eb916ec856b26 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 20 Nov 2013 01:49:37 +0100 Subject: [PATCH] Added init= attribute for fpga-style reset values --- README | 4 ++++ frontends/verilog/parser.y | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/README b/README index 9825bca45..eb60bc3fb 100644 --- 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 diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1dcc0d6cc..24c84514f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -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: -- 2.30.2