task_body_declaration ::= // from Annex A.2.7
[ interface_identifier . | class_scope] task_identifier ;
{ tf_item_declaration }
{ statement_or_null }
endtask
[ : task_identifier ]
| [ interface_identifier
. | class_scope]
task_identifier ( task_port_list [ tf_port_list ] ) ;
{ block_item_declaration }
{ statement_or_null }
endtask
[ : task_identifier ]
tf_item_declaration ::=
block_item_declaration
| { attribute_instance
} tf_input_declaration ;
| { attribute_instance
} tf_output_declaration ;
| { attribute_instance
} tf_inout_declaration ;
| { attribute_instance
} tf_ref_declaration ;
| tf_port_declaration
tf_port_list ::=
tf_port_item { , tf_port_item }
tf_port_item ::=
{ attribute_instance } tf_input_declaration
| { attribute_instance
} tf_output_declaration
| { attribute_instance
} tf_inout_declaration
| { attribute_instance
} tf_ref_declaration
| { attribute_instance
} [ signing ] { packed_dimension } list_of_tf_variable_identifiers
| { attribute_instance
} data_type list_of_tf_variable_identifiers
tf_port_item ::=
{ attribute_instance }
[ tf_port_direction ] data_type_or_implicit
port_identifier variable_dimension
[ = expression ]
tf_input_declaration ::=
input [ signing ] { packed_dimension
} list_of_tf_variable_identifiers
| input data_type list_of_tf_variable_identifiers
tf_output_declaration ::=
output [ signing ] { packed_dimension
} list_of_tf_variable_identifiers
| output data_type list_of_tf_variable_identifiers
tf_inout_declaration ::=
inout
[ signing ] { packed_dimension } list_of_tf_variable_identifiers
| inout data_type list_of_tf_variable_identifiers
tf_ref_declaration ::=
[ const ] ref
data_type list_of_tf_variable_identifiers
tf_port_direction ::= port_direction
| const ref
tf_port_declaration ::=
{ attribute_instance } tf_port_direction
data_type_or_implicit list_of_tf_variable_identifiers
;
signing ::=
signed | unsigned // from Annex A.2.2.1
data_type_or_implicit ::=
data_type
| [ signing ] { packed_dimension
}
function_data_type6 ::= data_type_common_item | void // from Annex A.2.6
function_body_declaration ::=
[ signing ] [ type_or_dimensions
]
[ interface_identifier . | class_scope ] function_identifier
;
{ tf_item_declaration }
{ function_statement_or_null }
endfunction
[ : function_identifier ]
| [ signing ] [ type_or_dimensions ]
[ interface_identifier . | class_scope ] function_identifier
( [ tf_port_list ]
) ;
{ block_item_declaration }
{ function_statement_or_null }
endfunction
[ : function_identifier ]
lifetime ::=
static | automatic // from Annex A.2.1 A.2.1.3
10.3.1
Void Return
values and void functions
function
[15:0] myfunc1 (input foo [7:0] x,y);
myfunc1 = 16’hbeef x
* y - 1; //return value is assigned to function name
endfunction
function
[15:0] myfunc2 (input foo [7:0] x,y);
return
16’hbeef x * y - 1;
//return value is specified using return statement
endfunction
Pass by
value Pass by value is the default mechanism for passing arguments to subroutines,
it is also the only one provided by Verilog-2001. This argument passing
mechanism works by copying each argument into the subroutine area. If the
subroutine is automatic, then the subroutine retains a local copy of the
arguments in its stack. If the arguments are changed within the subroutine, the
changes are not visible outside the subroutine. When the arguments are large,
it can be undesirable to copy the arguments. Also, programs sometimes need to
share a common piece of data that is not declared global.
When the formal argument is
declared as a const ref, the subroutine cannot alter the variable, and an attempt to do so
shall generate a compiler error.
fun( .j(2) ); // fun( 2, "no" );
fun( .s("yes"), .j(2) ); //
fun( 2 , "yes" );
fun( .s(), .j() ); //
fun( 1 , "no" );
fun( 2 ); // fun( 2,
"no" );
dpi_import_export ::= //
from Annex A.2.6
import
"DPI" [ dpi_function_import_property
] [ c_identifier = ] dpi_function_proto ;
| import "DPI" [ dpi_task_import_property ] [ c_identifier = ] dpi_task_proto ;
| export "DPI" [ c_identifier = ] function function_identifier ;
| export "DPI" [ c_identifier = ] task
task_identifier ;