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

下載本文檔

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

文檔簡介

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

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

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

第三十六頁,共206頁。

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

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

第七十六頁,共206頁。//調(diào)用已設計好的模塊 sin_waveone(.clk(clk),.data(data));//監(jiān)視設計塊輸出,變量初始化,設置仿真時間 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第七十七頁,共206頁。//控制驅動設計塊的時鐘信號,時鐘周期為10個時鐘單位 always #5clk=~clk;//clk周期為10 //將設計塊的輸出數(shù)據(jù)存放于文件,同時在命令窗口中顯示存放進度 always@(posedgeclk) begin if(!flag) begin $fdisplayh(vec_file,"%h",data); $display($time,"i=%0d,data:%d",i,data); if(i!=6'd63) begin第七十八頁,共206頁。i<=i+1; flag<=1'b0; end else begin flag<=1'b1; $fclose(vec_file); end end end //用存放于文件中的數(shù)據(jù)對數(shù)組進行初始化,并將數(shù)組內(nèi)容在命令窗口中顯示第七十九頁,共206頁。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第八十頁,共206頁。程序說明:(1)功能仿真結果分析。由于命令窗口顯示的功能仿真結果很長,所以僅摘抄一部分,供大家分析程序用。以下是部分功能仿真結果:#0sin_wavedata:0#5i=0,data:0#5sin_wavedata:255#15i=1,data:255

#15sin_wavedata:254

#25i=2,data:254

#25sin_wavedata:252第八十一頁,共206頁。#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第八十二頁,共206頁。#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第八十三頁,共206頁。(2)時序仿真結果分析。由于命令窗口顯示的時序仿真結果很長,所以僅摘抄一部分,供大家分析程序用。以下是部分時序仿真結果:#505sin_wavedata:139#505i=50,data:139#505sin_wavedata:138#505sin_wavedata:154#506sin_wavedata:158#506sin_wavedata:150#515i=51,data:150第八十四頁,共206頁。#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第八十五頁,共206頁。#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第八十六頁,共206頁。#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第八十七頁,共206頁。#576sin_wavedata:225#585i=58,data:225#586sin_wavedata:233#595sin_wavedata:235#595i=59,data:235#596sin_wavedata:239從仿真結果中我們可以直觀地看出仿真延時信息和毛刺存在的時間等信息。這些信息跟波形圖顯示的信息一致,兩者可以結合在一起分析。第八十八頁,共206頁。(3)本程序中使用了$display、$monitor、$fopen、$fclose、$fdisplayh、$readmemh、$finish等系統(tǒng)任務,關于這些任務的用法與含義詳見本章6.4節(jié)。通過本節(jié)的學習,我們可以發(fā)現(xiàn)ModelSim不僅好用,而且易用。第八十九頁,共206頁。6.2延時

前幾章我們描述的電路都是無延時的。事實上,在實際的電路中,任何一個邏輯門都具有延時。VerilogHDL允許用戶通過延時語句來說明邏輯電路中的延時。例6-4中,我們在編寫測試激勵模塊時使用了延時,下面對延時作進一步說明。第九十頁,共206頁。

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

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

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

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

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

joinendmodule第一百二十五頁,共206頁。程序說明:

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

VerilogHDL中有以下一些系統(tǒng)函數(shù)和任務:$bitstoreal、0$rtoi、$display、$setup、$finish、$skew、$hold、$setuphold、$itor、$strobe、$period、$time、$printtimescale、$timefoemat、$realtime、$width、$realtobits、$write、$recovery等。VerilogHDL中的每個系統(tǒng)函數(shù)和系統(tǒng)任務前面都用一個標識符$來加以確認。這些系統(tǒng)函數(shù)和系統(tǒng)任務提供了非常強大的功能,有興趣的讀者可以參閱相關書籍。下面對一些常用的系統(tǒng)函數(shù)和系統(tǒng)任務逐一加以介紹。第一百三十四頁,共206頁。1.系統(tǒng)任務$display、$write和$strobe格式:$display(p1,p2,…,pn);$write(p1,p2,...,pn);$strobe(p1,p2,...,pn);第一百三十五頁,共206頁。這三個系統(tǒng)任務的作用是輸出信息,即將參數(shù)p2到pn按參數(shù)p1給定的格式輸出。參數(shù)p1通常稱為“格式控制”,參數(shù)p2至pn通常稱為“輸出表列”。這三個任務的作用基本相同。$display自動地在輸出后進行換行;如果想在一行里輸出多個信息,可以使用$write;$strobe總是在同一仿真時刻的其他語句執(zhí)行完之后才執(zhí)行。$display、$write和$strobe的輸出格式控制是用雙引號括起來的字符串,它包括兩種信息:格式說明和普通字符。第一百三十六頁,共206頁。(1)格式說明,由“%”和格式字符組成。它的作用是將輸出的數(shù)據(jù)轉換成指定的格式輸出。格式說明總是由“%”字符開始的。對于不同類型的數(shù)據(jù),可用不同的格式輸出。表6-2給出了常用的幾種輸出格式。第一百三十七頁,共206頁。第一百三十八頁,共206頁。(2)普通字符,即需要原樣輸出的字符。其中一些特殊的字符可以通過表6-3中的轉換序列來輸出。第一百三十九頁,共206頁。在$display和$write的參數(shù)列表中,其“輸出表列”是需要輸出的一些數(shù)據(jù),可以是表達式。下面舉幾個例子進行說明。第一百四十頁,共206頁?!纠?-12】$display應用舉例。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;第一百四十一頁,共206頁。 $display("asciicharacter:%c",val); $display("string:%s",val); $display("\\\t%%\n\"\101");//轉義字符 #5 $display("currentscopeis%m"); $display("simulationtimeis%t",$time);endendmodule第一百四十二頁,共206頁。其輸出結果為:#hex:31,decimal:49#octal:061,binary:0110001#hex:31,decimal:49#octal:61,binary:110001#asciicharacter:a#string:a#\ %#"A#currentscopeisdisp#simulationtimeis5第一百四十三頁,共206頁。程序說明:(1)使用$display時,輸出表列中數(shù)據(jù)的顯示寬度是自動按照輸出格式進行調(diào)整的。這樣在顯示輸出數(shù)據(jù)時,在經(jīng)過格式轉換以后,總是用表達式的最大可能值所占的位數(shù)來顯示表達式的當前值。在用十進制數(shù)格式輸出時,輸出結果前面的0值用空格來代替。對于其他進制,輸出結果前面的0仍然顯示出來。對于一個位寬為7位的值,如按照十六進制數(shù)輸出,則輸出結果占2個字符的位置;如按照十進制數(shù)輸出,則輸出結果占3個字符的位置。這是因為這個表達式的最大可能值為7F(十六進制)、127(十進制)。!第一百四十四頁,共206頁??梢酝ㄟ^在%和表示進制的字符中間插入一個0來自動調(diào)整顯示輸出數(shù)據(jù)寬度的方式,使輸出時總是用最少的位數(shù)來顯示表達式的當前值。請注意觀察下面語句的輸出:$display("hex:%h,decimal:%0d",val,val);$display("octal:%0o,binary:%0b",val,val);。第一百四十五頁,共206頁。(2)?$time是時間度量系統(tǒng)函數(shù),其使用方法稍后介紹。如果輸出表列中表達式的值包含有不確定的值或高阻值時,其結果輸出應遵循一定的規(guī)則,下面舉例說明。第一百四十六頁,共206頁?!纠?-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);

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

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

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

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

#0data=x

#1.4data=0

#2.8data=1

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

溫馨提示

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

評論

0/150

提交評論