一、FPGA設(shè)計(jì)仿真驗(yàn)證簡(jiǎn)介
嚴(yán)格來(lái)講,F(xiàn)PGA設(shè)計(jì)驗(yàn)證包括功能仿真、時(shí)序仿真和電路驗(yàn)證,它們分別對(duì)應(yīng)整個(gè)開(kāi)發(fā)流程的每一個(gè)步驟。仿真是指使用設(shè)計(jì)軟件包對(duì)已實(shí)現(xiàn)的設(shè)計(jì)進(jìn)行完整的測(cè)試,并模擬實(shí)際物理環(huán)境下的工作情況。
功能仿真是指僅對(duì)邏輯功能進(jìn)行模擬測(cè)試,以了解其實(shí)現(xiàn)的功能是否滿(mǎn)足原設(shè)計(jì)的要求,仿真過(guò)程沒(méi)有加入時(shí)序信息,不涉及具體器件的硬件特性,如延時(shí)特性等,因此又叫前仿真,它是對(duì)HDL硬件描述語(yǔ)言的功能實(shí)現(xiàn)情況進(jìn)行仿真,以確保HDL語(yǔ)言描述能夠滿(mǎn)足設(shè)計(jì)者的最初意圖。
時(shí)序仿真則是在HDL可以滿(mǎn)足設(shè)計(jì)者功能要求的基礎(chǔ)上,在布局布線(xiàn)后,提取有關(guān)的器件延遲、連線(xiàn)延時(shí)等時(shí)序參數(shù)信息,并在此基礎(chǔ)上進(jìn)行的仿真,也成為后仿真,它是接近于器件真實(shí)運(yùn)行狀態(tài)的一種仿真。
二、仿真軟件ModelSim及其應(yīng)用
HDL的仿真軟件有很多種,如VCS、VSS、NC-Verilog、NC-VHDL、ModelSim等,對(duì)于開(kāi)發(fā)FPGA來(lái)說(shuō),一般是使用FPGA廠家提供的集成開(kāi)發(fā)環(huán)境,他們都有自己的仿真器,如Xilinx公司的ISE,Altera公司的Quartus II等,但是這些廠家開(kāi)發(fā)的仿真器的仿真功能往往比不上專(zhuān)業(yè)的EDA公司的仿真工具,如ModelSim AE(Altera Edition)、ModelSim XE(Xilinx Edition)等。Quartus II設(shè)有第三方仿真工具的接口,可以直接調(diào)用其他EDA公司的仿真工具,這極大地提高了EDA設(shè)計(jì)的水平和質(zhì)量。
ModelSim是Model Technology(Mentor Graphics的子公司)的HDL硬件描述語(yǔ)言的仿真軟件,該軟件可以用來(lái)實(shí)現(xiàn)對(duì)設(shè)計(jì)的VHDL、Verilog HDL 或是兩種語(yǔ)言混合的程序進(jìn)行仿真,同時(shí)也支持IEEE常見(jiàn)的各種硬件描述語(yǔ)言標(biāo)準(zhǔn)。
無(wú)論是從使用界面和調(diào)試環(huán)境,還是從仿真速度和效果上看,ModelSim都可以算的上是業(yè)界比較優(yōu)秀的HDL語(yǔ)言仿真軟件。它是唯一的單內(nèi)核支持VHDL和Verilog HDL混合仿真的仿真器,是做FPGA/ASIC設(shè)計(jì)的RTL級(jí)和門(mén)級(jí)電路仿真的好選擇,它采用直接優(yōu)化的編譯技術(shù),Tcl/Tk技術(shù)和單一內(nèi)核仿真技術(shù),具有仿真速度快,編譯的代碼與仿真平臺(tái)無(wú)關(guān),便于IP核的保護(hù)和加快錯(cuò)誤程序定位等優(yōu)點(diǎn)。
ModelSim分幾種不同的版本:ModelSim SE、ModelSim PE、ModelSim LE和ModelSim OEM,其中的SE、PE、LE是其最高版本,編譯速度是所有版本中最快的,而OEM版本就是集成在FPGA廠家設(shè)計(jì)工具中的版本,它們專(zhuān)門(mén)和某個(gè)廠家的FPGA配套來(lái)使用,如后面使用到的ModelSim AE就是專(zhuān)門(mén)針對(duì)Altera公司QuartusII的配套的OEM產(chǎn)品。
三、ModelSim的仿真流程
ModelSim不僅可以用于數(shù)字電路系統(tǒng)設(shè)計(jì)的功能仿真,還可以應(yīng)用于數(shù)字電路系統(tǒng)設(shè)計(jì)的時(shí)序仿真。 ModelSim的使用中,最基本的步驟包括創(chuàng)建工程、編寫(xiě)源代碼、編譯、啟動(dòng)仿真器和運(yùn)行仿真五個(gè)步驟,仿真流程如圖1所示:
圖1 ModelSim仿真的基本流程(基于工程的)
這個(gè)是基于工程的流程,還有一種是基于庫(kù)文件的,和基于工程的相比,它需要自己創(chuàng)建工作庫(kù),另外關(guān)閉ModelSim軟件后,下次還得自己手動(dòng)打開(kāi)設(shè)計(jì)文件,而基于工程的就不會(huì)這樣,工程是一直保持的狀態(tài),不用每次啟動(dòng)軟件后再手工加載,除非我們自己關(guān)掉這個(gè)工程。還有另外兩個(gè)流程,這里不提了,詳細(xì)內(nèi)容可參看ModelSim AlteraTutorial.PDF 。在軟件的安裝目錄的DOCS文件夾內(nèi)是全部的參考文檔,包括使用手冊(cè)等。
四、仿真測(cè)試文件(Test Bench)程序的設(shè)計(jì)方法
隨著設(shè)計(jì)量和復(fù)雜度的不斷增加,數(shù)字驗(yàn)證變得越來(lái)越難,所消耗的成本也越來(lái)越高,面對(duì)這種挑戰(zhàn),驗(yàn)證工程師必須依靠相應(yīng)的驗(yàn)證工具和方法。對(duì)于大型的設(shè)計(jì),比如上百萬(wàn)門(mén)的設(shè)計(jì)驗(yàn)證,工程師必須使用一整套規(guī)范的驗(yàn)證工具,而對(duì)于較小的設(shè)計(jì),使用具有HDL Test Bench的仿真器是一個(gè)不錯(cuò)的選擇。
一般來(lái)說(shuō),Test Bench使用工業(yè)標(biāo)準(zhǔn)VHDL或者Verilog HDL語(yǔ)言來(lái)描述,簡(jiǎn)單的Test Bench通過(guò)調(diào)用用戶(hù)設(shè)計(jì)的功能模塊,然后進(jìn)行仿真,較為復(fù)雜的Test Bench還包括一些其他的功能,比如包含特定的激勵(lì)向量或者進(jìn)行實(shí)際輸出與期望的比較等。
在開(kāi)始寫(xiě)Test Bench之前,很重要的一點(diǎn)就是要設(shè)計(jì)實(shí)例化DUT(Design Under Test,即就是被測(cè)元件),還要詳細(xì)了解整個(gè)的測(cè)試計(jì)劃和測(cè)試案例。整個(gè)的測(cè)試Test Bench環(huán)境如圖2所示:
圖2 Test Bench的測(cè)試環(huán)境
從圖中可以看見(jiàn),Test Bench和被測(cè)對(duì)象Counter構(gòu)成了一個(gè)封閉的循環(huán),Test Bench負(fù)責(zé)向被測(cè)元器件的輸入端口提供激勵(lì)(時(shí)鐘)和一些控制信號(hào)(復(fù)位和置位信號(hào)),另外Test Bench還監(jiān)測(cè)被測(cè)元器件的輸出端口所輸出的信號(hào)值是否和我們的設(shè)計(jì)預(yù)期相符,并把監(jiān)測(cè)的情況顯示給我們。
由于Test Bench程序和被測(cè)對(duì)象構(gòu)成了一個(gè)封閉的循環(huán),因此Test Bench的輸入端口需要與被測(cè)對(duì)象的輸出端口連接,Test Bench的輸出端口則要與被測(cè)對(duì)象的輸入端口相連接。所以在端口的定義上,Test Bench程序需要和被測(cè)對(duì)象相對(duì)應(yīng)。
被測(cè)元器件是一個(gè)已經(jīng)設(shè)計(jì)好的電路或系統(tǒng),Test Bench是用元件例化語(yǔ)句將其嵌入程序中。VerilogHDL測(cè)試平臺(tái)是一個(gè)設(shè)有輸入輸出端口的設(shè)計(jì)模塊,被測(cè)元器件的輸入端定義為reg(寄存器)型變量,在always塊或initial塊中賦值(產(chǎn)生測(cè)試條件),被測(cè)元器件的輸出端定義為wire(線(xiàn)網(wǎng))型變量,產(chǎn)生相應(yīng)輸入變化的輸出結(jié)果(波形)。
4.1 組合邏輯電路Test Bench的設(shè)計(jì)
組合邏輯的設(shè)計(jì)驗(yàn)證,主要就是檢查設(shè)計(jì)結(jié)果是不是符合該電路的真值表功能,因此在編寫(xiě)組合邏輯Test Bench時(shí),用initial塊把被測(cè)電路的輸入按照真值表提供的數(shù)據(jù)變化作為測(cè)試條件,就能實(shí)現(xiàn)Test Bench的設(shè)計(jì)。
例1. 編寫(xiě)一位全加器的Test Bench程序
全加器的A和B兩個(gè)是1位二進(jìn)制加數(shù)的輸入端,CI是低位來(lái)的進(jìn)位輸入端,CO是向高位進(jìn)位的輸出端,SO是全加器的本位和值。
用Verilog HDL語(yǔ)言編寫(xiě)的全加器程序adder.v如下:
//-----------------------------------------------------
// DesignName : adder1
// FileName : adder1.v
//Function : 1 bit full adder
//Coder : Cheng xu
//-----------------------------------------------------
moduleadder1(
a ,
b ,
ci ,
so ,
co
);
// Portdeclarations
input a ;
input b ;
input ci ;
output so ;
output co ;
//InternalVariables
wire a ;
wire b ;
wire ci ;
wire so ;
wire co ;
//CodeStarts Here
assign {co, so} = a + b + ci;
endmodule
根據(jù)全加器的真值表寫(xiě)的全加器的Test Bench程序test_adder1.v如下:
//test_adder1.v
`timescale1ns/1ns
moduletest_adder1;
wire so ;
wire co ;
reg a ;
reg b ;
reg ci ;
adder1 U(
.a(a),
.b(b),
.ci(ci),
.so(so),
.co(co)
);
initial
begin
#20 a = 0; b = 0; c = 0;
#20 a = 0; b = 0; c = 1;
#20 a = 0; b = 1; c = 0;
#20 a = 0; b = 1; c = 1;
#20 a = 1; b = 0; c = 0;
#20 a = 1; b = 0; c = 1;
#20 a = 1; b = 1; c = 0;
#20 a = 1; b = 1; c = 1;
#200 $stop;
end
endmodule
下面我們就以ModelSim為EDA平臺(tái),仿真上面的程序。這一講先暫時(shí)不講仿真測(cè)試的方法,留到下一講再來(lái)詳述,這一講主要講述的內(nèi)容是Test Bench程序的編寫(xiě)方法,故現(xiàn)在僅僅給出仿真的波形圖,全加器的仿真波形如圖3所示:
圖3 一位全加器的仿真波形圖
現(xiàn)在對(duì)著這個(gè)圖,我們返回來(lái)再來(lái)看看我們編寫(xiě)的test_adder1.v這個(gè)Test Bench程序究竟完成了哪些工作,是不是按照我們的要求來(lái)工作的:
①首先看程序第二行的`timescale1ns/1ns這句代碼,這個(gè)是時(shí)間尺度指令,它是用來(lái)定義模塊的仿真時(shí)間單位和時(shí)間精度的,其使用格式為:`timescale 仿真時(shí)間單位/時(shí)間精度,用于說(shuō)明仿真時(shí)間單位和時(shí)間精度的數(shù)字只能是1、10或100,不能為其它的數(shù)字,單位可以是s、ms、us、ns、ps和fs。仿真時(shí)間單位是指的模塊仿真時(shí)間和延時(shí)的基準(zhǔn)單位,也就是說(shuō)只有定義了仿真時(shí)間單位,程序中的延時(shí)符號(hào)"#"才有意義,如程序中的一行 #20 a = 0; b = 0; c = 0; 前面的 #20 就是延時(shí)20個(gè)時(shí)間基準(zhǔn)單位,按照程序中的1ns這個(gè)基準(zhǔn),就延時(shí)了20個(gè)ns。需要說(shuō)明的是該行程序的下一行 #20 a =0; b = 0; c = 1; 前面的延時(shí)20個(gè)ns是相對(duì)于前一個(gè)的延時(shí)來(lái)說(shuō)的,也就是第二行在第一行完了之后延時(shí)20ns執(zhí)行。這時(shí)候再看看仿真的波形圖就不難理解最開(kāi)始的線(xiàn)為什么是紅色而不是正常的綠色的原因了,因?yàn)槲覀冊(cè)诔绦蛑衎egin的下一行就是 #20 a =0; b = 0; c = 0; 它前面的延時(shí)20個(gè)ns是相對(duì)于begin的延時(shí),也就是說(shuō)程序開(kāi)始的時(shí)候是什么都不做的,輸出為不確定的值,過(guò)了20個(gè)ns才將全0賦給了a、b和ci,這個(gè)時(shí)候才是最開(kāi)始的綠線(xiàn)的部分。
②在Test Bench程序中,把全加器的輸入a、b和ci定義為了reg型變量,把輸出so和co定義為了wire型變量,這個(gè)和被測(cè)元件的定義情況剛好是反的,這樣也說(shuō)明了TestBench程序和被測(cè)元件是封閉的一個(gè)循環(huán)。用元件例化語(yǔ)句adder1U( .a(a), .b(b), .ci(ci), .so(so), .co(co) ) ; 把全加器設(shè)計(jì)電路嵌入到Test Bench程序中。
③程序的后面有一句 #200 $stop; 這個(gè)是一個(gè)系統(tǒng)任務(wù),用來(lái)暫停仿真過(guò)程的,將控制權(quán)交還給用戶(hù),用戶(hù)在取得控制權(quán)以后可以輸入其它的控制命令或者查看仿真結(jié)果等,之后可以從暫停的地方恢復(fù)仿真過(guò)程。$stop有兩種表達(dá)形式,帶參數(shù)的和不帶參數(shù)的:
$stop;
$stop(n); //n可以取0、1或2
不帶參數(shù)的$stop等同于$stop(0),在暫停時(shí)不輸出任何信息;$stop(1)在暫停時(shí)輸出當(dāng)前仿真時(shí)刻和暫停處在程序中的位置;$stop(2)不僅有$stop(1)的作用,還能輸出仿真時(shí)占用內(nèi)存大小和CPU時(shí)間。
而用于退出仿真過(guò)程的系統(tǒng)任務(wù)是 $finish,我們?cè)邳c(diǎn)擊Run(開(kāi)始運(yùn)行)的時(shí)候,系統(tǒng)會(huì)詢(xún)問(wèn)我們是否要結(jié)束仿真,假如我們選"是",這個(gè)系統(tǒng)任務(wù)會(huì)把ModelSim軟件在完成仿真后關(guān)閉,假如我們選"否",則可以繼續(xù)留在仿真界面。
和一位全加器的真值表進(jìn)行全部的對(duì)比后發(fā)現(xiàn)和該仿真波形完全一致,仿真結(jié)束。
4.2 時(shí)序邏輯電路Test Bench的設(shè)計(jì)
時(shí)序邏輯電路Test Bench的設(shè)計(jì)要求和組合邏輯電路基本相同,主要區(qū)別在于時(shí)序邏輯電路Test Bench軟件中,需要用always塊語(yǔ)句生成時(shí)鐘信號(hào)。
例2所編寫(xiě)的程序,就是在下一講當(dāng)中的實(shí)例,利用這個(gè)實(shí)例來(lái)講解軟件的全部操作流程和使用方法,這一講先來(lái)分析這個(gè)程序以及和它相配套的Test Bench程序,看看它們是否能夠按照我們?cè)O(shè)計(jì)期望的那樣輸出仿真結(jié)果。
例2. 編寫(xiě)8位加法器的Test Bench程序
第一個(gè)文件,源程序:
//-----------------------------------------------------
// DesignName : counter8
// FileName : counter8.v
//Function : 8 bits counter with asyncclear and sync load
//Coder : Cheng xu
//-----------------------------------------------------
modulecounter8(
clk ,
aclr ,
load ,
load_din ,
dout
);
// Portdeclarations
input clk ;
input aclr ;
input load ;
input [7:0] load_din ;
output [7:0] dout ;
//InternalVariables
wire clk ;
wire aclr ;
wire load ;
wire [7:0] load_din ;
wire [7:0] dout ;
reg [7:0] counter = 0 ;
//CodeStarts Here
always @(posedge clk or negedge aclr)
if(!aclr)
counter <= 0;
else if(load == 1)
counter <= load_din;
else
counter <= counter + 1;
assigndout = counter;
endmodule
第二個(gè)文件,Test Bench仿真測(cè)試程序:
//test_counter8.v
`timescale1ns/1ns //注意最前面的符號(hào)是數(shù)字鍵"1"左邊的那個(gè)符號(hào),不是單引號(hào)
moduletest_counter8;
reg clk ;
reg aclr ;
reg load ;
reg [7:0] load_din ;
wire [7:0] dout ;
initial
begin
clk = 0;
aclr = 1;
load = 0;
load_din = 0;
#120 aclr = 0;
#40 aclr = 1;
#20 load = 1;
load_din = 100;
#20 load = 0;
#100 $stop;
end
always#10 clk = ~clk;
counter8U(
.clk(clk),
.aclr(aclr),
.load(load),
.load_din(load_din),
.dout(dout)
);
endmodule
圖4 八位加法器仿真波形圖
現(xiàn)在就對(duì)著這個(gè)圖,來(lái)看看我們編寫(xiě)的test_counter8.v文件是不是按照我們的設(shè)計(jì)要求的那樣來(lái)工作的:
①和組合邏輯的設(shè)計(jì)一樣,我們要在test_counter8.v中例化被測(cè)元件counter8,把八位加法器元件嵌入到test_counter8.v這個(gè)Test Bench中來(lái)。
②和組合邏輯不同的是,我們要利用always #10 clk = ~clk; 這個(gè)語(yǔ)句來(lái)產(chǎn)生周期為20個(gè)時(shí)間基準(zhǔn)單位(1ns)的時(shí)鐘(方波),即就是20ns的時(shí)鐘信號(hào)。注意:時(shí)鐘只能用always塊才能生成,但要在initial塊中賦給時(shí)鐘的初始值(如clk=0或clk=1),如果不設(shè)置時(shí)鐘初始值,則在仿真的時(shí)鐘輸出端是一個(gè)未知x(不變,就是例1中的那段紅線(xiàn)了)。
③在initial塊中生成復(fù)位信號(hào)和加載信號(hào),注意:一定要給復(fù)位信號(hào)和加載信號(hào)賦給初始值,否則和不設(shè)置時(shí)鐘初始值一樣會(huì)出現(xiàn)問(wèn)題的。
④在initial塊的begin語(yǔ)句一開(kāi)始就設(shè)置相關(guān)的初始值是一個(gè)好習(xí)慣。
和test_counter8.v進(jìn)行全部的對(duì)比后發(fā)現(xiàn)和該仿真波形完全一致,仿真結(jié)束。
至此,第一講全部?jī)?nèi)容結(jié)束,主要是講了Test Bench程序的編寫(xiě)方法,下一講我們將介紹ModelSim軟件的使用方法。
ModelSim仿真入門(mén)之二:功能仿真
本實(shí)驗(yàn)的目的就是在ModelSim環(huán)境下學(xué)習(xí)掌握該軟件的一般仿真測(cè)試流程和仿真測(cè)試方法,另外學(xué)習(xí)編寫(xiě)簡(jiǎn)單的Test Bench程序并在ModelSim下進(jìn)行調(diào)試。
實(shí)驗(yàn)步驟如下:
1. 打開(kāi)ModelSim軟件,如圖1所示:
圖1 打開(kāi)軟件
2. 軟件的啟動(dòng)畫(huà)面如圖2所示,進(jìn)入界面后如圖3所示:
圖2 軟件的啟動(dòng)畫(huà)面
圖3 軟件進(jìn)入后的畫(huà)面
注意:如果是第一次使用軟件,進(jìn)入后會(huì)有一些諸如軟件的歡迎畫(huà)面等不相關(guān)的對(duì)話(huà)框,無(wú)須擔(dān)心,直接關(guān)閉即可,亦可選擇下次登陸時(shí)不顯示。
3. 進(jìn)入ModelSim主窗口后,選擇File菜單下的"New→Project",新建一個(gè)工程,在彈出的對(duì)話(huà)框中,給該工程命名并指定一個(gè)存放的路徑,如圖4所示:
圖4 新建工程
在這里,工程名和你的頂層文件名保持一致是推薦的做法。路徑的注意事項(xiàng)已經(jīng)說(shuō)過(guò),這里不再提及。默認(rèn)的庫(kù)名就是"work",這個(gè)無(wú)需更改,點(diǎn)擊"OK"即可。
4. 之后會(huì)彈出如圖5的對(duì)話(huà)框,選擇是新建一個(gè)文件還是添加已存在的文件,這兩個(gè)都可以選擇,假如事先編好了文件,就選擇添加進(jìn)來(lái),假如沒(méi)有就新建。在這里使用添加已有文件,在軟件開(kāi)始之前就編好所用的程序,這樣比較方便些。軟件自帶的編輯環(huán)境不是很好,使用第三方的編輯工具是推薦的方法。建議使用UltraEdit或Notepad++這些專(zhuān)業(yè)的代碼編輯軟件。
UltraEdit偏重于功能的強(qiáng)大和豐富的用戶(hù)可定制化特性,而Notepad++更加注重易用性。兩者在普通功能上差異不是特別大,根據(jù)自己的喜好選擇一款即可。
圖5 給工程中添加文件
在路徑G:\FPGA_Project\ModelSim\counter8下新建兩個(gè)文件,一個(gè)是counter8.v,一個(gè)是test_counter8.v,前者是我們的原始的設(shè)計(jì)文件,后者是其相應(yīng)的仿真測(cè)試文件。在這個(gè)路徑的Windows目錄下,在空白處右鍵選擇新建一個(gè)文本文檔.TXT格式,然后在這個(gè)文件上右鍵選擇UltraEdit或Edit with Notepad++就可以啟動(dòng)相應(yīng)的代碼編輯工具進(jìn)行編輯了,保存的時(shí)候注意存成".v"或".vhd"格式即可。
以下給出兩個(gè)文件的代碼:
第一個(gè)文件:
//-----------------------------------------------------
// DesignName : counter8
// FileName : counter8.v
//Function : 8 bits counter with asyncclear and sync load
//Coder : Cheng xu
//-----------------------------------------------------
modulecounter8(
clk ,
aclr ,
load ,
load_din ,
dout
);
// Portdeclarations
input clk ;
input aclr ;
input load ;
input [7:0] load_din ;
output [7:0] dout ;
//InternalVariables
wire clk ;
wire aclr ;
wire load ;
wire [7:0] load_din ;
wire [7:0] dout ;
reg [7:0] counter = 0 ;
//CodeStarts Here
always @(posedge clk or negedge aclr)
if(!aclr)
counter <= 0;
else if(load == 1)
counter <= load_din;
else
counter <= counter + 1;
assigndout = counter;
endmodule
第二個(gè)文件:
//test_counter8.v
`timescale1ns/1ns //注意最前面的符號(hào)是數(shù)字鍵"1"左邊的//那個(gè)符號(hào),不是單引號(hào)
moduletest_counter8;
reg clk ;
reg aclr ;
reg load ;
reg [7:0] load_din ;
wire [7:0] dout ;
initial
begin
clk = 0;
aclr = 1;
load = 0;
load_din = 0;
#120 aclr = 0;
#40 aclr = 1;
#20 load = 1;
load_din = 100;
#20 load = 0;
#100 $stop; //可以不添加這個(gè)仿真結(jié)束的系統(tǒng)任務(wù)
end
always#10 clk = ~clk;
counter8U(
.clk(clk),
.aclr(aclr),
.load(load),
.load_din(load_din),
.dout(dout)
);
endmodule
這樣,我們就在該工程路徑下建立好了這兩個(gè)文件。當(dāng)然新建這兩個(gè)文件的的工作可以是放在我們這個(gè)全部的工作開(kāi)始之前進(jìn)行的,無(wú)需等到第4個(gè)步驟開(kāi)始的時(shí)候再進(jìn)行。
5. 把剛才新建的文件添加到工程中去,點(diǎn)擊"AddExisting Flie"后出現(xiàn)如下畫(huà)面,如圖6所示:
圖6 添加原始的待測(cè)試程序文件
點(diǎn)擊"OK"后,繼續(xù)添加另外一個(gè)測(cè)試文件,如圖7所示:
圖7 添加仿真測(cè)試文件
之后點(diǎn)"OK",再關(guān)閉"Add items to the Project"這個(gè)對(duì)話(huà)框。最簡(jiǎn)單的辦法是一次同時(shí)添加兩個(gè)文件,點(diǎn)擊"Browse"之后,鼠標(biāo)直接框選這兩個(gè)文件,這樣可以一次添加多個(gè)文件到ModelSim工程中。
6. 我們?cè)谲浖腜roject區(qū)域已經(jīng)能看到我們添加的這兩個(gè)文件了,如圖8所示:
圖8 Project區(qū)域狀態(tài)
我們下面就可以編譯這兩個(gè)文件了,這時(shí)候因?yàn)檫€沒(méi)有編譯文件,所以Status一欄顯示的是兩個(gè)問(wèn)號(hào)。接著在這個(gè)Project區(qū)域單擊鼠標(biāo)右鍵,選擇"Compile→Compile All",把HDL源文件編譯到當(dāng)前工程的工作庫(kù)當(dāng)中去。如圖9所示:
圖9 編譯源文件和仿真測(cè)試文件
我們?cè)谲浖路降腡ranscript區(qū)域中假如看到如圖10的字樣,就說(shuō)明編譯通過(guò)了:
圖10 編譯成功畫(huà)面
注意中間的兩個(gè)successful說(shuō)明成功了。另外,我們?cè)赑roject區(qū)域中的Status一欄中能夠看見(jiàn)兩個(gè)綠色的勾,這也是一種編譯成功的提示。
7. 編譯通過(guò)之后,在Project區(qū)域鼠標(biāo)右鍵點(diǎn)擊"Add to Project → Simulation Configuration",如圖11所示:
圖11 添加Simulation Configuration
在出現(xiàn)的Add SimulationConfiguration對(duì)話(huà)框的右下角打開(kāi)OptimizationOptions,打開(kāi)后切換到Options選項(xiàng)卡頁(yè)面,在Optimization Level中選擇Disable Optimizations,如圖12所示:
圖12 關(guān)閉優(yōu)化選項(xiàng)
點(diǎn)擊OK確定之后返回Add Simulation Configuration對(duì)話(huà)框,在Optimization欄中關(guān)閉Enable Optimization,再展開(kāi)work目錄,選中Test Bench文件test_counter8,之后save保存。如圖13所示:
圖13 關(guān)閉優(yōu)化選項(xiàng)
此時(shí)會(huì)在Project區(qū)域出現(xiàn)一個(gè)仿真配置文件:Simulation 1,雙擊它就能進(jìn)入仿真了,在重啟ModelSim之后,還可以雙擊它進(jìn)入仿真,比較方便。
注意:如果不關(guān)閉優(yōu)化選項(xiàng)的話(huà),有時(shí)候ModelSim軟件會(huì)報(bào)錯(cuò)導(dǎo)致不能正常進(jìn)行仿真。
8. 雙擊"Simulation 1"后進(jìn)入仿真波形界面,在Object區(qū)域鼠標(biāo)右鍵選擇"Add → To Wave → Signals inRegion",把待仿真的信號(hào)添加入Wave窗口。如圖14所示:
圖14 待仿真的信號(hào)添加入Wave窗口
9. 接著我們把wave窗口中的兩個(gè)信號(hào)量改成無(wú)符號(hào)數(shù)顯示,方便我們觀察,在load_din和dout上依次單擊鼠標(biāo)右鍵,按照?qǐng)D15的方法修改即可:
ModelSim仿真入門(mén)之三:時(shí)序仿真
正如前面第二講所述,時(shí)序仿真在實(shí)際應(yīng)用中使用的并不多,但是為了保持仿真系列文檔的完整性,我們還是把仿真的方法寫(xiě)出來(lái)。
時(shí)序仿真就要比第二講的功能仿真步驟上要多一些,本講以目前的QuartusII的12.0SP2版本和Cyclone IV的EP4CE6F17C8為例,講解下時(shí)序仿真的方法和步驟。
時(shí)序仿真需要的文件總共有以下幾種:
①綜合后生成的網(wǎng)表文件" * .vo "(假如在Setting里面設(shè)置里輸出語(yǔ)言為VHDL的話(huà),則生成的網(wǎng)表文件為" * .vho")
②綜合后生成的具有工程延時(shí)信息的文件" * .sdo "(VHDL語(yǔ)言亦為此)
③ Test Bench程序文件
④ Altera的元器件庫(kù)
大致的過(guò)程就是先在Quartus II中生成網(wǎng)表文件和時(shí)延文件,然后調(diào)用ModelSim進(jìn)行仿真,具體的時(shí)序仿真步驟如下:
1. 打開(kāi)Quartus II軟件,新建工程,再新建文件counter8.v,把上一講中的counter8.v這個(gè)源文件復(fù)制到Quartus II的工程目錄中,并添加該文件到工程中。接著,選擇"Settings"→"EDA Tool Settings",選擇左欄的"Simulation",設(shè)置情況如圖1所示。
第一欄的"Tool name"選擇ModelSim-Altera
第二欄的"Format for output netlist"選擇自己熟悉的語(yǔ)言,VHDL或Verilog都可以,后面的"output directory"是選擇輸出的網(wǎng)表文件和延時(shí)信息文件的存放路徑,一般選擇默認(rèn)即可,這樣的話(huà),將來(lái)編譯成功后,會(huì)在Quartus II的工程文件夾(本例為counter8這個(gè)文件夾)下面生成一個(gè)simulation/modelsim的文件夾,里面存有將來(lái)要用到的.vo和.sdo這兩個(gè)文件。
再往下,看到有"More EDA Netlist WritterSettings…"按鈕,點(diǎn)擊后進(jìn)入設(shè)置畫(huà)面,設(shè)置情況如圖2所示。注意的地方就是Generatenetlist for functional simulation這一項(xiàng)后面是處于OFF的關(guān)閉狀態(tài),這樣才能生成我們所要的時(shí)序仿真文件。
圖1 simulation的設(shè)置
圖2 More EDA Netlist WritterSettings的設(shè)置
都設(shè)置好了以后,全部點(diǎn)擊"OK"后退出設(shè)置,在QII的編譯環(huán)境下執(zhí)行全編譯。編譯中的情況如圖3所示:
圖3 編譯中的情況
注意:下面比我們平時(shí)進(jìn)行的全編譯時(shí)多了一項(xiàng)"EDANetlist Writer",圖3的紅色箭頭指向的位置。
2. 找到新建工程目錄所在的文件夾,在里面找到simulation/modelsim這個(gè)文件夾,會(huì)發(fā)現(xiàn)文件夾內(nèi)有10個(gè)文件,如圖4所示:
圖4 生成的10個(gè)文件
注意:counter8.vo和counter8_v.sdo就是時(shí)序仿真需要的兩個(gè)重要的網(wǎng)表文件,它們與counter8_8_1200mv_85c_slow.vo和counter8_8_1200mv_85c_v_slow.sdo只是命名不同而已,文件的內(nèi)容其實(shí)是一樣的。后兩個(gè)是QuartusII目前新的網(wǎng)表文件的命名方法,文件名標(biāo)示出了速度等級(jí)(-8)、內(nèi)核電壓(1200mv)、溫度條件(85℃)以及時(shí)序模型(slow)。
之所以Altera還沒(méi)有取消舊的命名文件方法并讓QuartusII繼續(xù)生成這兩個(gè)網(wǎng)表文件,是因?yàn)橛蠺clScript文件是按照舊的命名方法寫(xiě)的,需要兼容它們。
以下時(shí)序仿真以counter8.vo和counter8_v.sdo為例,如果需要用fast時(shí)序模型做仿真,也是按照下面的方法進(jìn)行,只是把vo和sdo文件換為fast。
另外".xrf"和".sft"這兩個(gè)文件,是QuartusII編譯生成的一些相關(guān)的信息文件,時(shí)序仿真用不到。
3. 打開(kāi)ModelSim軟件,新建一個(gè)工程,如圖5所示:
圖5 新建工程并指定路徑
①接著把剛才生成的counter8.vo和counter8_v.sdo兩個(gè)文件拷貝到現(xiàn)在個(gè)仿真工程的目錄下面。
②之后還要拷貝一個(gè)很重要的文件,到QuartusII的安裝目錄下: \quartus\eda\sim_lib,找到cycloneive_atoms.v這個(gè)文件,這個(gè)是Altera器件庫(kù)的庫(kù)文件,進(jìn)行時(shí)序仿真就是基于這個(gè)庫(kù)文件的,把它也拷貝到仿真工程目錄。
注意:我們是以Cyclone IV的EP4CE6F17C8為例的,所以這里需要復(fù)制的就是cycloneive這個(gè)庫(kù)文件,如果是其它器件的話(huà),需要再對(duì)應(yīng)選擇。
③把test_counter8.v文件拷貝到這個(gè)仿真工程目錄下面。
④在QII安裝目錄的..altera\12.0\quartus\eda\fv_lib\verilog,把這里面的dffeas.v和dffep.v文件拷貝到這個(gè)仿真工程目錄下面。
4. 進(jìn)行完上面的步驟后,返回到ModelSim這個(gè)軟件界面,會(huì)發(fā)現(xiàn)軟件還停留在剛才新建工程,需要我們?yōu)槠涔こ烫砑游募膶?duì)話(huà)框,那我們就添加文件,把"counter8.vo"、"cycloneive_atoms.v"、"test_counter8.v"、"dffeas.v"和"dffep.v"這5個(gè)文件添加進(jìn)去,如圖6所示:
圖6 添加的5個(gè)文件
注意:此時(shí)不需要添加counter8.v這個(gè)文件了,.vo文件可以替代它。
5. 之后關(guān)閉添加文件對(duì)話(huà)框,可以看見(jiàn)Project區(qū)域有了我們添加的5個(gè)文件了,在該區(qū)域點(diǎn)右鍵,"Compile"→"Compile All"執(zhí)行全部編譯。
6. 在Project區(qū)域點(diǎn)右鍵,"Add to Project"→"Simulation Configuration"添加一個(gè)仿真配置的設(shè)置,這時(shí)會(huì)直接彈出添加仿真配置對(duì)話(huà)框,這里,我們要進(jìn)行如下的設(shè)置:
①在"Design"選項(xiàng)卡下展開(kāi)work前面的"+"號(hào)后點(diǎn)選test_counter8,這個(gè)就是Test Bench文件。如圖7所示:
圖7 Design選項(xiàng)卡的設(shè)置
②再切換到"SDF"選項(xiàng)卡,點(diǎn)擊"Add"添加".sdo"文件,點(diǎn)擊瀏覽后會(huì)直接出現(xiàn)這個(gè)".sdo"文件的,選擇即可,在下面的"Apply to Region"內(nèi)輸入"U",這個(gè)就是我們的Test Bench程序中例化頂層文件的例化名字。如圖8所示:
圖8 SDF選項(xiàng)卡的設(shè)置
接著把下面的兩個(gè)SDF選項(xiàng)的復(fù)選框都選中。如圖9所示:
圖9 選中SDF選項(xiàng)的兩個(gè)復(fù)選框
點(diǎn)擊"OK"退出配置設(shè)置界面。配置好了以后的Project區(qū)域的內(nèi)容如圖10所示:
圖10 Project區(qū)域的內(nèi)容
7. 雙擊Simulation執(zhí)行仿真,后面的步驟和功能仿真一樣的了,不再贅述。仿真的波形圖如圖11所示:
圖11 時(shí)序仿真的波形圖
從圖11中可以看到dout相對(duì)于主時(shí)鐘clk有明顯的延時(shí),這個(gè)延時(shí)大小與當(dāng)前使用的器件的時(shí)序模型有關(guān)。
在具體實(shí)踐過(guò)程中,可能還會(huì)遇到各種各樣的問(wèn)題,ModelSim正常運(yùn)行也依賴(lài)于仿真庫(kù)文件的齊備,所以碰到某些工程在仿真中遇到報(bào)錯(cuò)的情況時(shí),不妨檢查下ModelSim的提示信息,看看是否有仿真所必需的庫(kù)文件沒(méi)有添加進(jìn)來(lái)。