---
# System prepended metadata

title: '[DV筆記] Systemverilog - function vs. task'
tags: [DV筆記, systemverilog]

---

# [[DV筆記] Systemverilog - function vs. task](/LnkKNLLcS76GG7SLUYt_mA)
應該會有很多面試問這個概念



|                          Function                          |                  Task                   |
|:----------------------------------------------------------:|:---------------------------------------:|
|                    裡面不能有任何 delay                    |         裡面可以插入 時間delay          |
|              要有 return value 或是聲明 void               |          不需要有 return value          |
| 只能有一個 return value| 可以用output, inout 類型的 args 來輸出  |
|          不需要包在 initial or always block 裡面           | 一定要包在 initial or always block 裡面 |
|                       不能 call task                       |           可以 call function            |

需要特別注意:
如果 function 沒有寫 void function 且也沒有return值， default 會是 return int 0:
```
function sum (int a, int b)
    int c;
    c= a+b;
endfunction

int result, a, b;
a=1;
b=2;
result = sum(a,b); //這時候的 result 會得到 0, 因為 function 沒有寫 return值!
```

另外，如果是在 module裡面聲明的 function or task, 裡面的 variable default 都是屬於 static 的，表示如果重複呼叫了話， variable 可能不是你想要的，example:
```
module example();
  int a=1;
  int b=2;
  int result;
  
  function int add (int a, int b);
    int count=0;
    count++;
    $display("count=%d",count);
    return (a+b);
  endfunction
  
  initial begin
    result= add(a,b);
    $display("result=%d",result);
     result= add(a,b);
    $display("result=%d",result);
  end
endmodule
/////////////////////////////////////////////
/*
simulation 結果:
count= 1
result=3
count=2 //這邊累積到上一次呼叫的count 了!
result=3
*/
/////////////////////////////////////////////
```
如果要避免這個情況，就要在 function 後面加上 automatic 關鍵字:
```
module example();
  int a=1;
  int b=2;
  int result;
  
  function automatic int add (int a, int b); //加上 automatic
    int count=0;
    count++;
    $display("count=%d",count);
    return (a+b);
  endfunction
  
  initial begin
    result= add(a,b);
    $display("result=%d",result);
     result= add(a,b);
    $display("result=%d",result);
  end
endmodule
/////////////////////////////////////////////
/*
simulation 結果:
count= 1
result=3
count=1 // count 這邊就會每次都重數，變成 automatic 類型
result=3
*/
/////////////////////////////////////////////
```
這個是一開始學的時候很容易忽略的細節，卻常常導致bug!但是如果是在 class裡面聲明的 function or task，那default 都會是 automatic，就不會有上面的問題了
```
class add_class; //把 fucntion 包在 class裡面
    function int add (int a, int b);
     
    int count=0;
    count++;
    $display("count=%d",count);
    return (a+b);
  endfunction
endclass

module example();
  int a=1;
  int b=2;
  int result;
  add_class add_class;
 

  
  initial begin
    add_class=new(); //initalize class
    result= add_class.add(a,b);
    $display("result=%d",result);
     result= add_class.add(a,b);
    $display("result=%d",result);
  end
endmodule
/////////////////////////////////////////////
/*
simulation 結果:
count= 1
result=3
count=1 // class 裡面的 function default 都是 automatic!
result=3
*/
/////////////////////////////////////////////
```

# 總結
function 和 task 最主要的差異應該就是裡面能不能包含 time delay 還有 return value了，雖然看起來不難，但確實是有一些小細節容易忽略