diff options
author | Clifford Wolf <clifford@clifford.at> | 2019-10-14 05:24:31 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2019-10-14 05:24:31 +0200 |
commit | e84cedfae4211244da45ef51a84213874579117e (patch) | |
tree | fb0a14f4c06675a7d3dbb5a1f22d386402e22d0b /frontends/verilog | |
parent | 3c6a566d865e3d70f8793225a6d211ce3d6246a1 (diff) | |
parent | e46e8753c84ee83f871d5ce116ce4c08dd49a031 (diff) | |
download | yosys-e84cedfae4211244da45ef51a84213874579117e.tar.gz yosys-e84cedfae4211244da45ef51a84213874579117e.tar.bz2 yosys-e84cedfae4211244da45ef51a84213874579117e.zip |
Use "(id)" instead of "id" for types as temporary hack
Signed-off-by: Clifford Wolf <clifford@clifford.at>
Diffstat (limited to 'frontends/verilog')
-rw-r--r-- | frontends/verilog/verilog_parser.y | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 4afd72b73..77f6d2051 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -155,7 +155,7 @@ struct specify_rise_fall { %type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int %type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list -%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id +%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id %type <boolean> opt_signed opt_property unique_case_attr %type <al> attr case_attr @@ -206,6 +206,7 @@ design: task_func_decl design | param_decl design | localparam_decl design | + typedef_decl design | package design | interface design | /* empty */; @@ -290,6 +291,9 @@ hierarchical_id: $$ = $1; }; +hierarchical_type_id: + '(' hierarchical_id ')' { $$ = $2; }; + module: attr TOK_MODULE TOK_ID { do_not_require_port_stubs = false; @@ -324,13 +328,13 @@ single_module_para: astbuf1 = new AstNode(AST_PARAMETER); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); append_attr(astbuf1, $1); - } param_signed param_integer param_range single_param_decl | + } param_type single_param_decl | attr TOK_LOCALPARAM { if (astbuf1) delete astbuf1; astbuf1 = new AstNode(AST_LOCALPARAM); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); append_attr(astbuf1, $1); - } param_signed param_integer param_range single_param_decl | + } param_type single_param_decl | single_param_decl; module_args_opt: @@ -426,6 +430,7 @@ package_body: package_body package_body_stmt |; package_body_stmt: + typedef_decl | localparam_decl; interface: @@ -452,7 +457,7 @@ interface_body: interface_body interface_body_stmt |; interface_body_stmt: - param_decl | localparam_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | + param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | modport_stmt; non_opt_delay: @@ -475,8 +480,14 @@ wire_type: }; wire_type_token_list: - wire_type_token | wire_type_token_list wire_type_token | - wire_type_token_io ; + wire_type_token | + wire_type_token_list wire_type_token | + wire_type_token_io | + hierarchical_type_id { + astbuf3->is_custom_type = true; + astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); + astbuf3->children.back()->str = *$1; + }; wire_type_token_io: TOK_INPUT { @@ -591,7 +602,7 @@ module_body: /* empty */; module_body_stmt: - task_func_decl | specify_block |param_decl | localparam_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt | + task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt | always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block; checker_decl: @@ -1149,12 +1160,20 @@ param_range: } }; +param_type: + param_signed param_integer param_real param_range | + hierarchical_type_id { + astbuf1->is_custom_type = true; + astbuf1->children.push_back(new AstNode(AST_WIRETYPE)); + astbuf1->children.back()->str = *$1; + }; + param_decl: attr TOK_PARAMETER { astbuf1 = new AstNode(AST_PARAMETER); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); append_attr(astbuf1, $1); - } param_signed param_integer param_real param_range param_decl_list ';' { + } param_type param_decl_list ';' { delete astbuf1; }; @@ -1163,7 +1182,7 @@ localparam_decl: astbuf1 = new AstNode(AST_LOCALPARAM); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); append_attr(astbuf1, $1); - } param_signed param_integer param_real param_range param_decl_list ';' { + } param_type param_decl_list ';' { delete astbuf1; }; @@ -1327,7 +1346,7 @@ wire_name: if ($2 != NULL) { if (node->is_input || node->is_output) frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions."); - if (!astbuf2) { + if (!astbuf2 && !node->is_custom_type) { AstNode *rng = new AstNode(AST_RANGE); rng->children.push_back(AstNode::mkconst_int(0, true)); rng->children.push_back(AstNode::mkconst_int(0, true)); @@ -1377,6 +1396,45 @@ assign_expr: ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3)); }; +typedef_decl: + TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' { + astbuf1 = $2; + astbuf2 = $3; + if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) { + if (astbuf2) { + frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions."); + } else { + astbuf2 = new AstNode(AST_RANGE); + astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true)); + astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true)); + } + } + if (astbuf2 && astbuf2->children.size() != 2) + frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]"); + if (astbuf2) + astbuf1->children.push_back(astbuf2); + + if ($5 != NULL) { + if (!astbuf2) { + AstNode *rng = new AstNode(AST_RANGE); + rng->children.push_back(AstNode::mkconst_int(0, true)); + rng->children.push_back(AstNode::mkconst_int(0, true)); + astbuf1->children.push_back(rng); + } + astbuf1->type = AST_MEMORY; + auto *rangeNode = $5; + if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) { + // SV array size [n], rewrite as [n-1:0] + rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true)); + rangeNode->children.push_back(AstNode::mkconst_int(0, false)); + } + astbuf1->children.push_back(rangeNode); + } + + ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1)); + ast_stack.back()->children.back()->str = *$4; + }; + cell_stmt: attr TOK_ID { astbuf1 = new AstNode(AST_CELL); @@ -1823,7 +1881,7 @@ simple_behavioral_stmt: // this production creates the obligatory if-else shift/reduce conflict behavioral_stmt: - defattr | assert | wire_decl | param_decl | localparam_decl | + defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl | non_opt_delay behavioral_stmt | simple_behavioral_stmt ';' | ';' | hierarchical_id attr { |