1. 程式人生 > >搭建Modelsim SE模擬環境-使用do檔案模擬

搭建Modelsim SE模擬環境-使用do檔案模擬

本章我們介紹模擬環境搭建是基於Modelsim SE的。Modelsim有很多版本,比如說Modelsim-Altera,但是筆者還是建議大家使用Modelsim-SE,Modelsim-Altera實際是針對Altera 的OEM版本,它事先將Altera的一些IP核模擬庫新增到了工具中,但功能上有一些縮減。而Modelsim-SE需要自己手動新增這些模擬庫,但是功能更全,而且工作中,工程師更傾向用SE版本,因為今後的FPGA開發中我們會接觸更多其他廠商的FPGA,比如Xilinx、Lattice的,遇到這些FPGA時,我們同樣需要將他們的IP核的模擬庫新增到Modelsim 中。

1.1.1.模擬基本概念

FPGA的模擬實際就是一個驗證設計的過程,驗證在“模擬的輸入”的情況下,設計檔案的輸出是否和我們期望是一致的。這裡的“模擬的輸入”就是“測試激勵”,設計檔案就是待測設計,最終通過對輸出結果的分析來驗證設計的正確性。這就構成了模擬的三個基本組成部分:測試激勵(Test_bench)、待測設計(DUT)和最終結果的輸出驗證。

       上面介紹可能還是有些抽象,我們通過一個簡單的模擬例子來介紹模擬中的各個部分。大家開啟我們的例程《05_clk_div_even》。

       待測設計(DUT):首先看src資料夾下的clk_div_even.v就是我們待測設計(DUT)。這個比較好理解,就是我們設計的模組。這是一個偶數分頻的例子,每次計數從0-4,計數5次,計數器clk_div_cnt會清零一次,同時輸出分頻訊號o_clk_div翻轉一次,這樣每五個時鐘週期,輸出訊號都會翻轉一次,十個時鐘週期後又恢復到初始狀態,使得輸出訊號10分頻。這裡大家需要額外關注一下這個模組的輸入和輸出,輸入將來是我們激勵訊號進來的地方。

1.  module clk_div_even

2.      (

3.          input                  i_clk        , //模組輸入時鐘 ,50mhz

4.          input                  i_rst_n      ,    //復位訊號,低電平有效

5.          outputreg             o_clk_div         //偶數分頻輸出

6.      );

7.      

8.      parameter        DIV_EVEN      =10  ;   //10分頻,輸入50MHz,輸出頻率為

5Mhz

9.      reg    [3:0]clk_div_cnt           ;   //分頻計數器

10.//-------------------------------------------------------------------

11.//  分頻計數器,每次計數到N-1時歸零

12.//-------------------------------------------------------------------

13.    always @ (posedge i_clk ornegedge i_rst_n)

14.    begin

15.        if(!i_rst_n)

16.            clk_div_cnt  <=4'd0;  

17.        else    if(clk_div_cnt  ==DIV_EVEN/2-1)

18.            clk_div_cnt  <=4'd0;  

19.        else  

20.            clk_div_cnt  <=clk_div_cnt   +   4'd1;                              

21.    end

22.//-------------------------------------------------------------------

23.//  分頻計數器,每次計數N/2-1時,輸出分頻訊號翻轉

24.//-------------------------------------------------------------------    

25.    always @ (posedge i_clk ornegedge i_rst_n)

26.    begin

27.        if(!i_rst_n)

28.            o_clk_div  <=1'b0;  

29.        else    if(clk_div_cnt  ==DIV_EVEN/2-1)

30.            o_clk_div  <=~o_clk_div;

31.    end   

32.endmodule

測試激勵(Testbench):Testbench是FPGA模擬的關鍵,Testbench可以理解為一個激勵產生器。大家可以看到我們的待測設計的輸入是i_clk和i_rst_n,實際在開發板上,板子上的晶振輸出50MHz激勵時鐘訊號給FPGA,同樣電路中的復位電路給FPGA提供了i_rst_n的激勵訊號。在模擬過程中,Testbench就代替了實際的電路,通過Verilog模擬實現這些外部電路的激勵訊號,提供給DUT,從而通過輸出驗證設計。工程目錄的sim資料夾下的tb_clk_div_even.v 就是我們已經編寫好的Testbench。如下就是一個基本Testbench的設計。

下面從上圖所示5個部分介紹Testbench基本寫法。

1、`timescale 1ns/1ps 決定整個模擬中的時間單位資訊,在檔案中任何關於時間的資訊都是基於此的,1ns表示模擬中的基本時間單位,1ps則表示模擬精度可以達到1ps。例如 #10.005表示的就是延時10.005ns。實際模擬中,精度是可以控制到0.005ns的,即5ps。

2、tb_clk_div_even() 是實際testbench的名稱,同樣用module定義,但是注意testbenc是沒有埠描述的,這與我們待測檔案DUT是不一樣的。

3、激勵訊號和輸出訊號的定義,細心的同學應該可以看出,激勵訊號就是我們DUT檔案的輸入,輸出訊號也就是我們DUT檔案的輸出。不同的是在Testbench中,我們將激勵訊號定義為reg型別,輸出訊號定義為了wire型別。

4、第四部分就是產生激勵訊號,具體詳細實現我們就不介紹了,大家可以閱讀我們的文件《Testbench常用語法及技巧》,閱讀之後這個地方就很容易理解了。

5、最後一部分是待測設計的例項化,在FPGA設計中,模組的例項化就類似C語言中的函式呼叫,我們在其他模組中呼叫當前模組時,就需要以例項化的方式來實現。不同的是,Verilog檔案模組例項化時,我們需要標明每一個埠訊號。在我們設計的Testbench中,通過模組例項化,將我們的激勵訊號最終傳遞給了待測設計檔案。

輸出驗證:下圖是我們模擬的最終輸出的波形檔案,可以看出輸出訊號o_clk_div是輸入訊號i_clk的10分頻。

最後我們總結整個模擬過程中,各個部分之間的關係,如下圖。

1.1.2.  建立Modelsim模擬工程

本節我們介紹如何建立Modelsim模擬工程,瞭解Modelsim模擬工具的使用。

第一步:開啟Modelsim SE,點選選單欄“File—>New—>Project”,準備新建工程。

第二步:彈出“Create Project”對話方塊,按下圖填寫模擬工程名稱,以及工程的儲存路徑,以及預設庫的的名稱,這裡預設庫名為“work”,我們通常叫作工作庫。設定好後點擊OK。

這裡介紹一下庫的概念,即library。庫是Modelsim模擬的載體,Modelsim會將模擬工程中的設計檔案(DUT)和激勵檔案(Testbench)的編譯(Compile)結果存放在work庫中,在我們新建工程的時候就會帶著生成一個work庫,如下圖在Modelsim工作區,選擇Library選項卡,我們可以看到生成的work庫,此時work庫是空的,因為我們還沒有新增並模擬設計檔案和激勵檔案。

第三步:新建或新增設計檔案,這裡我們已經寫好的testbench和待測模組,所以選擇直接新增已存在檔案即可。

第四步:依次新增testbench和待測模組檔案。

第五步:編譯我們的DUT和Testbench檔案,如下圖在工作區域選擇Project選項卡,右鍵選擇Compile—>Compile All,編譯所有。

第六步:切回到Library,此時再看work庫就不是空的了,work庫裡的clk_div_even和tb_clk_div_even分別是tb_clk_div_even.v(Testbench)和clk_div_even.v(DUT)的編譯結果。選中Testbench模擬結果tb_clk_div_even,右鍵—>Simulate without Optimization,啟動無優化模擬。

第七步:彈出模擬波形視窗(wave視窗),但是視窗內沒有任何訊號波形,工作區域多了一個sim選項卡,進入sim選項頁,可以看到模擬例項clk_div_even和tb_clk_div_even。選擇相應的例項,右鍵—>add wave,新增訊號到wave視窗。

第八步:切到wave 視窗,如下圖,設定模擬執行時間為100us,這個時間根據具體設計所需時間來決定,再點選旁邊的,執行模擬。這樣我們就可以看到輸出的波形訊號了,從而驗證設計的正確性。

1.1.3.  使用do檔案進行Modelsim模擬

上一節我們介紹了通過Modelsim建立模擬工程的方法,但是這種方法我們需要使用介面操作,這樣會很費時很麻煩。這裡我們介紹一種快捷的方法,通過do檔案快速搭建模擬環境,只需要雙擊批處理檔案modelsim_run.bat,就可以自動呼叫Modelsim,並自動完成對Testbench和待驗證設計檔案的編譯和模擬,並且可以自動將要觀察的訊號新增到wave視窗。

首先開啟“02_Project_Examples\05_clk_div_even\sim”資料夾,可以看到如下檔案。

我們主要介紹一下前兩個檔案,最後一個是我們的testbench:

modelsim_run.bat檔案:這是一個批處理檔案,裡面就一行“modelsim -do sim.do”,這是一條DOS命令,意思就是呼叫Modelsim工具,並在Modelsim工具中執行sim.do這個檔案。

sim.do:do檔案是由tcl指令碼語言編寫的,這個參考例程中的do檔案是最基本的tcl指令碼語言。下面介紹一下關鍵指令碼語言的用法。以下是do檔案的內容。

1.  vlib work       

2.  vlog  ../sim/*.v

3.  vlog  ../src/*.v

4.  vsim-t ns -novopt +notimingchecks  work.tb_clk_div_even 

5.  radix hex

6.  addwave -position insertpoint sim:/tb_clk_div_even/clk_div_even_inst/*

7.  run -all

vlib work:建立work庫,相當於在上一節中新建工程時所生成的work庫,後期我們編譯的結果資訊存放到work庫中。

vlog ../sim/*.v:vlog相當於modelsim工具中的compile,“../sim/*.v ”表示編譯05_clk_div_even\sim路徑下所有的verilog檔案。vlog ../src/*.v表示編譯05_clk_div_even /src/路徑下的所有verilog檔案。

vsim -t  ns  -novopt  +notimingchecks  work.tb_clk_div_even:編譯完成所有verilog檔案後,就要啟動模擬了,vsim就是啟動模擬功能,vsim後面有許多關鍵詞,這裡簡單說明一下,-t表示模擬時間單位為ns,-novopt表示模擬時無優化,+notimingchecks表示無時序檢查,work.tb_clk_div_even表示對work庫中的tb_clk_div_even進行模擬,實際相當於在介面操作時,展開work庫,右鍵—>Simulate without Optimization,啟動模擬。

radix hex :表示要新增wave視窗的訊號,以16進位制的顯示。

add wave–position  insertpoint  sim:/tb_clk_div_even/clk_div_even_inst/*:表示將clk_div_even_inst中的所有訊號新增到wave視窗中去,執行這句以後,我們每次模擬時,就不用每次都手動去新增模擬波形了。但是這句話實際是Modelsim生成的,不需要我們自己編寫。最開始我們寫的do檔案是不包含這條語句的,當我們執行到如下圖狀態時,選擇要新增的訊號,右鍵—>add wave後,下面的指令碼視窗會彈出相應操作的tcl指令碼語句。這樣我們把這條語句賦值到我們的do檔案中即可。第二次再呼叫sim.do檔案時,就不用再手動新增波形了。

run –all :  執行全過程。當然也可以執行一段時間。run 10us 表示執行10us。

掌握這些最基本的tcl指令碼,使用do檔案模擬會為我們節省很多時間。後續的教程裡我們都會預設以這種方式進行模擬。當然這裡只是介紹了最基本的模擬指令碼語言,今後我們模擬時可能還會有第三方的IP核檔案,如altera的PLL、FIFO、RAM等需要新增到模擬用例中,這些我們後面在介紹IP核使用時會給大家介紹如何利用do檔案模擬含有IP核的設計。

現在我們可以體驗一下do檔案模擬所用的時間,雙擊“modelsim_run.bat”,即可執行模擬。