函数

函数的主要用途是编写一段可以随时调用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 值。

流程图:

01 (1)

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  

流程图:

02

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);

流程图:

03

示例:

          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  

流程图:

05