北大Verilog課件-17-Verilog任務與函數(shù)_第1頁
北大Verilog課件-17-Verilog任務與函數(shù)_第2頁
北大Verilog課件-17-Verilog任務與函數(shù)_第3頁
北大Verilog課件-17-Verilog任務與函數(shù)_第4頁
北大Verilog課件-17-Verilog任務與函數(shù)_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第17章

Verilog中的高級結(jié)構(gòu)學習內(nèi)容:任務和函數(shù)的定義和調(diào)用怎樣使用命名塊怎樣禁止命名塊和任務有限狀態(tài)機(FSM)及建模Verilog的任務及函數(shù)結(jié)構(gòu)化設計是將任務分解為較小的,更易管理的單元,并將可重用代碼進行封裝。這通過將設計分成模塊,或任務和函數(shù)實現(xiàn)。任務(task)通常用于調(diào)試,或?qū)τ布M行行為描述可以包含時序控制(#延遲,@,wait)可以有input,output,和inout參數(shù)可以調(diào)用其他任務或函數(shù)函數(shù)(function)通常用于計算,或描述組合邏輯不能包含任何延遲;函數(shù)仿真時間為0只含有input參數(shù)并由函數(shù)名返回一個結(jié)果可以調(diào)用其他函數(shù),但不能調(diào)用任務Verilog的任務及函數(shù)任務和函數(shù)必須在module內(nèi)調(diào)用在任務和函數(shù)中不能聲明wire所有輸入/輸出都是局部寄存器任務/函數(shù)執(zhí)行完成后才返回結(jié)果。例如,若任務/函數(shù)中有forever語句,則永遠不會返回結(jié)果任務下面的任務中含有時序控制和一個輸入,并引用了一個module變量,但沒有輸出、輸入輸出和內(nèi)部變量,也不顯示任何結(jié)果。時序控制中使用的信號(例如ck)一定不能作為任務的輸入,因為輸入值只向該任務傳送一次。moduletop;regclk,a,b;DUTu1(out,a,b,clk);always#5clk=!clk;

taskneg_clocks;input[31:0]number_of_edges;repeat(number_of_edges)@(negedgeclk);

endtaskinitialbeginclk=0;a=1;b=1;neg_clocks(3);//任務調(diào)用

a=0;neg_clocks(5);b=0;endendmodule任務任務可以有input,output和inout參數(shù)。傳送到任務的參數(shù)和與任務I/O說明順序相同。盡管傳送到任務的參數(shù)名稱與任務內(nèi)部I/O說明的名字可以相同,但在實際中這通常不是一個好的方法。參數(shù)名的唯一性可以使任務具有好的模塊性??梢栽谌蝿諆?nèi)使用時序控制。在Verilog中任務定義一個新范圍(scope)要禁止任務,使用關鍵字disable。主要特點:

從代碼中多處調(diào)用任務時要小心。因為任務的局部變量的只有一個拷貝,并行調(diào)用任務可能導致錯誤的結(jié)果。在任務中使用時序控制時這種情況時常發(fā)生。

在任務或函數(shù)中引用調(diào)用模塊的變量時要小心。如果想使任務或函數(shù)能從另一個模塊調(diào)用,則所有在任務或函數(shù)內(nèi)部用到的變量都必須列在端口列表中。任務下面的任務中有輸入,輸出,時序控制和一個內(nèi)部變量,并且引用了一個module變量。但沒有雙向端口,也沒有顯示。任務調(diào)用時的參數(shù)按任務定義的順序列出。modulemult(clk,a,b,out,en_mult);

inputclk,en_mult;

input[3:0]a,b;

output[7:0]out;

reg[7:0]out;

always

@(posedgeclk)multme(a,b,out);//任務調(diào)用

taskmultme;//任務定義

input[3:0]xme,tome;

output[7:0]result;

wait(en_mult)result=xme*tome;

endtaskendmodule函數(shù)(function)函數(shù)中不能有時序控制,但調(diào)用它的過程可以有時序控制。函數(shù)名f_or_and在函數(shù)中作為register使用moduleorand(a,b,c,d,e,out);input[7:0]a,b,c,d,e;output[7:0]out;reg[7:0]out;always

@(aorborcordore)out=f_or_and(a,b,c,d,e);//函數(shù)調(diào)用

function[7:0]f_or_and;

input[7:0]a,b,c,d,e;

if(e==1)f_or_and=(a|b)&(c|d);

elsef_or_and=0;

endfunctionendmodule函數(shù)主要特性:函數(shù)定義中不能包含任何時序控制語句。函數(shù)至少有一個輸入,不能包含任何輸出或雙向端口。函數(shù)只返回一個數(shù)據(jù),其缺省為reg類型。傳送到函數(shù)的參數(shù)順序和函數(shù)輸入?yún)?shù)的說明順序相同。函數(shù)在模塊(module)內(nèi)部定義。函數(shù)不能調(diào)用任務,但任務可以調(diào)用函數(shù)。函數(shù)在Verilog中定義了一個新的范圍(scope)。雖然函數(shù)只返回單個值,但返回的值可以直接給信號連接賦值。這在需要有多個輸出時非常有效。

{o1,o2,o3,o4}=f_or_and(a,b,c,d,e);函數(shù)要返回一個向量值(多于一位),在函數(shù)定義時在函數(shù)名前說明范圍。函數(shù)中需要多條語句時用begin和end。不管在函數(shù)內(nèi)對函數(shù)名進行多少次賦值,值只返回一次。下例中,函數(shù)還在內(nèi)部聲明了一個整數(shù)。modulefoo;

input[7:0]loo;

output[7:0]goo;//可以持續(xù)賦值中調(diào)用函數(shù)

wire[7:0]goo=zero_count(loo);

function

[3:0]

zero_count;

input[7:0]in_bus;

integerI;begin

zero_count=0;for(I=0;I<8;I=I+1)if(!in_bus[I])

zero_count=zero_count+1;end

endfunctionendmodule函數(shù)函數(shù)返回值可以聲明為其它register類型:integer,real,或time。在任何表達式中都可調(diào)用函數(shù)modulechecksub(neg,a,b);

outputneg;

regneg;

inputa,b;

function

integer

subtr;

input[7:0]in_a,in_b;

subtr=in_a-in_b;//結(jié)果可能為負

endfunction

always

@(aorb)

if(subtr(a,b)<0)neg=1;

elseneg=0;endmodule函數(shù)函數(shù)中可以對返回值的個別位進行賦值。函數(shù)值的位數(shù)、函數(shù)端口甚至函數(shù)功能都可以參數(shù)化。...parameterMAX_BITS=8;reg[MAX_BITS:1]D;function

[MAX_BITS:1]

reverse_bits;

input[MAX_BITS-1:0]data;

integerK;

for(K=0;K<MAX_BITS;K=K+1)reverse_bits[MAX_BITS-(K+1)]=data[K];endfunctionalways

@(posedgeclk)D=reverse_bits(D);...命名塊(namedblock)在關鍵詞begin或fork后加上:<塊名稱>

對塊進行命名modulenamed_blk;...begin:seq_blk...end...fork:par_blk...join...endmodule在命名塊中可以聲明局部變量可以使用關鍵詞disable禁止一個命名塊命名塊定義了一個新的范圍命名塊會降低仿真速度禁止命名塊和任務moduledo_arith(out,a,b,c,d,e,clk,en_mult);

inputclk,en_mult;

input[7:0]a,b,c,d,e;

output[15:0]out;

reg[15:0]out;

always@(posedgeclk)

begin:arith_block//***命名塊***

reg[3:0]tmp1,tmp2;//***局部變量***

{tmp1,tmp2}=f_or_and(a,b,c,d,e);//函數(shù)調(diào)用

if(en_mult)multme(tmp1,tmp2,out);//任務調(diào)用

end

always@(negedgeen_mult)begin//中止運算

disablemultme;//***禁止任務***

disable

arith_block;//***禁止命名塊***

end//下面[定義任務和函數(shù)

……endmodule禁止命名塊和任務disable語句終結(jié)一個命名塊或任務的所有活動。也就是說,在一個命名塊或任務中的所有語句執(zhí)行完之前就返回。語法:

disable<塊名稱>

disable<任務名稱>當命名塊或任務被禁止時,所有因他們調(diào)度的事件將從事件隊列中清除disable是典型的不可綜合語句。在前面的例子中,只禁止命名塊也可以達到同樣的目的:所有由命名塊、任務及其中的函數(shù)調(diào)度的事件都被取消。有限狀態(tài)機隱式狀態(tài)機FSM

不需要聲明狀態(tài)寄存器仿真效率高只適合于線性的狀態(tài)改變大多數(shù)綜合工具不能處理顯式FSM:利于結(jié)構(gòu)化易于處理缺省條件能處理復雜的狀態(tài)改變所有綜合工具都支持有限狀態(tài)機在隱式FSM中,只要數(shù)據(jù)在一個時鐘沿寫入并在另一個周期讀出,則會生成寄存器。所有FSM必須有復位,且狀態(tài)改變必須在單一時鐘信號的同一邊沿。通常,如果狀態(tài)改變簡單明確,且綜合工具接受隱式狀態(tài)機,就可以使用隱式類型。如果狀態(tài)改變很復雜,則顯式類型更加有效。隱式狀態(tài)機是一個行為級而非RTL代碼的典型例子。這種代碼依賴循環(huán)和內(nèi)嵌時序控制,有時也有命名事件、wait和disable語句。因此,隱式狀態(tài)機在綜合時通常不被支持。線性FSM是指從一個狀態(tài)到下一個狀態(tài)的轉(zhuǎn)換不需要任何條件。顯式有限狀態(tài)機moduleexp(out,datain,clk,rst);

inputclk,rst,datain;

outputout;regout;

regstate;

always@(posedgeclkorposedgerst)

if(rst){state,out}=2'b00;

else

case(state)1'b0:beginout=1'b0;

if(!datain)state=1'b0;

elsestate=1'b1;

end1'b1:beginout=datain;state=1'b0;

end

default:{state,out}=2'b00;

endcaseendmodule顯式有限狀態(tài)機可以在過程塊中用單一時鐘邊沿和case語句顯式地描述FSM。必須聲明定義狀態(tài)機的狀態(tài)狀態(tài)變量。要改變當前狀態(tài),必須在時鐘邊沿改變狀態(tài)變量的值。給通常不會發(fā)生的條件指定缺省動作是一個很好的描述方式。隱式有限狀態(tài)機moduleimp(out,datain,clk,rst);

outputout;regout;

inputclk,datain,rst;

always@(rst)//Synergyresetmethod

if(rst)assignout=1’b0;

else

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論