![Verilog HDL數(shù)字集成電路高級(jí)程序設(shè)計(jì)課件:仿真驗(yàn)證與Testbench編寫_第1頁](http://file4.renrendoc.com/view9/M02/1D/04/wKhkGWcw3HqAXaCMAAB3Gjok_6g058.jpg)
![Verilog HDL數(shù)字集成電路高級(jí)程序設(shè)計(jì)課件:仿真驗(yàn)證與Testbench編寫_第2頁](http://file4.renrendoc.com/view9/M02/1D/04/wKhkGWcw3HqAXaCMAAB3Gjok_6g0582.jpg)
![Verilog HDL數(shù)字集成電路高級(jí)程序設(shè)計(jì)課件:仿真驗(yàn)證與Testbench編寫_第3頁](http://file4.renrendoc.com/view9/M02/1D/04/wKhkGWcw3HqAXaCMAAB3Gjok_6g0583.jpg)
![Verilog HDL數(shù)字集成電路高級(jí)程序設(shè)計(jì)課件:仿真驗(yàn)證與Testbench編寫_第4頁](http://file4.renrendoc.com/view9/M02/1D/04/wKhkGWcw3HqAXaCMAAB3Gjok_6g0584.jpg)
![Verilog HDL數(shù)字集成電路高級(jí)程序設(shè)計(jì)課件:仿真驗(yàn)證與Testbench編寫_第5頁](http://file4.renrendoc.com/view9/M02/1D/04/wKhkGWcw3HqAXaCMAAB3Gjok_6g0585.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
仿真驗(yàn)證與Testbench編寫11/11/202415.1VerilogHDL電路仿真和驗(yàn)證概述仿真,也叫模擬,是通過使用EDA仿真工具,通過輸入測(cè)試信號(hào),比對(duì)輸出信號(hào)(波形、文本或者VCD文件)和期望值,來確認(rèn)是否得到與期望所一致的正確的設(shè)計(jì)結(jié)果,驗(yàn)證設(shè)計(jì)的正確性。驗(yàn)證是一個(gè)證明設(shè)計(jì)思路如何實(shí)現(xiàn),保證設(shè)計(jì)在功能上正確的一個(gè)過程。驗(yàn)證在VerilogHDL設(shè)計(jì)的整個(gè)流程中分為4個(gè)階段:階段1:功能驗(yàn)證;階段2:綜合后驗(yàn)證;階段3:時(shí)序驗(yàn)證;階段4:板級(jí)驗(yàn)證。11/11/202425.2VerilogHDL測(cè)試程序設(shè)計(jì)基礎(chǔ)5.2.1Testbench及其結(jié)構(gòu)在仿真的時(shí)候Testbench用來產(chǎn)生測(cè)試激勵(lì)給待驗(yàn)證設(shè)計(jì)(DesignUnderVerification,DUV),或者稱為待測(cè)設(shè)計(jì)(DesignUnderTest,DUT)。
Testbench平臺(tái)結(jié)構(gòu)測(cè)試程序的一般結(jié)構(gòu)
由于Testbench是一個(gè)測(cè)試平臺(tái),信號(hào)集成在模塊內(nèi)部,沒有輸入輸出。
在Testbench模塊內(nèi),例化待測(cè)設(shè)計(jì)的頂層模塊,并把測(cè)試行為的代碼封裝在內(nèi),直接對(duì)待測(cè)系統(tǒng)提供測(cè)試激勵(lì)。
例5.2-1T觸發(fā)器測(cè)試程序示例moduleTflipflop_tb;//數(shù)據(jù)類型聲明regclk,rst_n,T;wiredata_out;TFFU1(.data_out(data_out),.T(T),.clk(clk),.rst_n(rst_n));//對(duì)被測(cè)模塊實(shí)例化always//產(chǎn)生測(cè)試激勵(lì)#5clk=~clk;Initialbeginclk=0;#3rst_n=0;#5rst_n=1;T=1;#30T=0;#20T=1;endInitial//對(duì)輸出響應(yīng)進(jìn)行收集$monitor($time,"T=%b,clk=%b,rst_n=%b,data_out=%b",T,clk,rst_n,data_out);endmoduleT觸發(fā)器的仿真波形和部分文本輸出結(jié)果
:部分文本輸出結(jié)果:0T=x,clk=0,rst_n=x,data_out=x3T=x,clk=0,rst_n=0,data_out=05T=x,clk=1,rst_n=0,data_out=08T=1,clk=1,rst_n=1,data_out=110T=1,clk=0,rst_n=1,data_out=1從圖中可以清晰地看出Testbench的主要功能:(1)為DUT提供激勵(lì)信號(hào)。(2)正確實(shí)例化DUT。(3)將仿真數(shù)據(jù)顯示在終端或者存為文件,也可以顯示在波形窗口中以供分析檢查。(4)復(fù)雜設(shè)計(jì)可以使用EDA工具,或者通過用戶接口自動(dòng)比較仿真結(jié)果與理想值,實(shí)現(xiàn)結(jié)果的自動(dòng)檢查。在編寫Testbench時(shí)需要注意的問題
:(1)testbench代碼不需要可綜合Testbench代碼只是硬件行為描述不是硬件設(shè)計(jì)。(2)行為級(jí)描述效率高VerilogHDL語言具備5個(gè)描述層次,分別為開關(guān)級(jí)、門級(jí)、RTL級(jí)、算法級(jí)和系統(tǒng)級(jí)。(3)掌握結(jié)構(gòu)化、程式化的描述方式結(jié)構(gòu)化的描述有利于設(shè)計(jì)維護(hù),可通過initial、always以及assign語句將不同的測(cè)試激勵(lì)劃分開來。一般不要將所有的測(cè)試都放在一個(gè)語句塊中。5.2.2測(cè)試平臺(tái)舉例DUT的仿真平臺(tái)
測(cè)試平臺(tái)需要產(chǎn)生時(shí)鐘信號(hào)、復(fù)位信號(hào)和一系列的仿真向量,觀察DUT的響應(yīng),確認(rèn)仿真結(jié)果。(1)組合邏輯電路仿真環(huán)境的搭建moduleadder1(a,b,ci,so,co);inputa,b,ci;outputso,co;
assign{co,so}=a+b+ci;endmodule根據(jù)全加器的真值表(表5.2-1)編寫的全加器測(cè)試程序如下:moduleadder1_tb;wireso,co;rega,b,ci;adder1U1(a,b,ci,so,co); //模塊例化
initial //測(cè)試信號(hào)產(chǎn)生
begina=0;b=0;ci=0;#20a=0;b=0;ci=1;#20a=0;b=1;ci=0;#20a=0;b=1;ci=1;#20a=1;b=0;ci=0;#20a=1;b=0;ci=1;#20a=1;b=1;ci=0;#20a=1;b=1;ci=1;#200$finish;endendmodule全加器的輸入a、b和ci定義為reg型變量;把輸出so和co定義為wire型變量用模塊例化語句“adder1U1(a,b,ci,so,co);”把全加器設(shè)計(jì)電路例化到測(cè)試仿真環(huán)境中;用initial塊語句改變輸入的變化并生成測(cè)試條件,輸入的變化語句完全根據(jù)全加器的真值表編寫仿真結(jié)果:(2)時(shí)序邏輯電路仿真環(huán)境的搭建在于時(shí)序邏輯電路仿真環(huán)境中,需要考慮時(shí)序、定時(shí)信息和全局復(fù)位、置位等信號(hào)要求,并定義這些信號(hào)。用VerilogHDL編寫的十進(jìn)制加法計(jì)數(shù)器源程序代碼是:modulecnt10(clk,rst,ena,q,cout);inputclk,rst,ena;output[3:0]q;outputcout;reg[3:0]q;always@(posedgeclkorposedgerst)beginif(rst)q=4'b0000;elseif(ena)beginif(q<9)q=q+1;elseq=0;endendassigncout=q[3]&q[0];endmoduleVerilogHDL測(cè)試程序代碼是:modulecnt10_tb;regclk,rst,ena;wire[3:0]q;wirecout;cnt10U1(clk,rst,ena,q,cout);//模塊實(shí)例化
always#50clk=~clk; //時(shí)鐘信號(hào)產(chǎn)生
initialbeginclk=0;rst=0;ena=1; //控制信號(hào)產(chǎn)生
#1200rst=1;#120rst=0;#2000ena=0;#200ena=1;#20000$finish;endendmodule實(shí)例化語句“cnt10U1(clk,rst,ena,q,cout);”把十進(jìn)制計(jì)數(shù)模塊例化到仿真環(huán)境中;在always中用語句“#50clk=~clk;”產(chǎn)生周期為100(標(biāo)準(zhǔn)時(shí)間單位)的時(shí)鐘方波;用initial塊生成復(fù)位信號(hào)rst和使能控制信號(hào)ena的測(cè)試條件。測(cè)試結(jié)果如圖:5.2.3VerilogHDL仿真結(jié)果確認(rèn)(1)直接觀察波形通過直接觀察各信號(hào)波形的輸出,比較測(cè)試值和期望值的大小,來確定仿真結(jié)果的正確性。(2)打印文本輸出法moduleadder1_tb;wireso,co;rega,b,ci;adder1U1(a,b,ci,so,co);//模塊例化
initial//測(cè)試信號(hào)產(chǎn)生
begina=0;b=0;ci=0;#20a=0;b=0;ci=1;#20a=0;b=1;ci=0;#20a=0;b=1;ci=1;#20a=1;b=0;ci=0;#20a=1;b=0;ci=1;#20a=1;b=1;ci=0;#20a=1;b=1;ci=1;#200$finish;endinitial$monitor($time,"%b%b%b->%b%b",a,b,ci,so,co);endmodule其輸出的結(jié)果是:0000->0020001->1040010->1060011->0180100->10系統(tǒng)任務(wù)打印任務(wù):$display,直接輸出到標(biāo)準(zhǔn)輸出設(shè)備;$monitor,監(jiān)控參數(shù)的變化;$fdisplay,輸出到文件等(3)自動(dòng)檢查仿真結(jié)果自動(dòng)檢查仿真結(jié)果是通過在設(shè)計(jì)代碼中的關(guān)鍵節(jié)點(diǎn)添加斷言監(jiān)控器,形成對(duì)電路邏輯綜合的注釋或是對(duì)設(shè)計(jì)特點(diǎn)的說明,以提高設(shè)計(jì)模塊的觀察性。(4)使用VCD文件VerilogHDL提供一系列系統(tǒng)任務(wù)用于記錄信號(hào)值變化保存到標(biāo)準(zhǔn)的VCD(ValueChangeDump)格式數(shù)據(jù)庫中。VCD文件是一種標(biāo)準(zhǔn)格式的波形記錄文件,只記錄發(fā)生變化的波形。VCD文件將在第5.3.7小節(jié)中詳細(xì)講述。5.2.4VerilogHDL仿真效率因?yàn)橐ㄟ^串行軟件代碼完成并行語義的轉(zhuǎn)化,VerilogHDL行為級(jí)仿真代碼的執(zhí)行時(shí)間比較長。提高VerilogHDL代碼的仿真代碼執(zhí)行時(shí)間:(1)減小層次結(jié)構(gòu)仿真代碼的層次越少,執(zhí)行時(shí)間就越短。(2)減少門級(jí)代碼的使用由于門級(jí)建模屬于結(jié)構(gòu)級(jí)建模,建議仿真代碼盡量使用行為級(jí)語句,建模層次越抽象,執(zhí)行時(shí)間就越短。(3)仿真精度越高,效率越低計(jì)時(shí)單位值與計(jì)時(shí)精度值的差距越大,則模擬時(shí)間越長。`timescale仿真時(shí)間標(biāo)度將在第5.9.3小節(jié)中詳細(xì)講述。(4)進(jìn)程越少,效率越高代碼中的語句塊越少仿真越快,這是因?yàn)榉抡嫫髟诓煌M(jìn)程之間進(jìn)行切換也需要時(shí)間。(5)減少仿真器的輸出顯示VerilogHDL語言包含一些系統(tǒng)任務(wù),可以在仿真器的控制臺(tái)顯示窗口輸出一些提示信息,但會(huì)降低仿真器的執(zhí)行效率。5.3與仿真相關(guān)的系統(tǒng)任務(wù)5.3.1$display和$write語法格式如下:$display(“<format_specifiers>”,<signal1,signal2,...,signaln>);$write(“<format_specifiers>”,<signal1,signal2,...,signaln>);“<format_specifiers>”通常稱為“格式控制”“<signal1,signal2,……,signaln>”則為“信號(hào)輸出列表”$display自動(dòng)地在輸出后進(jìn)行換行$write輸出特定信息時(shí)不自動(dòng)換行輸出格式說明,由“%”和格式字符組成,其作用是將輸出的數(shù)據(jù)轉(zhuǎn)換成指定的格式輸出。
常用的幾種輸出格式如右表。輸出格式說明%h或%H以十六進(jìn)制數(shù)的形式輸出%d或%D以十進(jìn)制數(shù)的形式輸出%o或%O以八進(jìn)制數(shù)的形式輸出%b或%B以二進(jìn)制數(shù)的形式輸出%c或%C以ASCII碼字符的形式輸出%v或%V輸出網(wǎng)絡(luò)型數(shù)據(jù)信號(hào)強(qiáng)度%m或%M輸出等級(jí)層次的名字%s或%S以字符串的形式輸出%t或%T以當(dāng)前的時(shí)間格式輸出%e或%E以指數(shù)的形式輸出實(shí)型數(shù)%f或%F以十進(jìn)制數(shù)的形式輸出實(shí)型數(shù)%g或%G以指數(shù)或十進(jìn)制數(shù)的形式輸出實(shí)型數(shù)一些特殊的字符可以通過表中的轉(zhuǎn)換序列來輸出。換碼序列功能\n換行\(zhòng)t橫向跳格(即跳到下一個(gè)輸出區(qū))\\反斜杠字符\\"雙引號(hào)字符"\o1到3位八進(jìn)制數(shù)代表的字符%%百分符號(hào)%例5.3-1:$display和$write語句
moduledisp_tb;reg[31:0]rval;pulldown(pd);initialbeginrval=101;$display("\\\t%%\n\"\123");$display("rval=%hhex%ddecimal",rval,rval);$display("rval=%ootal%bbinary",rval,rval);$display("rvalhas%casciicharactervalue",rval);$display("pdstrengthvalueis%v",pd);$display("currentscopeis%m");$display("%sisasciivaluefor101",101);$write(“simulationtimeis”);$write(“%t\n”,$time);endendmodule其輸出結(jié)果為:\%"Srval=00000065hex101decimalrval=00000000145octal00000000000000000000000001100101binaryrvalhaseasciicharactervaluepdstrengthvalueisStXcurrentscopeisdispeisasciivaluefor101simulationtimeis0在$display中,輸出列表中數(shù)據(jù)的顯示寬度是自動(dòng)按照輸出格式進(jìn)行調(diào)整的,總是用表達(dá)式的最大可能值所占的位數(shù)來顯示表達(dá)式的當(dāng)前值。5.3.2$monitor和$strobe$monitor與$stobe都提供了監(jiān)控和輸出參數(shù)列表中字符或變量的值的功能(1)$monitor語法格式:$monitor(<“format_specifiers>”,<signal1,signal2,...,signaln>);任務(wù)$monitor提供了監(jiān)控和輸出參數(shù)列表中的表達(dá)式或變量值的功能。每當(dāng)參數(shù)列表中變量或表達(dá)式的值發(fā)生變化時(shí),整個(gè)參數(shù)列表中變量或表達(dá)式的值都將輸出顯示。
例如:$monitor($time,,"rxd=%btxd=%b",rxd,txd);注意在上面的語句中,“,,"代表一個(gè)空參數(shù)??諈?shù)在輸出時(shí)顯示為空格。
$monitoron和$monitoroff任務(wù)的作用是通過打開和關(guān)閉監(jiān)控標(biāo)志來控制監(jiān)控任務(wù)$monitor的啟動(dòng)和停止,這樣使得程序員可以很容易的控制$monitor何時(shí)發(fā)生。$monitor與$display的不同處在于$monitor往往在initial塊中調(diào)用,只要不調(diào)用$monitoroff,$monitor便不間斷地對(duì)所設(shè)定的信號(hào)進(jìn)行監(jiān)視。例5.3-2:$monitor系統(tǒng)任務(wù)的應(yīng)用實(shí)例modulemonitor_tb;integera,b;initialbegina=2;b=4;foreverbegin#5a=a+b;#5b=a-1;endend
initial#40$finish;
initial$monitor($time,"a=%d,b=%d",a,b);endmodule輸出結(jié)果為:0a=2,b=45a=6,b=410a=6,b=515a=11,b=520a=11,b=1025a=21,b=1030a=21,b=2035a=41,b=20(2)$strobe語法格式:$strobe(<functions_or_signals>);$strobe(“<string_and/or_variables>”,<functions_or_signals>);
探測(cè)任務(wù)用于在某時(shí)刻所有時(shí)間處理完后,在這個(gè)時(shí)間步的結(jié)尾輸出一行格式化的文本。常用的系統(tǒng)任務(wù)如下:$strobe:在所有時(shí)間處理完后,以十進(jìn)制格式輸出一行格式化的文本;$strobeb:在所有時(shí)間處理完后,以二進(jìn)制格式輸出一行格式化的文本;$strobeo:在所有時(shí)間處理完后,以八進(jìn)制格式輸出一行格式化的文本;$strobeh:在所有時(shí)間處理完后,以十六進(jìn)制格式輸出一行格式化的文本。$strobe任務(wù)在被調(diào)用的時(shí)刻所有的賦值語句都完成了,才輸出相應(yīng)的文字信息。$strobe任務(wù)提供了另一種數(shù)據(jù)顯示機(jī)制,可以保證數(shù)據(jù)只在所有賦值語句被執(zhí)行完畢后才被顯示。例5.3-3:$strobe系統(tǒng)任務(wù)的應(yīng)用實(shí)例modulestrobe_tb;rega,b;initialbegina=0;$display(“abydisplayis:”,a);$strobe(“abystrobeis:”,a);a=1;endinitialbeginb<=0;$display(“bbydisplayis:”,b);$strobe(“bbystrobeis:”,b);
#5;$display(“#5bbydisplayis:”,b);$strobe(“#5bbystrobeis:”,b);b<=1;endEndmodule顯示結(jié)果是:abydisplayis:0bbydisplayis:xabystrobeis:1bbystrobeis:0#5bbydisplayis:0#5bbystrobeis:15.3.3$time和$realtime用這兩個(gè)時(shí)間系統(tǒng)函數(shù)可以得到當(dāng)前的仿真時(shí)刻,所不同的是,$time函數(shù)以64位整數(shù)值的形式返回仿真時(shí)間,而$realtime函數(shù)則以實(shí)數(shù)型數(shù)據(jù)返回仿真時(shí)間。(1)系統(tǒng)函數(shù)$time例5.3-4:$time系統(tǒng)任務(wù)的應(yīng)用實(shí)例`timescale1ns/1nsmoduletime_tb;regts;parameterdelay=2;initialbegin#delayts=1;#delayts=0;#delayts=1;#delayts=0;endinitial$monitor($time,,,"ts=%b",ts);//使用函數(shù)$timeendmodule輸出結(jié)果為:0ts=x2ts=14ts=06ts=18ts=0(2)$realtime系統(tǒng)函數(shù)$realtime返回的時(shí)間數(shù)字是一個(gè)實(shí)型數(shù),該數(shù)字也是以時(shí)間尺度為基準(zhǔn)的。例5.3-5:$realtime系統(tǒng)任務(wù)的應(yīng)用實(shí)例`timescale1ns/1psmodulerealtime_tb;regset;parameterp=2.1;initialbegin$monitor($realtime,,"set=b%",set);//使用函數(shù)$realtime#pset=0;#pset=1;endendmodule輸出結(jié)果為:0set=x2.1set=04.2set=15.3.4$finish和$stop系統(tǒng)任務(wù)$finish和$stop是用于對(duì)仿真過程進(jìn)行控制,分別表示結(jié)束仿真和中斷仿真。其語法格式:$finish;$finish(n);$stop;$stop(n);其中,n是$finish和$stop的參數(shù),n可以取0、1或2幾個(gè)值,分別表示如下含義,如下表所示。n的取值含義0不輸出任何信息1給出仿真時(shí)間和位置2給出仿真時(shí)間和位置,同時(shí)還有所用memory及CPU時(shí)間的統(tǒng)計(jì)$finish的作用是退出仿真器,返回主操作系統(tǒng),也就是結(jié)束仿真過程。任務(wù)$finish可以帶參數(shù),根據(jù)參數(shù)的值輸出不同的特征信息。如果不帶參數(shù),默認(rèn)$finish的參數(shù)值為1。$stop任務(wù)的作用是把EDA工具(例如仿真器)置成暫停模式,在仿真環(huán)境下給出一個(gè)交互式的命令提示符,將控制權(quán)交給用戶。這個(gè)任務(wù)可以帶有參數(shù)表達(dá)式。根據(jù)參數(shù)值(0,1或2)的不同,輸出不同的信息。參數(shù)值越大,輸出的信息越多。$finish和$stop實(shí)例例5.3-6:$finish系統(tǒng)任務(wù)的應(yīng)用實(shí)例modulefinish_tb;integera,b;initialbegina=2;b=4;foreverbegin#5a=a+b;#5b=a-1;endendinitial#40$finish;initialbegin$monitor($time,"a=%d,b=%d",a,b);endendmodule在上例中,程序執(zhí)行到40個(gè)時(shí)間單位時(shí)退出仿真器。例5.3-7:$stop系統(tǒng)任務(wù)的應(yīng)用實(shí)例modulestop_tb;integera,b;initialbegina=2;b=4;foreverbegin#5a=a+b;#5b=a-1;endendinitial#40$stop;initialbegin$monitor($time,"a=%d,b=%d",a,b);endendmodule在上例中,程序執(zhí)行到40個(gè)時(shí)間單位時(shí)停止仿真,將EDA仿真器設(shè)置為暫停模式。5.3.6$random$random是產(chǎn)生隨機(jī)數(shù)的系統(tǒng)函數(shù),每次調(diào)用該函數(shù)將返回一個(gè)32位的隨機(jī)數(shù),該隨機(jī)數(shù)是一個(gè)帶符號(hào)的整數(shù)。語法格式:$random%<number>;這個(gè)系統(tǒng)函數(shù)提供了一個(gè)產(chǎn)生隨機(jī)數(shù)的手段。當(dāng)函數(shù)被調(diào)用時(shí)返回一個(gè)32bit的隨機(jī)數(shù)。它是一個(gè)帶符號(hào)的整形數(shù)。$random一般的用法是:$ramdom%b,其中b>0,它給出了一個(gè)范圍在(-b+1):(b-1)中的隨機(jī)數(shù)。11/11/202432例$random系統(tǒng)任務(wù)的應(yīng)用實(shí)例11/11/202433`timescale1ns/1nsmodulerandom_pulse(dout);output[9:0]dout;regdout;integerdelay1,delay2,k;initialbegin#10dout=0;for(k=0;k<100;k=k+1)begindelay1=20*({$random}%6); //delay1在0到100ns間變化delay2=20*(1+{$random}%3); //delay2在20到60ns間變化#delay1dout=1<<({$random}%10); //dout的0--9位中隨機(jī)出現(xiàn)1,并出現(xiàn)的時(shí)間在0-100ns間變化#delay2dout=0;
//脈沖的寬度在在20到60ns間變化endendendmodule
5.4信號(hào)時(shí)間賦值語句11/11/2024345.4.1時(shí)間延遲的語法說明延遲語句用于對(duì)各條語句的執(zhí)行時(shí)間進(jìn)行控制,從而快速滿足用戶的時(shí)序要求。VerilogHDL語言中延時(shí)控制的語法格式有兩類:(1)#<延遲時(shí)間>行為語句;(2)#<延遲時(shí)間>;其中,符號(hào)“#”是延遲控制的關(guān)鍵字符,<延遲時(shí)間>可以是直接指定的延遲時(shí)間量,并以多少個(gè)仿真時(shí)間單位的形式給出。在仿真過程中,所有時(shí)延都根據(jù)時(shí)間單位定義。下面是帶時(shí)延的賦值語句示例。#2Sum=A^B;//#2指定2個(gè)時(shí)間單位后,將A異或B的值賦值給Sum。11/11/202435根據(jù)時(shí)間控制部分在過程賦值語句中出現(xiàn)的位置,可以把過程賦值語句中的時(shí)間控制方式分為外部時(shí)間控制方式和內(nèi)部時(shí)間控制方式。(1)外部時(shí)間控制方式是時(shí)間控制出現(xiàn)在整個(gè)過程賦值語句的最左端,也就是出現(xiàn)賦值目標(biāo)變量的左邊的時(shí)間控制方式,其語法結(jié)構(gòu)如下例所示:#5a=b;在仿真執(zhí)行時(shí)就相當(dāng)于如下幾條語句的執(zhí)行:initialbegin#5;a=b;end11/11/202436(2)內(nèi)部時(shí)間控制方式是過程賦值語句中的時(shí)間控制部分還可以出現(xiàn)在“賦值操作符”和“賦值表達(dá)式”之間的時(shí)間控制方式。其語法結(jié)構(gòu)如下例所示:a=#5b;其中時(shí)間控制部分“#5”就出現(xiàn)在賦值操作符“=”和賦值表達(dá)式“b”的中間,因此在這條過程賦值語句內(nèi)帶有內(nèi)部時(shí)間控制方式的時(shí)間控制。它在執(zhí)行時(shí)就相當(dāng)于如下幾條語句的執(zhí)行:initialbegintemp=b;//先求b的值#5;a=temp;end11/11/2024375.4.2時(shí)間延遲的描述形式此處時(shí)間延遲的描述形式是指延時(shí)控制的描述形式,其分為串行延遲控制、并行延遲控制、阻塞式延遲控制和非阻塞式延遲控制四種形式。以實(shí)現(xiàn)兩組不同波形的信號(hào)為例(如圖所示q0_out和q1_out),說明四種不同時(shí)間延遲的描述形式。11/11/202438(1)串行延遲控制串行延遲控制是最為常見的信號(hào)延遲控制,它是由begin-end過程塊加上延遲賦值語句構(gòu)成,其中延遲賦值語句可以為外部時(shí)間控制方式,也可以為內(nèi)部時(shí)間控制方式。在<延遲時(shí)間>之后也可根據(jù)情況來確定是否執(zhí)行相應(yīng)的行為語句。在<延遲時(shí)間>后面有相應(yīng)的行為語句,則仿真進(jìn)程遇到這條帶有延遲控制的行為語句后并不立即執(zhí)行行為語句指定的操作,而是要延遲等待到“<延遲時(shí)間>”所指定的時(shí)間量過去后才真正開始執(zhí)行行為語句指定的操作。11/11/20243911/11/202440`timescale1ns/1nsmoduleserial_delay(q0_out,q1_out);outputq0_out,q1_out;regq0_out,q1_out;
initialbeginq0_out=1'b0;#50q0_out=1'b1;#100q0_out=1'b0;#100q0_out=1'b1;#50q0_out=1'b0;#100q0_out=1'b1;#50q0_out=1'b0;#50q0_out=1'b1;#50q0_out=1'b0;endinitialbeginq1_out=1'b0;#100q1_out=1'b1;#100q1_out=1'b0;#50q1_out=1'b1;#100q1_out=1'b0;#50q1_out=1'b1;#100q1_out=1'b0;#50q1_out=1'b1;#50q1_out=1'b0;endendmodule例VerilogHDL串行延遲控制方式設(shè)計(jì)圖示信號(hào)(2)并行延遲控制并行延遲控制方式是通過fork-join過程塊加上延遲賦值語句構(gòu)成,其中延遲賦值語句同串行延遲控制方式一樣,既可以是外部時(shí)間控制方式,也可以是內(nèi)部時(shí)間控制方式。在<延遲時(shí)間>之后也可根據(jù)情況來確定是否執(zhí)行相應(yīng)的行為語句。在<延遲時(shí)間>后面有相應(yīng)的行為語句,則仿真進(jìn)程遇到這條帶有延遲控制的行為語句后并不立即執(zhí)行行為語句指定的操作,而是要延遲等待到“<延遲時(shí)間>”所指定的時(shí)間量過去后才真正開始執(zhí)行行為語句指定的操作。但并行延遲控制方式與串行延遲控制方式不同在于并行延遲控制方式中的多條延遲語句時(shí)并行執(zhí)行的,并不需要等待上一條語句的執(zhí)行完成才開始執(zhí)行當(dāng)前的語句。11/11/20244111/11/202442`timescale1ns/1nsmoduleparallel_delay(q0_out,q1_out);outputq0_out,q1_out;regq0_out,q1_out;initialfork q0_out=1'b0;#50 q0_out=1'b1;#150 q0_out=1'b0;#250 q0_out=1'b1;#300 q0_out=1'b0;#400 q0_out=1'b1;#450 q0_out=1'b0;#500 q0_out=1'b1;#600 q0_out=1'b0;joininitialfork q1_out=1'b0;#100 q1_out=1'b1;#200 q1_out=1'b0;#250 q1_out=1'b1;#350 q1_out=1'b0;#400 q1_out=1'b1;#500 q1_out=1'b0;#550 q1_out=1'b1;#600 q1_out=1'b0;joinendmodule例VerilogHDL并行延遲控制方式設(shè)計(jì)圖示信號(hào)(3)阻塞式延遲控制以賦值操作符“=”來標(biāo)識(shí)的賦值操作稱為“阻塞式過程賦值”,阻塞式過程賦值在之前已經(jīng)介紹過,在此介紹阻塞式延遲控制。阻塞式延遲控制是在阻塞式過程賦值基礎(chǔ)上帶有延時(shí)控制的情況,例如initialbegin a=0; a=#51; a=#100; a=#151;end11/11/202443各條阻塞式賦值語句將依次得到執(zhí)行,并且在第一條語句所指定的賦值操作沒有完成之前第二條語句不會(huì)開始執(zhí)行。因此在仿真進(jìn)程開始時(shí)刻將“0”值賦給a,此條賦值語句完成之后才開始執(zhí)行第二條賦值語句;在完成第一條賦值語句之后,延遲5個(gè)時(shí)間單位將“1”賦值給a;同理第三條賦值語句是在第二條賦值語句完成之后延遲10個(gè)時(shí)間單位才開始執(zhí)行,將“0”賦值給a;最后一條賦值語句是在前三條語句都完成的時(shí)刻,延遲15個(gè)時(shí)間單位,將“1”賦值給a。下圖給出了上例中信號(hào)a的波形。上述兩例都采用的是阻塞式賦值語句。11/11/202444(4)非阻塞式延遲控制以賦值操作符“<=”來標(biāo)識(shí)的賦值操作稱為“非阻塞式過程賦值”,非阻塞式過程賦值也在之前講述過,在此主要介紹非阻塞式延遲控制。非阻塞式延遲控制是在非阻塞式過程賦值基礎(chǔ)上帶有延時(shí)控制的情況。如下例所示:initialbegin a<=0; a<=#51; a<=#100; a<=#151;end11/11/202445在上例中各條非阻塞式賦值語句均以并行方式執(zhí)行,雖然執(zhí)行語句在begin-end串行塊中,但其執(zhí)行方式與并行延遲控制方式一致,在仿真進(jìn)程開始時(shí)刻同時(shí)執(zhí)行四條延遲賦值語句。在仿真進(jìn)程開始時(shí),將“0”值賦值給a;在離仿真開始時(shí)刻5個(gè)時(shí)間單位時(shí),將“1”值賦值給a;在離仿真開始時(shí)刻10個(gè)時(shí)間單位時(shí),將“0”值賦值給a;最后在離仿真開始時(shí)刻15個(gè)時(shí)間單位時(shí),將“1”值賦值給a。下圖給出了上例中信號(hào)a的波形。11/11/20244611/11/202447`timescale1ns/1nsmodulenon_blocking_delay(q0_out,q1_out);outputq0_out,q1_out;regq0_out,q1_out;initialbeginq0_out<=1'b0;q0_out<=#501'b1;q0_out<=#1501'b0;q0_out<=#2501'b1;q0_out<=#3001'b0;q0_out<=#4001'b1;q0_out<=#4501'b0;q0_out<=#5001'b1;q0_out<=#6001'b0;endinitialbeginq1_out<=1'b0;q1_out<=#1001'b1;q1_out<=#2001'b0;q1_out<=#2501'b1;q1_out<=#3501'b0;q1_out<=#4001'b1;q1_out<=#5001'b0;q1_out<=#5501'b1;q1_out<=#6001'b0;endendmodule例VerilogHDL非阻塞延遲控制方式設(shè)計(jì)5.4.3邊沿觸發(fā)事件控制邊沿觸發(fā)事件控制的語法格式可以為如下四種形式:形式1:@(<事件表達(dá)式>)行為語句;形式2:@(<事件表達(dá)式>);形式3:@(<事件表達(dá)式1>or<事件表達(dá)式2>or……or<事件表達(dá)式n>)行為語句;形式4:@(<事件表達(dá)式1>or<事件表達(dá)式2>or……or<事件表達(dá)式n>);11/11/2024481.事件表達(dá)式在事件表達(dá)式中,可以以三種形式出現(xiàn):形式1:<信號(hào)名>形式2:posedge<信號(hào)名>形式3:negedge<信號(hào)名>其中,“<信號(hào)名>”可以是任何數(shù)據(jù)類型的標(biāo)量或矢量。形式1中,代表觸發(fā)事件的“<信號(hào)名>”在指定的信號(hào)發(fā)生邏輯變化時(shí),執(zhí)行下面的語句,如例所示:@(in)out=in;當(dāng)敏感事件in發(fā)生邏輯變化時(shí)(包括正跳變和負(fù)跳變),執(zhí)行對(duì)應(yīng)的賦值語句,將in的值賦值給out。11/11/202449形式2中,代表觸發(fā)事件的“posedge<信號(hào)名>”在指定的信號(hào)發(fā)生了正跳變時(shí),執(zhí)行下面的語句,如下例所示:@(posedgein)out=in;當(dāng)敏感事件in發(fā)生正跳變時(shí),執(zhí)行對(duì)應(yīng)的賦值語句,將in的值賦值給out。形式3中,代表觸發(fā)事件的“negedge<信號(hào)名>”在指定的信號(hào)發(fā)生了負(fù)跳變時(shí),執(zhí)行下面的語句,如下例所示:@(negedgein)out=in;當(dāng)敏感事件in發(fā)生負(fù)跳變時(shí),執(zhí)行對(duì)應(yīng)的賦值語句,將in的值賦值給out。11/11/202450在信號(hào)發(fā)生邏輯變化(正跳變或負(fù)跳變)的過程中,信號(hào)的值是從0、1、x、z四個(gè)值中的一個(gè)值變化到另一個(gè)值;而信號(hào)發(fā)生正跳變的過程是信號(hào)由低電平向高電平的轉(zhuǎn)變,負(fù)跳變是信號(hào)由高電平向低電平的轉(zhuǎn)變。表5.4-1為VerilogHDL中規(guī)定的正跳變和負(fù)跳變。11/11/202451正跳變負(fù)跳變0→x1→x0→z1→z0→11→0x→1x→0z→1z→02.邊沿觸發(fā)語法格式形式1:@(<事件表達(dá)式>)行為語句;這種語法格式的敏感事件列表內(nèi)只包含了一個(gè)觸發(fā)事件,只有當(dāng)這個(gè)指定的觸發(fā)事件發(fā)生之后,后面的行為語句才能啟動(dòng)執(zhí)行。在仿真進(jìn)程中遇到這種帶有事件控制的行為語句時(shí),如果指定的觸發(fā)事件還沒有發(fā)生,則仿真進(jìn)程就會(huì)停留在此處等待,直到指定觸發(fā)事件發(fā)生之后再啟動(dòng)執(zhí)行后面的行為語句,仿真進(jìn)程繼續(xù)向下進(jìn)行。11/11/202452例5.4-4:時(shí)鐘脈沖計(jì)數(shù)器moduleclk_counter(clk,count_out);inputclk;outputcount_out;reg[3:0]count_out;initialcount_out=0;always@(posedgeclk)count_out=count_out+1;//在clk的每個(gè)正跳變邊沿count_out增加1endmodule形式2:@(<事件表達(dá)式>);這種語法格式的敏感事件列表內(nèi)也只包含了一個(gè)觸發(fā)事件,沒有行為語句來指定觸發(fā)事件發(fā)生時(shí)要執(zhí)行的操作。這種格式的事件控制語句的執(zhí)行過程與延時(shí)控制語句中沒有行為語句的情況類似,仿真進(jìn)程在遇到這條事件控制語句后會(huì)進(jìn)入等待狀態(tài),直到指定的觸發(fā)事件發(fā)生后才結(jié)束等待狀態(tài),退出該事件控制語句的執(zhí)行并開始下一條語句的執(zhí)行。11/11/20245311/11/202454moduleclk_time_mea(clk);inputclk;timeposedge_time,negedge_time;timehigh_last_time,low_last_time,last_time;initialbegin@(posedgeclk); /*等待,直到時(shí)鐘發(fā)生正跳變后退出等待狀態(tài),繼續(xù)執(zhí)行下一條語句*/posedge_time=$time;@(negedgeclk); /*等待,直到時(shí)鐘發(fā)生負(fù)跳變后退出等待狀態(tài),
繼續(xù)執(zhí)行下一條語句*/negedge_time=$time;@(posedgeclk); /*等待,直到時(shí)鐘再次正跳變后退出等待狀態(tài),繼續(xù)執(zhí)行下一條語句*/last_time=$time-posedge_time;high_last_time=negedge_time-posedge_time;low_last_time=last_time-high_last_time;$display("TheclkstayinHighlevelfor:%t",high_last_time);$display("TheclkstayinLowlevelfor:%t",low_last_time);$display("TheclksignalPeriodis:%t",last_time);endendmodule例用于測(cè)定輸入時(shí)鐘正電平、負(fù)電平持續(xù)時(shí)間以及時(shí)鐘周期的模塊形式3:@(<事件表達(dá)式1>or<事件表達(dá)式2>or……or<事件表達(dá)式n>)行為語句;這種語法格式的“敏感事件列表”內(nèi)指定了由不同“<事件表達(dá)式>”代表的多個(gè)觸發(fā)事件,這些“<事件表達(dá)式>”之間要用關(guān)鍵詞“or”組合起來。只要這些觸發(fā)事件中的任何一個(gè)得到發(fā)生,就啟動(dòng)行為語句的執(zhí)行。在仿真進(jìn)程遇到這種格式的邊沿觸發(fā)事件控制語句時(shí)如果所有的觸發(fā)事件都沒有發(fā)生,則仿真進(jìn)程就會(huì)進(jìn)入等待狀態(tài),直到其中的某一個(gè)觸發(fā)事件發(fā)生后才啟動(dòng)執(zhí)行后面給出的行為語句,仿真進(jìn)程繼續(xù)向下進(jìn)行。11/11/202455形式4:@(<事件表達(dá)式1>or<事件表達(dá)式2>or……or<事件表達(dá)式n>);同第三種語法格式一樣,這種語法格式內(nèi)指定了多個(gè)觸發(fā)事件。但是在這種格式中沒有行為語句。在這種情況下,該語句的執(zhí)行過程與第二種語法格式的執(zhí)行過程類似,仿真進(jìn)程在遇到這條事件控制語句后會(huì)進(jìn)入等待狀態(tài),直到敏感事件列表包含的多個(gè)觸發(fā)事件中的任何一個(gè)得到發(fā)生后才結(jié)束等待狀態(tài),退出該事件控制語句并開始執(zhí)行該事件控制語句后的下一條語句。11/11/202456例在觸發(fā)事件發(fā)生后退出事件控制語句moduledisplay_information_change(a,b);inputa,b;wirea,b;alwaysbegin@(posedgeaornegedgeb);/*等待,直到a或b發(fā)生變化后退出等待狀態(tài),并開始下一條語句的執(zhí)行*/display("Oneofaandbchangedintime:%t",$time);endendmodule5.4.4電平敏感事件控制電平敏感時(shí)間控制是另一種事件控制方式,與邊沿觸發(fā)事件控制不同,它是在指定的條件表達(dá)式為真時(shí)啟動(dòng)需要執(zhí)行的語句。電平敏感時(shí)間控制是用關(guān)鍵詞“wait”來表示。電平觸發(fā)事件控制的語法格式可以為如下兩種:形式1:wait(條件表達(dá)式)行為語句;形式2:wait(條件表達(dá)式);電平敏感事件控制的第一種形式中包含了行為語句,它可以是串行塊(begin-end)語句或并行塊(fork-join)語句,也可以是單條行為語句。在這種事件控制語句形式下,行為語句啟動(dòng)執(zhí)行的觸發(fā)條件是:條件表達(dá)式的值為“真(邏輯1)”。如果當(dāng)仿真進(jìn)程執(zhí)行到這條電平敏感控制語句時(shí)條件表達(dá)式的值是“真”,那么語句塊立即得到執(zhí)行;否則語句塊要一直等到條件表達(dá)式變?yōu)椤罢妗睍r(shí)再開始執(zhí)行。11/11/20245711/11/202458例如:wait(enable==1)begin d=a&b; d=d|c;endwait語句的作用是根據(jù)條件表達(dá)式的真假來控制下面begin-end語句塊的執(zhí)行,在使能信號(hào)enable變?yōu)楦唠娖胶?,也就是enable==1的語句為真時(shí)進(jìn)行a,b,c之間的與或操作;若使能信號(hào)enable未變?yōu)楦唠娖?,則begin-end語句塊的執(zhí)行需要等到enable變?yōu)楦唠娖街蟛砰_始執(zhí)行。電平敏感事件控制的第2種形式中沒有包含行為語句。在這種電平敏感事件控制語句形式下,如果當(dāng)仿真進(jìn)程執(zhí)行到該wait控制語句時(shí)條件表達(dá)式的值是“真”,那么立即結(jié)束該wait事件控制語句的執(zhí)行,仿真進(jìn)程繼續(xù)往下進(jìn)行;而如果當(dāng)仿真進(jìn)程執(zhí)行到這條wait控制語句時(shí)條件表達(dá)式的值是“假”,則仿真進(jìn)程進(jìn)入等待狀態(tài),一直等到條件表達(dá)式取值變?yōu)椤罢妗睍r(shí)才退出等待狀態(tài)同時(shí)結(jié)束該wait語句的執(zhí)行,仿真進(jìn)程繼續(xù)往下進(jìn)行。這種形式的電平敏感時(shí)間控制常常用來對(duì)串行塊中各條語句的執(zhí)行時(shí)序進(jìn)行控制。11/11/202459例如:begin wait(enable==1); d=a&b; d=d|c;end5.5任務(wù)和函數(shù)在VerilogHDL語言中提供了任務(wù)和函數(shù),可以將較大的行為級(jí)設(shè)計(jì)劃分為較小的代碼段,允許設(shè)計(jì)者將需要在多個(gè)地方重復(fù)使用的相同代碼提取出來,編寫成任務(wù)和函數(shù),這樣可以使代碼更加簡(jiǎn)潔和易懂。5.5.1任務(wù)1.任務(wù)的定義任務(wù)定義的語法格式:11/11/202460task<任務(wù)名>;
端口和類型聲明
局部變量聲明 begin
語句1;
語句2; ……
語句n; endendtask任務(wù)定義是嵌入在關(guān)鍵字task和endtask之間的,其中關(guān)鍵詞task標(biāo)志著一個(gè)任務(wù)定義結(jié)構(gòu)的開端,endtask標(biāo)志著一個(gè)任務(wù)定義結(jié)構(gòu)的結(jié)束。“<任務(wù)名>”是所定義任務(wù)的名稱。在“<任務(wù)名>”后面不能出現(xiàn)輸入輸入端口列表。例以讀存儲(chǔ)器數(shù)據(jù)為例說明任務(wù)定義的操作11/11/202461taskread_memory; //任務(wù)定義的開頭,指定任務(wù)名為read_memory input[15:0]address; //輸入端口說明 output[31:0]data; //輸出端口說明 reg[3:0]counter; //變量類型說明 reg[7:0]temp[1:4]; //變量類型說明 begin //語句塊,任務(wù)被調(diào)用時(shí)執(zhí)行 for(counter=1;counter<=4;counter=counter+1) temp[counter]=mem[address+counter-1]; data={temp[1],temp[2],temp[3],temp[4]}; endendtask //任務(wù)定義結(jié)束任務(wù)定義時(shí)需注意以下事項(xiàng):(1)在第一行“task”語句中不能列出端口名列表。(2)任務(wù)中可以有延時(shí)語句、敏感事件控制語句等事件控制語句。(3)任務(wù)可以沒有或可以有一個(gè)或多個(gè)輸入、輸出和雙向端口。(4)任務(wù)可以沒有返回值,也可以通過輸出端口或雙向端口返回一個(gè)或多個(gè)返回值。(5)任務(wù)可以調(diào)用其它的任務(wù)或函數(shù),也可以調(diào)用該任務(wù)本身。(6)任務(wù)定義結(jié)構(gòu)內(nèi)不允許出現(xiàn)過程塊(initial或always過程塊)。(7)任務(wù)定義結(jié)構(gòu)內(nèi)可以出現(xiàn)disable終止語句,這條語句的執(zhí)行將中斷正在執(zhí)行的任務(wù)。在任務(wù)被中斷后,程序流程將返回到調(diào)用任務(wù)的地方繼續(xù)向下執(zhí)行。11/11/2024622、任務(wù)的調(diào)用任務(wù)的調(diào)用是通過“任務(wù)調(diào)用語句”來實(shí)現(xiàn)的。任務(wù)調(diào)用語句列出了傳入任務(wù)的參數(shù)值和接收結(jié)果的變量值,任務(wù)的調(diào)用格式如下:<任務(wù)名>(端口1,端口2……,端口n);例以測(cè)試仿真中常用的方式來說明任務(wù)的調(diào)用11/11/202463moduledemo_task_invo_tb;reg[7:0]mem[127:0];reg[15:0]a;reg[31:0]b;initialbegina=0;read_mem(a,b);//任務(wù)的第一次調(diào)用#10;a=64;read_mem(a,b);//任務(wù)的第二次調(diào)用end
taskread_mem;//任務(wù)定義部分input[15:0]address;output[31:0]data;reg[3:0]counter;reg[7:0]temp[1:4];beginfor(counter=1;counter<=4;counter=counter+1)temp[counter]=mem[address+counter-1];data={temp[1],temp[2],temp[3],temp[4]};endendtaskendmodule使用任務(wù)可以使程序更加簡(jiǎn)潔易懂,以實(shí)際中的交通燈控制為例說明任務(wù)的定義、調(diào)用的特點(diǎn)。11/11/202464moduletraffic_lights(red,amber,green);outputred,amber,green;reg[2:1]order;regclock,red,amber,green;parameterON=1,OFF=0,RED_TICS=350,AMBER_TICS=30,GREEN_TICS=200;//產(chǎn)生時(shí)鐘脈沖alwaysbegin#100clock=0;#100clock=1;end//任務(wù)的定義,該任務(wù)用于實(shí)現(xiàn)交通燈的開啟tasklight;outputred;outputamber;outputgreen;input[31:0]tic_time;input[2:1]order;beginred=OFF;green=OFF;amber=OFF;case(order)2'b01:red=ON;2'b10:green=ON;2'b11:amber=ON;endcase11/11/202465repeat(tic_time)@(posedgeclock);red=OFF;green=OFF;amber=OFF;endendtask//任務(wù)的調(diào)用,交通燈初始化initialbeginorder=2'b00;light(red,amber,green,0,order);end//任務(wù)的調(diào)用,交通燈控制時(shí)序alwaysbeginorder=2'b01;light(red,amber,green,RED_TICS,order);//調(diào)用開燈任務(wù),開紅燈order=2'b10;light(red,amber,green,GREEN_TICS,order);//調(diào)用開燈任務(wù),開綠燈order=2'b11;light(red,amber,green,AMBER_TICS,order);//調(diào)用開燈任務(wù),開黃燈endendmodule5.5.2函數(shù)
1.函數(shù)的定義11/11/202466function<返回值類型或位寬><函數(shù)名>;<輸入?yún)⒘颗c類型聲明><局部變量說明>begin
語句1;
語句2; ……
語句n;endendfunction函數(shù)定義是嵌入在關(guān)鍵字function和endfunction之間的,其中關(guān)鍵詞function標(biāo)志著一個(gè)函數(shù)定義結(jié)構(gòu)的開端,endfunction標(biāo)志著一個(gè)函數(shù)定義結(jié)構(gòu)的結(jié)束?!?lt;函數(shù)名>”是給被定義函數(shù)取的名稱。這個(gè)函數(shù)名在函數(shù)定義結(jié)構(gòu)內(nèi)部還代表著一個(gè)內(nèi)部變量,函數(shù)調(diào)用后的返回值是通過這個(gè)函數(shù)名變量傳遞給調(diào)用語句的。<返回值類型或位寬>是一個(gè)可選項(xiàng),它是用來對(duì)函數(shù)調(diào)用返回?cái)?shù)據(jù)的類型或?qū)挾冗M(jìn)行說明,它可以有如下三種形式:(1)“[msb:lsb]”:這種形式說明函數(shù)名所代表的返回?cái)?shù)據(jù)變量時(shí)一個(gè)多位的寄存器變量,它的位寬由[msb:lsb]指定,比如如下函數(shù)定義語句:function[7:0]adder;就定義了一個(gè)函數(shù)“adder”,它的函數(shù)名“adder”還代表著一個(gè)8位寬的寄存器變量,其中最高位為第7位,最低位為第0位。(2)“integer”:這種形式說明函數(shù)名代表的返回變量是一個(gè)整數(shù)型變量。(3)“real”:這種形式說明函數(shù)名代表的返回變量是一個(gè)實(shí)數(shù)型變量。11/11/202467“<輸入?yún)⒘颗c類型聲明>”是對(duì)函數(shù)各個(gè)輸入端口的寬度和類型進(jìn)行說明,在函數(shù)定義中,必須至少有一個(gè)輸入端口(input)的聲明,不能有輸出端口(output)的聲明。數(shù)據(jù)類型聲明語句用來對(duì)函數(shù)內(nèi)用到的局部變量進(jìn)行寬度和類型說明,這個(gè)說明語句的語法與進(jìn)行模塊定義時(shí)的相應(yīng)說明語句語法是一致的。“<局部變量說明>”是對(duì)函數(shù)內(nèi)部局部變量進(jìn)行寬度和類型的說明。由“begin”與“end”關(guān)鍵詞界定的一系列語句和任務(wù)一樣,用來指明函數(shù)被調(diào)用時(shí)要執(zhí)行的操作,在函數(shù)被調(diào)用時(shí),這些語句將以串行方式得到執(zhí)行。11/11/20246811/11/202469例5.5-4:統(tǒng)計(jì)輸入數(shù)據(jù)中“0”的個(gè)數(shù)
function[3:0]out0; input[7:0]x; reg[3:0]count; integeri; begin count=0; for(i=0;i<=7;i=i+1) if(x[i]==1’b0) count=count+1; out0=count; end endfunction在進(jìn)行函數(shù)定義時(shí)需要注意以下幾點(diǎn):(1)與任務(wù)一樣,函數(shù)定義結(jié)構(gòu)只能出現(xiàn)在模塊中,而不能出現(xiàn)在過程塊內(nèi)。(2)函數(shù)至少必須有一個(gè)輸入端口。(3)函數(shù)不能有任何類型的輸出端口(output端口)和雙向端口(inout端口)。(4)在函數(shù)定義結(jié)構(gòu)中的行為語句部分內(nèi)不能出現(xiàn)任何類型的時(shí)間控制描述,也不允許使用disable終止語句。(5)與任務(wù)定義一樣,函數(shù)定義結(jié)構(gòu)內(nèi)部不能出現(xiàn)過程塊。(6)在一個(gè)函數(shù)內(nèi)可以對(duì)其它函數(shù)進(jìn)行調(diào)用,但是函數(shù)不能調(diào)用其它任務(wù)。(7)在第一行“function”語句中不能出現(xiàn)端口名列表。(8)在函數(shù)聲明的時(shí)候,在VerilogHDL的內(nèi)部隱含地聲明了一個(gè)名為function_identifier(函數(shù)標(biāo)識(shí)符)的寄存器類型變量,函數(shù)的輸出結(jié)果將通過這個(gè)寄存器類型變量被傳遞回來。11/11/2024702.函數(shù)的調(diào)用函數(shù)的調(diào)用是通過將函數(shù)作為表達(dá)式中的操作數(shù)來實(shí)現(xiàn)的。函數(shù)的調(diào)用格式如下:<函數(shù)名>(<輸入表達(dá)式1>,<輸入表達(dá)式2>……<輸入表達(dá)式n>);其中,輸入表達(dá)式應(yīng)與函數(shù)定義結(jié)構(gòu)中說明的輸入端口一一對(duì)應(yīng),它們代表著各個(gè)輸入端口的輸入數(shù)據(jù)。函數(shù)調(diào)用時(shí)要注意以下幾點(diǎn):(1)函數(shù)的調(diào)用不能單獨(dú)作為一條語句出現(xiàn),它只能作為一個(gè)操作數(shù)出現(xiàn)在調(diào)用語句內(nèi)。(2)函數(shù)的調(diào)用既能出現(xiàn)在過程塊中,也能出現(xiàn)在assign連續(xù)賦值語句中。(3)函數(shù)定義中聲明的所有局部寄存器都是靜態(tài)的,即函數(shù)中的局部寄存器在函數(shù)的多個(gè)調(diào)用之間保持它們的值。11/11/202471例5.5-5:階乘函數(shù)11/11/202472moduletryfact_tb; function[31:0]factorial;//函數(shù)的定義部分 input[3:0]operand; reg[3:0]index; begin factorial=1; for(index=1;index<=operand;index=index+1) factorial=index*factorial; end endfunction reg[31:0]result; reg[3:0]n; initial begin result=1; for(n=1;n<=9;n=n+1) begin result=factorial(n);//函數(shù)的調(diào)用部分 $display("n=%dresult=%d",n,result); end end endmodule11/11/202473上例由函數(shù)定義和initial過程塊構(gòu)成,其中定義了一個(gè)名為factorial的函數(shù),該函數(shù)是一個(gè)進(jìn)行階乘運(yùn)算的函數(shù),具有一個(gè)4位的輸入端口,同時(shí)返回一個(gè)32位的寄存器類型的值;在initial塊中定義了兩個(gè)寄存器變量,分別為32位的result和4位的n,initial塊對(duì)1至9進(jìn)行階乘運(yùn)算,并打印出結(jié)果值。
n=1result=1n=2result=2n=3result=6n=4result=24n=5result=120n=6result=720n=7result=5040n=8result=40320n=9result=3628805.5.3任務(wù)與函數(shù)的區(qū)別11/11/202474函數(shù)任務(wù)函數(shù)能調(diào)用另一個(gè)函數(shù),但不能調(diào)用另一個(gè)任務(wù)任務(wù)能調(diào)用另一個(gè)任務(wù),也能用另一個(gè)函數(shù)函數(shù)總是在仿真時(shí)刻0就開始執(zhí)行任務(wù)可以在非零仿真時(shí)刻執(zhí)行函數(shù)一定不能包含任何延遲、事件或者時(shí)序控制聲明語句任務(wù)可以包含延遲、時(shí)間或者時(shí)序控制聲明語句函數(shù)至少有一個(gè)輸入變量,沒有輸出變量任務(wù)可以沒有或者有多個(gè)輸入(input)、輸出(output)和雙向(inout)變量函數(shù)只能返回一個(gè)值,函數(shù)不能有輸出(output)或者雙向(inout)變量任務(wù)不返回任何值,任務(wù)可以通過輸出(output)或者雙向(inout)變量傳遞多個(gè)值函數(shù)不能單獨(dú)作為一條語句出現(xiàn),它只能以語句的一部分的形式出現(xiàn)任務(wù)的調(diào)用則是通過一條單獨(dú)的任務(wù)調(diào)用語句實(shí)現(xiàn)函數(shù)調(diào)用可以出現(xiàn)在過程塊或連續(xù)賦值語句中任務(wù)調(diào)用只能出現(xiàn)在過程塊中函數(shù)的執(zhí)行不允許由disable語句進(jìn)行中斷任務(wù)的執(zhí)行可以由disable語句進(jìn)行中斷5.6典型測(cè)試向量的設(shè)計(jì)5.6.1變量初始化在VerilogHDL語言中,有兩種方法可以初始化變量:一種是利用初始化變量;另一種就是在定義變量時(shí)直接賦值初始化。這兩種初始化任務(wù)是不可綜合的,主要用于仿真過程。(1)initial初始化方式在大多數(shù)情況下,Testbench中變量初始化的工作通過initial過程塊來完成,可以產(chǎn)生豐富的仿真激勵(lì)。initial語句只執(zhí)行一次,即在設(shè)計(jì)被開始模擬執(zhí)行時(shí)開始(0時(shí)刻)直到過程結(jié)束,專門用于對(duì)輸入信號(hào)進(jìn)行初始化和產(chǎn)生特定的信號(hào)波形。一個(gè)Testbench可以包含多個(gè)initial過程語句塊,所有的initial過程都同時(shí)執(zhí)行。需要注意的是,initial語句中的變量必須為reg類型。11/11/20247511/11/202476例5.6-1:利用initial初始化方式的測(cè)試向量產(chǎn)生modulecounter_demo2(cnt);output[3:0]cnt;regclk;reg[3:0]temp;initial temp=0;initial clk=0;endmodule(2)定義變量時(shí)初始化在定義變量時(shí)初始化的語法非常簡(jiǎn)單,直接用“=”在變量右端賦值即可,如:reg[7:0]cnt=8’b00000000;就將8比特的寄存器變量cnt初始化為0。5.6.2數(shù)據(jù)信號(hào)測(cè)試向量產(chǎn)生數(shù)據(jù)信號(hào)的產(chǎn)生有兩種形式:其一是初始化和產(chǎn)生都在單個(gè)initial塊中進(jìn)行;其二是初始化在initial語句中完成,而產(chǎn)生在always語句塊中完成。前者適合不規(guī)則數(shù)據(jù)序列,并且要求長度較短;后者適合具有一定規(guī)律的數(shù)據(jù)序列,長度不限。例5.6-2:產(chǎn)生位寬為4的質(zhì)數(shù)序列{1、2、3、5、7、11、13},并且重復(fù)兩次,其中樣值間隔為4個(gè)仿真時(shí)間單位由于該序列無明顯規(guī)律,因此利用initial語句最為合適。11/11/20247711/11/202478`timescale1ns/1psmodulesequence_tb;reg[3:0]q_out;parametersample_period=4;parameterqueue_num=2;initialbeginq_out=0;repeat(queue_num)begin#sample_periodq_out=1;#sample_periodq_out=2;#sample_periodq_out=3;#sample_periodq_out=5;#sample
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度建筑電氣安全檢測(cè)與維修服務(wù)合同
- 2025年度智慧社區(qū)建設(shè)勞務(wù)分包合同規(guī)范
- 2025年度建筑勞務(wù)分包合同樣本(全新版)
- 2025年度健身房與健身服裝品牌合作合同協(xié)議
- 2025年度建筑工程施工現(xiàn)場(chǎng)環(huán)境管理規(guī)范執(zhí)行合同
- 2025年機(jī)械壓力機(jī)項(xiàng)目可行性研究報(bào)告
- 2025年纖維混紡織項(xiàng)目可行性研究報(bào)告
- 2025年度高端設(shè)備租賃合同示范文本
- 2025年度會(huì)展行業(yè)知識(shí)產(chǎn)權(quán)保護(hù)服務(wù)合同范本
- 2025年度建筑工程勞務(wù)分包撥款及結(jié)算協(xié)議
- GB/T 4151-1996硝酸鈰
- GB/T 29594-2013可再分散性乳膠粉
- 危房鑒定報(bào)告
- 西子奧的斯電梯ACD2調(diào)試說明書
- GA/T 1499-2018卷簾門安全性要求
- 成長感恩責(zé)任高中主題班會(huì)-課件
- 化工裝置實(shí)用操作技術(shù)指南
- 建設(shè)項(xiàng)目全過程工程咨詢服務(wù)指引(咨詢企業(yè)版)(征求意見稿)
- 2020年度安徽省中考數(shù)學(xué)科目試卷
- 攝影攝像技術(shù)專業(yè)申請(qǐng)表
- 牡丹區(qū)中心醫(yī)院食源性疾病監(jiān)測(cè)培訓(xùn)課件
評(píng)論
0/150
提交評(píng)論