『壹』 verilog語言中任務和函數的區別
任務和函數有助於簡化程序,有點類似與Fortran語言的subroutine和function。
任務和函數的共同點:
1.任務和函數必須在模塊內定義,其作用范圍僅適用於該模塊,可以在模塊內多次調用。
2.任務和函數中可以聲明局部變數,如寄存器,時間,整數,實數和事件,但是不能聲明線網類型的變數。
3.任務和函數中只能使用行為級語句,但是不能包含always和initial塊,設計者可以在always和initial塊中調用任務和函數。
任務和函數的不同點:
函數 任務
函數能調用另一個函數,但是不能調用任務 任務可以調用另一個任務,也可以調用函數
函數總是在模擬時刻0開始 任務可以在非零時刻開始執行
函數一定不能包含任何延遲,事件或者時序控制聲明語句 任務可以包含延遲,事件或者時序控制聲明語句
函數至少要有一個輸入變數,也可以有多個輸入變數 任務可以沒有或者有多個輸入,輸出,輸入輸出變數
函數只能返回一個值,函數不能有輸出或者雙向變數 任務不返回任何值,或者返回多個輸出或雙向變數值
由上述的特點決定:函數用於替代純組合邏輯的verilog代碼,而任務可以代替verilog的任何代碼。
8.2任務
任務使用關鍵字task和endtask來進行聲明,如果子程序滿足下面任何一個條件,則必須使用任務而不能使用函數。
1.子程序中包含有延遲,時序或者事件控制結構
2.沒有輸出或者輸出變數超過一個
3.沒有輸入變數
例:
mole operation;
parameter delay=10;
reg [15:0] A,B, AB_AND,AB_OR,AB_XOR;
always @(A or B)
begin
bitwise_ope(AB_AND,AB_OR,AB_XOR,A,B);
end
task bitwise_oper;
output [15:0] ab_and,ab_or,ab_xor;
input [15:0] a,b;
begin
#delay ab_and=a&b;
ab_or=a|b;
ab_xor=a^b;
end
endtask
always @(posedge clk)
bitwise_xor(ef_xor,e,f);
always @(posedege clk2)
bitwise_xor(cd_xor,c,d)
task autumatic bitwise_xor;
output ab_xor;
input a,b;
begin
ab_xor=a^b;
end
endtask
endmole
自動(可重入)任務:verilog任務中所有聲明的變數地址空間都是靜態分配的,因此如果在一個模塊中多次調用任務時,可能會造成地址空間的沖突,為了避免這個問題,verilog通過在task關鍵字後面添加automatic使任務稱為可重入的,這時在調用任務時,會自動給任務聲明變數分配動態地址空間,這樣有效避免了地址空間的沖突。
8.3 函數
函數使用關鍵字function和endfunction定義,對於子程序,如果滿足下述所有條件則可以用函數來完成:
1.在子程序中不含有延遲時序或者控制結構
2.子程序只有一個返回值
3.至少有一個輸入變數
4.沒有輸出或者雙向變數
5.不含有非阻塞賦值語句
例:
mole parity;
reg [31:0] addr;
reg parity;
always @(addr)
begin
parity=calc_parity(addr);
end
function calc_parity;
input [31:0] addr;
begin
calc_parity=^addr;
end
endfunction
endmole
跟任務調用一樣,在模塊中如果調用多次函數,也會碰到地址沖突的問題,因此也引入automatic關鍵字來對函數可重用性聲明。沒有進行可重用性聲明的函數不可以多次或者遞歸調用,進行了可重用性聲明的函數可以遞歸調用。
常量函數和帶符號函數(函數聲明時加signed關鍵字說明)
mole ram;
parameter RAM_DEPTH=256;
input [clogb2(RAM_DEPTH)-1:0] addr;//clogb2函數返回值為8
function integer clogb2(input integer depth);
begin
for(clogb2=0; depth>0;clogb2=clogb2+1)
depth=depth>1;
end
endfunction
endmole
練習:用兩種不同的方法設計一個功能相同的模塊,完成4個8位2進制輸入數據的冒泡排序。第一種,用純組合邏輯實現;第二種,假設8位數據按照時鍾節拍串列輸入,要求時鍾觸發任務的執行,每個時鍾周期完成一次數據交換的操作。
//----------------- 第一種 ------------------
mole sort4(ra,rb,rc,rd,a,b,c,d);
output[7:0] ra,rb,rc,rd;
input[7:0] a,b,c,d;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (a or b or c or d)
begin
{va,vb,vc,vd}={a,b,c,d};
change(va,vb);
change(vb,vc);
change(vc,vd);
change(va,vb);
change(vb,vc);
change(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task change; //make a task of comparing
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmole
//----------------- 第二種 ------------------
mole sort4(clk,reset,ra,rb,rc,rd,a);
output[7:0] ra,rb,rc,rd;
input[7:0] a;
input clk,reset;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (posedge clk)
begin
if(!reset)
begin
va<=0;vb<=0;vc<=0;vd<=0;
end
else
va<=a;
end
always @ (posedge clk)
begin
change(va,vb);
change(vb,vc);
change(vc,vd);
change(va,vb);
change(vb,vc);
change(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task change; //make a task of comparing
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmole