函数的主要用途是编写一段可以随时调用n次的代码,只需调用函数名即可,不需要任何模拟时间来执行。
函数是返回类型,仅返回函数声明中提到的单个值,如果未声明则返回一个位的值。
语法:
initial
begin
function_name(arguments);
end
function <return_type(optional)> function_name(arguments);`
statement1;
statement2;
.
.
statementN;
endfunction
限制:
- 函数内部的代码中不允许有#、@、wait等耗时语句
- 只能返回一个值
- 无法从函数中调用任务,因为任务允许有耗时的语句
调用函数有很多变体:
- 调用以值作为参数的函数
- 调用以变量作为参数的函数
- 使用表达式中的值调用函数
- C使用带位置参数的变量调用函数
- 调用自动函数
- 通过变量的引用调用带有变量的函数
- 调用返回类型为 void 的函数
- 通过传递数组来调用函数
- 调用具有默认值的变量的函数
- 从函数调用任务(使用 fork 和 join_none 的例外情况)
1. 调用以值作为参数的函数#
示例:
int result;
initial
begin
result=sum(5,6);
$display("\treturned from function and");
$display("\tstored the value of sum in result");
$display("\n\t@ %0t ns, value of sum is %0d",$time,result);
end
function int sum(int var1,var2);
$display("entered into function");
return var1+var2;
endfunction
在上面的示例中,函数名称是 sum,其返回类型为 int,即它仅返回一个 int 值。
流程图:
2. 调用以变量作为参数的函数#
示例:
int result,a=5,b=6;
initial
begin
$display("\tcalling the function");
result=sum(a,b);
$display("\treturned from function and");
$display("\tstored the value of sum in result");
$display("\n\t@ %0t ns, value of sum is %0d",$time,result);
end
function int sum(input int a,b);
$display("entered into function");
return a+b;
endfunction
流程图:
3. 使用表达式中的值调用函数#
示例:
initial
begin
$display("\n\t@ %0t ns, value of sum is %0d",$time,sum(5,6));
end
function int sum(int var1,var2);
$display("entered into function");
return var1+var2;
endfunction
4. 使用带位置参数的变量调用函数#
示例:
initial
begin
result=sum(.var1(5),.var2(6));
$display("\treturned from function and");
$display("\tstored the value of sum in result");
$display("\n\t@ %0t ns, value of sum is %0d",$time,result);
end
function int sum(int var1,var2);
$display("entered into function");
return var1+var2;
endfunction
5. 调用自动函数#
语法:
function automatic function_name(arguments);
示例:
module func_automatic();
int result1,result2;
function int factorial_static(int var1);
if(var1>=2)
result1=factorial_static(var1-1)*var1;
else
begin
result1=1;
end
return result1;
endfunction
function automatic int factorial_automatic(int var1);
if(var1>=2)
result2=factorial_automatic(var1-1)*var1;
else
begin
result2=1;
end
return result2;
endfunction
initial
begin
result1=factorial_static(5);
result2=factorial_automatic(5);
$display("factorial_static:%0d",result1);
$display("factorial_automatic:%0d",result2);
end
endmodule: func_automatic
这里我们使用带有 automatic 关键字的函数,这意味着每当调用该函数时都会创建新的内存,而在 static 中,每当调用该函数时都会使用相同的内存。
6. 通过变量的引用调用带有变量的函数#
语法:
function automatic data_type function_name(ref arguments);
流程图:
示例:
int result,addend,augend;
initial
begin
addend=5;
augend=6;
$display("\tBefore calling function -> addend = %0d , augend = %0d",addend,augend);
$display("\tcalling the functions");
result=sum_without_ref(addend,augend);
$display("\tafter calling function without ref -> addend = %0d, augend =%0d",addend,augend);
result=sum_with_ref(addend,augend);
$display("\tafter calling function with ref -> addend = %0d, augend =%0d",addend,augend);
end
function automatic int sum_with_ref(ref int var1,var2);
int temp;
$display("\n\tentered into with ref function");
temp=var1;
var1=var2;
var2=temp;
$display("\tswapped variables by using ref ");
return var1+var2;
endfunction : sum_with_ref
function int sum_without_ref(input int var1,var2);
int temp;
$display("\n\tentered into without ref function");
temp=var1;
var1=var2;
var2=temp;
$display("\tswapped variables by without using ref ");
return var1+var2;
endfunction : sum_without_ref
当通过传递变量引用来调用函数时,需要提及关键字 automatic 和 ref,如上例所示。
7. 调用返回类型为 void 的函数#
语法:
//type casting
void'(function_name(arguments));
或者
//declaring the function as void type which doesn't return any value.
function void function_name(arguments);
示例:
initial
begin
display("\t ----output for function void return type-----");
display("\t passing string to function for displaying");
end
function void display(string str);
$display("%s",str);
endfunction: display
8. 通过传递数组来调用函数#
语法:
data_type array_name[size];
function automatic return_type function_name(ref data_type array_name);
示例:
int array[5];
void'(fun_arr(array));
$display("\treturned from function");
$display("\n\t@ %0t ns, Array elements = %0p",$time,array);
end
function automatic int fun_arr(ref int arr[5]);
$display("\tEntered the function");
foreach(arr[i])begin
arr[i]=i+1;
end
$display("\t values assigned to array elements starts from 1");
return 0;
endfunction
一般来说,我们不能从函数返回数组,但可以使用引用传递来传递数组,并且可以在函数中操作该数组。
9. 调用具有默认值的变量的函数#
语法:
function_name()
function <return_type> function_name(varable1=deafult_value,variable2=default_value)
示例:
initial
begin
$display("\t ----output for function passing by values through variables-----");
$display("\tcalling the function");
result=sum();
$display("\treturned from function and");
$display("\tstored the value of sum in result");
$display("\n\t@ %0t ns, value of sum is %0d",$time,result);
end
function int sum(input int var1=2,var2=3);
$display("\n\tentered into function ");
return var1+var2;
endfunction: sum
在此示例中,调用函数但不传递任何值或变量,那么在这种情况下,函数所需的两个变量将采用分配给它们的默认值,即在本例中为 2 & 3 得出的总和为 5。
如果调用函数时没有值和变量,并且函数没有任何默认值,则模拟器将抛出错误。
10. 从函数调用任务#
一般来说,从函数调用任务是非法的,编译器会报错,但有一种特殊情况,可以使用 fork join_none 从函数调用任务,如下例所示。
示例:
initial
begin
$display("\t@ %0t ns, In the initial block",$time);
$display("\tcalling function");
#1 void'(function_call);
end
function function_call;
fork
$display( "\t@ %0t ns I'm in function",$time);
$display("\t@ %0t ns, calling task from func",$time);
task_call;
join_none
endfunction
task task_call;
#1 $display( "\t@ %0t ns , I'm in task",$time);
#1 $display("\t@ %0t ns,leaving from task",$time);
endtask
流程图: