From: Clifford Wolf Date: Mon, 27 Oct 2014 12:21:57 +0000 (+0100) Subject: Added support for task and function args in parentheses X-Git-Tag: yosys-0.4~19 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f9c096eedabdf7cd2cdd770da73bdd17d86559e7;p=yosys.git Added support for task and function args in parentheses --- diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index cf02a56a9..e1304bff2 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -449,7 +449,7 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | - attr TOK_TASK TOK_ID ';' { + attr TOK_TASK TOK_ID { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; append_attr(current_function_or_task, $1); @@ -457,11 +457,11 @@ task_func_decl: ast_stack.push_back(current_function_or_task); current_function_or_task_port_id = 1; delete $3; - } task_func_body TOK_ENDTASK { + } task_func_args_opt ';' task_func_body TOK_ENDTASK { current_function_or_task = NULL; ast_stack.pop_back(); } | - attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { + attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$5; append_attr(current_function_or_task, $1); @@ -478,7 +478,7 @@ task_func_decl: current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; delete $5; - } task_func_body TOK_ENDFUNCTION { + } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION { current_function_or_task = NULL; ast_stack.pop_back(); }; @@ -512,6 +512,45 @@ opt_signed: $$ = false; }; +task_func_args_opt: + '(' ')' | /* empty */ | '(' { + albuf = nullptr; + astbuf1 = nullptr; + astbuf2 = nullptr; + } task_func_args optional_comma { + delete astbuf1; + if (astbuf2 != NULL) + delete astbuf2; + free_attr(albuf); + } ')'; + +task_func_args: + task_func_port | task_func_args ',' task_func_port; + +task_func_port: + attr wire_type range { + if (albuf) { + delete astbuf1; + if (astbuf2 != NULL) + delete astbuf2; + free_attr(albuf); + } + albuf = $1; + astbuf1 = $2; + astbuf2 = $3; + if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) { + if (astbuf2) { + frontend_verilog_yyerror("Syntax error."); + } 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("Syntax error."); + } wire_name | wire_name; + task_func_body: task_func_body behavioral_stmt | /* empty */; @@ -609,12 +648,12 @@ wire_decl: } if (astbuf2 && astbuf2->children.size() != 2) frontend_verilog_yyerror("Syntax error."); - } wire_name_list ';' { + } wire_name_list { delete astbuf1; if (astbuf2 != NULL) delete astbuf2; free_attr(albuf); - } | + } ';' | attr TOK_SUPPLY0 TOK_ID ';' { ast_stack.back()->children.push_back(new AstNode(AST_WIRE)); ast_stack.back()->children.back()->str = *$3; diff --git a/tests/simple/task_func.v b/tests/simple/task_func.v index 51e31015f..9b8e26e51 100644 --- a/tests/simple/task_func.v +++ b/tests/simple/task_func.v @@ -33,8 +33,42 @@ end endmodule +// ------------------------------------------------------------------- -module task_func_test02( input [7:0] din_a, input [7:0] din_b, output [7:0] dout_a); +module task_func_test02(clk, a, b, c, x, y, z, w); + +input clk; +input [7:0] a, b, c; +output reg [7:0] x, y, z, w; + +function [7:0] sum_shift(input [3:0] s1, s2, s3); +sum_shift = s1 + (s2 << 2) + (s3 << 4); +endfunction + +task reset_w; +w = 0; +endtask + +task add_to(output [7:0] out, input [7:0] in); +out = out + in; +endtask + +always @(posedge clk) begin + x = sum_shift(a, b, c); + y = sum_shift(a[7:4], b[5:2], c[3:0]); + z = sum_shift(a[0], b[5:4], c >> 5) ^ sum_shift(1, 2, 3); + + reset_w; + add_to(w, x); + add_to(w, y); + add_to(w, z); +end + +endmodule + +// ------------------------------------------------------------------- + +module task_func_test03( input [7:0] din_a, input [7:0] din_b, output [7:0] dout_a); assign dout_a = test(din_a,din_b); function [7:0] test; input [7:0] a;