FPGA應(yīng)用與開發(fā)實踐教程 課件 附A5 Verilog HDL語言描述形式-條件語句和循環(huán)語句_第1頁
FPGA應(yīng)用與開發(fā)實踐教程 課件 附A5 Verilog HDL語言描述形式-條件語句和循環(huán)語句_第2頁
FPGA應(yīng)用與開發(fā)實踐教程 課件 附A5 Verilog HDL語言描述形式-條件語句和循環(huán)語句_第3頁
FPGA應(yīng)用與開發(fā)實踐教程 課件 附A5 Verilog HDL語言描述形式-條件語句和循環(huán)語句_第4頁
FPGA應(yīng)用與開發(fā)實踐教程 課件 附A5 Verilog HDL語言描述形式-條件語句和循環(huán)語句_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

VerilogHDL基本語法運(yùn)算符及表達(dá)式過程語句(initial、always)塊語句(begin-end、fork-join)賦值語句條件語句循環(huán)語句task和function說明語句主要內(nèi)容2if語句的結(jié)構(gòu)大致可歸納成以下三種1、if_else語句//只有一個if的形式if(表達(dá)式)語句;

例如:if(a>b)out=1;//if…else嵌套形式if(表達(dá)式1)語句1;elseif(表達(dá)式2)語句2;elseif(表達(dá)式3)語句3;........elseif(表達(dá)式m)語句m;else語句n;例如:if(a>b)out1=int1;elseif(a==b)out1=int2;elseout1=int3;//if…else的形式if(表達(dá)式)語句1;

else 語句2;例如:if(a>b)out=1;elseout=0;一、條件語句3if后面的表達(dá)式可為:邏輯表達(dá)式,關(guān)系表達(dá)式,一位的變量。執(zhí)行if語句時,系統(tǒng)首先計算表達(dá)式的值,若結(jié)果為0,x,z,按“假”處理,若結(jié)果為1,按“真”處理,執(zhí)行相應(yīng)的語句,每條語句必須以分號結(jié)束。語句可以是單句,也可以是多句,多句時用“begin-end”塊語句括起來。4if(a>b)beginout1=int1;out2=int2;endelsebeginout1=int2;out2=int1;end優(yōu)先級

5優(yōu)先級下面用if-else語句實現(xiàn)中斷優(yōu)先級moduleinterrupt(active,int0,int1,int2,int3);inputint0,int1,int2,int3;output[3:0]active;reg[3:0]active;always@(int0orint1orint2orint3)beginactive[3:0]<=4'b0;if(int0)active[0]<=1'b1;elseif(int1)active[1]<=1'b1;elseif(int2)active[2]<=1'b1;elseif(int3)active[3]<=1'b1;endendmodule6Verilog語言提供的case語句直接處理多分支選擇,通常用于描述譯碼器、數(shù)據(jù)選擇器、狀態(tài)機(jī)及微處理器的指令譯碼等,一般形式如下:2、case語句case(表達(dá)式)

分支表達(dá)式1:語句1;分支表達(dá)式2:語句2;……

分支表達(dá)式n:語句n;default:語句n+1;//如果前面列出了表達(dá)式所有可能取值,default語句可以省略endcase7case語句實現(xiàn)解碼器的代碼如下:moduledecoder(sel,res);input[2:0]sel;output[7:0]res;

reg[7:0]res;always@(selorres)begincase(sel)3’b000:res=8’b00000001;3’b001:res=8’b00000010;3’b010:res=8’b00000100;3’b011:res=8’b00001000;3’b100:res=8’b00010000;3’b101:res=8’b00100000;3’b110:res=8’b01000000;default:res=8’b10000000;

endcaseend

endmodulecase語句綜合后的電路,是不帶優(yōu)先級的多分支選擇電路。case(sel)2’b00:q=a;2’b01:q=b;2’b10:q=c;

default:q=d;

endcase8在case語句中,表達(dá)式與分支表達(dá)式1~分支表達(dá)式n之間的比較是一種全等比較,必須保證兩者的對應(yīng)位全等。如果表達(dá)式的值和分支表達(dá)式的值同時為不定值或者同時為高阻態(tài),則認(rèn)為是相等的。case(a)2’b1x:out=1;//只有a=1x,才有out=12’b1z:out=0;//只有a=1z,才有out=0

9case語句還有兩種變種,即casez語句和casex語句。

casez

忽略比較過程中值為z的位,即如果比較的雙方(表達(dá)式的值與分支表達(dá)式的值)有一方的某一位的值是z,那么對這些位的比較就不予考慮,只需關(guān)注其他位的比較結(jié)果。casex在casex語句中,則把這種處理方式進(jìn)一步擴(kuò)展到對x的處理,即將z和x均視為無關(guān)值。10case,casez,casex的真值表除了上面介紹的if…else語句、case語句,還有一種是前面簡單介紹過的條件操作符“?:”也能實現(xiàn)條件結(jié)構(gòu)。比如用條件操作符實現(xiàn)1位數(shù)值比較器assignout=(a>b)?1:0//表述簡潔易懂11注意事項:

一般經(jīng)常使用到的是casez語句,最好少用casex

case/casez/casex都是可綜合的

在電路中,可以用?來表示無關(guān)值的z

case的描述、匹配都是從上到下進(jìn)行的123、條件的描述完備性如果if語句和case語句的條件描述不完備,會造成不必要的鎖存器。可在if語句最后加上else;在case語句的最后加上default語句。if(a==1‘b1)q=1’b1;//生成鎖存器!

if(a==1'b1)q=1'b1;elseq=1'b0;//q有明確的值,不會生成鎖存器(1)if語句條件不完全情況13對于修改后的代碼,綜合工具將‘bx作為無關(guān)值,對沒有定義的項給出了缺省行為,其綜合結(jié)果為純組合邏輯——沒有不期望的鎖存器產(chǎn)生。//修改前,有鎖存器moduleincpif(a,b,c,d,q);inputa,b,c,d;outputq;regq;always@(aorborcord)if(a&b)q=d;elseif(a&~b)q=~c;endmodule//修改后,沒有鎖存器modulecompif(a,b,c,d,q);inputa,b,c,d;outputq;regq;always@(aorborcord)if(a&b)q=d;elseif(a&~b)q=~c;elseq='bx;endmodule14VerilogHDL程序另一種偶然生成鎖存器是在使用case語句時缺少default項的情況下發(fā)生的。(2)case語句條件不完全情況//修改前,有鎖存器moduleinccase(i_sel,i_a,i_b,q);input[1:0]i_sel;input:i_a,i_b;outputq;regq;always@(i_selori_aori_b)case(i_sel)2'b11:q=i_a;2'b10:q=i_b;endcaseendmodule

//修改后,無鎖存器moduleinccase(i_sel,i_a,i_b,q);input[1:0]i_sel;input:i_a,i_b;outputq;regq;always@(i_selori_aori_b)case(i_sel)2'b11:q=i_a;2'b10:q=i_b;default:q='bx;endcaseendmodule

case語句的default分支雖然可以缺省,但是一般不要缺省,否則在組合邏輯中,會和if語句中缺少else分支一樣,生成鎖存器。if語句指定了一個有優(yōu)先級的編碼邏輯,而case語句生成的邏輯是并行的,不具有優(yōu)先級。if語句可以包含一系列不同的表達(dá)式,而case語句比較的是一個公共的控制表達(dá)式。通常if-else結(jié)構(gòu)速度較慢,但占用的面積小,case結(jié)構(gòu)速度較快,但占用面積較大,有時為了兼顧面積和速度,可以將if和case語句合用。注意事項16

大多數(shù)綜合工具都能處理綜合指令,綜合指令可以嵌在Verilog注釋中,因此在Verilog仿真時被忽略,只在綜合工具解析時有意義,不同工具使用的綜合指令在語法上不同。但其目的相同,都是在RTL代碼內(nèi)部進(jìn)行最優(yōu)化。通常綜合指令中包含工具或公司的名稱。(3)綜合指令17case和if語句一樣,都是用于選擇輸出的,但是case語句隱含的是平行的電路結(jié)構(gòu)。modulecomcase(a,b,c,d,e);inputa,b,c,d;outpute;rege;always@(aorborcord)case({a,b})2'b11:e=d;2'b10:e=~c;2'b01:e=1'b0;2'b00:e=1'b1;endcaseendmodule例如:全譯碼的case語句18modulecase_parallel(w,x,b);input[1:0]w;input[1:0]x;output[1:0]b;reg[1:0]b;always@(worx) begin case(2'b11)//synopsysparallel_case w: b<=2'b10; x: b<=2'b01; endcase endendmodule

VerilogHDL基本語法運(yùn)算符及表達(dá)式過程語句(initial、always)塊語句(begin-end、fork-join)賦值語句條件語句循環(huán)語句task和function說明語句主要內(nèi)容七、循環(huán)語句20VerilogHDL提供了如下4種循環(huán)語句,可用于控制語句的執(zhí)行次數(shù)。forever:連續(xù)的執(zhí)行語句。repeat:連續(xù)執(zhí)行一條語句n次。while:執(zhí)行一條語句直到某個條件不滿足。for:有條件的循環(huán)語句。二、循環(huán)語句注意:for、while和repeat是“可綜合”的,但循環(huán)的次數(shù)需要在編譯前就確定下來,動態(tài)改變循環(huán)次數(shù)的語句則是不可綜合的;forever語句是“不可綜合”的,常用于產(chǎn)生各類仿真激勵。211、forever語句

forever語句;或foreverbegin語句1;語句2;……endforever語句的格式如下:22forever表示永久循環(huán),無條件地?zé)o限次執(zhí)行其后的語句,相當(dāng)于while(1),直到遇到系統(tǒng)任務(wù)$finish或$stop,如果需要從循環(huán)中退出,可以使用disable。循環(huán)語句多用于生成時鐘等周期性波形,它與always語句不同之處在于不能獨(dú)立寫在程序中,而必須寫在initial塊中。initialbegin

clk=0;forever#25clk=~clk;end232、repeat語句repeat語句的格式如下:repeat(循環(huán)次數(shù)表達(dá)式)語句;或repeat(循環(huán)次數(shù)表達(dá)式)begin語句1;語句2;……end例如:if(rotate==1)repeat(8)begin

tmp=data[15]; data={data<<1,temp};//data循環(huán)左移8次

end24modulemult_acc(out,opa,opb);parametersize=8,longsize=16;input[size:1]opa,opb;output[longsize:1]out;wire[size:1]opa,opb;reg[longsize:0]out;reg[size:1]temp_opa,temp_opb;always@(opaoropb)beginout=0;temp_opa=opa;temp_opb=opb;repeat(size);//repeat語句,size為循環(huán)次數(shù)beginif(temp_opb[1])//如果opb的最低位為1,就執(zhí)行下面的加法out=out+temp_opa;temp_opa=temp_opa<<1;//操作數(shù)opa左移一位temp_opb=temp_opb>>1;/操作數(shù)opb右移一位endendendmodule仿真實例263、while語句while語句的格式如下:while(表達(dá)式)語句;或用如下格式:while(表達(dá)式)begin語句1;

語句2;……end下面舉一個while語句的例子,該例子用while循環(huán)語句實現(xiàn)從0到100計數(shù)并顯示出來。initialbegin count=0; while(count<101)begin $display(“count=%d”,count); count=count+1; endend仿真實例284、for語句for(循環(huán)變量賦初值;條件表達(dá)式;循環(huán)變量增值)語句;或

for(循環(huán)變量賦初值;條件表達(dá)式;循環(huán)變量增值)begin

語句1;

語句2; ……endfor語句的一般形式為:(同C語言類似)29例如:用for語句來實現(xiàn)8位數(shù)據(jù)中低4位左移到高4位:integeri;always@(inporcnt)beginresult[7:4]=0;result[3:0]=inp;if(cnt==1)beginfor(i=4;i<=7;i=i+1)begin result[i]=result[i-4];endresult[3:0]=0;endend

例如:在一個時鐘周期內(nèi)用for語句計算出13路脈沖信號為高電平的個數(shù)。moduletest_1(clk,rst,datain,numout);inputclk;inputrst;input[12:0]datain;

//輸入13路數(shù)據(jù)output[15:0]numout;

//13路數(shù)據(jù)電平為高的路數(shù)wire[15:0]numout;reg[3:0]i;reg[15:0]num;always@(posedge

clk)begin

if(!rst)begin

num=0;

end

elsebegin

for(i=0;i<13;i=i+1)//用for循環(huán)進(jìn)行計算begin

if(datain[i])num=num+1;end

endendassignnumout=num;

endmodule仿真實例315、disable語句一般情況下,循環(huán)語句都留有正常的出口用于退出循環(huán),但是在有些特殊情況下,仍需要強(qiáng)制退出循環(huán)。disable語句是強(qiáng)制退出循環(huán)的方法。//做4次加1操作后強(qiáng)制退出循環(huán),然后繼續(xù)執(zhí)行后續(xù)操作begin:continuefor(i=0;i<5;i=i+1)beginsum=sum+1;if(i==3)disablecontinue;endend

后續(xù)操作1;后續(xù)操作2;…

VerilogHDL基本語法運(yùn)算符及表達(dá)式過程語句(initial、always)塊語句(begin-end、fork-join)賦值語句條件語句循環(huán)語句task和function說明語句主要內(nèi)容八、task和function說明語句33程序中重復(fù)描述或功能比較單一的部分,可以簡化了程序的結(jié)構(gòu),增強(qiáng)了代碼的易懂性。注意task和function定義和調(diào)用都包含在一個module模塊內(nèi)部,格式與module模塊類似,但也有不同。它們一般用于行為建模,在編寫測試驗證程序時用得較多,佷多邏輯綜合軟件都不能佷好地支持任務(wù)和函數(shù)。三、task和function說明語句341、task說明語句(1)task的定義task定義的形式如下:task<任務(wù)名>;

//注意無端口列表//定義端口以及內(nèi)部變量input輸入端口名;//可以有一個或多個輸入端口,也可以沒有output輸出端口名;//可以有一個或多個輸出端口,也可以沒有inout雙向端口名;//可以有一個或多個雙向端口,也可以沒有wire內(nèi)部變量名;//可以有一個或多個內(nèi)部變量,也可以沒有reg內(nèi)部變量名;

//任務(wù)主體begin語句1;語句2;.....語句n;endendtask35(2)task的調(diào)用啟動任務(wù)并傳遞輸入輸出變量的聲明語句的語法如下:任務(wù)的調(diào)用:<任務(wù)名>(端口1,端口2,...,端口n);下面的例子說明怎樣定義任務(wù)和調(diào)用任務(wù):任務(wù)定義:tasktest;inputa,b,c;outputd,e;d=a&b; //對任務(wù)的輸出變量賦值e=a|c;endtask任務(wù)調(diào)用:test(in1,in2,in3,out1,out2);36下面是一個具體的例子用來說明怎樣在模塊的設(shè)計中使用任務(wù),使程序容易讀懂:moduletraffic_lights;regclock,red,amber,green;parameteron=1,off=0,red_tics=350,amber_tics=30,green_tics=200;//交通燈初始化initial red=off;initial amber=off;initial green=off;//交通燈控制時序alwaysbeginred=on; //開紅燈light(red,red_tics); //調(diào)用等待任務(wù)green=on; //開綠燈light(green,green_tics); //等待amber=on; //開黃燈light(amber,amber_tics); //等待end//定義交通燈開啟時間的任務(wù)tasklight;//注意此行不需要端口名列表outputcolor;

//task的輸出參量input[31:0]tics;

//task的輸入?yún)⒘縝eginrepeat(tics)@(posedgeclock);//等待tics個時鐘的上升沿color=off;//關(guān)燈endendtask//產(chǎn)生時鐘脈沖的always塊alwaysbegin#100clock=0;#100clock=1;endendmodule37例如:一個CPU總線控制的任務(wù)如下:`timescale1ns/10psmodulebus_ctrl_tb;reg[7:0]data;regdata_valid;regdata_rd;cpuu1(data_valid,data,data_rd);initialbegin cpu_driver(8'b0000_0000);//任務(wù)調(diào)用

cpu_driver(8'b1010_1010);//任務(wù)調(diào)用

cpu_driver(8'b0101_0101);//任務(wù)調(diào)用end//定義任務(wù)taskcpu_driver;input[7:0]data_in;begin #30data_valid=1; wait(data_rd==1); #20data=data_in; wait(data_rd==0); #20data=8'hzz; #30data_valid=0;endendtask//任務(wù)結(jié)束endmodule382、function說明語句(1)function的定義function定義的形式如下:function[返回值位寬或類型說明](函數(shù)名);//注意無端口列表//定義端口以及內(nèi)部變量input輸入端口名;//至少要有一個輸入端口作為參數(shù)wire內(nèi)部變量名;//定義內(nèi)部變量reg內(nèi)部變量名;//定義內(nèi)部變量//函數(shù)主體begin語句1;語句2;.....語句n;endendfunction392)function調(diào)用例如:定義一個四選一的函數(shù)//functionthatspecifiesamux4to1functionmux4to1;//注意:此處為分號。input[3:0]X;input[1:0]S4;case(S4)0:mux4to1=X[0];1:mux4to1=X[1];2:mux4to1=X[2];3:mux4to1=X[3];endcaseendfunction其調(diào)用格式如下:<函數(shù)名>(<表達(dá)式><表達(dá)式>);例如:通過調(diào)用4選1函數(shù)來實現(xiàn)16選1:modulemux16to1(W,S,f);input[15:0]W;input[3:0]

S;output

reg

f;always@(W,S)case(S[3:2])0:f=mux4to1(W[0:3],S[1:0]);//函數(shù)調(diào)用

1:f=mux4to1(W[4:7],S[1:0]);2:f=mux4to1(W[8:11],S[1:0]);3:f=mux4to1(W[12:15],S[1:0]);endcaseendmodule

VerilogHDL基本語法運(yùn)算符及表達(dá)式過程語句(initial、always)塊語句(begin-end、fork-join)賦值語句條件語句循環(huán)語句task和function說明語句編譯向?qū)е饕獌?nèi)容41編譯向?qū)荲erilogHDL編譯系統(tǒng)的一個組成部分,其含義就是在程序被編譯之前,將編譯向?qū)?幾種特殊的命令)進(jìn)行預(yù)處理,然后再將預(yù)處理的結(jié)果和源程序一起進(jìn)行通常的編譯處理。四、編譯向?qū)?、宏定義語句`define`define標(biāo)識符(宏名)字符串(宏內(nèi)容)42(1)用一個有意義的標(biāo)識符取代程序中反復(fù)出現(xiàn)的含義不明顯的字

符串。例如:宏定義主要可以起到兩個作用:(2)用一個較短的標(biāo)識符代替反復(fù)出現(xiàn)的較長的字

符串。例如:`defineWORDSIZE8reg[1:`WORDSIZE]data; //這相當(dāng)于定義reg[1:8]data;43`define

sum1ina+inb+inc+indmodulecalculate(out1,out2,ina,inb,inc,ind,ine);inputina,inb,inc,ind,ine;output[2:0]out1,out2;wireina,inb,inc,ind,ine;reg[2:0]out1,out2;always@(inaorinborincorine)beginout1=`sum1+ine;out2=`sum1-ine;endendmodule44上題中如果把宏定義改為:`define

sum1ina+inb+inc+ind;

經(jīng)過宏展開以后:out1=ina+inb+inc+ind;+ine;out2=ina+inb+inc+ind;-ine;顯然出現(xiàn)語法錯此外,在使用宏定義說明語句時候,還需注意:(1)宏定義不是VerilogHDL語句,不必在行末加分號,如果加了分號會連分號一起進(jìn)行置換。45(2)宏定義語句可以出現(xiàn)在程序中的任意位置。通常,`define命令寫在模塊定義的外面,作為程序的一部分,在此程序內(nèi)有效。如果對同一個宏名做了多次定義則只有最后一次定義生效。例如:`define

a=1modulemuti_define;reg[1:0]out1,out2,out3;initialbeginout1=`a;`definea=2out2=`a;definea=3out3=`a;end經(jīng)過宏展開以后:out1=1;out2=2,out3=346(3)在進(jìn)行宏定義時,可以引用已定義的宏名,實現(xiàn)層層置換。如:`defineaaa+b`defineccc+`aamoduletest;rega,b,c,d;wireout;assignout=`cc+d;endmodule這樣經(jīng)過宏展開以后,assign語句為assignout=c+a+b+d;47例如:元件符號如圖所示的帶有宏定義的8分頻器代碼如下。`defineN3`defineDataWidth`Nmoduleclk_div8(clkout,clkin);inputclkin;outputclkout;reg

clkout;reg

clk;reg[`DataWidth-1:0]counter;always@(posedge

clkin)begin

溫馨提示

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

評論

0/150

提交評論