From 6dce878638d09f714eb83921932db9479283fbe3 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 20 Feb 2018 20:59:26 +0000 Subject: [PATCH] Fix for br1027: incorrect inference of task/function port direction. In traditional Verilog, each task_port_item must have an explicit port direction. In SystemVerilog, if the port direction is not specified, it should be inherited from the preceding task_port_item for that task/function, and only the first task_port_item should infer the direction to be 'input'. (cherry picked from commit 6b1b402a790d29a7948897d33462b934c2e97cca) --- parse.y | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/parse.y b/parse.y index da95f2b73..9544382f6 100644 --- a/parse.y +++ b/parse.y @@ -598,7 +598,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector %type function_item function_item_list function_item_list_opt %type task_item task_item_list task_item_list_opt -%type tf_port_declaration tf_port_item tf_port_list tf_port_list_opt +%type tf_port_declaration tf_port_item tf_port_item_list tf_port_list tf_port_list_opt %type modport_simple_port port_name parameter_value_byname %type port_name_list parameter_value_byname_list @@ -2122,10 +2122,14 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ : port_direction_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt { vector*tmp; - NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; + NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT ? port_declaration_context.port_type : $1; perm_string name = lex_strings.make($3); list* ilist = list_from_identifier($3); + if (use_port_type == NetNet::PIMPLICIT) { + yyerror(@1, "error: missing task/function port direction."); + use_port_type = NetNet::PINPUT; // for error recovery + } if (($2 == 0) && ($1==NetNet::PIMPLICIT)) { // Detect special case this is an undecorated // identifier and we need to get the declaration from @@ -2137,7 +2141,6 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ port_declaration_context.data_type, ilist); - } else { // Otherwise, the decorations for this identifier // indicate the type. Save the type for any right @@ -2184,8 +2187,15 @@ tf_port_item_expr_opt ; tf_port_list /* IEEE1800-2005: A.2.7 */ + : { port_declaration_context.port_type = gn_system_verilog() ? NetNet::PINPUT : NetNet::PIMPLICIT; + port_declaration_context.data_type = 0; + } + tf_port_item_list + { $$ = $2; } + ; - : tf_port_list ',' tf_port_item +tf_port_item_list + : tf_port_item_list ',' tf_port_item { vector*tmp; if ($1 && $3) { size_t s1 = $1->size(); @@ -2211,11 +2221,11 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ { yyerror(@2, "error: Syntax error in task/function port declaration."); $$ = $3; } - | tf_port_list ',' + | tf_port_item_list ',' { yyerror(@2, "error: NULL port declarations are not allowed."); $$ = $1; } - | tf_port_list ';' + | tf_port_item_list ';' { yyerror(@2, "error: ';' is an invalid port declaration separator."); $$ = $1; }