1:函數只能與主模塊共用同一個仿真時間單位,而任務能夠定義本身的仿真時間單位;express
2:函數不能啓動任務,而任務能啓動其它任務和函數;函數
3:函數至少要有一個輸入變量,而任務能夠沒有或有多個任何類型的變量;spa
4:函數返回一個值,而任務則不返回值。code
任務的定義:blog
task <任務名>;get
<端口及數據類型聲明語句>input
<各個語句>it
endtaskio
若是傳給任務的變量值和任務完成後接收結果的變量已經定義,就能夠用一條語句啓動任務,任務完成之後控制就傳回啓動過程。若是任務內部有定時控制,則啓動的時間能夠與控制返回的時間不一樣。任務能夠啓動其它任務,其它任務又能夠啓動別的任務,能夠啓動的任務數是沒有限制的。無論有多少任務啓動,只有當全部的啓動任務完成之後,控制才能返回。function
下面舉例,交通燈,這個代碼模塊只是一個行爲模塊,不能綜合成電路網表:
`timescale 10ns / 1ns module taskdemo; reg clock,red,amber,green; parameter on=1,off=0,red_tics=3,amber_tics=5,green_tics=6; initial red=off; initial amber=off; initial green=off; always begin red=on; light(.color(red),.tics(red_tics)); green=on; light(.color(green),.tics(green_tics)); amber=on; light(.color(amber),.tics(amber_tics)); end task light; `timescale 1ns / 100ps output color; input[31:0] tics; begin repeat(tics) @(posedge clock); color=off; end endtask always begin #1 clock=0; #1 clock=1; end endmodule
上面代碼在task中又從新定義了仿真時間。仿真波形以下:
函數的定義:
function <返回值的類型或範圍> (函數名);
<端口說明語句>
<變量類型說明語句>
begin
<語句>
end
endfunction
<返回值的類型或範圍>這一項是可選項,若是默認則返回值爲一位寄存器類型數據:
function [7:0] getbyte; input [15:0] address; begin <說明語句> getbyte = result_expression; //從地址字中取低字節,把結果賦予函數的返回字節 end endfunction
函數的定義蘊含聲明瞭與函數同名的,函數內部的寄存器。若是<返回值的類型或範圍>爲默認,則這個寄存器是一位的,不然是與函數定義中<返回值的類型或範圍>一致的寄存器。函數的定義把函數返回值所賦值寄存器的名稱初始化爲與函數同名的內部變量。上面的代碼中說明了這個概念:getbyte被賦予的值就是函數的返回值。
函數調用形式:<函數名>(<表達式>,...<表達式>)
其中函數名做爲確認符。下面的例子中,再次調用函數getbyte,把兩次調用產生的值進行位拼接運算,以生成一個字:
word = control ? {getbyte(msbyte),getbyte(lsbyte)} : 0;
函數的使用規則:
1:函數的定義不能包含有任何的時間控制語句,即任何用#、@、或wait來標識的語句;
2:函數不能啓動任務;
3:定義函數時至少要有一個輸入參量;
4:在函數的定義中必須有一條賦值語句給函數中的一個內部變量賦以函數的結果值,該內部變量具備和函數名相同的名字;