ModelSim 仿真流程簡要
1. ModelSim簡介
ModelSim分幾種不同的版本:SE、PE和OEM,其中集成在 Actel(愛特公司)、Altera (阿爾特拉)、Xilinx(賽靈思)以及Lattice(萊迪思)等FPGA廠商設計工具中的均是其OEM版本,SE版本為最高級版本。ModelSim仿真分為功能仿真,門級仿真,時序仿真
◆ 功能仿真(前仿真,代碼仿真)
主旨在於驗證電路的功能是否符合設計要求,其特點是不考慮電路門延遲與線延遲,主要是驗證電路與理想情況是否一致。可綜合FPGA代碼是用RTL級代碼語言描述的,其輸入為RTL級代碼與Testbench.在設計的最初階段發現問題,可節省大量的精力。
◆ 門級仿真和時序列仿真 (後仿真)
使用綜合軟件綜合後生成的門級網表進行仿真,不加入時延文件的仿真就是門級仿真.可以檢驗綜合後的功能是否滿足功能要求,其速度比功能仿真要慢,比時序仿真要快。
◆ 在門級仿真的基礎上加入時延文件(.sdf)的仿真就是時序仿真, 比較真實地反映了邏輯的時延與功能.綜合考慮電路的路徑延遲與門延遲的影響,驗證電路能否在一定時序條件下滿足設計構想的過程,是否存在時序違規。
2. ModelSim仿真的基本步驟
首次運行modelsim時,先建立一個工作庫,一般將這個工作庫命名為work。後面建立的仿真工程(project)一般都是在這個work下面工作的。在用戶界面模式下,點 File->New->Library,選擇 a new library and a logical mapping to it,如下圖所示(ModelSim SE 10),
1)建立工程,啟動ModelSim,選擇菜單“File New Poject”,會打開“Creat Project”對話框,在“Creat Projec”t對話框中填寫“Project Name”為“Test”,然後在“Project Location”欄中選擇Project文件的存儲目錄,保留“Default Library Name”的設置為work,在彈出的對話框中選擇Add Existing File,添加已經寫好的源文件及測試文件(如果沒有,可選擇Create New File 進行創建)。
2) 在工作區中的Project標簽頁中可以看到新加入的文件,單擊右鍵,選取“Compile Compile All”命令對加入的文件進行編譯
3) 文件編譯完後,用鼠標點擊“Library”標簽欄。在標簽欄中用鼠標點擊work庫前面的“+”,展開work庫,就會看到編譯好的設計單元,點擊測試文件選擇仿真。
4) 調出窗口(View -> Structure,View -> object,View -> Wave),在object 窗口添加觀察變量,運行仿真,在Wave中查看波形。
5) 在Run_Length中選擇單步運行時間;鼠標在黃線不同端,按住Ctrl,移動滑輪可調整觀察波形時間
3. ModelSim斷點仿真
1) 選擇View > Files打開文件窗口,單擊sim前的+,雙擊block.v打開源文件
2) 滑動到21行,在行標的右側單擊。一個紅色的球出現在行標的右邊表示已經設置了一個斷點(此斷點可進行使能或移除)。
3) 點擊Run-All 運行,可見程序執行到斷點處
4. 命令行執行
force指令
指令格式:force item_name value time,value time(item_name為端口信號或內部信號,支持通配符號,但只能匹配一個;value不能默認,time,可選項,支持時間單元)
force din 10#40000000 //從當前時刻起給din賦值10進制40000000; force bus 10#F @100ns //在100ns時刻給bus賦值10進制F; force clr 0 //在當前仿真時間強制clr到0 force clr 1 100 //經歷100個默認時間單元延遲後為clr賦值1; force clr 1,0 100 //表示clr賦值1後,經歷100個默認時間單元延遲後為clr賦值為0;
force-repeat指令
指令格式:force
開始時間 開始電平值,結束電平值 忽略時間(即0電平保持時間)
-repeat 周期
force clk 0 0,1 20 -repeat 100 //表示強制clk從0時間單元開始,起始電平為0,結束電平為1,0電平保持時間為20個默認時間單元,周期為100個默認時間單元,占空比為80%
force-cancel指令
指令格式:force-cancel
period(執行period周期時間後取消force命令)
force clk 0 0,1 30 -repeat 60-cancel 1000 //強制clk從0時間單元開始,到1000時間單元結束;
run指令
指令格式:run
timesteps time_unit(timesteps時間步長,time_unit時間單元,可以是ps、ns等)
run 10 //表示運行10個默認時間單元; run 200ns //表示運行200ns; run -all //表示運行全過程; run -continue //表示繼續運行
本例代碼
1 `timescale 1ns / 1ps 2 module block( 3 input clk_i, 4 input rst_n_i, 5 output reg [4:0]result_o 6 ); 7 reg [3:0]A; 8 reg [3:0]B; 9 reg [4:0]C; 10 11 always @(posedge clk_i) 12 if(!rst_n_i) 13 begin 14 #2 A = 4‘d4; 15 #0.2 B = 4‘d12; 16 #0.2 C = 5‘d0; 17 #0.2 result_o = 5‘d0; 18 end 19 else 20 begin 21 #2 C = A + B; 22 #0.2 result_o = (C >> 1); 23 end 24 endmoduleblock.v
1 `timescale 1ns / 1ps //仿真時間單位/時間精度 2 module unblock 3 ( 4 input clk_i, 5 input rst_n_i, 6 output reg [4:0]result_o 7 ); 8 reg [3:0]A; 9 reg [3:0]B; 10 reg [4:0]C; 11 always @(posedge clk_i ) 12 if(!rst_n_i) 13 begin 14 #2 15 A <= 4‘d4; 16 B <= 4‘d12; 17 C <= 5‘d0; 18 result_o = 5‘d0; 19 end 20 else 21 begin 22 #2 23 C <= A + B; 24 result_o <= (C >> 1); 25 end 26 endmoduleunblock.v
1 `timescale 1ns / 1ps 2 module tb_test(); 3 reg clk_i; 4 reg rst_n_i; 5 wire[4:0]result1_o,result2_o; 6 unblock unblcok_inst 7 ( 8 .clk_i(clk_i), 9 .rst_n_i(rst_n_i), 10 .result_o(result1_o) 11 ); 12 13 block blcok_inst 14 ( 15 .clk_i(clk_i), 16 .rst_n_i(rst_n_i), 17 .result_o(result2_o) 18 ); 19 20 initial 21 begin 22 clk_i =0; 23 rst_n_i =0; 24 #22 25 rst_n_i =1; 26 end 27 28 always #5 clk_i = ~clk_i; 29 endmoduletb_test.v
ModelSim 仿真流程簡要