VerilogHDL數(shù)字設(shè)計(jì)教程(賀敬凱)第6章_第1頁(yè)
VerilogHDL數(shù)字設(shè)計(jì)教程(賀敬凱)第6章_第2頁(yè)
VerilogHDL數(shù)字設(shè)計(jì)教程(賀敬凱)第6章_第3頁(yè)
VerilogHDL數(shù)字設(shè)計(jì)教程(賀敬凱)第6章_第4頁(yè)
VerilogHDL數(shù)字設(shè)計(jì)教程(賀敬凱)第6章_第5頁(yè)
已閱讀5頁(yè),還剩201頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

VerilogHDL數(shù)字設(shè)計(jì)教程(賀敬凱)第6章第一頁(yè),共206頁(yè)。6.1ModelSim軟件的使用

6.1.1ModelSim軟件簡(jiǎn)介ModelSim為HDL仿真工具,支持IEEE常見的各種硬件描述語(yǔ)言標(biāo)準(zhǔn)。我們可以利用該軟件來(lái)實(shí)現(xiàn)對(duì)所設(shè)計(jì)的VerilogHDL程序的仿真。ModelSim常見的版本分為ModelSimAE、ModelSimXE和ModelSimSE三種。ModelSim的版本更新得很快,本章使用的版本為ModelSim6.1SE版本,該版本支持VerilogHDL的2001標(biāo)準(zhǔn)。第二頁(yè),共206頁(yè)。本章為ModelSim的初級(jí)教程,讀者學(xué)完本章可以較為熟練地使用ModelSim進(jìn)行設(shè)計(jì)仿真,本章沒有也不可能涉及ModelSim的各個(gè)方面,要想全面地掌握ModelSim,可以參閱ModelSim附帶的文檔。第三頁(yè),共206頁(yè)。這里以ModelSimSEPLUS6.1b為例來(lái)說(shuō)明。本節(jié)主要說(shuō)明ModelSim的菜單和工具欄,讀者對(duì)此有一個(gè)初步的了解就可以了。點(diǎn)擊“開始—程序—ModelSimSEPLUS6.1b—ModelSim”或雙擊桌面上的快捷方式,打開ModelSim軟件,出現(xiàn)的界面如圖6-1所示。在圖的最上端為標(biāo)題欄;下面一行為菜單欄;再下面為工具欄;左半部分為工作區(qū)(Workspace),在其中可以通過(guò)雙擊查看當(dāng)前的工程及對(duì)庫(kù)進(jìn)行管理;右半部分為信息顯示區(qū),用于顯示和編輯文件、顯示仿真波形以及其他信息;下面為命令窗口區(qū),在其中出現(xiàn)的命令行及提示信息稱為腳本(Transcript);最下面一行為狀態(tài)欄。第四頁(yè),共206頁(yè)。這里要注意的是,有些操作是無(wú)法通過(guò)菜單和工具欄來(lái)完成的,必須使用命令行方式來(lái)操作。常用的命令并不多,不是很難掌握,建議大家參閱相關(guān)書籍學(xué)習(xí)仿真中的一些用的命令。第五頁(yè),共206頁(yè)。圖6-1ModelSim界面第六頁(yè),共206頁(yè)。6.1.2使用圖形界面對(duì)設(shè)計(jì)進(jìn)行仿真作為一種簡(jiǎn)單易用、功能強(qiáng)大的邏輯仿真工具,ModelSim的應(yīng)用廣泛。本小節(jié)結(jié)合QuartusⅡ軟件,通過(guò)一個(gè)簡(jiǎn)單的例子對(duì)ModelSim作一個(gè)入門性的簡(jiǎn)單介紹,首先介紹ModelSim的功能仿真,然后介紹時(shí)序仿真。第七頁(yè),共206頁(yè)。1.設(shè)計(jì)塊與激勵(lì)塊本設(shè)計(jì)是完成一個(gè)正弦波信號(hào)發(fā)生器。正弦波信號(hào)發(fā)生器的結(jié)構(gòu)如圖6-2所示。在每一個(gè)時(shí)鐘上升沿使ROM當(dāng)前地址的數(shù)據(jù)輸出,同時(shí)計(jì)數(shù)器增1,這對(duì)于ROM來(lái)說(shuō)就是指向下一個(gè)存放數(shù)據(jù)的地址。第八頁(yè),共206頁(yè)。圖6-2頂層設(shè)計(jì)sin_wave框圖第九頁(yè),共206頁(yè)。該設(shè)計(jì)的頂層文件sin_wave以及底層文件counter_64和rom_64X8的設(shè)計(jì)源碼分別參見例6-1~例6-3?!纠?-1】頂層設(shè)計(jì)sin_wave的VerilogHDL代碼。modulesin_wave(clk,data);input clk;output [7:0]data;wire [5:0]WIRE0;counter_64 inst1(.clock(clk),.q(WIRE0));rom_64X8inst2(.inclock(clk),.address(WIRE0),.q(data));endmodule第十頁(yè),共206頁(yè)?!纠?-2】底層counter_64模塊的VerilogHDL代碼。modulecounter_64(clock,q); input clock; output [5:0]q; wire[5:0]sub_wire0; wire[5:0]q=sub_wire0[5:0];第十一頁(yè),共206頁(yè)。lpm_counter lpm_counter_component( .clock(clock), .q(sub_wire0), .aclr(1'b0), .aload(1'b0), .aset(1'b0), .cin(1'b1), .clk_en(1'b1),

.cnt_en(1'b1), .cout(), .data({6{1'b0}}),第十二頁(yè),共206頁(yè)。.eq(),.sclr(1'b0),.sload(1'b0),.sset(1'b0),.updown(1'b1));defparamlpm_counter_component.lpm_direction="UP",第十三頁(yè),共206頁(yè)。lpm_counter_component.lpm_port_updown="PORT_UNUSED",lpm_counter_component.lpm_type="LPM_COUNTER",lpm_counter_component.lpm_width=6;endmodule第十四頁(yè),共206頁(yè)。【例6-3】底層rom_64X8模塊的VerilogHDL代碼。modulerom_64X8(address,inclock,q); input [5:0]address; input inclock; output [7:0]q; wire[7:0]sub_wire0; wire[7:0]q=sub_wire0[7:0];第十五頁(yè),共206頁(yè)。altsyncram altsyncram_component( .clock0(inclock), .address_a(address), .q_a(sub_wire0), .aclr0(1'b0), .aclr1(1'b0), .address_b(1'b1), .addressstall_a(1'b0), .addressstall_b(1'b0), .byteena_a(1'b1),第十六頁(yè),共206頁(yè)。.byteena_b(1'b1),.clock1(1'b1),.clocken0(1'b1),.clocken1(1'b1),.data_a({8{1'b1}}),.data_b(1'b1),.q_b(),.rden_b(1'b1),.wren_a(1'b0),.wren_b(1'b0));第十七頁(yè),共206頁(yè)。defparam altsyncram_component.address_aclr_a="NONE", altsyncram_component.init_file="sin_rom_64.mif",altsyncram_ended_device_family="Cyclone", altsyncram_component.lpm_hint="ENABLE_RUNTIME_MOD=YES, INSTANCE_NAME=SIN",

altsyncram_component.lpm_type="altsyncram", altsyncram_component.numwords_a=64,

第十八頁(yè),共206頁(yè)。altsyncram_component.operation_mode="ROM",altsyncram_component.outdata_aclr_a="NONE",altsyncram_component.outdata_reg_a="UNREGISTERED",altsyncram_component.widthad_a=6,altsyncram_component.width_a=8,altsyncram_component.width_byteena_a=1;endmodule第十九頁(yè),共206頁(yè)。例6-1至例6-3程序說(shuō)明:(1)例6-1為sin_wave頂層設(shè)計(jì),調(diào)用了底層模塊counter_64和rom_64X8,模塊間的連接關(guān)系如圖6-2所示。(2)模塊counter_64和rom_64X8的實(shí)現(xiàn)過(guò)程中,分別調(diào)用了QuartusⅡ自帶的宏功能模塊lpm_counter和altsyncram。宏功能模塊的定制可使用MegaWizardPlug-inManager…向?qū)?chuàng)建完成。第二十頁(yè),共206頁(yè)。下面以rom_64X8為例,介紹宏功能模塊的定制步驟。首先,打開MegaWizardPlug-inManager初始對(duì)話框。選擇Tools—MegaWizardPlug-inManager…,打開如圖6-3所示的對(duì)話框。第二十一頁(yè),共206頁(yè)。圖6-3定制新的宏功能模塊第二十二頁(yè),共206頁(yè)。在圖6-3中作圖示選擇,然后點(diǎn)擊Next按鈕,進(jìn)入圖6-4。圖6-4LPM_ROM宏功能模塊設(shè)定第二十三頁(yè),共206頁(yè)。在圖6-4中作圖示選擇,并對(duì)定制模塊命名后,點(diǎn)擊Next按鈕,進(jìn)入圖6-5。第二十四頁(yè),共206頁(yè)。圖6-5選擇rom_64X8模塊的數(shù)據(jù)線和地址線寬度第二十五頁(yè),共206頁(yè)。在圖6-5中作圖示選擇,然后點(diǎn)擊Next按鈕,進(jìn)入圖6-6。圖6-6選擇rom_64X8模塊的地址鎖存信號(hào)inclock第二十六頁(yè),共206頁(yè)。在圖6-6中作圖示選擇,然后點(diǎn)擊Next按鈕,進(jìn)入圖6-7。圖6-7選擇rom_64X8模塊的數(shù)據(jù)初始化文件第二十七頁(yè),共206頁(yè)。在圖6-7中選擇存儲(chǔ)器初始化文件(關(guān)于存儲(chǔ)器初始化文件的創(chuàng)建方法隨后在本小節(jié)介紹),然后點(diǎn)擊Next按鈕,進(jìn)入下一個(gè)界面。在后面的page6of7界面點(diǎn)選Next按鈕,在page7of7界面點(diǎn)選Finish按鈕,完成ROM的定制。LPM_COUNTER宏功能模塊的定制步驟同LPM_ROM,在LPM_COUNTER宏功能模塊的定制步驟中,將模塊名命名為counter_64,然后需要修改計(jì)數(shù)器輸出的位數(shù)為6,見圖6-8,其余步驟均取默認(rèn)值即可。第二十八頁(yè),共206頁(yè)。圖6-8設(shè)置LPM_COUNTER的位數(shù)第二十九頁(yè),共206頁(yè)。下面再簡(jiǎn)單介紹確定圖6-2中ROM內(nèi)的波形數(shù)據(jù)文件的過(guò)程。首先在QuartusⅡ中打開ROM數(shù)據(jù)文件編輯窗口,即選擇命令,并在New窗口中選擇Otherfiles選項(xiàng)卡,再選擇MemoryInitializationFile選項(xiàng),單擊OK按鈕后產(chǎn)生ROM數(shù)據(jù)文件大小選擇窗口,在NumberofWords中填寫64,在Wordsize中填寫8。單擊OK按鈕,將出現(xiàn)如圖6-9所示的空的mif數(shù)據(jù)表格,然后按圖6-9中的數(shù)值將表格填寫完整。完成后選擇命令,保存此數(shù)據(jù)文件,取名為sin_rom_64.mif。第三十頁(yè),共206頁(yè)。圖6-9頂層設(shè)計(jì)中ROM的初始化內(nèi)容第三十一頁(yè),共206頁(yè)。設(shè)計(jì)模塊完成之后,需要設(shè)計(jì)激勵(lì)模塊對(duì)該正弦信號(hào)發(fā)生器進(jìn)行測(cè)試,一個(gè)可使用的測(cè)試激勵(lì)模塊如例6-4所示?!纠?-4】sin_wave模塊的測(cè)試塊。`timescale1ns/100psmoduletest_module1; regclk; wire[7:0]data; //調(diào)用已設(shè)計(jì)好的模塊 sin_waveone(.clk(clk),.data(data)); initial第三十二頁(yè),共206頁(yè)。begin clk<=1'b0; //clk初值為0 #3000$finish; //終止仿真 end //控制驅(qū)動(dòng)設(shè)計(jì)塊的時(shí)鐘信號(hào),時(shí)鐘周期為10個(gè)時(shí)鐘單位 always #5clk=~clk; //clk周期為10 initial $monitor($time,"sin_wave_data:%d",data);//監(jiān)視輸出endmodule第三十三頁(yè),共206頁(yè)。測(cè)試激勵(lì)模塊的主要功能是為sin_wave模塊提供輸入信號(hào),同時(shí)監(jiān)視sin_wave模塊的輸出,并與預(yù)期輸出比較,以判斷sin_wave模塊的功能是否正確。第三十四頁(yè),共206頁(yè)。2.仿真前的準(zhǔn)備使用QuartusⅡ設(shè)計(jì)完硬件工程后,進(jìn)行全程編譯,可生成ModelSim仿真網(wǎng)表,使用這個(gè)網(wǎng)表、測(cè)試文件,再加上幾個(gè)庫(kù)文件就可以方便快速地進(jìn)行功能仿真。仿真所需文件:(1)設(shè)計(jì)HDL源代碼:可以使用VerilogHDL源文件或者Quartus產(chǎn)生的網(wǎng)表文件。(2)測(cè)試激勵(lì)代碼:根據(jù)設(shè)計(jì)塊而設(shè)計(jì)的激勵(lì)程序,由于不需要進(jìn)行綜合,因此其書寫具有很大的靈活性。第三十五頁(yè),共206頁(yè)。(3)仿真模型/庫(kù):根據(jù)設(shè)計(jì)內(nèi)調(diào)用的器件供應(yīng)商提供的模塊而定。AlteraFPGA的仿真模型庫(kù)在C:\altera\quartus\eda\sim_lib中。針對(duì)不同的目標(biāo)器件,可選用不同的XXXX_atoms.v文件。比如使用cyclone系列器件,那就要使用cyclone_atoms.v.如果使用了Altera的IP核,還需要altera_mf.v文件。altera_mf.v包含了所有宏功能模塊的仿真模型。

第三十六頁(yè),共206頁(yè)。

如果Altera的IP核中包括了用戶原語(yǔ),則還需要加入220model.v文件。注:以上所列文件為對(duì)應(yīng)的VerilogHDL的庫(kù)文件,若對(duì)VHDL完成的設(shè)計(jì)進(jìn)行仿真,則需要使用VHDL的庫(kù)文件,后綴為.VHD。第三十七頁(yè),共206頁(yè)。3.仿真步驟下面詳細(xì)說(shuō)明使用ModelSim對(duì)QuartusⅡ中完成的正弦波發(fā)生器進(jìn)行功能仿真和時(shí)序仿真的步驟。(1)?QuartusⅡ工程設(shè)置。在QuartusⅡ中創(chuàng)建sine_wave工程時(shí),選擇Setting,對(duì)第三方仿真工具進(jìn)行設(shè)置,界面如圖6-10所示。第三十八頁(yè),共206頁(yè)。圖6-10仿真設(shè)置界面第三十九頁(yè),共206頁(yè)。點(diǎn)擊OK按鈕后,對(duì)工程重新進(jìn)行全程編譯,編譯成功后,我們可以看到工程目錄下多出了simulation\modelsim文件夾,該文件夾里有三個(gè)文件,其中*.vo為網(wǎng)表文件,*.sdo為延時(shí)文件,如圖6-11所示。第四十頁(yè),共206頁(yè)。圖6-11仿真目錄內(nèi)容第四十一頁(yè),共206頁(yè)。(2)運(yùn)行ModelSim,創(chuàng)造ModelSim工程。點(diǎn)擊開始—程序—ModelSimSEPLUS6.1b—ModelSim或雙擊桌面上的快捷方式,打開ModelSim軟件。然后點(diǎn)擊—Project,會(huì)出現(xiàn)如圖6-12所示的界面。在ProjectName中我們輸入建立的工程名字為sin_wave_simulation。在ProjectLocation中輸入工程保存的路徑為C:/sin_wave_example/simulation/modelsim。第四十二頁(yè),共206頁(yè)。

注意,ModelSim不能為一個(gè)工程自動(dòng)建立一個(gè)目錄,我們最好是自己在ProjectLocation中輸入路徑來(lái)為工程建立目錄,這里我們使用仿真文件存放的目錄。在DefaultLibraryName中設(shè)置設(shè)計(jì)編譯后存放的目標(biāo)庫(kù),這里我們使用默認(rèn)值。這樣,在我們編譯設(shè)計(jì)文件后,在Workspace窗口的Library中就會(huì)出現(xiàn)work庫(kù)。完成各項(xiàng)設(shè)置后,點(diǎn)擊OK按鈕。第四十三頁(yè),共206頁(yè)。(3)添加工程文件。在隨后出現(xiàn)的如圖6-13所示的界面中,可以點(diǎn)擊不同的圖標(biāo)來(lái)為工程添加不同的項(xiàng)目。點(diǎn)擊CreateNewFile可以為工程添加新建的文件,點(diǎn)擊AddExistingFile可以為工程添加已經(jīng)存在的文件,點(diǎn)擊CreateSimulation可以為工程添加仿真,點(diǎn)擊CreateNewFolder可以為工程添加新的目錄。第四十四頁(yè),共206頁(yè)。圖6-12新建工程窗口第四十五頁(yè),共206頁(yè)。圖6-13為工程添加文件第四十六頁(yè),共206頁(yè)。這里我們點(diǎn)擊AddExistingFile,出現(xiàn)如圖6-14所示的界面。點(diǎn)擊框右側(cè)的Browse,找到網(wǎng)表文件sin_wave.vo,選中它,將文件拷貝至工程目錄,點(diǎn)擊OK按鈕。第四十七頁(yè),共206頁(yè)。圖6-14為工程添加已存在的文件第四十八頁(yè),共206頁(yè)。按照以上方法,依次將altera_mf.v、cyclone_atoms.v、test_module.v添加進(jìn)工程中。添加后的工程界面如圖6-15所示。第四十九頁(yè),共206頁(yè)。圖6-15添加文件后的工程界面第五十頁(yè),共206頁(yè)。(4)編譯工程。通過(guò)圖6-15可以看出,在Workspace窗口中的Project選項(xiàng)卡里,有4個(gè)文件的狀態(tài)欄有問(wèn)號(hào),這表示這些文件未編譯。選擇Compile—CompileAll,如圖6-16所示,在命令窗口中將出現(xiàn)4行綠色字體“CompileofXXXwassuccessful.”,XXX為上面4個(gè)文件的名字,說(shuō)明文件編譯成功;在狀態(tài)欄后有一綠色的對(duì)號(hào),也表示編譯成功。編譯結(jié)果如圖6-17所示。第五十一頁(yè),共206頁(yè)。圖6-16編譯設(shè)計(jì)中的文件第五十二頁(yè),共206頁(yè)。圖6-17編譯結(jié)果第五十三頁(yè),共206頁(yè)。功能仿真和時(shí)序仿真之間的不同之處是:功能仿真時(shí)不需要延時(shí)信息,時(shí)序仿真則需要延時(shí)信息。如圖6-18所示,修改?*.vo文件,去掉延時(shí)信息,再對(duì)修改的文件重新進(jìn)行編譯(不用再編譯其他已編譯過(guò)而且未做修改的文件),然后進(jìn)行功能仿真。而進(jìn)行時(shí)序仿真時(shí),則需要將?*.vo文件復(fù)原,保留延時(shí)信息。第五十四頁(yè),共206頁(yè)。圖6-18功能仿真前的設(shè)置第五十五頁(yè),共206頁(yè)。(5)仿真。點(diǎn)擊菜單Simulate—StartSimulation…,會(huì)出現(xiàn)如同6-19所示的界面。我們展開Design選項(xiàng)卡下的work庫(kù),并選中其中的test_module,即頂層測(cè)試模塊,這是我們所要仿真的對(duì)象。Resolution為仿真的時(shí)間精度,這里我們使用默認(rèn)值。選擇SDF標(biāo)簽頁(yè),在其中還要添加SDF文件,并作好相應(yīng)的設(shè)置。點(diǎn)擊OK按鈕,出現(xiàn)如圖6-20所示界面,在該界面中可以看到sim標(biāo)簽頁(yè)和wave標(biāo)簽頁(yè),這表明仿真設(shè)置成功。第五十六頁(yè),共206頁(yè)。圖6-19選擇仿真對(duì)象第五十七頁(yè),共206頁(yè)。圖6-20仿真界面第五十八頁(yè),共206頁(yè)。為了觀察波形窗口,我們要為該窗口添加我們需要觀察的對(duì)象。首先在主窗口勾選View—DebugWindows—Objects,打開信號(hào)列表窗口,如圖6-21所示。在該窗口中點(diǎn)擊AddtoWave—SelectedSignals,這時(shí)候在波形窗口中就可以看到clk和data信號(hào)了。第五十九頁(yè),共206頁(yè)。圖6-21仿真時(shí)添加clk和data兩個(gè)變量于波形圖的界面第六十頁(yè),共206頁(yè)。在主窗口中輸入run15μs后回車,表示運(yùn)行仿真15μs,仿真時(shí)CPU的利用率一直為100%。如果仿真很慢,則還可以觀察狀態(tài)欄里的當(dāng)前仿真時(shí)間。在仿真時(shí)間為3μs時(shí),仿真雖然沒有完成,但會(huì)彈出如圖6-22所示的窗口,這是系統(tǒng)任務(wù)$finish執(zhí)行的結(jié)果。點(diǎn)擊“否”即可。如果點(diǎn)擊“是”,則會(huì)退出ModelSim軟件。第六十一頁(yè),共206頁(yè)。圖6-22仿真過(guò)程中彈出的窗口第六十二頁(yè),共206頁(yè)。這時(shí)候點(diǎn)擊wave標(biāo)簽頁(yè),可以看到已經(jīng)有了仿真波形,如圖6-23所示。我們還可以在波形窗口添加標(biāo)尺,用于測(cè)量信號(hào)的周期、延時(shí)等信息。第六十三頁(yè),共206頁(yè)。圖6-23仿真波形窗口第六十四頁(yè),共206頁(yè)。退出仿真,在主窗口中點(diǎn)擊Simulate—EndSimulation,會(huì)出現(xiàn)對(duì)話框,提示我們是否確認(rèn)退出仿真,我們點(diǎn)擊“是”退出仿真。第六十五頁(yè),共206頁(yè)。(6)功能仿真結(jié)果分析。首先將Wave窗口中的data輸出數(shù)據(jù)轉(zhuǎn)變?yōu)槟M信號(hào),這樣可以看得很清楚。設(shè)置界面如圖6-24所示。第六十六頁(yè),共206頁(yè)。圖6-24設(shè)置成模擬信號(hào)顯示第六十七頁(yè),共206頁(yè)。按圖6-24所示將Height設(shè)為200,Scale設(shè)為0.5,選擇Format為Analog,則可以看到輸出的功能仿真波形,如圖6-25所示??梢栽O(shè)置不同的Height值來(lái)調(diào)整模擬波形的位置,也可以設(shè)置不同的Scale來(lái)使波形適于觀察。第六十八頁(yè),共206頁(yè)。圖6-25功能仿真的結(jié)果(圖形)第六十九頁(yè),共206頁(yè)。(7)時(shí)序仿真結(jié)果分析。通過(guò)修改*.vo文件可以添加延時(shí)信息。時(shí)序仿真結(jié)果如圖6-26所示。第七十頁(yè),共206頁(yè)。圖6-26時(shí)序仿真的結(jié)果(圖形)第七十一頁(yè),共206頁(yè)。從時(shí)序仿真的結(jié)果可以看出,與功能仿真結(jié)果不同,時(shí)序仿真結(jié)果有延時(shí)和毛刺。通過(guò)單擊InsertCursor可多加入幾個(gè)標(biāo)尺,用于測(cè)量延時(shí)和毛刺周期。經(jīng)測(cè)量,延時(shí)大概為十幾個(gè)微秒左右,毛刺周期為幾百個(gè)皮秒。一般情況下,F(xiàn)PGA一個(gè)門的延時(shí)為9ns左右,所以產(chǎn)生的毛刺不會(huì)影響FPGA的正常工作。第七十二頁(yè),共206頁(yè)。6.1.3使用ModelSim讀/寫文件ModelSim軟件的功能十分強(qiáng)大,剛才介紹的只是常用功能之一,下面再介紹其另一個(gè)常用的讀/寫文件的功能。圖6-27sin_wave.dat的數(shù)據(jù)格式在實(shí)際的應(yīng)用中,需要的數(shù)據(jù)量可能很大,使用傳統(tǒng)的方法在測(cè)試文件中指定輸入數(shù)據(jù)是不現(xiàn)實(shí)的。通常,用其他軟件比如C、MATLAB等軟件生成所需數(shù)據(jù),保存在*.dat文件中,然后在ModelSim中調(diào)用該文本文件,將文本中的數(shù)據(jù)讀出使用。第七十三頁(yè),共206頁(yè)。同樣地,輸出數(shù)據(jù)量也很大時(shí),我們用傳統(tǒng)的方法去看輸出波形也是不可靠的,我們需要把結(jié)果也輸出到文本中,與行為模型所產(chǎn)生的標(biāo)準(zhǔn)輸出向量作對(duì)比,這樣就可以很容易、很準(zhǔn)確地指示結(jié)果是否正確。首先,我們創(chuàng)建sin_wave.dat文件,其格式如圖6-27所示。然后通過(guò)例6-5來(lái)說(shuō)明如何使用ModelSim讀/寫文件。第七十四頁(yè),共206頁(yè)。圖6-27sin_wave.dat的數(shù)據(jù)格式第七十五頁(yè),共206頁(yè)?!纠?-5】使用ModelSim讀/寫文件。`timescale1ns/100psmoduletest_module; regclk; wire[7:0]data; reg[0:7]mem[0:63];//使用文件進(jìn)行初始化的數(shù)組 integervec_;//定義文件句柄,控制變量 regflag;//寫文件完畢后flag=1讀開始

第七十六頁(yè),共206頁(yè)。//調(diào)用已設(shè)計(jì)好的模塊 sin_waveone(.clk(clk),.data(data));//監(jiān)視設(shè)計(jì)塊輸出,變量初始化,設(shè)置仿真時(shí)間 initial begin clk<=1'b0;flag<=1'b0;i<=1'b0;j<=1'b0; //clk,flag,i,j初值為0 $monitor($time,"sin_wavedata:%d",data); vec_file=$fopen("sin_wave.dat"); //打開文件 #3000$finish; //終止仿真 end第七十七頁(yè),共206頁(yè)。//控制驅(qū)動(dòng)設(shè)計(jì)塊的時(shí)鐘信號(hào),時(shí)鐘周期為10個(gè)時(shí)鐘單位 always #5clk=~clk;//clk周期為10 //將設(shè)計(jì)塊的輸出數(shù)據(jù)存放于文件,同時(shí)在命令窗口中顯示存放進(jìn)度 always@(posedgeclk) begin if(!flag) begin $fdisplayh(vec_file,"%h",data); $display($time,"i=%0d,data:%d",i,data); if(i!=6'd63) begin第七十八頁(yè),共206頁(yè)。i<=i+1; flag<=1'b0; end else begin flag<=1'b1; $fclose(vec_file); end end end //用存放于文件中的數(shù)據(jù)對(duì)數(shù)組進(jìn)行初始化,并將數(shù)組內(nèi)容在命令窗口中顯示第七十九頁(yè),共206頁(yè)。always@(posedgeclk) if(flag) begin $readmemh("sin_wave.dat",mem); if(j!=64) begin j<=j+1; $display($time,"\tj=%0d,mem[%0d]=%0d",j,j,mem[j]); end endendmodule第八十頁(yè),共206頁(yè)。程序說(shuō)明:(1)功能仿真結(jié)果分析。由于命令窗口顯示的功能仿真結(jié)果很長(zhǎng),所以僅摘抄一部分,供大家分析程序用。以下是部分功能仿真結(jié)果:#0sin_wavedata:0#5i=0,data:0#5sin_wavedata:255#15i=1,data:255

#15sin_wavedata:254

#25i=2,data:254

#25sin_wavedata:252第八十一頁(yè),共206頁(yè)。#35i=3,data:252#35sin_wavedata:249#45i=4,data:249#45sin_wavedata:245#55i=5,data:245#55sin_wavedata:239#65i=6,data:239第八十二頁(yè),共206頁(yè)。#65sin_wavedata:233#75i=7,data:233#75sin_wavedata:225#85i=8,data:225#85sin_wavedata:217#95i=9,data:217#95sin_wavedata:207#105i=10,data:207#105sin_wavedata:197第八十三頁(yè),共206頁(yè)。(2)時(shí)序仿真結(jié)果分析。由于命令窗口顯示的時(shí)序仿真結(jié)果很長(zhǎng),所以僅摘抄一部分,供大家分析程序用。以下是部分時(shí)序仿真結(jié)果:#505sin_wavedata:139#505i=50,data:139#505sin_wavedata:138#505sin_wavedata:154#506sin_wavedata:158#506sin_wavedata:150#515i=51,data:150第八十四頁(yè),共206頁(yè)。#516sin_wavedata:182#516sin_wavedata:166#516sin_wavedata:162#525i=52,data:162#526sin_wavedata:170#526sin_wavedata:174#535i=53,data:174#535sin_wavedata:190#536sin_wavedata:186第八十五頁(yè),共206頁(yè)。#545sin_wavedata:250#545sin_wavedata:251#545sin_wavedata:249#545i=54,data:249#546sin_wavedata:233#546sin_wavedata:237#546sin_wavedata:229#546sin_wavedata:197#555sin_wavedata:199#555i=55,data:199第八十六頁(yè),共206頁(yè)。#556sin_wavedata:207#565sin_wavedata:205#565i=56,data:205#565sin_wavedata:221#566sin_wavedata:217#575i=57,data:217#576sin_wavedata:249#576sin_wavedata:233第八十七頁(yè),共206頁(yè)。#576sin_wavedata:225#585i=58,data:225#586sin_wavedata:233#595sin_wavedata:235#595i=59,data:235#596sin_wavedata:239從仿真結(jié)果中我們可以直觀地看出仿真延時(shí)信息和毛刺存在的時(shí)間等信息。這些信息跟波形圖顯示的信息一致,兩者可以結(jié)合在一起分析。第八十八頁(yè),共206頁(yè)。(3)本程序中使用了$display、$monitor、$fopen、$fclose、$fdisplayh、$readmemh、$finish等系統(tǒng)任務(wù),關(guān)于這些任務(wù)的用法與含義詳見本章6.4節(jié)。通過(guò)本節(jié)的學(xué)習(xí),我們可以發(fā)現(xiàn)ModelSim不僅好用,而且易用。第八十九頁(yè),共206頁(yè)。6.2延時(shí)

前幾章我們描述的電路都是無(wú)延時(shí)的。事實(shí)上,在實(shí)際的電路中,任何一個(gè)邏輯門都具有延時(shí)。VerilogHDL允許用戶通過(guò)延時(shí)語(yǔ)句來(lái)說(shuō)明邏輯電路中的延時(shí)。例6-4中,我們?cè)诰帉憸y(cè)試激勵(lì)模塊時(shí)使用了延時(shí),下面對(duì)延時(shí)作進(jìn)一步說(shuō)明。第九十頁(yè),共206頁(yè)。

1.延時(shí)信號(hào)在電路中傳輸會(huì)有傳播延時(shí)等,如線延時(shí)、器件延時(shí)等。延時(shí)語(yǔ)句就是對(duì)延時(shí)特性的HDL描述。舉例如下:assign#2B=A;表示B信號(hào)在2個(gè)時(shí)間單位后得到A信號(hào)的值,如圖6-28所示。第九十一頁(yè),共206頁(yè)。圖6-28延時(shí)第九十二頁(yè),共206頁(yè)。在VerilogHDL中,所有延時(shí)都必須根據(jù)時(shí)間單位進(jìn)行定義,定義的方法是在文件頭添加如下語(yǔ)句:`timescale1ns/100ps其中,`timescale是VerilogHDL提供的編譯預(yù)處理命令,1?ns表示時(shí)間單位是1?ns,100?ps表示時(shí)間精度是100?ps。根據(jù)該命令,編譯工具才可以認(rèn)知#2為2?ns。在VerilogHDL的IEEE標(biāo)準(zhǔn)中沒有規(guī)定時(shí)間單位的缺省值,其值由各仿真工具確定。因此,在編寫代碼時(shí)必須確定。第九十三頁(yè),共206頁(yè)。在VerilogHDL中,時(shí)序控制起著非常重要的作用,它使得設(shè)計(jì)者可以指定賦值發(fā)生的時(shí)刻,進(jìn)而控制仿真時(shí)間的推進(jìn)過(guò)程?;谘訒r(shí)的時(shí)序控制出現(xiàn)在表達(dá)式中,它指定了語(yǔ)句開始執(zhí)行到執(zhí)行完成之間的時(shí)間間隔。延時(shí)值可以是數(shù)字、標(biāo)識(shí)符或表達(dá)式,需要在延時(shí)值前加上關(guān)鍵字#。第九十四頁(yè),共206頁(yè)。2.時(shí)間尺度`timescale`timescale命令用來(lái)說(shuō)明跟在該命令后的模塊的時(shí)間單位和時(shí)間精度。使用`timescale命令可以在同一個(gè)設(shè)計(jì)里包含采用了不同的時(shí)間單位的模塊。例如,一個(gè)設(shè)計(jì)中包含了兩個(gè)模塊,其中一個(gè)模塊的時(shí)間延時(shí)單位為ns,另一個(gè)模塊的時(shí)間延時(shí)單位為ps。EDA工具仍然可以對(duì)這個(gè)設(shè)計(jì)進(jìn)行仿真測(cè)試。第九十五頁(yè),共206頁(yè)。`timescale命令的格式如下:`timescale<時(shí)間單位>/<時(shí)間精度>在這條命令中,時(shí)間單位參量是用來(lái)定義模塊中仿真時(shí)間和延時(shí)時(shí)間的基準(zhǔn)單位的。時(shí)間精度參量是用來(lái)聲明該模塊的仿真時(shí)間的精確程度的,該參量被用來(lái)對(duì)延時(shí)時(shí)間值進(jìn)行取整操作(仿真前),因此該參量又可以稱為取整精度。如果在同一個(gè)程序設(shè)計(jì)里存在多個(gè)`timescale命令,則用最小的時(shí)間精度值來(lái)決定仿真的時(shí)間單位。另外,時(shí)間精度至少要和時(shí)間單位一樣精確,即時(shí)間精度值不能大于時(shí)間單位值。第九十六頁(yè),共206頁(yè)。在`timescale命令中,用于說(shuō)明時(shí)間單位和時(shí)間精度參量值的數(shù)字必須是整數(shù),其有效數(shù)字為1、10、100,單位為秒(s)、毫秒(ms)、微秒(μs)、納秒(ns)、皮秒(ps)、毫皮秒(fs)。這幾種單位的意義見表6-1。第九十七頁(yè),共206頁(yè)。第九十八頁(yè),共206頁(yè)?!纠?-6】`timescale命令的用法舉例。`timescale10ns/1nsmoduletest;regset;parameterd=1.37;initialbegin$monitor($realtime,"set=",set);#dset=0;#dset=1;endendmodule第九十九頁(yè),共206頁(yè)。程序運(yùn)行結(jié)果:#0set=x#1set=0#3set=1第一百頁(yè),共206頁(yè)。程序說(shuō)明:(1)?`timescale命令定義了模塊test的時(shí)間單位為10?ns、時(shí)間精度為1?ns。在這個(gè)命令之后,模塊中所有的時(shí)間值都是10?ns的倍數(shù),并且可表達(dá)為帶一位小數(shù)的實(shí)型數(shù),這是因?yàn)閌timescale命令定義的時(shí)間精度為時(shí)間單位的1/10。(2)參數(shù)d?=?1.37,根據(jù)時(shí)間精度可知,d的值應(yīng)為1.4(四舍五入),再根據(jù)時(shí)間單位可知,d所代表的時(shí)間為14ns(即1.4?×?10ns)。第一百零一頁(yè),共206頁(yè)。(3)?#dset=0;中d為延時(shí)值,#d表示延時(shí)d秒,整個(gè)句子表達(dá)的意思是延時(shí)d秒后再將set賦值為0。延時(shí)值可以是數(shù)字、標(biāo)識(shí)符或表達(dá)式,表示延時(shí)時(shí)需要在延時(shí)值前加上關(guān)鍵字#。(4)本例的仿真過(guò)程為:在仿真時(shí)刻為14?ns時(shí),寄存器set被賦值0,在仿真時(shí)刻為28?ns時(shí),寄存器set被賦值1。第一百零二頁(yè),共206頁(yè)。6.3常?用?塊?語(yǔ)?句

1.?initial塊語(yǔ)句所有在initial語(yǔ)句內(nèi)的語(yǔ)句構(gòu)成了一個(gè)initial塊。initial塊從仿真0時(shí)刻開始執(zhí)行,在整個(gè)仿真過(guò)程中只執(zhí)行一次。如果一個(gè)模塊中包括了若干個(gè)initial塊,則這些initial塊從仿真0時(shí)刻開始并發(fā)執(zhí)行,且每個(gè)塊的執(zhí)行是各自獨(dú)立的。第一百零三頁(yè),共206頁(yè)。initial塊的使用類似于always塊,塊內(nèi)使用的語(yǔ)句必須是行為語(yǔ)句,應(yīng)用于always塊內(nèi)的語(yǔ)句均可應(yīng)用于initial塊。在一個(gè)模塊內(nèi),可同時(shí)包括若干個(gè)initial塊和若干個(gè)always塊,所有這些塊均從仿真0時(shí)刻開始并發(fā)執(zhí)行,且每個(gè)塊的執(zhí)行是各自獨(dú)立的。如果在initial塊內(nèi)包含了多條行為語(yǔ)句,那么需要將這些語(yǔ)句組成一組,使用關(guān)鍵字begin和end(或者fork和join)將它們組合為一個(gè)塊語(yǔ)句;如果塊內(nèi)只有一條語(yǔ)句,則不必使用關(guān)鍵字begin和end(或者fork和join)。這一點(diǎn)類似于C語(yǔ)言中的復(fù)合語(yǔ)句{}。第一百零四頁(yè),共206頁(yè)。initial語(yǔ)句的格式如下:initialbegin語(yǔ)句1;語(yǔ)句2;...語(yǔ)句n;end由于initial塊語(yǔ)句在整個(gè)仿真期間只能執(zhí)行一次,因此它一般被用于初始化、信號(hào)監(jiān)視、生成仿真波形等目的。下面舉例說(shuō)明initial語(yǔ)句的使用。

第一百零五頁(yè),共206頁(yè)?!纠?-7】initial塊語(yǔ)句舉例1。`timescale1ns/1nsmoduletest_initial_0;parametersize=4;reg[7:0]y;integerindex;reg[7:0]memory[0:size-1];initial begin第一百零六頁(yè),共206頁(yè)。y=10; //初始化寄存器aregfor(index=0;index<size;index=index+1) #5memory[index]=index; //初始化一個(gè)memory endendmodule第一百零七頁(yè),共206頁(yè)。程序說(shuō)明:(1)程序中各變量的波形如圖6-29所示。圖6-29例6-7中各變量的波形第一百零八頁(yè),共206頁(yè)。(2)在程序的for語(yǔ)句中加入延時(shí),是為了看清楚初始化過(guò)程。實(shí)際仿真時(shí),需要去掉該延時(shí)。從這個(gè)例子可以看出,initial語(yǔ)句的用途之一是初始化各變量。第一百零九頁(yè),共206頁(yè)?!纠?-8】initial塊語(yǔ)句舉例2。`timescale1ns/1nsmoduletest_initial;regx;initial#10x=1'b1;//只有一條語(yǔ)句,不需要使用begin...endinitialbeginx=1'b0;//多條語(yǔ)句,需要使用begin...end #5x=1'bx;第一百一十頁(yè),共206頁(yè)。endinitialbegin:block//定義塊內(nèi)局部變量,需要給塊命名 integerI; I=5; #(10+I)x=1'b0; #(I)x=1'b1; #(I)x=1'b0;endendmodule第一百一十一頁(yè),共206頁(yè)。程序說(shuō)明:(1)程序中x的波形如圖6-30所示。從仿真波形可以看出,多個(gè)initial塊是從仿真0時(shí)刻開始并發(fā)執(zhí)行的。圖6-30例6-8中x的波形第一百一十二頁(yè),共206頁(yè)。(2)在仿真過(guò)程中,如果某條語(yǔ)句前面存在延時(shí),那么對(duì)這條語(yǔ)句的仿真將會(huì)停頓下來(lái),經(jīng)過(guò)指定的延時(shí)時(shí)間之后再繼續(xù)執(zhí)行,這點(diǎn)可結(jié)合代碼和波形圖進(jìn)行理解。(3)在VerilgHDL中,對(duì)于順序塊和并行塊,可以給每個(gè)塊取一個(gè)名字,只需將名字加在關(guān)鍵詞begin或fork后面即可。這樣做的原因有以下幾點(diǎn):第一百一十三頁(yè),共206頁(yè)。這樣可以在塊內(nèi)定義局部變量,即只在塊內(nèi)使用的變量。這樣可以允許塊被其他語(yǔ)句調(diào)用,如被disable語(yǔ)句調(diào)用。在VerilogHDL中,所有的變量都是靜態(tài)的,即所有的變量都只有一個(gè)唯一的存儲(chǔ)地址,因此進(jìn)入或跳出塊并不影響存儲(chǔ)在變量?jī)?nèi)的值?;谝陨显颍瑝K名就提供了一個(gè)在任何仿真時(shí)刻確認(rèn)變量值的方法。第一百一十四頁(yè),共206頁(yè)。(4)從這個(gè)例子中我們可以看到initial語(yǔ)句的另一用途,即生成激勵(lì)波形作為電路的測(cè)試仿真信號(hào),如例6-8中的x即可用作電路的激勵(lì)信號(hào)。initial塊常用于測(cè)試文件的編寫,用來(lái)產(chǎn)生仿真測(cè)試信號(hào)和設(shè)置信號(hào)記錄等仿真環(huán)境。第一百一十五頁(yè),共206頁(yè)。2.順序塊begin…end關(guān)鍵字begin和end用于將多條語(yǔ)句組成順序塊。順序塊的格式如下:begin語(yǔ)句1;語(yǔ)句2;...語(yǔ)句n;end或第一百一十六頁(yè),共206頁(yè)。begin:塊名塊內(nèi)聲明語(yǔ)句 語(yǔ)句1;語(yǔ)句2;...語(yǔ)句n;end其中:塊名即該塊的名字,即一個(gè)標(biāo)識(shí)名。塊內(nèi)聲明語(yǔ)句可以是參數(shù)聲明語(yǔ)句、reg型變量聲明語(yǔ)句、integer型變量聲明語(yǔ)句、real型變量聲明語(yǔ)句等。第一百一十七頁(yè),共206頁(yè)?!纠?-9】順序塊應(yīng)用舉例。`timescale1ns/1nsmoduletest_begin;parameterd=20; //聲明d是一個(gè)參數(shù)reg[7:0]data; //聲明data是一個(gè)8位的寄存器變量initial

第一百一十八頁(yè),共206頁(yè)。begin //由一系列延時(shí)產(chǎn)生的波形 #ddata='h11; #ddata='h22; #ddata='h33; #ddata='h44; #d$stop; endendmodule第一百一十九頁(yè),共206頁(yè)。程序說(shuō)明:

(1)這個(gè)例子中用順序塊和延時(shí)控制組合來(lái)產(chǎn)生一個(gè)時(shí)序波形,如圖6-31所示。圖6-31例6-9產(chǎn)生的時(shí)序波形第一百二十頁(yè),共206頁(yè)。(2)塊內(nèi)的語(yǔ)句是按順序執(zhí)行的,即只有上面一條語(yǔ)句執(zhí)行完后下面的語(yǔ)句才能執(zhí)行。(3)每條語(yǔ)句的延時(shí)時(shí)間是相對(duì)于前一條語(yǔ)句的仿真時(shí)間而言的。(4)直到最后一條語(yǔ)句執(zhí)行完,程序流程控制才跳出該語(yǔ)句塊。第一百二十一頁(yè),共206頁(yè)。3.并行塊fork…join并行塊的格式如下:fork語(yǔ)句1;語(yǔ)句2;...語(yǔ)句n;join或第一百二十二頁(yè),共206頁(yè)。fork:塊名塊內(nèi)聲明語(yǔ)句 語(yǔ)句1;語(yǔ)句2;...語(yǔ)句n;join第一百二十三頁(yè),共206頁(yè)。其中:塊名即標(biāo)識(shí)該塊的一個(gè)名字,相當(dāng)于一個(gè)標(biāo)識(shí)符。塊內(nèi)說(shuō)明語(yǔ)句可以是參數(shù)說(shuō)明語(yǔ)句、reg型變量聲明語(yǔ)句、integer型變量聲明語(yǔ)句、real型變量聲明語(yǔ)句、time型變量聲明語(yǔ)句、事件(event)說(shuō)明語(yǔ)句等。下面使用fork…join語(yǔ)句重寫例6-9。第一百二十四頁(yè),共206頁(yè)?!纠?-10】并行塊應(yīng)用舉例。`timescale1ns/1nsmoduletest_fork;parameterd=20; //聲明d是一個(gè)參數(shù)reg[7:0]data; //聲明data是一個(gè)8位的寄存器變量initialfork //由一系列延時(shí)產(chǎn)生的波形 #ddata='h11; #(2*d)data='h22; #(3*d)data='h33; #(4*d)data='h44; #(5*d)$stop;

joinendmodule第一百二十五頁(yè),共206頁(yè)。程序說(shuō)明:

(1)本例用并行塊替代了例6-9中的順序塊來(lái)產(chǎn)生波形,用這兩種方法生成的波形是一樣的。(2)塊內(nèi)語(yǔ)句是同時(shí)執(zhí)行的,即程序流程控制一進(jìn)入到該并行塊,塊內(nèi)語(yǔ)句則開始同時(shí)并行地執(zhí)行。(3)塊內(nèi)每條語(yǔ)句的延時(shí)時(shí)間是相對(duì)于程序流程控制進(jìn)入塊內(nèi)時(shí)的仿真時(shí)間的。(4)延時(shí)時(shí)間是用來(lái)給賦值語(yǔ)句提供執(zhí)行時(shí)序的。第一百二十六頁(yè),共206頁(yè)。(5)當(dāng)按時(shí)序排在最后的語(yǔ)句執(zhí)行完后或一個(gè)disable語(yǔ)句執(zhí)行時(shí),程序流程控制跳出該程序塊。注意,順序塊和并行塊之間的根本區(qū)別在于:當(dāng)控制轉(zhuǎn)移到塊語(yǔ)句的時(shí)刻,并行塊中所有的語(yǔ)句同時(shí)開始執(zhí)行,語(yǔ)句之間的先后順序是無(wú)關(guān)緊要的,因此在fork_join塊內(nèi),不必關(guān)心各條語(yǔ)句的出現(xiàn)順序。第一百二十七頁(yè),共206頁(yè)。4.嵌套塊當(dāng)一個(gè)塊嵌入另一個(gè)塊時(shí),塊的起始時(shí)間和結(jié)束時(shí)間是很重要的。跟在塊后面的語(yǔ)句只有在該塊的結(jié)束時(shí)間到了后才能開始執(zhí)行,也就是說(shuō),只有該塊完全執(zhí)行完后,后面的語(yǔ)句才可以執(zhí)行。第一百二十八頁(yè),共206頁(yè)?!纠?-11】嵌套塊應(yīng)用舉例。`timescale1ns/1nsmoduletest_nested;parameterd=20; //聲明d是一個(gè)參數(shù)reg[7:0]data; //聲明data是一個(gè)8位的寄存器變量initialfork:block1 //并行塊 #ddata='h11; #(2*d)data='h12; #(3*d)data='h13;第一百二十九頁(yè),共206頁(yè)。begin:block2 //內(nèi)嵌順序塊 #(d-10)data='h2f; #ddata='h2e; fork:block3 //內(nèi)嵌并行塊 #5data='h38; #15data='h39; join #ddata='h2d; end #(4*d)data='h14; joinendmodule第一百三十頁(yè),共206頁(yè)。程序說(shuō)明:(1)本例輸出的data的波形如圖6-32所示。圖6-32例6-11中data的波形第一百三十一頁(yè),共206頁(yè)。(2)程序中,block2的起始時(shí)間跟block1的其他并行語(yǔ)句一樣都是仿真時(shí)刻0;block3的起始時(shí)間跟它在block2中的位置有關(guān)。由于block3之前還有2條順序語(yǔ)句,經(jīng)計(jì)算可知,block3的起始時(shí)間為仿真時(shí)刻30??蓪⒊绦虼a和波形圖結(jié)合起來(lái)分析。第一百三十二頁(yè),共206頁(yè)。關(guān)于起始時(shí)間和結(jié)束時(shí)間的進(jìn)一步說(shuō)明:在并行塊和順序塊中都有一個(gè)起始時(shí)間和結(jié)束時(shí)間的概念。對(duì)于順序塊,起始時(shí)間就是第一條語(yǔ)句開始被執(zhí)行的時(shí)間,結(jié)束時(shí)間就是最后一條語(yǔ)句執(zhí)行完的時(shí)間。而對(duì)于并行塊來(lái)說(shuō),起始時(shí)間對(duì)于塊內(nèi)所有的語(yǔ)句是相同的,即程序流程控制進(jìn)入該塊的時(shí)間,其結(jié)束時(shí)間是按時(shí)序排在最后的語(yǔ)句執(zhí)行完的時(shí)間。第一百三十三頁(yè),共206頁(yè)。6.4常用系統(tǒng)函數(shù)和系統(tǒng)任務(wù)

VerilogHDL中有以下一些系統(tǒng)函數(shù)和任務(wù):$bitstoreal、0$rtoi、$display、$setup、$finish、$skew、$hold、$setuphold、$itor、$strobe、$period、$time、$printtimescale、$timefoemat、$realtime、$width、$realtobits、$write、$recovery等。VerilogHDL中的每個(gè)系統(tǒng)函數(shù)和系統(tǒng)任務(wù)前面都用一個(gè)標(biāo)識(shí)符$來(lái)加以確認(rèn)。這些系統(tǒng)函數(shù)和系統(tǒng)任務(wù)提供了非常強(qiáng)大的功能,有興趣的讀者可以參閱相關(guān)書籍。下面對(duì)一些常用的系統(tǒng)函數(shù)和系統(tǒng)任務(wù)逐一加以介紹。第一百三十四頁(yè),共206頁(yè)。1.系統(tǒng)任務(wù)$display、$write和$strobe格式:$display(p1,p2,…,pn);$write(p1,p2,...,pn);$strobe(p1,p2,...,pn);第一百三十五頁(yè),共206頁(yè)。這三個(gè)系統(tǒng)任務(wù)的作用是輸出信息,即將參數(shù)p2到pn按參數(shù)p1給定的格式輸出。參數(shù)p1通常稱為“格式控制”,參數(shù)p2至pn通常稱為“輸出表列”。這三個(gè)任務(wù)的作用基本相同。$display自動(dòng)地在輸出后進(jìn)行換行;如果想在一行里輸出多個(gè)信息,可以使用$write;$strobe總是在同一仿真時(shí)刻的其他語(yǔ)句執(zhí)行完之后才執(zhí)行。$display、$write和$strobe的輸出格式控制是用雙引號(hào)括起來(lái)的字符串,它包括兩種信息:格式說(shuō)明和普通字符。第一百三十六頁(yè),共206頁(yè)。(1)格式說(shuō)明,由“%”和格式字符組成。它的作用是將輸出的數(shù)據(jù)轉(zhuǎn)換成指定的格式輸出。格式說(shuō)明總是由“%”字符開始的。對(duì)于不同類型的數(shù)據(jù),可用不同的格式輸出。表6-2給出了常用的幾種輸出格式。第一百三十七頁(yè),共206頁(yè)。第一百三十八頁(yè),共206頁(yè)。(2)普通字符,即需要原樣輸出的字符。其中一些特殊的字符可以通過(guò)表6-3中的轉(zhuǎn)換序列來(lái)輸出。第一百三十九頁(yè),共206頁(yè)。在$display和$write的參數(shù)列表中,其“輸出表列”是需要輸出的一些數(shù)據(jù),可以是表達(dá)式。下面舉幾個(gè)例子進(jìn)行說(shuō)明。第一百四十頁(yè),共206頁(yè)?!纠?-12】$display應(yīng)用舉例。moduledisp;reg[6:0]val;initialbegin

val=49; $display("hex:%h,decimal:%d",val,val); $display("octal:%o,binary:%b",val,val); $display("hex:%h,decimal:%0d",val,val); $display("octal:%0o,binary:%0b",val,val); val=97;第一百四十一頁(yè),共206頁(yè)。 $display("asciicharacter:%c",val); $display("string:%s",val); $display("\\\t%%\n\"\101");//轉(zhuǎn)義字符 #5 $display("currentscopeis%m"); $display("simulationtimeis%t",$time);endendmodule第一百四十二頁(yè),共206頁(yè)。其輸出結(jié)果為:#hex:31,decimal:49#octal:061,binary:0110001#hex:31,decimal:49#octal:61,binary:110001#asciicharacter:a#string:a#\ %#"A#currentscopeisdisp#simulationtimeis5第一百四十三頁(yè),共206頁(yè)。程序說(shuō)明:(1)使用$display時(shí),輸出表列中數(shù)據(jù)的顯示寬度是自動(dòng)按照輸出格式進(jìn)行調(diào)整的。這樣在顯示輸出數(shù)據(jù)時(shí),在經(jīng)過(guò)格式轉(zhuǎn)換以后,總是用表達(dá)式的最大可能值所占的位數(shù)來(lái)顯示表達(dá)式的當(dāng)前值。在用十進(jìn)制數(shù)格式輸出時(shí),輸出結(jié)果前面的0值用空格來(lái)代替。對(duì)于其他進(jìn)制,輸出結(jié)果前面的0仍然顯示出來(lái)。對(duì)于一個(gè)位寬為7位的值,如按照十六進(jìn)制數(shù)輸出,則輸出結(jié)果占2個(gè)字符的位置;如按照十進(jìn)制數(shù)輸出,則輸出結(jié)果占3個(gè)字符的位置。這是因?yàn)檫@個(gè)表達(dá)式的最大可能值為7F(十六進(jìn)制)、127(十進(jìn)制)。!第一百四十四頁(yè),共206頁(yè)??梢酝ㄟ^(guò)在%和表示進(jìn)制的字符中間插入一個(gè)0來(lái)自動(dòng)調(diào)整顯示輸出數(shù)據(jù)寬度的方式,使輸出時(shí)總是用最少的位數(shù)來(lái)顯示表達(dá)式的當(dāng)前值。請(qǐng)注意觀察下面語(yǔ)句的輸出:$display("hex:%h,decimal:%0d",val,val);$display("octal:%0o,binary:%0b",val,val);。第一百四十五頁(yè),共206頁(yè)。(2)?$time是時(shí)間度量系統(tǒng)函數(shù),其使用方法稍后介紹。如果輸出表列中表達(dá)式的值包含有不確定的值或高阻值時(shí),其結(jié)果輸出應(yīng)遵循一定的規(guī)則,下面舉例說(shuō)明。第一百四十六頁(yè),共206頁(yè)?!纠?-13】不定值、高阻值輸出舉例。moduledisp;reg[11:0]val;initialbegin val=12'b001_xxx_xx0_zzz; $display("hex:%h,decimal:%d",val,val); $display("otal:%o,binary:%b",val,val);

第一百四十七頁(yè),共206頁(yè)。endendmodule輸出結(jié)果為:#hex:XxZ,decimal:X#otal:1xXz,binary:001xxxxx0zzz第一百四十八頁(yè),共206頁(yè)。程序說(shuō)明:(1)在輸出格式為十進(jìn)制的情況下:如果表達(dá)式值的所有位均為不定值,則輸出結(jié)果為小寫的x。如果表達(dá)式值的所有位均為高阻值,則輸出結(jié)果為小寫的z。如果表達(dá)式值的部分位為不定值,則輸出結(jié)果為大寫的X。如果表達(dá)式值的部分位為高阻值,則輸出結(jié)果為大寫的Z。第一百四十九頁(yè),共206頁(yè)。(2)在輸出格式為十六進(jìn)制和八進(jìn)制的情況下:每4位二進(jìn)制數(shù)為一組,代表一位十六進(jìn)制數(shù);每3位二進(jìn)制數(shù)為一組,代表一位八進(jìn)制數(shù)。如果表達(dá)式值相對(duì)應(yīng)的一位八進(jìn)制(十六進(jìn)制)數(shù)的所有位均為不定值,則該位八進(jìn)制(十六進(jìn)制)數(shù)的輸出結(jié)果為小寫的x。如果表達(dá)式值相對(duì)應(yīng)的一位八進(jìn)制(十六進(jìn)制)數(shù)的所有位均為高阻值,則該位八進(jìn)制(十六進(jìn)制)數(shù)的輸出結(jié)果為小寫的z。第一百五十頁(yè),共206頁(yè)。如果表達(dá)式值相對(duì)應(yīng)的一位八進(jìn)制(十六進(jìn)制)數(shù)的部分位為不定值,則該位八進(jìn)制(十六進(jìn)制)數(shù)的輸出結(jié)果為大寫的X。如果表達(dá)式值相對(duì)應(yīng)的一位八進(jìn)制(十六進(jìn)制)數(shù)的部分位為高阻值,則該位八進(jìn)制(十六進(jìn)制)數(shù)的輸出結(jié)果為大寫的Z。第一百五十一頁(yè),共206頁(yè)。(3)對(duì)于二進(jìn)制輸出格式,表達(dá)式值的每一位的輸出結(jié)果為0、1、x、z。選通顯示($strobe)與$display的作用大同小異。如果許多其他語(yǔ)句與$display任務(wù)在同一時(shí)刻執(zhí)行,那么這些語(yǔ)句與$display任務(wù)的執(zhí)行順序是不確定的。如果使用$strobe,該語(yǔ)句總是在同一時(shí)刻的其他語(yǔ)句執(zhí)行完之后才執(zhí)行。因此,它可以確保所有在同一時(shí)刻賦值的其他語(yǔ)句執(zhí)行完后才顯示數(shù)據(jù)。第一百五十二頁(yè),共206頁(yè)?!纠?-14】$strobe應(yīng)用舉例。modulestrob;regval;initialbegin

$strobe("\$strobe:val=%b",val); val=0; val<=1; $display("\$display:val=%b",val);endendmodule輸出結(jié)果為:#$display:val=0#$strobe:val=1第一百五十三頁(yè),共206頁(yè)。程序說(shuō)明:(1)由于val<=1;是非阻塞賦值,要在此仿真時(shí)刻最后才完成賦值,因此非阻塞語(yǔ)句的賦值在所有的$display命令執(zhí)行以后才更新數(shù)值;因?yàn)?display在val=0;語(yǔ)句之后,所以顯示的val值為此刻的值0。(2)?$strobe語(yǔ)句總是在同一時(shí)刻的其他語(yǔ)句執(zhí)行完之后才執(zhí)行,因此它顯示val非阻塞賦值完成后的值1。因此,建議讀者用$strobe系統(tǒng)任務(wù)來(lái)顯示用非阻塞賦值的變量的值。第一百五十四頁(yè),共206頁(yè)。2.系統(tǒng)任務(wù)$monitor格式:$monitor(p1,p2,...,pn);$monitor;$monitoron;$monitoroff;第一百五十五頁(yè),共206頁(yè)。任務(wù)$monitor提供了監(jiān)控和輸出參數(shù)列表中的表達(dá)式或變量值的功能。其參數(shù)列表中輸出控制格式字符串和輸出表列的規(guī)則與$display中的一樣。當(dāng)啟動(dòng)一個(gè)帶有一個(gè)或多個(gè)參數(shù)的$monitor任務(wù)時(shí),仿真器建立一個(gè)處理機(jī)制,使得每當(dāng)參數(shù)列表中變量或表達(dá)式的值發(fā)生變化時(shí),整個(gè)參數(shù)列表中變量或表達(dá)式的值都將輸出顯示。如果在同一時(shí)刻兩個(gè)或多個(gè)參數(shù)的值發(fā)生變化,則在該時(shí)刻只輸出顯示一次。第一百五十六頁(yè),共206頁(yè)。$monitoron和$monitoroff任務(wù)的作用是通過(guò)打開和關(guān)閉監(jiān)控標(biāo)志來(lái)控制監(jiān)控任務(wù)$monitor的啟動(dòng)和停止,這樣使得程序員可以很容易地控制監(jiān)控任務(wù)$monitor。其中,$monitoroff任務(wù)用于關(guān)閉監(jiān)控標(biāo)志,停止監(jiān)控任務(wù)$monitor;$monitoron則用于打開監(jiān)控標(biāo)志,啟動(dòng)監(jiān)控任務(wù)$monitor。通常在通過(guò)調(diào)用$monitoron啟動(dòng)$monitor時(shí),不管$monitor參數(shù)列表中的值是否發(fā)生變化,總是立刻輸出顯示當(dāng)前時(shí)刻參數(shù)列表中的值,這用于在監(jiān)控的初始時(shí)刻設(shè)定初始比較值。在缺省情況下,控制標(biāo)志在仿真的起始時(shí)刻就已經(jīng)打開了。第一百五十七頁(yè),共206頁(yè)。在多模塊調(diào)試的情況下,許多模塊中都調(diào)用了$monitor,因?yàn)槿魏螘r(shí)刻只能有一個(gè)$monitor起作用,因此需配合$monitoron與$monitoroff使用,把需要監(jiān)視的模塊用$monitoron打開,在監(jiān)視完畢后及時(shí)用$monitoroff關(guān)閉,以便把$monitor讓給其他模塊使用。$monitor與$display的不同之處還在于$monitor往往在initial塊中調(diào)用,只要不調(diào)用$monitoroff,$monitor便不間斷地對(duì)所設(shè)定的信號(hào)進(jìn)行監(jiān)視。第一百五十八頁(yè),共206頁(yè)。3.時(shí)間度量系統(tǒng)函數(shù)$time在VerilogHDL中有兩種類型的時(shí)間系統(tǒng)函數(shù):$time和$realtime。用這兩個(gè)時(shí)間系統(tǒng)函數(shù)可以得到當(dāng)前的仿真時(shí)刻。系統(tǒng)函數(shù)$time可以返回一個(gè)用64bit整數(shù)表示的當(dāng)前仿真時(shí)刻值,該時(shí)刻以模塊的仿真時(shí)間尺度為基準(zhǔn)。$realtime和$time的作用是一樣的,只是$realtime返回的時(shí)間數(shù)字是一個(gè)實(shí)型數(shù),該數(shù)字也是以時(shí)間尺度為基準(zhǔn)的。第一百五十九頁(yè),共206頁(yè)?!纠?-15】$monitor和$time應(yīng)用舉例。`timescale10ns/1nsmodulemonit;regdata;parameterp=1.4;initialbegin $monitor($time,"data=",data);// $monitor($realtime,"data=",data);第一百六十頁(yè),共206頁(yè)。

#pdata=0; #pdata=1; #pdata=0; #pdata=1;endendmodule輸出結(jié)果為:#0data=x#1data=0#3data=1#4data=0#6data=1第一百六十一頁(yè),共206頁(yè)。程序說(shuō)明:

(1)在這個(gè)例子中,模塊monit預(yù)想在時(shí)刻為14ns時(shí)設(shè)置寄存器data為0,在時(shí)刻為28?ns時(shí)設(shè)置寄存器data為1,在42?ns時(shí)設(shè)置寄存器data為0,在56?ns時(shí)設(shè)置寄存器data為1。但是由$time記錄的data變化時(shí)刻卻和預(yù)想的不一樣。第一百六十二頁(yè),共206頁(yè)。(2)?$time顯示時(shí)刻受時(shí)間尺度比例的影響。在上面的例子中,時(shí)間單位是10?ns,因?yàn)?time輸出的時(shí)刻總是時(shí)間單位的倍數(shù),所以就將14ns、28ns、42ns和56ns輸出為1.4、2.8、4.2和5.6。又因?yàn)?time總是輸出整數(shù),所以在將經(jīng)過(guò)尺度比例變換的數(shù)字輸出時(shí),要先進(jìn)行取整。在上面的例子中,1.4、2.8、4.2和5.6經(jīng)取整后為1、3、4和6輸出。注意:時(shí)間精度并不影響數(shù)字的取整。第一百六十三頁(yè),共206頁(yè)。(3)若將例子中$monitor($time,“data=”,data);改為$monitor($realtime,"data=",data);,則輸出結(jié)果如下:

#0data=x

#1.4data=0

#2.8data=1

#4.2data=0#5.6data=1從結(jié)果可以看出,$realtime將仿真時(shí)刻經(jīng)過(guò)尺度變換以后輸出,不需進(jìn)行取整操作。所以$realtime返回的時(shí)刻是實(shí)型數(shù)。第一百六十四頁(yè),共206頁(yè)。4.系統(tǒng)任務(wù)$finish和$stop(1)?$finish。格式:$finish;$finish(n);系統(tǒng)任務(wù)$finish的作用是退出仿真器,返回主操作系統(tǒng),也就是結(jié)束仿真過(guò)程。任務(wù)$finish可以帶參數(shù),根據(jù)參數(shù)的值輸出不同的特征信息。如果不帶參數(shù),默認(rèn)$finish的參數(shù)值為1。下面給出了對(duì)于不同的參數(shù)值,系統(tǒng)輸出的特征信息:第一百六十五頁(yè),共206頁(yè)。0:不輸出任何信息;1:輸出當(dāng)前仿真時(shí)刻和位置;2:輸出當(dāng)前仿真時(shí)刻、位置和在仿真過(guò)程中所用memeory及CPU時(shí)間的統(tǒng)計(jì)。第一百六十六頁(yè),共206頁(yè)。(2)?$stop。格式:$stop;$stop(n);$stop任務(wù)的作用是把EDA仿真器置成暫停模式,在仿真環(huán)境下給出一個(gè)交互式的命令提示符,將控制權(quán)交給用戶。這個(gè)任務(wù)可以帶有參數(shù)表達(dá)式。根據(jù)參數(shù)值(0、1或2)的不同,輸出不同的信息。參數(shù)值越大,輸出的信息越多。第一百六十七頁(yè),共206頁(yè)。5.系統(tǒng)任務(wù)$readmemb和$readmemh在VerilogHDL程序中有兩個(gè)系統(tǒng)任務(wù)$readmemb和$readmemh,用來(lái)從文件中讀取數(shù)據(jù)到存儲(chǔ)器中。這兩個(gè)系統(tǒng)任務(wù)可以在仿真的任何時(shí)刻被執(zhí)行使用,其使用格式共有以下六種:$readmemb("<數(shù)據(jù)文件名>",<存儲(chǔ)器名>);$readmemb("<數(shù)據(jù)文件名>",<存儲(chǔ)器名>,<起始地址>);$readmemb("<數(shù)據(jù)文件名>",<存儲(chǔ)器名>,<起始地址>,<結(jié)束地址>);第一百六十八頁(yè),共206頁(yè)。

溫馨提示

  • 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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論