task 和 function 說明語句分別用來定義任務和函數,利用任務和函數可以把函數模塊分成許多小的任務和函數便於理解和調試。任務和函數往往還是大的程序模塊在不同地點多次用到的相同的程序段。輸入、輸出和總線信號的數據可以傳入、傳出任務和函數。
task 和 function 的不同:
1)函數只能與主模塊共用同一個仿真的時間單位,而任務可以自己定義自己的仿真時間單位。
2)函數不能啟動任務,但是可以調用其它函數,但是任務可以調用其他函數和任務;
3)函數至少要有一個輸入變量,而任務可以沒有或者有多個任何類型的變量。
4)函數返回一個值,而任務不返回任何值。
函數的目的值通過一個返回值對輸入的信號進行響應。而任務可以支持多種目的,能計算多個結果值,這些值只能通過任務的輸出端口或者總線端口輸出。
A) task說明語句
如果傳給任務的變量和任務完成后接受結果的變量已經定義,就可以用一條語句啟動任務,任務完成以后控制就傳回啟動過程。如果任務內部有定時設置,則啟動的時間可以與控制返回的時間不同。
1)任務的定義;
task <任務名>;
<端口及數據類型聲明語句>
<語句1>
...
<語句n>
endtask
2)任務的調用以及變量的傳遞:
任務定義;
task my_task;
input a,b;
inout c;
output d,e;
.... //執行任務的相應語句
c=foo1; //對任務的變量賦初始值
b=foo2;
e=foo3;
endtask
任務的調用: my_task(v,w,x,y,z)
任務調用變量(v,w,x,y,z)和任務定義的I/O變量(a,b,c,d,e)是一一對應的。任務啟動時,v,w和x的值給了a b c,結束時c,d,e的值返回給x,y,z。
B)function說明語句
函數的目的是返回一個用於表達式的值。定義函數的語法:
function <返回值的類型或范圍>函數名;
<端口說明語句>
<變量類型說明語句>
begin
<語句>
...
end
endfunction
在這里,<返回值的類型或范圍>可以不定義,如果默認則代表一位寄存器類型數據。
1)函數返回的值:函數的定義蘊含聲明了一個與函數同名的,函數內部的寄存器,其位數與定義的相同;
2)函數的調用:函數的調用是通過將函數作為表達式中的操作數來實現的。例:word=control ? {getbyte(msbyte),getbyte(lsbyte)} : 0;
3)函數的使用規則:
a)函數的定義不能包含任何的時間控制語句,及任何用# ,@,或wait來標識的語句。
b)函數不能啟動任務,定義函數至少輸入一個輸入參量;
c)函數的定義中必須有一條賦值語句給函數中的一個內部變量賦以函數的值,該內部變量具有和函數名一樣的名字。
d)函數的輸入變臉不能像模塊的端口那樣列在函數名后面的括弧內,在聲明輸入時把這些輸入端口列出即可。函數不能被禁用。

1 module parity; 2 reg [31:0]sddr; 3 reg parity; 4 initial 5 begin 6 addr=32'b3456_789a; 7 #10 addr=32'bc4c6_78ff; 8 #10 addr=32'bff56_ff9a; 9 #10 addr=32'b3faa_aaaa; 10 end 11 //每當地址未發生變化,重新計算偶校驗位 12 always @(addr) 13 begin 14 parity=cal_parity(addr); 15 $display("parity calculated = %b",cal_paraty(addr)); 16 end 17 //定義偶檢驗函數 18 function cal_parity; 19 input [31:0]address; 20 begin 21 cal_parity=^address; 22 end 23 endfunction 24 endmodule
在上例中,函數的定義也可以采用C語言的風格定義,如:function cal_paruty(input [31:0] address);
Verilog中的函數是不能進行遞歸調用的。在設計模塊中如果某個函數在兩個不同位置同時並發被調用,由於這兩個調用同時對同一地址進行操作,那么計算結果將是不定值。但是可以在函數聲明時使用automatic關鍵字,那么在調用時,仿真器將為函數分配不同的地址。每個函數調用各自的地址。因此:自動函數中聲明的局部變量不能通過層次名進行訪問,而自動函數本身可以通過層次名進行調用。
例:factorial=factorial(n-1)*n;
關於函數和任務的小結:
1)任務和函數都是用來對設計中多處使用的公共代碼進行定義,使用任務和函數增強模塊的可讀性和可維護性。
2)可重入任務用關鍵詞automatic定義,他的每一次調用都對不同的地址進行操作。因此可以多次並發調用時,也可得到正確的結果。
3)函數只能返回一個值,並且至少需要一個輸入變量;在函數中不能使用延遲、事件和時序控制結構,但是可以調用其他函數,不能調用任務。
4)任務可以具有任意個輸入、輸入輸出/輸出、輸出變量,在任務中可以使用延時、事件和時序控制結構,可以自定義時鍾,可以調用其他函數和任務。
5)遞歸函數必須使用automatic關鍵詞進行定義,遞歸函數的每一次調用都調用不同的地址空間,因此這種函數的遞歸調用和並發調用可以得到正確結果。