summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-11-20 01:49:37 +0100
committerClifford Wolf <clifford@clifford.at>2013-11-20 01:49:37 +0100
commite340532ce5d60129fbfb2e1b0a3eb916ec856b26 (patch)
tree5aed3e9da1417ba879fd8543290133deacf46e54
parenta1353ec61b00442bb5ebe9f30408324b89cf6a82 (diff)
Added init= attribute for fpga-style reset values
-rw-r--r--README4
-rw-r--r--frontends/verilog/parser.y25
2 files changed, 23 insertions, 6 deletions
diff --git a/README b/README
index 9825bca4..eb60bc3f 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 1dcc0d6c..24c84514 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: