OpenVera supports two means of encapsulating program fragments:
functions and tasks. All functions and tasks are re-entrant and
therefore can be called recursively.
Function :
Functions are provided for implementing operations containing arguments passed to the function and one return value.Functions can return values of any valid data type as well as data structures.
Task :
Tasks are identical to functions except they do not return a value.
Subroutine Arguments :
OpenVera provides two means of accessing arguments in functions and tasks: pass by value and pass by reference.
Pass By Value :
Pass by value is the default method through which arguments are passed into functions and tasks. Each subroutine retains a local copy of the argument. If the arguments are changed within the subroutine declaration, the changes do not affect the caller.
EXAMPLE : pass by value program main{
integer i;
i=0;
fork
pass(i);
display();
join
printf("End of Program at %d\n",get_time(LO) );
}
task pass(int i) {
delay(10);
i = 1;
printf(" i is changed to %d at %d\n",i,get_time(LO) );
delay(10);
i = 2;
printf(" i is changed to %d at %d\n",i,get_time(LO) );
}
task display(){
delay(15);
printf(" i is %d at %d\n",i,get_time(LO));
delay(10);
printf(" i is %d at %d\n",i,get_time(LO));
}
RESULTS
i is changed to 1 at 10 i is 0 at 15 i is changed to 2 at 20 i is 0 at 25 End of Program at 25
Pass By Reference :
In pass by reference functions and tasks directly access the specified variables passed as arguments.Its like passing pointer of the variable.
EXAMPLE : pass by reference program main{
integer i;
i=0;
fork
pass(i);
display();
join
printf("End of Program at %d\n",get_time(LO) );
}
task pass(varint i) {
delay(10);
i = 1;
printf(" i is changed to %d at %d\n",i,get_time(LO) );
delay(10);
i = 2;
printf(" i is changed to %d at %d\n",i,get_time(LO) );
}
task display(){
delay(15);
printf(" i is %d at %d\n",i,get_time(LO));
delay(10);
printf(" i is %d at %d\n",i,get_time(LO));
}
RESULTS
i is changed to 1 at 10 i is 1 at 15 i is changed to 2 at 20 i is 2 at 25 End of Program at 25
Default Arguments:
To handle common cases or allow for unused arguments, OpenVera allows you to define default values for each scalar argument.When the subroutine is called, you can omit an argument that has a default defined for it. Use an asterisk (*) as a placeholder in the subroutine call.
EXAMPLE : Default Arguments: task display(integer i = 0, integer k, reg[5:0] data = 6'b0)
{
printf(" i si %d k is %d , datat is %b \n",i,k,data);
}
program main{
integer i;
i=0;
display(1,4,6);
display(*,4,*);
display(*,8,4);
}
RESULTS
i si 1 k is 4 , datat is 000110 i si 0 k is 4 , datat is 000000 i si 0 k is 8 , datat is 000100
Optional Arguments:
To allow subroutines to evolve over time without having to change all of the existing calls, OpenVera supports optional arguments.Optional arguments must have default values.Any number of additional optional arguments can be created.Parentheses are used to determine the depth level of an optional argument.
EXAMPLE : optional arguments task my_task(integer a, ((integer b=1)), (integer c=1)){
printf (" a is %d, b is %d c is %d\n",a,b,c);
}
program main{
integer i;
i=0;
my_task(1,2,3);
my_task(1);
my_task(1,2);
}
RESULTS
a is 1, b is 2 c is 3 a is 1, b is 1 c is 1 a is 1, b is 2 c is 1
Subroutine Termination :
Normally, functions and tasks return control to the caller after the last statement of the block is executed. OpenVera provides the return statement to manually pass control back to the caller.