《Verilog HDL數字系統設計與應用》 課件 FPGA-第4章-行為描述語言_第1頁
《Verilog HDL數字系統設計與應用》 課件 FPGA-第4章-行為描述語言_第2頁
《Verilog HDL數字系統設計與應用》 課件 FPGA-第4章-行為描述語言_第3頁
《Verilog HDL數字系統設計與應用》 課件 FPGA-第4章-行為描述語言_第4頁
《Verilog HDL數字系統設計與應用》 課件 FPGA-第4章-行為描述語言_第5頁
已閱讀5頁,還剩34頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

第4章行為描述的語法4行為描述語言行為描述是一種從抽象角度來表示硬件電路,通過表達輸入與輸出之間的關系來描述硬件行為的方法。行為描述直接根據電路外部行為進行描述,與硬件電路結構無關。VerilogHDL語法中的行為語句主要包括過程語句、塊語句、條件語句和循環語句。這些語句的用法與C語言很類似,容易理解,但也存在一些不同之處,如塊語句、casex和casez等。行為描述一般使用initial和always過程結構語句,其他行為語句只能出現在這兩種過程結構語句中。

VerilogHDL的過程語句主要包括initial語句和always語句。在一個模塊(module)中,使用initial和always語句的次數是不受限制的,而且每個initial和always都是并行執行的。initial語句通常用于仿真中的初始化,只在程序開始時執行一次。當觸發方式滿足后,always塊內的語句一直重復執行。該語句可綜合也可用于仿真,是一種被廣泛采用的電路設計方式。4.1過程語句

initial語句主要用于仿真測試,在仿真0時刻開始對變量進行初始化或激勵波形的產生。一個模塊中可以有多個initial語句,每個initial語句都是同時從仿真0時刻開始并行執行。initial語句不能被綜合,其格式如下:

initial begin/fork

語句1; 語句2;

……

語句n;

end/join

begin-end與fork-join塊語句類似C語言中的{},區別在于begin-end是串行執行的而fork-join是并行執行的。4.1.1initial語句4.1過程語句4.1過程語句【例4.1】用initial過程語句對測量變量a的賦值。

'timescasle10ns/1nsmoduletest; reg[2:0]a; initialbegina=3'b000; #5a=3'b001;#5a=3'b010;#5a=3'b011;#5a=3'b100;end endmodule在例4.1中,'timescasle10ns/1ns表示模塊仿真的時間單位為10ns,時間精度為1ns,并定義變量a,在initial語句中對a進行賦值。initial語句中的內容在仿真0時刻開始執行,并且只執行一次:仿真0時刻開始,a值為3'b000,經過50ns后a值為3'b001,再經過50ns后a值為3'b010,最后經過200ns后a值一直保持為3'b100。4.1過程語句4.1.2always語句只有當觸發條件滿足時,always語句才會不斷重復的執行其后的塊語句。always語句可被綜合也可用于仿真,多個always語句間是并行執行的,與書寫先后順序無關。always語句格式如下: always@(敏感信號列表) begin

語句1;

語句2; ……

語句n; end敏感信號分為兩種:一種為電平敏感型信號,一種為邊沿敏感型信號。敏感信號之間用“or”或者“,”隔開。例如:電平敏感型信號always@(A,B)與always@(AorB)這兩種書寫格式表示的內容是一樣。電平敏感型是指信號變量發生電平的變化,一般用于組合邏輯電路中。使用時應把可以引起always語句中的被賦值變量變化的所有信號都放入敏感信號列表中。4.1過程語句【例4.2】

用case語句描述一個3輸入與非門。modulemy_nand(f,a,b,c);inputa,b,c; outputregf; always@(aorborc)//等價于always@(a,b,c) case({a,b,c}) 3'b000:f=1;3'b001:f=1;3'b010:f=1;3'b011:f=1;3'b100:f=1;3'b101:f=1;3'b110:f=1;3'b111:f=0;default:f=1'bx;endcase endmodule4.1過程語句在例4.2中,只要a、b、c任何一個輸入信號發生變化,都會執行always語句一次。在case語句中,根據{a,b,c}的值來選擇執行其中一個分支。用always語句設計組合邏輯電路時,需將所有輸入變量都列入敏感信號列表中。可以用“*”來表示always過程語句中所有的輸入信號變量,其書寫格式有always*或always(*)。4.1過程語句例4.2中的程序可以寫為modulemy_nand(f,a,b,c);inputa,b,c; outputregf; always@(*) case({a,b,c}) 3'b000:f=1;3'b001:f=1;3'b010:f=1;3'b011:f=1;3'b100:f=1;3'b101:f=1;3'b110:f=1;3'b111:f=0;default:f=1'bx;endcase endmodule邊沿敏感型信號是指信號變量出現上升沿或者下降沿變化,主要用于時序邏輯電路中,有兩種表示形式:posedge表示上升沿,negedge表示下降沿。4.1過程語句【例4.3】設計一個同步清零、同步置數的D觸發器。 moduleDff(inputD,clk,reset,set,outputregQ); always@(posedgeclk) begin if(!reset)Q<=0; //同步清零,低電平有效 elseif(!set)Q<=1; //同步置數,低電平有效 else Q<=D; end endmodule在例4.3中,always語句的敏感信號列表為上升沿clk,當clk上升沿到來時,將執行always中的語句一次。執行always語句時會優先判斷reset復位信號,如果復位信號無效,則判斷set置數信號,這體現了清零的優先級高于置數的優先級的。當敏感信號列表中加入reset和set的邊沿信號時,D觸發器將變成異步清零、異步置數的D觸發器,當三個敏感信號的其中之一滿足觸發條件時,always后的塊語句執行一次,修改如下:always@(posedgeclk,negedgereset,negedgeset)4.1過程語句例如,下面的描述是錯誤的:always@(posedgeclk,negedgereset,negedgeset) begin if(reset)Q<=0; //應改為if(!reset) elseif(!set)Q<=1; else Q<=D; end語句的邏輯描述要與敏感信號列表中的有效電平一致。例如,采用reset信號下降沿為觸發信號,則低電平為有效置數電平,在描述置數功能時切勿寫成高電平有效。4.2塊語句4.2.1串行塊語句begin-end當語句有兩條以上時,要用塊語句將語句結合成一個整體,當塊內只有一條語句時,塊標識符就不需要了。塊語句分為串行塊語句begin-end和并行塊語句fork-join兩種。串行塊內各條語句按它們在塊內位置順序執行,比如:begin b=a;//先執行 c=b; //后執行 end串行塊語句begin-end塊內的語句順序執行:先將a的值賦值給b,再將b的值賦值給c,最后a,b,c的值相同。 begin-end也常用于仿真中的驅動波形的產生。4.2塊語句【例4.4】采用begin-end語句產生3輸入與非門的驅動波形。 `timescale1ns/1psmoduletest1_TF; rega,b,c; wiref; my_nanduut(.f(f),.a(a),.b(b),.c(c) ); initial begin {a,b,c}=3'b000; #100{a,b,c}=3'b000;#100{a,b,c}=3'b001; #100{a,b,c}=3'b010; #100{a,b,c}=3'b011; #100{a,b,c}=3'b100;#100{a,b,c}=3'b101; #100{a,b,c}=3'b110; #100{a,b,c}=3'b111; endendmodule4.2塊語句并行塊內各條語句各自獨立地同時開始執行,即塊內各條語句開始執行時間都是進入塊內的時間,屬于并發執行。比如:假設執行下面語句前a=1,b=2,c=3。 fork b=a; c=b; join

上述fork-join塊語句執行完后,等式左邊b和c同時得到等式右邊的值,即:b=1,c=2。

在進行仿真時,fork-join并行塊中每條語句前面的延時都是相對于該并行塊的起始執行時間的。4.2.2并行塊語句fork-join4.2塊語句【例4.5】采用fork-join語句產生3輸入與非門的驅動波形。 `timescale1ns/1psmoduletest1_TF; rega,b,c; wiref; my_nanduut(.f(f),.a(a),.b(b),.c(c) ); initial fork {a,b,c}=3'b000; #100{a,b,c}=3'b000;#200{a,b,c}=3'b001; #300{a,b,c}=3'b010; #400{a,b,c}=3'b011; #500{a,b,c}=3'b100;#600{a,b,c}=3'b101; #700{a,b,c}=3'b110; #800{a,b,c}=3'b111; joinendmodule4.3條件語句VerilogHDL提供兩種條件語句:if-else語句和case語句,兩種語句都屬于順序執行語句,而且必須在過程塊如initial或always等內使用。4.3.1if-else語句

用if-else語句來判定所給條件是否滿足,根據判定結果(真或假)決定執行給出的兩種操作之一。與C語言中if語句類似,VerilogHDL提供三種形式的if語句。C語言中用{}將語句括起來,VreilogHDL語言則用begin-end將語句括起來。1、if(表達式)

語句;單分支語句,如果表達式為真,則執行語句,否則不執行語句。例如:if(a==b)out1<=int1;2、if(表達式)

語句1;else語句2;雙分支語句,如果表達式為真,則執行語句1,否則執行語句2。例如:if(a==b)out1<=int1;elseout1<=int2;4.2塊語句3、if(表達式1)

語句1;elseif(表達式2)語句2;elseif(表達式3)語句3;……elseif(表達式n)語句n;else語句n+1;

多分支語句:如果表達式1為真,則執行語句1,否則再判斷表達式2;如果表達式2為真,執行語句2,否則再判斷表達式3,以此類推,直到最后。例如:if(a==b)out1<=int1; elseif(a<b)out1<=int2; elseout1<=int3;

上述三種形式中的“表達式”一般為邏輯表達式、關系表達式或1位變量。if語句對表達式的值進行判斷,若值為0、x或z則按“假”處理,若值為1則按“真”處理。盡量不要使用方式一,因為有if沒有else會容易產生不必要的觸發器用于保存if語句不成立時的值。4.2塊語句語句可是單句,也可是多句,多句時用begin-end塊語句括起來。比如: if(a>b)begina<=b;b<=c;end else beginc<=a;b<=c;end

注意:在end后面不需要加分號。

在if與else配對關系上,else總是與它前面最近if配對,且else不能單獨出現,有else的地方必須要有一個if與它配對。4.2塊語句比如:

下面為錯誤例子: if(a>b)out1<=int1;if(c==0)beginout1<=int2;endout2<=int3; else out2<=int4;

上述例子中由于書寫格式不清晰,導致else配對出現錯誤和語法錯誤,可以將上面程序寫成:if(a>b)beginout1<=int1;if(c==0)beginout1<=int2;endout2<=int3;endelse beginout2<=int4;end4.2塊語句【例4.6】使用if-else語句設計八位數據選擇器。moduleMUX8(out,in0,in1,sel); parameterN=8; outputreg[N:1]out; input[N:1]in0,in1; inputsel; always@(*) begin if(sel)out<=in0; elseout<=in1;endendmodule4.2塊語句【例4.7】

設計一個帶同步清零和加載端(低電平有效)的模60的BCD碼計數器。 `timescale1ns/1ps modulecounter //模塊聲明采用Verilog-2001格式 (inputload,clk,reset, input[7:0]data, outputreg[7:0]BCDout, outputcout); always@(negedgeclk) //時鐘下降沿觸發always begin if(!reset) BCDout<=0; //同步復位,reset=1時復位 elseif(!load)BCDout<=data;//同步加載,load=1時加載 elsebegin if(BCDout[3:0]>=9)//個位在0~9內加1 beginBCDout[3:0]<=0; if(BCDout[7:4]==5)BCDout[7:4]<=0;//十位在0~5內加1 elseBCDout[7:4]<=BCDout[7:4]+1; end elseBCDout[3:0]<=BCDout[3:0]+1; end end assigncout=(BCDout==8'h59)?1:0; endmodule4.2塊語句

case語句是一種多分支選擇語句,使用case語句代替if-else語句可使讀者更容易讀懂代碼,邏輯利用率和性能上都有所提高。case語句有case、casez、casex三種方式,casez忽視“z”而casex忽視“x”,使用方法有所不同。4.3.2case語句1.case語句case語句的使用格式如下:case(條件表達式)

值1:語句1; //case分支項

值2:語句2; ……

值n:語句n; default:語句n+1;//缺省項 endcase//結束case語句4.2塊語句case語句執行過程:首先計算出條件表達式的值,按順序將它和各分支項值進行比較,然后執行相匹配的分支語句;如果都不滿足匹配條件,則執行default后面的語句。

若前面已列出了條件表達式所有可能的取值,則default語句可以省略;若未列全所有取值,最好不要省略default語句,否則會產生不必要的鎖存器。說明:(1)case分支表達式值1~n必須互不相同,否則會出現矛盾現象,同一個值有多種執行語句。(2)執行完case分支語句后,則跳出case語句結構,終止case語句執行(無需像C語言要break才跳出分支)。(3)case語句條件表達式與分支值的位寬必須相等。4.2塊語句【例4.8】

使用case語句實現一個有使能控制端res(低電平復位)的四選一數據選擇器。modulemux(EN,IN0,IN1,IN2,IN3,SEL,OUT); inputEN;input[3:0]IN0,IN1,IN2,IN3;input[1:0]SEL; outputreg[3:0]OUT; always@(SELorENorIN0orIN1orIN2orIN3) begin if(EN==0)OUT={4{1'b0}}; elsecase(SEL) 0:OUT=IN0; 1:OUT=IN1; 2:OUT=IN2; 3:OUT=IN3; default:OUT=4'bx; endcase endendmodule4.2塊語句【例4.9】

使用case語句描述的3人表決電路。 modulevote3 (inputa,b,c,outputregpass); always@(a,b,c)begin case({a,b,c}) //用case語句進行譯碼 3’b000:pass=1'b0; //表決不通過 3’b001:pass=1'b0; 3’b010:pass=1'b0; 3’b011:pass=1'b1; //表決通過 3’b100:pass=1'b0; 3’b101:pass=1'b1; //表決通過 3’b110:pass=1'b1; //表決通過 3’b111:pass=1'b1; //表決通過 default:pass=1'b0; endcase end endmodule4.2塊語句2.casez語句與casex語句(1)在case語句中,條件表達式與分支值1~n的比較是一種全等(===)的比較,條件表達式與分支的值必須完全相等。(2)在casez語句中,條件表達式與分支值1~n的比較不是全等的比較,如果分支表達式某些位的值為高阻z,則不比較忽略考慮,只需關注其他位的比較結果。(3)在casex語句中,條件表達式與分支值1~n的比較不是全等的比較,如果分支表達式某些位的值為高阻z或者是未知狀態x,則不比較忽略考慮,只需關注其他位的比較結果。例如:case(in)2'b1z:out=1; //只有in=2'b1z,才有out=1casez(in)2'b1x:out=1; //如果in=2'b1z或2'b1x,則out=1casex(in)2'b1z:out=1; //如果in=2'b1z、2'b1x、2'b11或2'b10,則out=14.2塊語句此外,還有一種表示x或z的方式,即用表示無關值的符號“?”來表示。例如:casez(in) 2'b1?:out=1; //如果in=2’b10、2’b11、2’b1x或2’b1z,則out=1case、casez和casex語句的比較如表4.1所示。表4.1case、casez和casex語句的比較4.2塊語句【例4.10】

用casez語句描述8-3編碼器。modulecoder_83(inputx,input[7:0]data,outputreg[2:0]code);always

@(data)begincasez

(data)8'b1xxx_xxxx:code=3'b111;8'b01xx_xxxx:code=3'b110;8'b001x_xxxx:code=3'b101;8'b0001_xxxx:code=3'b100;8'b0000_1xxx:code=3'b011;8'b0000_01xx:code=3'b010;8'b0000_001x:code=3'b001;8'b0000_0001:code=3'b000;default:code=3'bx;endcaseendendmodule4.4循環語句VerilogHDL中的循環語句用于控制語句的執行次數。循環語句語句主要有以下4種:(1)for:有條件的循環語句;(2)repeat(n):連續執行循環語句n次;(3)while:執行一條語句直到某個條件不滿足,如果條件不滿足,則直接退出循環;(4)forever:永遠連續執行語句,可以用作時鐘等周期性波形的生成。4.4循環語句4.4.1for語句for

語句的格式如下(同C語言):for

(循環變量初始化;循環結束條件;循環變量增量)

執行語句;其中:循環變量初始化用于提供循環變量的初始值;循環結束條件一般為表達式用于指定循環結束的條件;循環變量增量通常為增加或減少循環變量的計數值;執行語句即需要循環的語句,有多條語句時用begin-end括起來。for語句的執行過程如下:(1)執行循環變量賦初值一次。(2)判斷循環結束條件是否成立,如果不成立,則退出for循環;如果成

立,則執行循環語句,再執行循環變量增量語句。(3)重復過程(2)。4.4循環語句【例4.11】用for語句描述10人表決器。

module

responder(input[9:0]

vote,output

reg

result)

;

reg[2:0]

sum;

integer

i;

always

@(vote)beginsum=0

;

for(i=0;

i<=9;

i=i+1)if

(vote[i])

sum=sum+1;if

(sum>5)result=1;//若超過5人贊成,則result=1

elseresult=0;endendmodule4.4循環語句【例4.12】用for語句計算輸入的九位數據中1的個數。

moduleget1(in,count); input[8:0]in; outputreg[3:0]count; integeri; always@(in) begin for(i=0;i<=8;i=i+1) if(in[i]==1'b1)count=count+1; end endmoudule一般情況下,綜合器都支持for循環語句,而不支持其他三種循環語句。4.4循環語句repeat語句的格式如下:repeat(表達式)

語句或 repeat(表達式)begin多條語句endrepeat循環語句的執行過程為:先計算表達式的值,再根據其值決定循環次數;如果表達式的值不確定(x或z)則循環次數按0次處理。4.4.2repeat語

溫馨提示

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

評論

0/150

提交評論