![《基于FPGA的現(xiàn)代數(shù)字系統(tǒng)設(shè)計(jì)》課件第3章_第1頁(yè)](http://file4.renrendoc.com/view14/M01/32/3F/wKhkGWdFZmmAXHkLAAQCKH6IUfk362.jpg)
![《基于FPGA的現(xiàn)代數(shù)字系統(tǒng)設(shè)計(jì)》課件第3章_第2頁(yè)](http://file4.renrendoc.com/view14/M01/32/3F/wKhkGWdFZmmAXHkLAAQCKH6IUfk3622.jpg)
![《基于FPGA的現(xiàn)代數(shù)字系統(tǒng)設(shè)計(jì)》課件第3章_第3頁(yè)](http://file4.renrendoc.com/view14/M01/32/3F/wKhkGWdFZmmAXHkLAAQCKH6IUfk3623.jpg)
![《基于FPGA的現(xiàn)代數(shù)字系統(tǒng)設(shè)計(jì)》課件第3章_第4頁(yè)](http://file4.renrendoc.com/view14/M01/32/3F/wKhkGWdFZmmAXHkLAAQCKH6IUfk3624.jpg)
![《基于FPGA的現(xiàn)代數(shù)字系統(tǒng)設(shè)計(jì)》課件第3章_第5頁(yè)](http://file4.renrendoc.com/view14/M01/32/3F/wKhkGWdFZmmAXHkLAAQCKH6IUfk3625.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第3章基于VerilogHDL語(yǔ)言的設(shè)計(jì)3.1VerilogHDL概述3.2門(mén)級(jí)建模3.3數(shù)據(jù)流建模3.4行為級(jí)建模3.5VerilogHDL的可綜合設(shè)計(jì)3.6Testbench文件與設(shè)計(jì)3.7VerilogHDL在ISE軟件中設(shè)計(jì)示例小結(jié)習(xí)題實(shí)驗(yàn)項(xiàng)目 3.1VerilogHDL概述
硬件描述語(yǔ)言支持層次化的設(shè)計(jì)、IPCore可重用設(shè)計(jì),在EDA工具、FPGA芯片支持下,實(shí)現(xiàn)了一種貫穿設(shè)計(jì)、綜合、仿真和下載等多個(gè)環(huán)節(jié)的數(shù)字系統(tǒng)快速實(shí)現(xiàn)的方法。設(shè)計(jì)者可以在較為抽象的層次上用HDL對(duì)電路進(jìn)行描述,將繁瑣的實(shí)現(xiàn)細(xì)節(jié)交由EDA工具完成,極大地降低了設(shè)計(jì)復(fù)雜度,縮短了開(kāi)發(fā)周期。
使用硬件描述語(yǔ)言設(shè)計(jì)的數(shù)字系統(tǒng),可不依賴特定的廠商和器件,可移植性好。常用的HDL語(yǔ)言有VerilogHDL和VHDL兩種。
VerilogHDL由GDA公司的PhilMoorby在1983年末首創(chuàng),1989年CADENCE公司收購(gòu)了GDA公司,1990年CADENCE公司公開(kāi)發(fā)表了VerilogHDL,成立了OVI(OpenVerilogInternational)組織。隨后IEEE制定了VerilogHDL的IEEE標(biāo)準(zhǔn),進(jìn)一步推動(dòng)了VerilogHDL的應(yīng)用。
VHDL(VHSICHardwareDescriptionLanguage)中的VHSIC是VeryHighSpeedIntegeratedCircuit的縮寫(xiě)。VHDL是美國(guó)國(guó)防部為了解決項(xiàng)目的多個(gè)承包人的信息交換困難、設(shè)計(jì)維修困難的問(wèn)題而提出的,由TI、IBM和INTERMETRICS公司完成,于1987年制定為IEEE標(biāo)準(zhǔn),即IEEEstd1076-1987[LRM87],后又進(jìn)行一些修改,成為新的標(biāo)準(zhǔn)版本。
VHDL和VerilogHDL兩種語(yǔ)言的主要功能差別不大,它們的描述能力類(lèi)似,相比較而言,VHDL較VerilogHDL系統(tǒng)描述能力稍強(qiáng),VerilogHDL的底層描述能力比VHDL強(qiáng)得多。VerilogHDL擁有廣泛的設(shè)計(jì)群體,成熟的資源比VHDL豐富;完成同一功能描述,VerilogHDL的描述較VHDL更為簡(jiǎn)潔;VerilogHDL也較易于學(xué)習(xí),只要有C語(yǔ)言的編程基礎(chǔ),一般經(jīng)過(guò)2~3個(gè)月的認(rèn)真學(xué)習(xí)和實(shí)際操作就能掌握,而VHDL設(shè)計(jì)不很直觀,一般需要有半年多的專(zhuān)業(yè)培訓(xùn)才能掌握。
本節(jié)通過(guò)用VerilogHDL描述幾個(gè)簡(jiǎn)單的數(shù)字電路,總結(jié)出VerilogHDL的基本特點(diǎn)、設(shè)計(jì)規(guī)則,并建立層次建模的概念,實(shí)現(xiàn)VerilogHDL學(xué)習(xí)的快速入門(mén)。3.1.1幾個(gè)簡(jiǎn)單的VerilogHDL例子
例3-1
設(shè)計(jì)一個(gè)二選一電路,實(shí)現(xiàn)表3.1的功能。
modulemux21(a,b,sel,c);
inputa,b;
inputsel;
outputc;
wirec;
assignc=sel?b:a;
endmodule從例3-1可以看出:
(1)?VerilogHDL的程序描述必須位于關(guān)鍵詞module和endmodule之間。
(2)每個(gè)模塊必須有一個(gè)模塊名,如上例的mux21。
(3)需要對(duì)模塊的輸入、輸出端口進(jìn)行說(shuō)明,如上例程序的第二、三、四行表述模塊的輸入端口是a、b、sel,輸出端口是c。
(4)模塊的變量說(shuō)明,如程序的第五行聲明了一個(gè)線網(wǎng)變量c。
(5)第六行語(yǔ)句使用條件操作符,實(shí)現(xiàn)模塊的功能,即判斷sel是否等于1,如果等于1,b的值賦給c,否則a的值賦給c。這段程序描述通過(guò)綜合工具,可轉(zhuǎn)換成圖3.1的門(mén)級(jí)電路圖。圖3.1二選一的電路圖例3-2用VerilogHDL描述一個(gè)用時(shí)鐘上升沿觸發(fā)、同步復(fù)位的D觸發(fā)器。
moduleDflop(d,reset,clk,q);
inputd,clk;
inputreset;
outputq;
regq;
always@(posedgeclk)
if(reset==1)
q<=0;
else
q<=d;
endmodule從例3-2可以看出:
(1)模塊名是Dflop,輸入端口有三個(gè):d、clk和reset,輸出端口是q。
(2)程序的第五行聲明了一個(gè)寄存器變量q。
(3)always語(yǔ)句描述模塊的功能是:在每個(gè)clk上升沿時(shí),首先檢測(cè)reset的值,當(dāng)reset=1時(shí),輸出端口q復(fù)位為0,否則將輸入值d賦給輸出端口q。
(4)例3-2實(shí)現(xiàn)了圖3.2的數(shù)字時(shí)序電路。圖3.2D觸發(fā)器
例3-3
調(diào)用例3-2的D觸發(fā)器實(shí)現(xiàn)一個(gè)四位的移位寄存器。
寄存器存儲(chǔ)的數(shù)據(jù)在移位時(shí)鐘clock的作用下依次右移,這樣構(gòu)成移位寄存器。移位寄存器既可以存儲(chǔ)代碼,也可以用來(lái)實(shí)現(xiàn)數(shù)據(jù)的串行到并行的轉(zhuǎn)換。電路結(jié)構(gòu)如圖3.3所示。圖3.3四位的移位寄存器調(diào)用例3-2設(shè)計(jì)的D觸發(fā)器按照?qǐng)D3.3的結(jié)構(gòu)連接,在每次時(shí)鐘上升沿時(shí),數(shù)據(jù)依次向右移動(dòng)一位。經(jīng)過(guò)四個(gè)周期時(shí)鐘信號(hào)后,串行輸入的四位數(shù)據(jù)全部移入到移位寄存器中。如果在四個(gè)觸發(fā)器的輸出端引出數(shù)據(jù),就可實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)拇?并轉(zhuǎn)換。程序如下:
moduleshift_flop(D,reset,clock,Q);
//端口聲明
inputD,clock,reset;
output[3:0]Q;
wire[3:0]Q;//變量說(shuō)明
/*調(diào)用D觸發(fā)器Dflop四次,例化名分別命名成u1、u2、u3和u4,同時(shí)連接對(duì)應(yīng)的端口,
組成四位移位寄存器*/
Dflopu1(D,reset,clock,Q[3]);
Dflopu2(Q[3],reset,clock,Q[2]);
Dflopu3(Q[2],reset,clock,Q[1]);
Dflopu4(Q[1],reset,clock,Q[0]);
endmodule從例3-3可以看到,VerilogHDL很好地支持了“自頂向下”的設(shè)計(jì)理念。
VerilogHDL支持測(cè)試激勵(lì)模塊的設(shè)計(jì)。在仿真軟件,如Modelsim(詳見(jiàn)第5章)的支持下,將測(cè)試模塊描述的激勵(lì)信號(hào)傳輸?shù)酱郎y(cè)的功能模塊中,在仿真軟件中可以觀察功能模塊的輸出情況,從而實(shí)現(xiàn)對(duì)功能模塊的軟件測(cè)試,及早發(fā)現(xiàn)設(shè)計(jì)中的問(wèn)題。
例3-4
對(duì)例3-3設(shè)計(jì)的模塊編寫(xiě)測(cè)試文件。
`timescale1ns/100ps //定義測(cè)試文件中一個(gè)時(shí)間的單位是1ns、時(shí)間精度是100ps
moduletestbench();
//說(shuō)明測(cè)試輸入端口
regD;
regclock;
regreset;
wire[3:0]Q;
//例化待測(cè)試的移位寄存器
shift_flopu1(D,reset,clock,Q);
//產(chǎn)生時(shí)鐘信號(hào)
initial
begin
clock=0;
forever#10clock=~clock;
end
//產(chǎn)生輸入信號(hào)D,復(fù)位信號(hào)reset
initial
begin
D=1'b1;reset=0;
#20reset=1;
#15D=1'b0;
#20D=1'b1;
#100reset=0;
#10$stop;
end
endmodule3.1.2VerilogHDL的基礎(chǔ)知識(shí)
1.VerilogHDL的基本結(jié)構(gòu)
VerilogHDL可以描述數(shù)字系統(tǒng)的邏輯功能,描述組合成為一個(gè)系統(tǒng)的多個(gè)數(shù)字模塊之間的連接,并建立測(cè)試文件等功能。
模塊(module)是VerilogHDL設(shè)計(jì)的基本單元,VerilogHDL模塊可分為兩種類(lèi)型:一種是功能模塊,描述數(shù)字電路系統(tǒng)的結(jié)構(gòu)和功能,在EDA工具的支持下轉(zhuǎn)換成電路結(jié)構(gòu),完成布局、布線、下載,最后在FPGA上實(shí)現(xiàn)目標(biāo)系統(tǒng),功能模塊也可以僅以向仿真軟件提供仿真模型為目的,從而對(duì)設(shè)計(jì)方案進(jìn)行快速驗(yàn)證;另一種是測(cè)試模塊,為功能模塊的測(cè)試提供信號(hào)激勵(lì)、輸出數(shù)據(jù)監(jiān)測(cè),完成功能模塊的仿真測(cè)試。測(cè)試模塊的設(shè)計(jì)詳見(jiàn)3.6節(jié)。一般而言,模塊包括模塊名、端口名說(shuō)明、I/O端口聲明、各類(lèi)型變量聲明和模塊功能描述等。VerilogHDL模塊的一般結(jié)構(gòu)如以下程序所示。
module模塊名(input_port1,…input_portn,
output_port1,…output_portN,模塊名及模塊端口羅列
inout_port1,…inout_portM);
input[width_1-1:0]input_port1;
…
input[width_n-1:0]input_portn;下面介紹模塊中的基本內(nèi)容。
1)模塊名、端口名說(shuō)明
格式:
module模塊名(端口1,端口2,端口3,…,端口n);
VerilogHDL程序的模塊名是必須的,所有程序必須位于關(guān)鍵詞module、endmodule之間。
為便于工程管理,模塊名一般和實(shí)現(xiàn)的功能相關(guān),如halfadder(半加器)、top(頂層模塊)、testbench(測(cè)試模塊)等。命名的字符串必須符合VerilogHDL對(duì)字符串的規(guī)定。端口名說(shuō)明是一個(gè)可選項(xiàng)。
(1)當(dāng)模塊與外界沒(méi)有信息交互、無(wú)端口連接時(shí),聲明中就不需要無(wú)端口名的羅列。如包含了待測(cè)模塊和激勵(lì)信號(hào)的測(cè)試模塊,可聲明為moduletestbench();
(2)當(dāng)模塊和外界有信息交互時(shí),各端口名必須全部羅列,相互之間用逗號(hào)隔開(kāi),如
modulemux21(a,b,sel,c);
對(duì)于外界環(huán)境來(lái)說(shuō),模塊內(nèi)部是一個(gè)“黑盒子”,對(duì)模塊的例化(instance或稱(chēng)調(diào)用)都是通過(guò)對(duì)模塊端口的操作來(lái)完成的。
2)?I/O端口聲明
所有聲明的端口都必須說(shuō)明端口類(lèi)型、位寬。端口之間需用逗號(hào)隔開(kāi),語(yǔ)句用分號(hào)結(jié)束。
根據(jù)信號(hào)的方向不同,VerilogHDL中的端口類(lèi)型有以下三種:
(1)輸入端口:其聲明格式為
input[width-1:0]端口名1,端口名2,…,端口名n;
(2)輸出端口:其聲明格式為
output[width-1:0]端口名1,端口名2,…,端口名n;
(3)輸入/輸出端口:其聲明格式為
inout[width-1:0]端口名1,端口名2,…,端口名n;
width是端口的位寬,如果無(wú)位寬說(shuō)明,系統(tǒng)將默認(rèn)位寬為1。例如,
input[7:0]data_in; //一個(gè)名為data_in,位寬為8位的輸入數(shù)據(jù)
outputS,CO; //名為S和CO,位寬均為1位的兩個(gè)輸出數(shù)據(jù)
3)數(shù)據(jù)類(lèi)型說(shuō)明
對(duì)于模塊端口信號(hào)和模塊內(nèi)部信號(hào),需有相應(yīng)的數(shù)據(jù)類(lèi)型說(shuō)明。VerilogHDL的常用的數(shù)據(jù)類(lèi)型分為線網(wǎng)型和寄存器型。線網(wǎng)型表示結(jié)構(gòu)化元件之間的物理連線,寄存器型表示數(shù)據(jù)的存儲(chǔ)單元。為盡可能地反映真實(shí)硬件電路的工作情況,可對(duì)數(shù)字信號(hào)的邏輯、強(qiáng)度進(jìn)行建模,變量的邏輯值有0、1、x和z。x表示未初始化或者未知的邏輯值,z表示高阻狀態(tài)。
VerilogHDL定義了八種信號(hào)強(qiáng)度用于判斷數(shù)字電路中不同強(qiáng)度的驅(qū)動(dòng)源之間的賦值沖突,如表3.2所示。多個(gè)信號(hào)驅(qū)動(dòng)同一個(gè)線網(wǎng)時(shí),輸出信號(hào)邏輯強(qiáng)度的建立可以按如下方法判斷:
(1)邏輯值相同而強(qiáng)度不同的多個(gè)信號(hào)驅(qū)動(dòng)時(shí),輸出信號(hào)的邏輯值和強(qiáng)度由強(qiáng)度大的信號(hào)決定。
(2)邏輯值不同,但強(qiáng)度相同的多個(gè)信號(hào)驅(qū)動(dòng)時(shí),輸出信號(hào)的邏輯值可能會(huì)得到不定值。
4)模塊功能說(shuō)明
模塊邏輯功能的描述是模塊中最重要的部分,可根據(jù)設(shè)計(jì)需要選用以下四類(lèi)常用方法:
(1)用連續(xù)賦值語(yǔ)句“assign”進(jìn)行數(shù)據(jù)流建模。描述數(shù)據(jù)在各個(gè)寄存器、邏輯門(mén)之間的傳遞,詳見(jiàn)3.3節(jié)。
(2)調(diào)用已設(shè)計(jì)好的子模塊,組合成更復(fù)雜的系統(tǒng)。VerilogHDL支持“自頂向下”的設(shè)計(jì)方法,大型的、復(fù)雜的數(shù)字系統(tǒng)逐層分解成多個(gè)簡(jiǎn)單的模塊構(gòu)成,在分別完成各個(gè)子模塊設(shè)計(jì)后,通過(guò)上層模塊例化(或稱(chēng)調(diào)用)低層模塊的方式,完成目標(biāo)系統(tǒng)的組合。
(3)使用結(jié)構(gòu)說(shuō)明語(yǔ)句“always”、“initial”可以進(jìn)行變量初始化、組合電路和時(shí)序電路塊的描述,具體語(yǔ)法詳見(jiàn)3.4節(jié)。
(4)編寫(xiě)任務(wù)(task)和函數(shù)(function),對(duì)重復(fù)使用的功能進(jìn)行描述,為復(fù)雜系統(tǒng)的設(shè)計(jì)提供支持,具體語(yǔ)法詳見(jiàn)3.4節(jié)。
2.模塊的例化
通過(guò)模塊的例化(或稱(chēng)調(diào)用),VerilogHDL可以支持層次化設(shè)計(jì),實(shí)現(xiàn)“自頂向下”的設(shè)計(jì)思路,模塊例化的基本格式為
<模塊名><例化名>(<端口列表>);
根據(jù)被調(diào)用的低層模塊與上層模塊的端口連接方式描述的不同,有兩種例化方法:
(1)按端口順序連接:低層模塊定義時(shí)聲明的端口順序與上層模塊相應(yīng)的連接端口順序保持一致,其格式為
模塊名例化名(PORT_1,PORT_2,…,PORT_N);
(2)按端口名稱(chēng)連接:被調(diào)用的低層模塊和上層模塊是通過(guò)端口名稱(chēng)進(jìn)行連接,其格式為
模塊名例化名(.port_1(PORT_1),.port_2(PORT_2),…,.port_n(PORT_N));
其中:port_1,port_2,…,port_n表示被調(diào)用模塊設(shè)計(jì)聲明的各個(gè)端口;
PORT_1,PORT_2,…,PORT_N表示上一層模塊調(diào)用時(shí)對(duì)應(yīng)的端口名稱(chēng)。
這種連接端口的順序可以是任意的,只要保證上層模塊的端口名和被調(diào)用模塊端口的對(duì)應(yīng)即可。如果被調(diào)用模塊有不需要連接的端口,該端口可懸空寫(xiě)成.port_n(),也可將此端口忽略。例如,port_2不需要和外界連接,可以寫(xiě)成:
模塊名例化名(.port_1(PORT_1),.port_2(),…,.port_n(PORT_N));
或者
模塊名例化名(.port_1(PORT_1),,…,.port_n(PORT_N));/*注意,port_2雖然未寫(xiě)出,但其位置仍然保留*/
當(dāng)被調(diào)用模塊有較多端口時(shí),根據(jù)端口名稱(chēng)進(jìn)行信號(hào)連接,可避免因記錯(cuò)端口順序而出錯(cuò),并且在被調(diào)用模塊因修改使得端口順序發(fā)生變化時(shí),只要端口名稱(chēng)、功能不變,上層模塊調(diào)用就可以不更改。
在實(shí)際應(yīng)用中,可根據(jù)設(shè)計(jì)的復(fù)雜程度和設(shè)計(jì)習(xí)慣來(lái)選擇例化的方法。例3-5通過(guò)調(diào)用半加器模塊、或門(mén)模塊來(lái)實(shí)現(xiàn)一位全加器。
半加器模塊的端口如圖3.4所示。圖3.4半加器模塊的端口
(1)設(shè)計(jì)半加器。
modulehalfadder(A,B,CO,S);
inputA,B;
//輸入兩個(gè)1位的數(shù)據(jù)作為加數(shù)、被加數(shù)
outputS; //加法器輸出的和
outputCO; //加法器輸出的進(jìn)位
wireS,CO;
assignS=A^B;
assignCO=A&B;
endmodule
(2)設(shè)計(jì)一位全加器。
根據(jù)數(shù)字邏輯電路關(guān)系,調(diào)用半加器、或門(mén)組成一位全加器,其電路連接圖如圖3.5所示。圖3.5全加器電路連接圖
VerilogHDL可用以下兩種方法描述:
方法一:采用按端口順序連接
modulefulladder(a,b,co_in,co_out,s);
inputa,b,co_in;
outputco_out,s;
halfadderu1(a,b,co_temp1,s_temp);
halfadderu2(s_temp,co_in,co_temp2,s);
oru3(co_out,co_temp1,co_temp2);
endmodule方法二:采用按端口名稱(chēng)連接
modulefulladder(a,b,co_in,co_out,s);
inputa,b,co_in;
outputco_out,s;
halfadderu1(.A(a),.B(b),.CO(co_temp1),.S(s_temp));
halfadderu2(.A(s_temp),.B(co_in),.CO(co_temp2),.S(s));
oru3(co_out,co_temp1,co_temp2);
endmodule
3.?VerilogHDL基本概念
1)詞法約定
VerilogHDL中的基本詞法約定與C語(yǔ)言類(lèi)似,可以有空白、注釋、分隔符、數(shù)字、字符串、標(biāo)識(shí)符和關(guān)鍵詞等,其中關(guān)鍵詞全是小寫(xiě)字母。
(1)注釋?zhuān)簽榧訌?qiáng)程序的可讀性和文檔管理,設(shè)計(jì)程序中應(yīng)適當(dāng)?shù)丶尤胱⑨寖?nèi)容。注釋有兩種方式:?jiǎn)涡凶⑨尯投嘈凶⑨尅?/p>
①單行注釋以“//”開(kāi)始,只能寫(xiě)在一行中。例如,
assignc=a+b;//?c等于a,b的和
②多行注釋以“/*”開(kāi)始,以“*/?”結(jié)束,注釋的內(nèi)容可以跨越多行,例如,
assignc=a+b;/*?c等于a,b的和,本語(yǔ)句可綜合成一個(gè)加法器,實(shí)現(xiàn)加法的組合邏輯*/
(2)標(biāo)識(shí)符(identifier):用于定義模塊名、端口名、連線、信號(hào)名等。標(biāo)識(shí)符可以是任意一組字母、數(shù)字、$?符號(hào)和?_?(下劃線)符號(hào)的組合,但標(biāo)識(shí)符的第一個(gè)字符必須是字母或者下劃線,字符數(shù)不能多于1024個(gè)。此外,標(biāo)識(shí)符區(qū)分大、小寫(xiě)。例如,
state,State //這兩個(gè)標(biāo)識(shí)符是不同的
2and,&write //非法標(biāo)識(shí)符
(3)空白符:由空格(\b)、制表符(\t)和換行符定義而成,除了出現(xiàn)在字符串里,VerilogHDL中其它位置的空白符僅僅用于分隔標(biāo)識(shí)符,在編譯階段被忽略。
2)數(shù)據(jù)類(lèi)型
在程序設(shè)計(jì)中,數(shù)據(jù)有常量和變量?jī)煞N,下面分別進(jìn)行介紹。
(1)常量:是指在程序運(yùn)行中,其值不能改變的量。
①數(shù)字:其表達(dá)方式為
<位寬>′<進(jìn)制><數(shù)值>
說(shuō)明:
●?<位寬>:用十進(jìn)制表示的數(shù)字的位數(shù),如果缺省,位寬由具體機(jī)器系統(tǒng)決定(至少為32位)。
●?<進(jìn)制>:可以用四種進(jìn)制表示:二進(jìn)制(b或B)、八進(jìn)制(o或O)、十進(jìn)制(d或D)、十六進(jìn)制(h或H)。缺省時(shí)為十進(jìn)制。●?<數(shù)值>:可以是所選進(jìn)制表述的任意有效數(shù)字,包括不定值x和高阻態(tài)z。當(dāng)<數(shù)值>位寬大于指定的大小時(shí),截去高位。
例如,
8'b11001100 //位寬為8的二進(jìn)制數(shù),'b表示二進(jìn)制
'h1f23 //十六進(jìn)制數(shù),采用機(jī)器的默認(rèn)位寬
2'b110x //表示2'b0x,因?yàn)楫?dāng)數(shù)值大于指定的大小時(shí),截去高位
16'h1z0x //位寬為16位的十六進(jìn)制數(shù),其值的二進(jìn)制表示為16'b0001zzzz0000xxxx
可在數(shù)字之間使用下劃線“_”對(duì)數(shù)字進(jìn)行分隔,下劃線只增加數(shù)字的可讀性,在編譯階段將被忽略,如8'b1100_1100。②參數(shù)型(parameter):可以用parameter為關(guān)鍵詞,指定一個(gè)標(biāo)識(shí)符(即名字)來(lái)代表一個(gè)常數(shù),參數(shù)的定義常用在信號(hào)位寬定義,延遲時(shí)間定義等位置,以增加程序的可讀性,方便程序的修改,其格式為
parameter標(biāo)識(shí)符1?=?表達(dá)式1,標(biāo)識(shí)符2?=?表達(dá)式2,…標(biāo)識(shí)符n?=?表達(dá)式n;
這里的表達(dá)式可以是常數(shù),也可以是以前定義過(guò)的標(biāo)識(shí)符。例如,
parameterwidth=8; //定義了一個(gè)常數(shù)參數(shù)
input[width-1:0]data_in; //表示輸入信號(hào)data_in的位寬為8
parametera=1,b=3; //定義了兩個(gè)常數(shù)參數(shù)
parameterc=a+b; //表示c的值是前面定義的a、b值的和
(2)變量:指在程序運(yùn)行中,其值可以改變的量。VerilogHDL中常用的三種數(shù)據(jù)類(lèi)型為wire型、reg型和memory型,其它數(shù)據(jù)類(lèi)型的說(shuō)明請(qǐng)查閱VerilogHDL的相關(guān)手冊(cè)。
①線網(wǎng)wire型變量:wire型線網(wǎng)變量表示硬件單元之間的連接,它的值由驅(qū)動(dòng)元件的值決定。如果沒(méi)有驅(qū)動(dòng)元件連接到線網(wǎng),線網(wǎng)的缺省值為z。VerilogHDL模塊端口信號(hào)的數(shù)據(jù)類(lèi)型如無(wú)定義,默認(rèn)為wire型,其定義格式為
wire[width-1:0]變量名1,變量名2,…,變量名n;說(shuō)明:
●?[width-1:0]指明了變量的位寬,缺省此項(xiàng)時(shí)默認(rèn)變量位寬為1。
●?wire為關(guān)鍵詞,多個(gè)變量名之間用逗號(hào)隔開(kāi)。
●?模塊的輸入/輸出信號(hào)的數(shù)據(jù)類(lèi)型默認(rèn)為wire型。
例如,
wire[7:0]a,b; //位寬為8的wire型變量a和b
wirec; //?wire型變量c,位寬為1②reg型:reg型寄存器變量表示一個(gè)抽象的數(shù)據(jù)存儲(chǔ)單元,只能在initial語(yǔ)句和always語(yǔ)句中被賦值。寄存器型變量的默認(rèn)值是不定值x。其定義格式為
reg[width-1:0]變量名1,變量名2,…,變量名n;
例如,
reg[7:0]b,c; //兩個(gè)位寬為8的reg型變量b和c
rega; //?reg型變量a,位寬為1③memory型:memory型數(shù)據(jù)常用于寄存器文件,以及ROM、RAM的建模等。memory型數(shù)據(jù)是將reg型變量進(jìn)行地址擴(kuò)展而得到的,其格式為
reg[n-1:0]存儲(chǔ)器名[N-1:0];//定義位寬為n,深度為N的寄存器組
例如,
reg[7:0]mem[255:0]; //每個(gè)寄存器位寬為8,共有256個(gè)寄存器的寄存器組
對(duì)一組存儲(chǔ)單元進(jìn)行讀寫(xiě),必須指定該單元的地址,如對(duì)上例的mem寄存器的第200個(gè)存儲(chǔ)單元進(jìn)行賦0值的操作語(yǔ)句為
mem[200]=0; //對(duì)存儲(chǔ)器mem的第200個(gè)存儲(chǔ)單元賦值為0
需要注意memory型數(shù)據(jù)和reg型數(shù)據(jù)的區(qū)別。例如,
regmem[N-1:0]; //由N個(gè)位寬為1的寄存器組成的寄存器組mem
reg[N-1:0]a; //一個(gè)N位的寄存器變量a3.1.3VerilogHDL的描述層次
根據(jù)對(duì)電路描述的抽象程度不同,VerilogHDL描述有四個(gè)層次。
(1)行為級(jí)或算法級(jí):這是VerilogHDL支持的最高抽象級(jí)別,在這一級(jí)別上設(shè)計(jì)者關(guān)注算法的實(shí)現(xiàn),不關(guān)心具體的硬件實(shí)現(xiàn)細(xì)節(jié),幾乎可以使用VerilogHDL提供的所有語(yǔ)句。
(2)數(shù)據(jù)流級(jí):通過(guò)描述模塊內(nèi)部數(shù)據(jù)流的情況來(lái)描述該邏輯單元的功能,在這一級(jí)別上設(shè)計(jì)者關(guān)注數(shù)據(jù)的處理及其如何在線網(wǎng)上和寄存器間的傳遞。
一般情況下,寄存器傳輸級(jí)(RTL)描述指的是能夠通過(guò)綜合工具轉(zhuǎn)化為門(mén)級(jí)電路的行為級(jí)描述和數(shù)據(jù)流級(jí)描述。
(3)門(mén)級(jí):調(diào)用已設(shè)計(jì)好的邏輯門(mén)基本單元(原語(yǔ)),如與門(mén)、或門(mén)、異或門(mén)等,描述邏輯門(mén)之間的連接,構(gòu)成電路。
(4)開(kāi)關(guān)級(jí):這是VerilogHDL支持的最低抽象層次,通過(guò)描述器件中的晶體管、存儲(chǔ)節(jié)點(diǎn)及其它們的互聯(lián)來(lái)設(shè)計(jì)模塊。
由于開(kāi)關(guān)級(jí)描述的應(yīng)用較少,本章將從門(mén)級(jí)建模、數(shù)據(jù)流級(jí)建模和行為級(jí)建模等三個(gè)層次對(duì)VerilogHDL的語(yǔ)法進(jìn)行討論。 3.2門(mén)級(jí)建模
3.2.1門(mén)的類(lèi)型
VerilogHDL定義了兩類(lèi)基本的邏輯門(mén):與/或門(mén)類(lèi)(and/or)、緩沖/非門(mén)類(lèi)(buf/not),稱(chēng)為預(yù)定義的邏輯門(mén),在使用預(yù)定義的邏輯門(mén)原語(yǔ)例化邏輯門(mén)時(shí),可以直接使用相關(guān)原語(yǔ),無(wú)需再次聲明定義。預(yù)定義邏輯門(mén)調(diào)用時(shí),例化名可選,其格式為
<預(yù)定義邏輯門(mén)名><例化名>(端口列表);
例如,調(diào)用與門(mén)可以寫(xiě)成
oror1(out,in1,in2);
或or(out,in1,in2);
1.與/或門(mén)類(lèi)(見(jiàn)表3.3所示)
說(shuō)明:
(1)與/或門(mén)類(lèi)都有一個(gè)輸出端和多個(gè)輸入端,門(mén)端口列表中的第一個(gè)端口必定是輸出端口,其它是輸入端口。
(2)在門(mén)的例化調(diào)用中,如果輸入端口的個(gè)數(shù)超過(guò)兩個(gè),只需將輸入端口直接排列在端口列表中即可,VerilogHDL根據(jù)輸入端口數(shù)自動(dòng)選擇合適端口的邏輯門(mén)。
例如,設(shè)輸出端口為out,輸入端口為in1、in2、in3和in4。
andu1(out,in1,in2); //二輸入與門(mén)
xorx1(out,in1,in2,in3,in4); //四輸入異或門(mén),輸入端口數(shù)目超過(guò)2個(gè)
(3)基本門(mén)的真值表如表3.4所示。表3.4基本門(mén)的真值表
(4)如果輸入端口多于兩個(gè),則可以通過(guò)重復(fù)使用兩輸入真值表來(lái)計(jì)算輸出的值。
2.緩沖/非門(mén)類(lèi)
VerilogHDL提供了緩沖器和非門(mén)原語(yǔ),其邏輯符號(hào)和功能如表3.5所示。說(shuō)明:
(1)緩沖/非門(mén)類(lèi)邏輯門(mén)具有一個(gè)輸入,多個(gè)輸出,端口列表的最后一個(gè)端口是輸入端口,其它是輸出端口。
(2)如果輸出端口多于一個(gè),只需將所有的輸出端口排列在端口列表中,VerilogHDL可以根據(jù)端口自動(dòng)選擇合適的邏輯門(mén)。
例如,設(shè)in是輸入端口,out、out1、out2和out3是輸出端口。
buf(out,in); //單輸出緩沖門(mén)
not(out,in); //單輸出非門(mén)
bufb2(out1,out2,out3,in);//多輸出緩沖門(mén),例化名為b2
notn2(out1,out2,in);//多輸出非門(mén),例化名為n2
(3)緩沖器和非門(mén)的真值表如表3.6所示。
(4)?VerilogHDL還支持四個(gè)帶控制的條件緩沖器和條件反相器,它們有輸出、輸入和控制三個(gè)引腳,其功能和符號(hào)見(jiàn)表3.7,相關(guān)真值表見(jiàn)表3.8。例如,設(shè)out是輸出端口,in是輸入端口,control是控制端口。
bufif1u1(out,in,control);
bufif0u2(out,in,control);
notif1u3(out,in,control);
notif0u4(out,in,control);
在調(diào)用四種條件緩沖器和條件反相器時(shí),注意端口羅列的順序規(guī)則。3.2.2實(shí)例數(shù)組(ArrayofInstances)
在實(shí)際應(yīng)用中,常會(huì)對(duì)某種邏輯門(mén)進(jìn)行多次調(diào)用,實(shí)現(xiàn)多位寬數(shù)據(jù)的邏輯運(yùn)算,這可以通過(guò)實(shí)例數(shù)組的方式來(lái)表述,以簡(jiǎn)化書(shū)寫(xiě),其格式為
<邏輯門(mén)名字><實(shí)例名字><位寬>(端口列表);例3-6實(shí)現(xiàn)兩個(gè)3位數(shù)據(jù)的或運(yùn)算。3.2.3應(yīng)用舉例
下面用預(yù)定義邏輯門(mén)原語(yǔ)設(shè)計(jì)三個(gè)數(shù)據(jù)的奇偶校驗(yàn)位電路。
由于信道的噪聲干擾、傳輸中斷等原因容易使傳送的數(shù)據(jù)產(chǎn)生誤碼,奇偶校驗(yàn)是比較常用的檢錯(cuò)碼。它是一種通過(guò)增加冗余位使得碼字中1或0的個(gè)數(shù)恒為奇數(shù)或偶數(shù)的方法。
例3-7
設(shè)輸入是A、B、C,輸出的校驗(yàn)位碼字是F,其真值表如表3.9所示。
可以使用異或邏輯門(mén)來(lái)實(shí)現(xiàn)這個(gè)電路,其奇偶校驗(yàn)位電路如圖3.6所示。表3.9奇偶校驗(yàn)位的真值表圖3.6三個(gè)數(shù)據(jù)的奇偶校驗(yàn)位電路
邏輯圖與VerilogHDL的描述有一一對(duì)應(yīng)的關(guān)系。奇偶校驗(yàn)位電路的VerilogHDL門(mén)級(jí)描述如下:
moduleCRC_test(A,B,C,F(xiàn)); //端口說(shuō)明
inputA,B,C;
outputF;
wiretemp; //內(nèi)部線網(wǎng)temp聲明
xor(temp,B,C); //調(diào)用兩輸入的異或門(mén)
xor(F,temp,A);
endmodule3.2.4門(mén)延遲
1.上升、下降和關(guān)斷延遲
在VerilogHDL中,定義了三種輸入到輸出的延遲:
(1)上升延遲:邏輯門(mén)的輸出從低電平0、未知態(tài)x、高阻態(tài)z變化成為高電平1所需的時(shí)間。
(2)下降延遲:邏輯門(mén)的輸出從高電平1、未知態(tài)x、高阻態(tài)z變化成低電平0所需的時(shí)間。
(3)關(guān)斷延遲:邏輯門(mén)的輸出從高電平1、低電平0、未知態(tài)x變化成高阻態(tài)z所需的時(shí)間。
在VerilogHDL中,用戶可以使用表3.10中的三種方法指定邏輯門(mén)延時(shí)。
2.最小/典型/最大延遲
由于受集成電路制造工藝過(guò)程的影響,真實(shí)器件的延時(shí)會(huì)有一個(gè)變化的范圍。在VerilogHDL中,除了支持上述的三種延時(shí)以外,還可以分別指定每種延時(shí)的最小值、最大值和典型值。
(1)最小值(min_delay_time):邏輯門(mén)所具有的最小延時(shí)。
(2)典型值(typical_delay_time):邏輯門(mén)所具有的典型延時(shí)。
(3)最大值(max_delay_time):邏輯門(mén)所具有的最大延時(shí)。格式:
<邏輯門(mén)名>#(min_delay_time:typical_delay_time:max_delay_time)(portdeclare);
用戶可以在仿真一開(kāi)始就指定具體選用哪一種延時(shí)值(最大值/典型值/最小值),以建立不同的仿真模型。用戶也可以在仿真過(guò)程中控制延遲值的使用,具體的控制方法與使用的仿真器和操作系統(tǒng)有關(guān)。例如,
and#(4:5:6)(out,a,b);/*只聲明了一個(gè)延時(shí)時(shí)間,所有延時(shí)的最小值=4,典型值=5,最大值=6*/
or#(4:5:6,5:6:7)(out,c,d);/*聲明了兩個(gè)延時(shí),上升延時(shí)的最小值?=?4,典型值?=?5,最大值?=?6;下降延時(shí)的最小值?=?5,典型值?=?6,最大值=7*/
xor#(4:5:6,6:7:8,7:8:9)(out,in1,in2);/*聲明了三個(gè)延時(shí),
上升延時(shí)的最小值?=4,典型值?=?5,最大值?=?6
下降延時(shí)的最小值?=6,典型值?=?7,最大值?=?8
關(guān)斷延時(shí)的最小值?=7,典型值?=?8,最大值?=?9*/ 3.3數(shù)?據(jù)?流?建?模
3.3.1連續(xù)賦值語(yǔ)句
連續(xù)賦值語(yǔ)句常用于數(shù)據(jù)流行為建模,以assign為關(guān)鍵詞,操作符是“=”。
assign賦值語(yǔ)句執(zhí)行將數(shù)值賦給線網(wǎng),可以完成門(mén)級(jí)描述,也可從更抽象的角度對(duì)線網(wǎng)電路進(jìn)行描述,多用于組合邏輯電路的表述,其格式為
assign賦值目標(biāo)線網(wǎng)?=?表達(dá)式;
例如,
assigna=b|c; //兩輸入的或門(mén)
assign{c,sum[3:0]}=a[3:0]+b[3:0]+c_in;/*一個(gè)四位的加法器,a、b是加數(shù)和被加數(shù),
c_in是進(jìn)位,sum、c分別是相加后的和、進(jìn)位*/
assignc=max(a,b);//調(diào)用了求最大值的函數(shù)max,將函數(shù)返回值賦給c說(shuō)明:
(1)式子左邊的“賦值目標(biāo)線網(wǎng)”只能是線網(wǎng)變量,不能是寄存器變量。
(2)式子右邊表達(dá)式的操作數(shù)可以是線網(wǎng)、寄存器,也可以是函數(shù)調(diào)用。
(3)一旦等式右邊任何一個(gè)操作數(shù)發(fā)生變化,右邊的表達(dá)式就會(huì)立刻被重新計(jì)算,再進(jìn)行一次新的賦值。
(4)assign可以使用條件運(yùn)算符進(jìn)行條件判斷后再賦值,如下述語(yǔ)句:
assigndata_out=sel?a:b;/*如果sel等于1,將a賦給data_out,否則將b賦給data_out,
?實(shí)現(xiàn)一個(gè)二選一的電路*/
(5)可用賦值延時(shí)控制對(duì)線網(wǎng)賦予新值的延時(shí)時(shí)間,延時(shí)值位于關(guān)鍵詞assign的后面,但標(biāo)注的延時(shí)時(shí)間在編譯過(guò)程中將被忽略。
assign#10data_out=data_in1&data_in2;/*計(jì)算data_in1&data_in2的值,延遲10個(gè)時(shí)間單位賦給data_out,時(shí)間單位由'timescale給定*/3.3.2表達(dá)式、運(yùn)算符和操作數(shù)
表3.11運(yùn)算符的分類(lèi)和優(yōu)先級(jí)根據(jù)參加運(yùn)算的操作數(shù)的數(shù)目,運(yùn)算符可分為
(1)單目運(yùn)算符:對(duì)一個(gè)操作數(shù)進(jìn)行運(yùn)算的運(yùn)算符,如clock=~clock。
(2)雙目運(yùn)算符:對(duì)兩個(gè)操作數(shù)進(jìn)行運(yùn)算的運(yùn)算符,如a=b&c。
(3)三目運(yùn)算符:對(duì)三個(gè)操作數(shù)進(jìn)行運(yùn)算的運(yùn)算符,如D_out=condition?D_in1:D_in2。
1.算術(shù)運(yùn)算符
算術(shù)運(yùn)算符有加法(?+?)、減法(?-?)、乘法(?*?)、除法(?/?)和取模(%)。
例如,設(shè)a?=4'b0101,b=4'b0010
a+b //?a和b相加,等于4'b0111
a/b //?a除以b,等于4'b0010,余數(shù)部分舍棄,取整
a%b //?a對(duì)b取模,即求a、b相除的余數(shù)部分,結(jié)果等于1
注意:在算術(shù)運(yùn)算時(shí),如有一個(gè)操作數(shù)是不定值x,則運(yùn)算結(jié)果將不能得到確定數(shù)值。如果使用“+”、“-”運(yùn)算符作為操作數(shù)的正、負(fù)表示時(shí),它們的優(yōu)先級(jí)比雙目運(yùn)算符更高。
2.邏輯運(yùn)算符
邏輯運(yùn)算符有邏輯與(&&)、邏輯或(?||?)和邏輯非(?!?)。
說(shuō)明:
(1)“&&”和“||”是雙目運(yùn)算符,“!”是單目運(yùn)算符。
(2)邏輯運(yùn)算符的計(jì)算結(jié)果是一個(gè)一位的值,可以是:邏輯假(0)、邏輯真(1)和不確定(x)。
(3)如果操作數(shù)為具體數(shù)值時(shí),操作數(shù)不等于0,等價(jià)于邏輯真(1);操作數(shù)等于0,等價(jià)于邏輯假(0);操作數(shù)的任何一位為不定值x或者高阻態(tài)z,等價(jià)于不定值。例如,設(shè)a?=?2,b?=?0
a&&b //等于0,相當(dāng)于(邏輯1&&邏輯0)
a||b //等于1,相當(dāng)于(邏輯1||邏輯0)
!a //等于0,相當(dāng)于邏輯1取反
(a==3)&&(b==0)/*等于0,相當(dāng)于兩個(gè)表達(dá)式是否成立(為真),即如果a=3成立,則(a==3)
為邏輯1,否則為邏輯0*/
x&&a //等于x,相當(dāng)于(x&&邏輯1)
3.按位運(yùn)算符
按位運(yùn)算符有取反(?~?)、與(&)、或(?|?)、異或(?^?)和同或(?~^,^~?)。
說(shuō)明:
(1)取反運(yùn)算是單目運(yùn)算符,其余是雙目運(yùn)算符。
(2)按位運(yùn)算是對(duì)操作數(shù)中的每一位進(jìn)行按位操作。若兩個(gè)數(shù)的位寬不相同,系統(tǒng)先將兩個(gè)操作數(shù)右對(duì)齊,較短的操作數(shù)左端補(bǔ)0,使得兩個(gè)操作數(shù)位寬相同,然后再按位運(yùn)算。
(3)注意按位運(yùn)算和邏輯運(yùn)算的差別,邏輯運(yùn)算結(jié)果是一個(gè)一位的邏輯值,按位運(yùn)算產(chǎn)生一個(gè)與較長(zhǎng)位寬操作數(shù)等寬的數(shù)值。例如,設(shè)a?=4'b0011,b?=4'b1010,c?=3'b011,d=4'b11x0
~a //按位取反,結(jié)果等于4'b1100
b&c //按位與運(yùn)算,結(jié)果等于4'b0010
a^~d //按位同或運(yùn)算,結(jié)果等于4'b00x0
a&b //按位與運(yùn)算,結(jié)果等于4'b0010
下句與前句比較:
a&&b//邏輯與運(yùn)算,等價(jià)于1&&1,結(jié)果等于1
4.關(guān)系運(yùn)算符
關(guān)系運(yùn)算符包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)。
在運(yùn)算中,如果表達(dá)式成立,運(yùn)算結(jié)果是真(1);如果表達(dá)式不成立,運(yùn)算結(jié)果為假(0);如果操作數(shù)中某一位是不確定的,則表達(dá)式的結(jié)果是不定值。
例如,設(shè)a=4'b1010,b=4'b0001,c=4'b1xz0
a>b //結(jié)果等于邏輯值1
a<=c //結(jié)果等于邏輯值x
13–a>b /*由于算術(shù)運(yùn)算優(yōu)先級(jí)較高,先進(jìn)行13–a的計(jì)算,得到3,再和b進(jìn)行比較,結(jié)果等于邏輯值1*/
13–(a>b) /*由于括號(hào)表明了關(guān)系運(yùn)算的優(yōu)先級(jí),a>b成立,結(jié)果是真值為1,所以算術(shù)
結(jié)果等于12*/
5.等式運(yùn)算符
等式運(yùn)算符包括邏輯等(==)、邏輯不等(!=)、case等(===)、case不等(!==)。
說(shuō)明:
(1)若兩個(gè)操作數(shù)位寬不等,先將兩個(gè)操作數(shù)右對(duì)齊,用0填充較短數(shù)的左邊。
(2)邏輯等(==)和邏輯不等(!=)中,如果兩操作數(shù)中某一位是不確定的,則返回值是x;在邏輯等運(yùn)算時(shí),如果兩個(gè)數(shù)相同,返回邏輯值1,否則返回邏輯0。邏輯不等運(yùn)算,反之同理。
例如,設(shè)a=4'b1010,b=4'b1100,d=4'b101x
a==b; //結(jié)果為邏輯值0
a!=b; //結(jié)果為邏輯1
a==d; //結(jié)果為邏輯x
(3)?case等(===)、case不等(!==)與邏輯等式運(yùn)算符不同。在對(duì)兩個(gè)操作數(shù)進(jìn)行逐位比較時(shí),即使有x、z位,也要進(jìn)行精確比較。在case等運(yùn)算中,只有在兩者完全相等的情況下結(jié)果為1,否則為0。case等運(yùn)算符的結(jié)果不可能為x。
例如,設(shè)a=4'b1010,b=4'b1xzz,c=4'b1xzz,d=4'b1xzx
a===b; //結(jié)果為邏輯值0
b===c; //結(jié)果為邏輯值1(兩個(gè)數(shù)每一位都相同,包括x、z)
b===d; //結(jié)果為邏輯值0
b!==d; //結(jié)果為邏輯值1
6.縮減運(yùn)算符
縮減運(yùn)算符包括縮減與(?&?)、縮減與非(?~&?)、縮減或(?|?)、縮減或非(?~|?)、縮減異或(?^?)、縮減同或(?~^?)。這類(lèi)操作符將對(duì)操作數(shù)由左向右進(jìn)行操作,它們的運(yùn)算規(guī)則和按位操作符相同。
注意:縮減運(yùn)算符只有一個(gè)操作數(shù),按位運(yùn)算符有兩個(gè)操作數(shù)。
例如,設(shè)a=4'b1010
b=&a //?b=1&0&1&0=0
b=|a //?b=1|0|1|0=1
b=^a //?b=1^0^1^0=0
可以看到,用縮減異或、縮減同或可以產(chǎn)生一個(gè)向量的奇偶校驗(yàn)位。
7.移位運(yùn)算符
移位運(yùn)算符有右移(>>)、左移(<<)。右移(>>)和左移(<<)是分別將操作數(shù)向右、向左移動(dòng)指定的位數(shù),空出的位置用0補(bǔ)足。
例如,設(shè)a=4'b1010
b=a>>1; //右移1位,結(jié)果是b=4'b0101
b=a<<2; //左移2位,結(jié)果是b=4'b1000
移位運(yùn)算符在具體設(shè)計(jì)中有很多應(yīng)用,如乘法運(yùn)算可以轉(zhuǎn)換成移位相加來(lái)完成,可以進(jìn)行移位寄存器的移位操作等。
8.拼接運(yùn)算符
位拼接運(yùn)算符{}可以將兩個(gè)或多個(gè)操作數(shù)的某些位拼接起來(lái)成為一個(gè)操作數(shù)。拼接運(yùn)算時(shí),需要將拼接的操作數(shù)按照順序羅列出來(lái),其間用逗號(hào)隔開(kāi),操作數(shù)的類(lèi)型可以是線網(wǎng)變量、寄存器、線網(wǎng)向量、有確定位寬的常數(shù)等。
注意:進(jìn)行拼接的每個(gè)操作數(shù)必須是確定位寬的,因?yàn)橄到y(tǒng)進(jìn)行拼接時(shí)必須要確定拼接結(jié)果的位寬。例如,設(shè)a=1'b1,b=3'b101,c=4'b1010
X={a,b,c}; //結(jié)果是X=8'b11011010
Y={a,b,2'b01}; //結(jié)果是Y=6'b110101
Z={b[1:0],c[1],c[0]}; //結(jié)果是Z=4'b0110
位拼接可以使用重復(fù)操作、嵌套的方式來(lái)簡(jiǎn)化表達(dá)式。例如,
3{1'b1}=3'b111
{1'b0,3{1'b1}}=4'b0111
{1'b0,{3{2'b01}}=7'b0010101
9.條件運(yùn)算符
條件運(yùn)算符是一個(gè)三目的運(yùn)算符,其格式為
條件表達(dá)式?表達(dá)式1:表達(dá)式2
判斷過(guò)程是首先計(jì)算條件表達(dá)式:
(1)如果條件表達(dá)式為真,計(jì)算表達(dá)式1的值。
(2)如果條件表達(dá)式為假,計(jì)算表達(dá)式2的值。
(3)如果表達(dá)式為不確定值x,且表達(dá)式1和表達(dá)式2的值不相等,輸出結(jié)果為不確定值。
例如,
assignc=a>b?a:b//?a>b如果成立(真),c=a;反之,c=b3.3.3舉例
對(duì)同一個(gè)電路,可以從門(mén)級(jí)、數(shù)據(jù)流級(jí)和行為級(jí)不同角度進(jìn)行描述?,F(xiàn)在從數(shù)據(jù)流級(jí)的角度設(shè)計(jì)一個(gè)四選一電路和一位全加器。
例3-8
用數(shù)據(jù)流建模方式描述四選一選擇器,四選一選擇器模塊端口如圖3.7所示。
modulemux4_1(in1,in2,in3,in4,sel,out);
inputin1,in2,in3,in4;
input[1:0]sel;
outputout;
…
assignout=sel[1]?(sel[0]?in4:in3)
:(sel[0]?in2:in1);
endmodule圖3.7四選一選擇器模塊端口例3-9
用數(shù)據(jù)流建模方式設(shè)計(jì)一位全加器,電路圖如圖3.8所示。
modulefulladder(a,b,cin,s,co);
inputa,b;
inputcin;
outputs;
outputco;
assign{co,s}=a+b+cin;
endmodule圖3.8全加器電路圖 3.4行?為?級(jí)?建?模
3.4.1順序塊和并行塊語(yǔ)句
VerilogHDL中使用塊語(yǔ)句將多條語(yǔ)句組合成一條復(fù)合語(yǔ)句。塊語(yǔ)句分為順序塊語(yǔ)句和并行塊語(yǔ)句。
1.順序塊
順序塊中的語(yǔ)句按書(shū)寫(xiě)順序執(zhí)行,由begin…end標(biāo)識(shí),其格式為
beginbegin塊名
執(zhí)行語(yǔ)句1;塊內(nèi)變量、參數(shù)定義;
執(zhí)行語(yǔ)句2;或者執(zhí)行語(yǔ)句1;
…?執(zhí)行語(yǔ)句2;
end…
end說(shuō)明:
(1)塊名是可選的,它是一個(gè)塊的標(biāo)識(shí)名。
(2)塊內(nèi)可以根據(jù)需要定義變量,聲明參數(shù),但這些內(nèi)容只能在塊內(nèi)使用,類(lèi)似于局部變量和局部聲明。
(3)順序塊內(nèi)的語(yǔ)句是按照語(yǔ)句的書(shū)寫(xiě)順序執(zhí)行的。在仿真開(kāi)始時(shí)執(zhí)行第一條語(yǔ)句,后面語(yǔ)句的開(kāi)始執(zhí)行時(shí)間和前一條語(yǔ)句的執(zhí)行時(shí)間是相關(guān)的,如果有延時(shí),延時(shí)也是相對(duì)于前一條語(yǔ)句執(zhí)行完的仿真時(shí)間而言的。當(dāng)塊內(nèi)的最后一條語(yǔ)句執(zhí)行完后,才跳出該順序塊。
2.并行塊
并行塊中的語(yǔ)句并行執(zhí)行,由fork…join標(biāo)識(shí),其格式為
forkfork塊名
執(zhí)行語(yǔ)句1;塊內(nèi)變量、參數(shù)定義語(yǔ)句;
執(zhí)行語(yǔ)句2;或者執(zhí)行語(yǔ)句1;
…?執(zhí)行語(yǔ)句2;
join…
join說(shuō)明:
(1)塊名、塊內(nèi)變量、參數(shù)定義語(yǔ)句的理解與順序塊相同。
(2)并行塊的語(yǔ)句是同時(shí)執(zhí)行的,可以將每一條語(yǔ)句看成一個(gè)獨(dú)立的進(jìn)程,語(yǔ)句的書(shū)寫(xiě)順序不會(huì)影響到語(yǔ)句的執(zhí)行結(jié)果。應(yīng)注意避免并行塊中的多條語(yǔ)句對(duì)同一個(gè)變量進(jìn)行改變,否則可能會(huì)引起競(jìng)爭(zhēng)。
(3)塊內(nèi)每條語(yǔ)句的起始執(zhí)行時(shí)間是相同的,當(dāng)塊中執(zhí)行時(shí)間最長(zhǎng)的語(yǔ)句執(zhí)行完后,跳出并行塊的執(zhí)行。例3-10寫(xiě)出下面兩個(gè)順序塊和并行塊程序的執(zhí)行結(jié)果。
順序塊:
begin
s=0;
#2s=1;
#4s=0;
#5s=1;
#1s=0;
end并行塊:fork
s=0;
#2s=1;
#4s=0;
#5s=1;
#1s=0;?join
例3-10的順序塊和并行塊完成了對(duì)變量s的賦值過(guò)程,假設(shè)塊語(yǔ)句都從仿真時(shí)刻0開(kāi)始執(zhí)行,其實(shí)現(xiàn)的賦值過(guò)程如表3-12所示。3.4.2條件語(yǔ)句
1.if語(yǔ)句
if語(yǔ)句和它的變化形式是條件語(yǔ)句的常見(jiàn)形式。常見(jiàn)格式如下:
(1)?if(表達(dá)式)
<語(yǔ)句>;
(2)?if(表達(dá)式)
<語(yǔ)句1>;
else
<語(yǔ)句2>;
(3)?if(表達(dá)式1)
<語(yǔ)句1>;
elseif(表達(dá)式2)
<語(yǔ)句2>;
…
elseif(表達(dá)式n)
<語(yǔ)句n>;
else
<語(yǔ)句n+1>;說(shuō)明:
(1)?if后面的表達(dá)式,可以是邏輯表達(dá)式或關(guān)系表達(dá)式。如果表達(dá)式的值是真(1),執(zhí)行緊接在后的語(yǔ)句;如果是假(0),執(zhí)行else后的語(yǔ)句。
(2)?if后的表達(dá)式還可以是操作數(shù)。如果操作數(shù)是0、x、z等價(jià)于邏輯假,反之為邏輯真。下式是一種表達(dá)式的簡(jiǎn)化寫(xiě)法:
if(reset)等價(jià)于if(reset==1)
(3)?else不能作為單獨(dú)的語(yǔ)句使用,必須與if語(yǔ)句配對(duì)使用。
(4)如果if和else后有多個(gè)執(zhí)行語(yǔ)句,可以用begin…end塊將其整合在一起。例如,
if(a>b)
begin
data_out1<=a;
data_out2<=b;
end
else
…
(5)?if語(yǔ)句可以嵌套使用,但是在嵌套使用過(guò)程中,應(yīng)注意與if配對(duì)的else語(yǔ)句。通常,else與最近的if語(yǔ)句配對(duì)。例如,
if(a>b)//第一個(gè)if語(yǔ)句
if(c) //第二個(gè)if語(yǔ)句
data_out<=c+1;
else //與第二個(gè)if語(yǔ)句的配對(duì)else
data_out<=a+1;
else //與第一個(gè)if語(yǔ)句的配對(duì)else
data_out<=b;特別在if-else數(shù)目不一致時(shí),最好使用begin-end塊,如同算術(shù)表達(dá)式的括號(hào)一樣,確定if-else的配對(duì)關(guān)系,避免邏輯描述錯(cuò)誤。例如,
if(…)
begin
if(…)
執(zhí)行語(yǔ)句
if(…)
執(zhí)行語(yǔ)句;
else
執(zhí)行語(yǔ)句;
end
else
…
(6)如果不能正確使用else,可能會(huì)生成不需要的鎖存器。例如,
always@(aorb)//當(dāng)a或者b的數(shù)值發(fā)生變化時(shí),觸發(fā)always塊執(zhí)行
begin
if(a)
data_out<=a;
end
如果設(shè)計(jì)者的設(shè)計(jì)意圖是:當(dāng)a不為0時(shí),data_out賦值為a,否則被賦值為b。但上例描述的電路,在a等于0時(shí),data_out仍為前一個(gè)a值,從而生成了一個(gè)不希望的鎖存器。
(7)?if-else表達(dá)了條件選擇的設(shè)計(jì)意圖,它與條件操作符有重要的區(qū)別。
條件操作符可以出現(xiàn)在一個(gè)表達(dá)式中,而這個(gè)表達(dá)式可以使用在過(guò)程賦值中或者連續(xù)賦值中,可進(jìn)行行為建模,也可以進(jìn)行門(mén)級(jí)建模。
if-else語(yǔ)句只能出現(xiàn)在always、initial塊語(yǔ)句、函數(shù)和任務(wù)中,一般只能在行為建模中使用。
2.case語(yǔ)句
if-else語(yǔ)句提供了選擇操作,但如果選擇項(xiàng)數(shù)目較多,使用會(huì)很不方便,如果判斷用的條件是同一個(gè)表達(dá)式時(shí),使用case語(yǔ)句就很簡(jiǎn)便。
case是一種多分支選擇語(yǔ)句,其格式為:
case(控制表達(dá)式)
分支表達(dá)式1:語(yǔ)句1;
分支表達(dá)式2:語(yǔ)句2;
…
分支表達(dá)式n:語(yǔ)句n;
default:默認(rèn)語(yǔ)句;
endcase控制表達(dá)式常表示為控制信號(hào)的某些位,分支表達(dá)式是這些控制信號(hào)的具體狀態(tài)值。
語(yǔ)句執(zhí)行時(shí),先計(jì)算case后的控制表達(dá)式,然后將得到的值與后面的分支表達(dá)式的值進(jìn)行比較,當(dāng)控制表達(dá)式的值與某分支表達(dá)式的值相等時(shí),執(zhí)行該分支表達(dá)式后的語(yǔ)句,如果沒(méi)有匹配的分支表達(dá)式,執(zhí)行default后的默認(rèn)語(yǔ)句。
case語(yǔ)句的作用類(lèi)似于多路選擇器。用case語(yǔ)句可以容易、簡(jiǎn)潔地實(shí)現(xiàn)四選一、八選一、十六選一等電路描述。
例3-11
使用case語(yǔ)句設(shè)計(jì)數(shù)據(jù)選擇器MUX,其系統(tǒng)模塊圖和功能表如圖3.9所示。圖3.9選擇器的模塊圖和功能表
modulemux(data_in1,data_in2,sel,data_out);
input[1:0]data_in1,data_in2;
input[1:0]sel;
output[1:0]data_out;
always@(data_in1,data_in2,sel)
begin
case(sel)
2′b00:data_out<=data_in1^data_in2;
2′b01:data_out<=data_in1|data_in2;
2′b10:data_out<=data_in1&data_in2;
2′b11:data_out<=~data_in1;
default:data_out<=2‘bxx;
endcase
end
endmodule應(yīng)該注意:
(1)每個(gè)分支表達(dá)式的值必須是互不相同的,否則會(huì)出現(xiàn)同一個(gè)控制表達(dá)式值有多種執(zhí)行語(yǔ)句的矛盾。
(2)case語(yǔ)句執(zhí)行中,逐位對(duì)控制表達(dá)式的值和分支表達(dá)式的值進(jìn)行比較,每一位的值可能是0、1、x、z。如果兩者的位寬不一致,在較短數(shù)據(jù)左端加0,調(diào)整使兩者位寬相等。如果多個(gè)不同的狀態(tài)值有相同的執(zhí)行語(yǔ)句,可以用逗號(hào)將各個(gè)狀態(tài)隔開(kāi)。例如,
case(select)
2'b00:data_out<=data_in1;
…
2'b11:data_out<=data_in4;
//如果select中有不確定位x,輸出值是x
2'b0x,2'bx0,2'b1x,2'bx1,2'bxx:data_out<=4'bxxxx;
//如果select中有高阻態(tài)位,輸出值是z
2'b0z,2'bz0,2'b1z,2'bz1,2'bzz:data_out<=4'bzzzz;
default:$display("thecontrolsignalisinvalid");
endcase
(3)default語(yǔ)句是可選的,一個(gè)case語(yǔ)句中只能有一個(gè)default選項(xiàng)。建議在case語(yǔ)句中最好加入default分支,以避免因分支表達(dá)式未能對(duì)控制表達(dá)式的所有狀態(tài)進(jìn)行窮舉,而生成不需要的鎖存器。
(4)?case與if-else-if的比較。
①if-else-if結(jié)構(gòu)中的條件表達(dá)式更具一般性,更直觀。
②case語(yǔ)句為表達(dá)式值存在不定值x、高阻值z(mì)位的情況提供了逐位比較,執(zhí)行對(duì)應(yīng)語(yǔ)句的操作。
case語(yǔ)句還有兩種變形,關(guān)鍵詞為casez和casex。這可以在比較中對(duì)不關(guān)心的值進(jìn)行忽略。其中,casex將條件表達(dá)式或者分支表達(dá)式中的不定態(tài)x的位視為不關(guān)心的位,casez則將高阻態(tài)z視為不關(guān)心的位,這樣設(shè)計(jì)者就可以根據(jù)具體要求,只對(duì)信號(hào)的某些位進(jìn)行比較。具體請(qǐng)查閱VerilogHDL相關(guān)手冊(cè)。3.4.3循環(huán)語(yǔ)句
循環(huán)語(yǔ)句只能在initial、always塊中使用。VerilogHDL中有四種循環(huán)語(yǔ)句:for、forever、repeat、while,它們的語(yǔ)法規(guī)則類(lèi)似于C語(yǔ)言的循環(huán)語(yǔ)句。
1.for語(yǔ)句
for語(yǔ)句格式:
for(表達(dá)式1;表達(dá)式2;表達(dá)式3)語(yǔ)句;說(shuō)明:
(1)表達(dá)式1是初始條件表達(dá)式,表達(dá)式2是循環(huán)終止條件,表達(dá)式3是改變循環(huán)控制變量的賦值語(yǔ)句。
(2)語(yǔ)句執(zhí)行過(guò)程:
第一步:求解表達(dá)式1。
第二步:求解表達(dá)式2,如果其值為真(非0),執(zhí)行for語(yǔ)句中內(nèi)嵌的語(yǔ)句組,然后執(zhí)行第三步;如果為假(等于0),結(jié)束循環(huán),執(zhí)行for循環(huán)后的語(yǔ)句。
第三步:求解表達(dá)式3,得到新的循環(huán)控制變量的值,轉(zhuǎn)到第二步繼續(xù)執(zhí)行。例3-12
用for語(yǔ)句對(duì)存儲(chǔ)器組進(jìn)行初始化。
reg[7:0]my_memory[511:0]; //定義寄存器型數(shù)組,有變量512個(gè),變量位寬是8
integeri;
initial
begin
for(i=0;i<512;i=i+1)
my_memory[i]<=8'b0; //把數(shù)組中所有變量賦0值
end
2.while語(yǔ)句
while語(yǔ)句格式:
while(條件表達(dá)式)語(yǔ)句;
語(yǔ)句執(zhí)行過(guò)程:先求解條件表達(dá)式的值,如果值為真(等于1),執(zhí)行內(nèi)嵌的執(zhí)行語(yǔ)句(組),否則結(jié)束循環(huán)。如果一開(kāi)始就不滿足條件表達(dá)式,則循環(huán)一次都不執(zhí)行。
例3-13
用while語(yǔ)句求從1加到100的值,加法完成后打印結(jié)果。
modulecount(clk,data_out);
inputclk;
output[12:0]data_out;
reg[12:0]data_out;
integerj;
initial//?data_out和j賦初值為0
begin
data_out=0;
j=0;
end
always@(posedgeclk)
begin
while(j<=100)/*如果j小于等于100,則執(zhí)行循環(huán)內(nèi)容,執(zhí)行100次后,j大于100之后,跳出循環(huán)*/
begin
data_out=data_out+j;
j=j+1;
end
$display(“thesumis%d,j=%d”,data_out,j);
end
endmodule
3.forever語(yǔ)句
forever語(yǔ)句格式:
forever語(yǔ)句;
forever表示永久循環(huán),無(wú)條件地?zé)o限次執(zhí)行其后的語(yǔ)句,相當(dāng)于while(1),直到遇到系統(tǒng)任務(wù)?$finish、$stop才結(jié)束循環(huán),如果需要從循環(huán)中退出,可以使用disable語(yǔ)句。
forever不能獨(dú)立寫(xiě)在程序中,必須寫(xiě)在initial塊中。
例3-14
使用forever語(yǔ)句生成一個(gè)周期為20個(gè)時(shí)間單位的時(shí)鐘信號(hào)。
regclock;
initial
begin
clock=0;
//對(duì)clock賦初始值
forever#10clock=~clock; /*每過(guò)10個(gè)仿真時(shí)間,clock的值進(jìn)行一次翻轉(zhuǎn),從而生成的時(shí)鐘周期是20個(gè)時(shí)間單位*/
end
這段程序常用于測(cè)試文件的編寫(xiě)中。
4.repeat語(yǔ)句
語(yǔ)句格式:
repeat(表達(dá)式)語(yǔ)句;
repeat語(yǔ)句執(zhí)行表達(dá)式所指定的固定次數(shù)的循環(huán)操作,其表達(dá)式通常是常數(shù),也可以是一個(gè)變量,或者一個(gè)信號(hào)。如果是變量或者信號(hào),循環(huán)次數(shù)是循環(huán)開(kāi)始時(shí)刻變量或信號(hào)的值,而不是循環(huán)執(zhí)行期間的值
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 河北中考化學(xué)試題帶答案
- 初級(jí)銀行業(yè)法律法規(guī)與綜合能力-銀行專(zhuān)業(yè)初級(jí)《法律法規(guī)》模考試卷3
- 電力充儲(chǔ)放一張網(wǎng)平臺(tái)信息化建設(shè)設(shè)計(jì)及監(jiān)理服務(wù)需求
- DB36T-桑芽茶加工技術(shù)規(guī)程
- 貧困生獎(jiǎng)學(xué)金申請(qǐng)書(shū)
- 企業(yè)內(nèi)部信息轉(zhuǎn)換管理細(xì)則
- 特困人員供養(yǎng)申請(qǐng)書(shū)
- DB2111-T 0025-2023 水稻綠色抗逆栽培技術(shù)規(guī)程
- 2024-2025學(xué)年山東省泰安市高二上學(xué)期11月期中物理試題(解析版)
- 籃球運(yùn)動(dòng)員代表資格協(xié)議書(shū)(2篇)
- 2024年3月山東省直監(jiān)獄類(lèi)面試題及參考答案全套
- 新產(chǎn)品研發(fā)工作總結(jié)匯報(bào)
- pi粉末成型工藝
- Optix-OSN3500智能化光傳輸設(shè)備業(yè)務(wù)配置手冊(cè)范本
- swagelok管接頭安裝培訓(xùn)教程
- 公墓管理考核方案
- 把子肉店創(chuàng)業(yè)計(jì)劃書(shū)
- 綜合樓裝修改造項(xiàng)目 投標(biāo)方案(技術(shù)方案)
- 冀教版五年級(jí)上冊(cè)英語(yǔ)全冊(cè)單元測(cè)試卷(含期中期末試卷及聽(tīng)力音頻)
- 靜脈用藥安全輸注藥護(hù)專(zhuān)家指引
- 華住酒店管理制度
評(píng)論
0/150
提交評(píng)論