Added support for task and function args in parentheses
authorClifford Wolf <clifford@clifford.at>
Mon, 27 Oct 2014 12:21:57 +0000 (13:21 +0100)
committerClifford Wolf <clifford@clifford.at>
Mon, 27 Oct 2014 12:21:57 +0000 (13:21 +0100)
frontends/verilog/verilog_parser.y
tests/simple/task_func.v

index cf02a56a9ce4115dd48e8d6cf154850c31743365..e1304bff26fa4dcc2a34f4ef1a266a82afc0d339 100644 (file)
@@ -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;
index 51e31015fcce7d52ce28d0e7c75f9ceb2c0d8e05..9b8e26e514c98ebe9454e7cc3e3925768d6b76a2 100644 (file)
@@ -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;