【友晶科技Terasic】Modesim 完整教程 18.1版本(單口RAM的 設計和模擬)
Modelsim模擬
一、Modelsim的簡介
點選檢視程式碼
- [ module
end]
ModelSim分幾種不同的版本:ModelSim SE、ModelSim PE、ModelSim LE和ModelSim OEM,其中的SE、PE、LE是其最高版本,編譯速度是所有版本中最快的,而OEM版本就是整合在FPGA廠家設計工具中的版本,它們專門和某個廠家的FPGA配套來使用,如後面使用到的ModelSim AE就是專門針對Intel公司Quartus Prime的配套的OEM產品 。
二、Modelsim軟體的安裝
- 軟體下載
ModelSim軟體的下載連結可以從MyFPGA論壇獲取,然後按圖2.1所示下載軟體。本教程中所用到的ModelSim版本是Intel FPGA Starter Edition 10.5b。
- 軟體安裝
- 雙擊下載的ModelSimSetup-18.1.0.625-windows.exe應用程式,出現如圖2.2所示的ModelSim安裝介面,點選Next。
- 在出現的“Select the ModelSim edition you like to install 介面, 選擇ModelSim-Intel FPGA Starter Edition(該版本是不需要License的),如圖2.3所示,之後點選Next。
- 在License Agreement介面選擇“I accept the agreement”,並點選Next。
- 將ModelSim軟體的安裝路徑選擇到Quartus的安裝路徑下,如圖2.5所示,點選兩次Next,便可以開始安裝軟體。
- 等待軟體安裝,如圖2.6所示。
- 軟體安裝完成後,點選Finish,退出安裝介面。到此,ModelSim模擬軟體安裝成功。
三、Test Bench測試平臺的結構
Test Bench主要是為測試或模擬Verilog程式搭建了一個平臺,給被測試的模組施加激勵訊號,通過觀察被測試模組的輸出響應,來判斷其邏輯功能和時序關係是否正確。
測試模組的結構如下:
`timescale 時間單位/時間精度 //編譯指令,設定modeule的時間單位和時間精度
module 模擬模組名; //無埠列表
各種輸入、輸出變數的定義,資料型別說明 //其中,激勵訊號定義為reg,顯示訊號定義為 wire
parameter //引數
模擬模組名 u_模擬模組名 //例化被測試模組
激勵向量的定義 //always、initial過程塊;function、task結構塊;
// if-else,for,case,while,repeat,disable等控制語句
顯示格式定義 //$monitor, $time, $dsplay
endmodule
測試模組與一般的Verilog程式碼書寫方式類似,其主要特點如下:
- 時間單位和時間精度一般是1、10和100這三種整數,單位有s、ms、us、ns、ps和fs;
- 測試模組只有模組名字,沒有埠列表;
- 輸入訊號(激勵訊號)必須定義為reg型別,用來保持訊號值;
- 輸出訊號(顯示訊號)必須定義為wire型別;
- 例化測試模組時,需要注意埠排列的順序與模組定義時的順序要一致;
- 一般使用initial 、always來定義激勵訊號波形;
- 在激勵訊號的定義中還可以使用一些控制語句,比如if-else、case、while、repeat、wait、begin-end等;
四、Modelsim模擬應用例項
這部分將以第六講中建立的全加器工程為例,介紹如何編寫模擬指令碼檔案(即test bench檔案),以及使用ModelSim工具對建立的工程進行模擬測試。
1. ModelSim軟體呼叫設定
在第一次用Quartus Prime呼叫ModelSim-Altera之前,需要指定EDA工具來為支援的模擬器生成模擬檔案。首先,開啟full_adder.qpf工程。然後,點選Tools --> Options --> EDA Tool Options,在ModelSim-Altera欄選擇對應的ModleSim-Altera的安裝路徑,如圖5.1所示。點選OK即可在Quartus Prime中呼叫ModelSim-Altera軟體。
2. 新建Test Bench檔案
- 選擇 File --> New --> Verilog HDL,如圖4.2所示,新建空白.v文件。
- 點選File --> Save as... ,因為我們要對加法器模組(而不是頂層工程)進行模擬,所以這裡將該.v檔案命名為fa_tb.v,點選儲存,如圖4.3所示。
- 在名為fa_tb.v的Verilog空白文件中輸入如下程式碼,並儲存。
`timescale 1ns / 1ns //設定時間單位和時間精度,時延單位為1ns,時延精度為1ns
module fa_tb; //待測試的加法器模組
reg a,b,cin; //資料輸入
wire sum,cout; //輸出訊號
parameter DELAY=50; //設定延遲引數為50
fa u_fa( //例化被測試模組
a,
b,
cin,
sum,
cout
);
initial //使用initial過程快定義激勵訊號波形
begin //使用begin-end控制語句
a = 1'b0; b = 1'b0; cin = 1'b0; //初始化輸入,被加數a被賦值為0,加數b被賦值為0,
//進位輸入c被賦值為0,
//此時加和sum和進位輸出cout都應該為0
#DELAY a = 1'b1; b = 1'b0; cin = 1'b0;//在50ns時,被加數a被賦值為1,加數b被賦值為0,
//進位輸入c被賦值為0,此時加和sum應該為1,
//進位輸出cout應該為0
#DELAY a = 1'b0; b = 1'b1; cin = 1'b1;//在100ns時,被加數a被賦值為0,加數b被賦值為1,
//進位輸入c被賦值為1,此時加和sum應該為0,
//進位輸出cout應該為1
#DELAY a = 1'b1; b = 1'b1; cin = 1'b0;//在150ns時,被加數a被賦值為1,加數b被賦值為1,
//進位輸入c被賦值為0,此時加和sum應該為0,
//進位輸出cout應該為1
#DELAY a = 1'b1; b = 1'b1; cin = 1'b1;//在200ns時,被加數a被賦值為1,加數b被賦值為1,
//進位輸入c被賦值為1,此時加和sum應該為1,
//進位輸出cout應該為1
#DELAY $stop; //在250ns時,執行$stop系統任務,停止模擬
end
initial $monitor($time,,,"a=%b,b=%b,cin=%b,sum=%b,cout=%b",a,b,cin,sum,cout);
//執行monitor系統任務,設定顯示結果的格式
endmodule
這裡,對test bench的編寫需要做以下說明:
(1)timescale是時間標尺定義語句,用於定義模組的時間單位和時間精度,其格式為`timescale<time_unit>/<time_precision>,時間精度的設定會影響模擬時間,因此建議將時間精度設定大一些。
延時的表示有多種方法,上述程式碼中先定義了一個引數parameter DELAY=50,在測試模組中用#DELAY來表示延遲時間,這些延遲的具體時間由時間定義語句`timescale來確定。如#DELAY a = 1'b0; b = 1'b1; cin = 1'b1表示每執行一次 #DELAY 語句,延時 50 ns,然後對激勵訊號a、b、cin賦新的值。還可以不定義parameter DELAY引數,而是直接在測試模組中使用#50 來表示延遲時間。
(2)Verilog HDL語言中預先定義了一些任務和函式,用於完成一些特殊的功能,它們被稱為系統任務和系統函式,系統任務和系統函式主要用於模擬。如本例中使用到的功能有:$$%$stop、$$%$time、$$%$monitor。
系統任務和系統函式一般以“$”開頭,在initial或always塊中進行呼叫,使用者還可以通過程式語言介面(PLI)將自己定義的系統任務和系統函式加到語言中,進行除錯和模擬。
下面將簡單說明幾個系統任務和系統函式的用法。
-
$$%$stop與$$%$finish——用於對模擬過程進行控制,表示中斷模擬和結束模擬。當模擬執行到$$%$stop語句時,將暫停模擬,此時設計者可以輸入命令,對模擬器進行互動控制;當模擬執行到$$%$finish語句時,則終止模擬,結束整個模擬過程,返回主系統。兩者的使用格式為
$stop; $stop(n); $finish; $finish(n);
n是引數,可以是0,1,2等值,0表示不輸出任何資訊;1表示給出模擬時間和位置;2表示給出模擬時間和位置,還有 其他一些執行統計資料;如果不帶引數,則預設引數值為1.
-
$$%$time與$$%$realtime——屬於顯示模擬時間標度的系統函式,呼叫時都返回當前時刻距離模擬開始時刻的時間量值,不同的是$$%$time函式以64位整數值的形式返回模擬時間,$$%$realtime函式以實數型資料返回模擬時間。
-
$$%$monitor與$$%$strobe——提供監控和輸出引數列表中字元或變數的值的功能,兩者所不同的是$$%$monitor相當於一個持續監聽器,一旦被呼叫,只要輸出變數列表中的任何變數發生變化,則系統將按照$$%$monitor語句中規定的格式將結果輸出一次;而$$%$strobe只有在模擬時間發生改變時,並且所有事件處理完畢後,才輸出結果,更多用來顯示用非阻塞方式賦值的變數的值。兩者的使用格式為
$monitor(“格式控制符”,輸出變數名列表); $strobe(“格式控制符”,輸出變數名列表);
以上例中的 程式碼為例,
$monitor($time,,,"a=%b,b=%b,cin=%b,sum=%b,cout=%b",a,b,cin,sum,cout); //每次a,b,cin訊號的值發生變化都會啟用上面的語句,並顯示當前的模擬時間、二進位制格式的a,b,cin,sum,cout訊號。
顯示的訊號還可以是十六進位制、八進位制等,關於訊號的格式控制符可以查看錶4.1.
表4.1 格式控制符
格式控制符 | 說明 |
---|---|
%h或%H | 以十六進位制格式顯示 |
%d或%D | 以十進位制格式顯示 |
%o或%O | 以八進位制格式顯示 |
%b或%B | 以二進位制格式顯示 |
%c或%C | 以ASCII字元形式顯示 |
%v或%V | 顯示net型資料的驅動強度 |
%m或%M | 顯示層次名 |
%s或%S | 以字串形式輸出 |
%t或%T | 以當前時間格式顯示 |
3. 新增測試檔案
- 點選Assignments --> Settings,如圖4.4;然後選中Simulation欄,Tool name選擇ModelSim-Altera,然後選擇新建Test Bench檔案,如圖4.5所示的步驟。
- 按照圖4.6所示的步驟選擇fa_tb.v檔案,點選Add進行新增,然後點選OK,如圖4.6所示。
- 這樣就可以在Test Bench看到新增的 fa_tb.v檔案,點選OK ,如圖4.7所示。新增完成後,在Settings視窗點選OK,然後將其關閉。
4. 開始模擬
- 在Quartus Prime中選擇選單項Tools --> Run Simulation Tool --> RTL Simulation,即可呼叫ModelSim工具進行模擬,如圖4.8所示。
- 運模擬結果如圖4.9所示,注意,如果wave視窗沒有顯示波形,可以在右下角點選一下Wave選項進行切換。
sim視窗顯示的是需要模擬的激勵模組;Objects(物件)視窗顯示的是模擬中的激勵訊號和顯示訊號;Transcript視窗(命令列視窗)會按照系統任務 $monitor 規定的格式列印輸出結果。
wave(波形)視窗顯示的是模擬波形,如果發現波形顯示的不夠完整,可以在波形視窗右鍵–>Range,按自己的需要調整顯示範圍,如圖4.10所示選擇。
從4.9中的波形圖可以看出:
在第0 ns時,當a=0,b=0,cin=0時,sum=0,cout=0;
延時50ns,即在第50 ns,當a=1,b=0,cin=0時,sum=1,cout=0;
延時50 ns,即在第100 ns,當a=0,b=1,cin=1時,sum=0,cout=1;
延時50 ns, 即在第150 ns,當a=1,b=1,cin=0時,sum=0,cout=1;
延時50 ns,即在第200 ns,當a=1,b=1,cin=1時,sum=1,cout=1;
延時50 ns,即在第250 ns時,模擬結束。
結果與預期一致,說明我們的全加器功能已實現。