Subroutines

Welcome to the System Verilog tutorial series! If you have any doubts / suggestions, please let us know!  Dear visitor, please Sign up / Login for Free and get privileged access! You can copy code, download free tutorials and do more when you’re logged in!

Begin End:

With SystemVerilog, multiple statements can be written between the task declaration and endtask, which means that the begin …. end can be omitted. If begin …. end is omitted, statements are executed sequentially, the same as if they were enclosed in a begin …. end group. It shall also be legal to have no statements at all.

Tasks:

A Verilog task declaration has the formal arguments either in parentheses or in declaration.

task mytask1 (output int x, input logic y);

With SystemVerilog, there is a default direction of input if no direction has been specified. Once a direction is given, subsequent formals default to the same direction.

In the following example, the formal arguments a and b default to inputs, and u and v are both outputs.

task mytask3(a, b, output logic [15:0] u, v);

Return In Tasks:

In Verilog, a task exits when the endtask is reached. With SystemVerilog, the return statement can be used to exit the task before the endtask keyword.

In the following example, Message “Inside Task : After return statement” is not executed because the task exited before return statement.

EXAMPLE:

program main();
task task_return();
$display("Inside Task : Before return statement");
return;
$display("Inside Task : After return statement");
endtask
initial
task_return();
endprogram

RESULT:
Inside Task : Before return statement

Functions:

function logic [15:0] myfunc1(int x, int y);

Function declarations default to the formal direction input if no direction has been specified. Once a direction is given, subsequent formals default to the same direction.

In the following example, the formal arguments a and b default to inputs, and u and v are both outputs:

function logic [15:0] myfunc3(int a, int b, output logic [15:0] u, v);

Return Values And Void Functions:

SystemVerilog allows functions to be declared as type void, which do not have a return value. For nonvoid functions, a value can be returned by assigning the function name to a value, as in Verilog, or by using return with a value. The return statement shall override any value assigned to the function name. When the return statement is used, nonvoid functions must specify an expression with the return.

EXAMPLE:

function [15:0] myfunc2 (input [7:0] x,y);
return x * y - 1; //return value is specified using return statement
endfunction
// void functions
function void myprint (int a);

Pass By Reference:

In verilog,method arguments takes as pass by value.The inputs are copyed when the method is called and the outputs are assigned to outputs when exiting the method.In SystemVerilog ,methods can have pass by reference.Arguments passed by reference are not copied into the subroutine area, rather, a reference to the original argument is passed to the subroutine. The subroutine can then access the argument data via the reference.

In the following example, variable a is changed at time 10,20 and 30. The method pass_by_val , copies only the value of the variable a, so the changes in variable a which are occurred after the task pass_by_val call, are not visible to pass_by_val. Method pass_by_ref is directly referring to the variable a. So the changes in variable a are visible inside pass_by_ref.

EXAMPLE:

program main();
int a;
initial
begin
#10 a = 10;
#10 a = 20;
#10 a = 30;
#10 $finish;
end
task pass_by_val(int i);
forever
@i $display("pass_by_val: I is %0d",i);
endtask
task pass_by_ref(ref int i);
forever
@i $display("pass_by_ref: I is %0d",i);
endtask
initial
pass_by_val(a);
initial
pass_by_ref(a);
endprogram

RESULT:
pass_by_ref: I is 10
pass_by_ref: I is 20
pass_by_ref: I is 30

Default Values To Arguments:

SystemVerilog allows to declare default values to arguments.When the subrotunies are called,arguments those are omited,will take default value.

EXAMPLE:

program main();
task display(int a = 0,int b,int c = 1 );
$display(" %0d %0d %0d ",a,b,c);
endtask
initial
begin
display( , 5 ); // is equivalent to display( 0, 5, 1 );
display( 2, 5 ); // is equivalent to display( 2, 5, 1 );
display( , 5, ); // is equivalent to display( 0, 5, 1 );
display( , 5, 7 ); // is equivalent to display( 0, 5, 7 );
display( 1, 5, 2 ); // is equivalent to display( 1, 5, 2 );
end
endprogram

RESULT:
0 5 1
2 5 1
0 5 1
0 5 7
1 5 2

Argument Binding By Name:

SystemVerilog allows arguments to tasks and functions to be bound by name as well as by position. This allows specifying non-consecutive default arguments and easily specifying the argument to be passed at the call.

EXAMPLE:

program main();
function void fun( int j = 1, string s = "no" );
$display("j is %0d : s is %s ",j,s);
endfunction
initial
begin
fun( .j(2), .s("yes") ); // fun( 2, "yes" );
fun( .s("yes") ); // fun( 1, "yes" );
fun( , "yes" ); // fun( 1, "yes" );
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" );
fun( ); // fun( 1, "no" );
end
endprogram

RESULT:
j is 2 : s is yes
j is 1 : s is yes
j is 1 : s is yes
j is 2 : s is no
j is 2 : s is yes
j is 1 : s is no
j is 2 : s is no
j is 1 : s is no

Optional Argument List:

When a task or function specifies no arguments, the empty parenthesis, (), following the task/function name shall be optional. This is also true for tasks or functions that require arguments, when all arguments have defaults specified.

EXAMPLE:

program main();
function void fun( );
$display("Inside function");
endfunction
initial
begin
fun( );
fun;
end
endprogram

RESULT:
Inside function
Inside function