文章目錄
- 引言
- 一、軟件介紹
- 1. VCS
- 2. DVE
- 3. Verdi
- 二、VCS的使用
- 1. VCS的編譯流程
- 2. 常用的編譯選項
- 1)基礎編譯選項
- 2)調試相關選項
- 3)性能優化選項
- 4)文件和路徑選項
- 3. 常用仿真選項
- 1)基礎仿真選項
- 2)運行控制選項
- 3)調試和分析選項
- 3. VCS生成物
- 4. 波形文件的生成
- 1)VCD (Value Change Dump)的生成
- 2)VPD (Verilog Procedural Dump)的生成
- 3)FSDB (Fast Signal Database)的生成
- 三、DVE/Verdi波形查看
- 1. DVE查看波形
- 2. Verdi查看波形
- 四、VCS-Verdi lab(入門)
- 1. 文件管理
- 2. VCS編譯和仿真
- 1)一步(推薦)
- Verdi查看波形
- DVE查看波形(需要修改tb中的波形生成部分成vpd和vcd)
- 2)兩步
- DVE查看波形
- Verdi查看波形
- 3. makefile
- 附錄
- 1. ALU代碼
- 2. TestBench代碼
參考文獻
VCS使用教程 (Synopsys VCS Simulator Tutorial)
Linux下VCS與Verdi聯合仿真簡易教程及例子示范
Verdi快速使用技巧
Verdi的使用
引言
??在FPGAer/ICer的實際項目中,仿真無疑占了大量的時間。我想對于仿真工具有人更傾向于使用Vivado、ModelSim、QuestaSim這些編譯-仿真-看波形一體化的工具,也有人更傾向于VCS(編譯仿真)、Verdi和DVE(看波形)這些獨立功能的工具。兩者各有優劣。
??前者工具鏈簡單易上手,甚至Vivado除了編譯、仿真和看波形以外還能實現綜合、布局布線等等功能,可謂神器。但是前者也有明顯的缺點,比如說綜合、編譯、仿真速度很慢。
??而后者工具鏈較為復雜,編譯和看波形為獨立的工具。如果在做ASIC項目中,后者會更加方便和專業。首先,VCS編譯和仿真速度極快,效率極高,能夠大量節約仿真時間(仿真速度:FPGA>VCS>ModelSim/QuestaSim>Vivado)。而Verdi查看波形也十分方便,支持信號追溯等等功能。
??綜上所述,為了提高開發效率,下面將以一個簡單的ALU的工程來展示如何在Linux下使用VCS和Verdi進行邏輯仿真。此部分只涉及前仿,后仿涉及DC等綜合工具。
??可以看完第四部分跑完lab后再返回看VCS的詳細的選項功能
一、軟件介紹
1. VCS
?? VCS(Verilog Compiled Simulator)是 Synopsys 公司開發的一款高性能仿真工具,它采用編譯型仿真技術,將 Verilog/SystemVerilog 代碼編譯成優化的 C 代碼,再編譯成可執行文件,從而實現高速仿真。雖然 VCS 本身不直接提供圖形化調試界面,但它可以與 Synopsys 的其他工具(如 Verdi)集成,實現高效的調試和波形查看。
??同時,VCS 提供了豐富的編譯和仿真選項,可以根據設計需求進行靈活配置。VCS 提供了豐富的覆蓋率分析選項,包括行覆蓋率、條件覆蓋率、狀態機覆蓋率和翻轉覆蓋率等,有助于Verifier全面評估測試的充分性。
??為什么VCS會更快?因為VCS采用了編譯型仿真。相較于解釋型仿真(傳統模式),其優點在于仿真速度極快、內存使用效率高、支持大規模設計以及優化程度高,但是編譯時間較長、調試較為復雜并且修改代碼需要重新編譯。
2. DVE
??DVE(Design Verification Environment)是由Synopsys公司開發的一款強大的硬件設計驗證工具,主要用于協助工程師分析和調試仿真結果。DVE是集成在了VCS中。
3. Verdi
??Verdi 是 Synopsys 提供的一款強大的自動化電子設計自動化(EDA)工具,主要用于功能驗證和調試。Verdi 綜合了多種調試功能,如波形查看、信號追蹤、時序分析和覆蓋規劃等,為設計驗證工程師提供了一個全面的環境進行設計錯誤的識別和修正。Verdi是比DVE更強大的調試平臺,尤其在協議分析、性能分析和根本原因分析(RCA)方面表現出色。
??Verdi 工具集包括以下幾個組件:
- Waveform Viewer (波形查看器):圖形化展示波形數據,支持對仿真數據進行深入分析。
- Signal Spy (信號監視器):實時監測設計中的信號變化,用于調試。
- Time Analysis (時序分析):分析設計中時序問題,幫助識別時序違規。
- Coverage (覆蓋率分析器):分析驗證的覆蓋面,確保測試充分。
- Data Mining (數據挖掘):利用高級算法來發現設計中的潛在問題。
二、VCS的使用
??值得注意的是VCS本身不提供圖形化界面,因此只能通過terminal來運行。
1. VCS的編譯流程
??VCS采用兩階段編譯模式,提供靈活性和高性能。
RTL源碼—>vlogan前端編譯—>生成數據庫文件—>vcs后端編譯—>生成simv可執行文件—>./simv仿真執行—>生成波形和日志
??因此,VCS也提供了兩種編譯方式,分別為一步編譯(推薦用于簡單項目),兩步編譯(推薦用于復雜項目)。
# 一步編譯
vcs [編譯選項] [源文件] -o [輸出文件名]
# 兩步編譯
vlogan [編譯選項] [源文件] # 前端編譯
vcs [鏈接選項] [頂層模塊] -o [輸出文件名] # 后端編譯
??該文以一步編譯模式為主。
2. 常用的編譯選項
1)基礎編譯選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
-help | 顯示幫助文檔 | vcs -help | 查看vcs的可用選項 |
-full64 | 64位編譯模式 | vcs -full64 | |
-sverilog | 支持SystemVerilog | vcs -sverilog | |
+v2k | 支持Verilog-2001 | vcs +v2k | |
-timescale | 指定時間精度 | vcs -timescale=1ns/1ps | 也可以tb中指定 |
-o | 輸出文件名 | vcs -o my_sim | 默認simv |
-kdb | 輸出fsdb文件需要 | vcs -kdb |
2)調試相關選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
-debug_access+all | 完全調試訪問 | vcs -debug_access+all | 查看所有信號 |
-debug_access+r | 只讀調試訪問 | vcs -debug_access+r | 只讀模式 |
-line | 啟用行號調試 | vcs -line | |
+lca | 生成覆蓋率數據庫 | vcs +lca | 用于覆蓋率分析 |
-cm | 覆蓋率采集類型 | vcs -cm line+cond+fsm+tgl | 采集line/cond/fsm/tgl覆蓋率 |
-cm_dir | 指定存放覆蓋率數據庫的目錄 | ||
-cm_name | 為當次仿真產生的覆蓋率數據命名 |
NOTE:收集行覆蓋率(line)、條件覆蓋率(cond)、有限狀態機覆蓋率(fsm)和翻轉覆蓋率(tgl)
覆蓋率類型:
代碼覆蓋率 (Code Coverage):
- line: 每行可執行代碼是否被執行。
- cond: if-else、case語句的每個分支是否被走到。
- fsm: 狀態機的每個狀態和狀態轉移是否被訪問。
- tgl: 每個bit信號是否經歷了0->1和1->0的翻轉。
功能覆蓋率 (Functional Coverage):通過SystemVerilog的 covergroup 定義,衡量設計規格中的功能點是否被測試到。
斷言覆蓋率 (Assertion Coverage):衡量SVA斷言被觸發、成功和失敗的次數。
3)性能優化選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
-Mupdate | 增量編譯 | vcs -Mupdate | 只編譯修改的文件 |
-j | 并行編譯核心數 | vcs -j8 | 8個CPU核心 |
-comp | 優化編譯 | vcs -comp | 編譯時優化 |
-no_save | 不保存中間文件 | vcs vcs -no_save | 節省可見 |
-fast | 快速模式 | vcs -fast |
4)文件和路徑選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
-f | 文件列表 | vcs -f filelist.f | 包含源文件路徑 |
-v | 庫文件 | vcs -v my_lib.v | 單個庫文件 |
-y | 庫目錄 | vcs -y ./lib | 單個庫目錄 |
+libext+ | 庫文件擴展名 | +libext+.v+.sv | 搜索文件類型 |
+incdir+ | include目錄 | +incdir+./inc | `include文件路徑 |
+define+ | 預定義宏 | +define+SIM_MODE | 編譯時宏定義 |
3. 常用仿真選項
1)基礎仿真選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
-R | 編譯后立即運行 | vcs -R tb.v | 一步完成 |
-gui | 啟動圖形界面 | ./simv -gui=dve | DVE調試界面,也可以-gui=verdi |
-l | 日志文件 | ./simv -l sim.log | 指定仿真日志路徑 |
-s | 交互模式 | ./simv -s | 在時間0停止 |
2)運行控制選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
+ntb_random_seed= | 隨機種子 | ./simv +ntb_random_seed=123 | 確定性隨機序列 |
+vcs+lic_wait | 等待license | ./simv +vcs+lic_wait | license不足時等待 |
+vcs+stop+ | 指定停止時間 | ./simv +vcs+stop+1000 | 1000時間單位后停止 |
3)調試和分析選項
指令 | 功能 | 示例 | 描述 |
---|---|---|---|
-ucli | 啟動UCLI | ./simv -ucli | 統一命令行界面 |
-vpd_file | VPD文件名 | ./simv -vpd_file sim.vpd | 指定波形文件 |
-cm_name | 覆蓋率名稱 | ./simv -cm_name test1 | 覆蓋率數據庫名 |
-cm_dir | 覆蓋率目錄 | ./simv -cm_dir ./cov | 覆蓋率存儲路徑 |
3. VCS生成物
??執行vcs指令后一般會生成一些文件。其中比較關鍵的是:
- simv:為可執行文件,可以使用./simv來運行仿真。
- sim.log:為vcs的運行日志,名字為用戶自己設置。
- csrc:存放vcs生成的C語言源碼。vcs將RTL代碼轉換成C代碼后再使用系統的C/C++編譯器來創建最終的可執行文件,
- simv.daidir:為vcs的中間數據庫目錄,包含了設計的層次化信息。
- .vcd/vpd/.fsdb:為波形文件,vcs生成,dve和verdi可以直接打開此類文件查看波形,無需重新編譯和仿真。
4. 波形文件的生成
??vcs可以生成不同格式的波形文件。常見的有以下三種:
格式 | 優點 | 缺點 | 查看工具 |
---|---|---|---|
VCD | 通用性強,可讀 | 文件大,速度慢 | DVE,Verdi |
VPD | 壓縮率高,VCS原生 | Synopsys生態 | DVE,Verdi |
FSDB | 壓縮率極高,功能強 | Verdi生態 | Verdi |
??以上這些波形文件格式的生成代碼需要放置再testbench中,指定波形文件格式和保存的內容。
1)VCD (Value Change Dump)的生成
//在Testbench中添加系統任務
initial begin$dumpfile("tb.vcd");$dumpvars(0, top_module_name); // 0表示dump所有層級
end
2)VPD (Verilog Procedural Dump)的生成
//在Testbench中添加 $vcdpluson; 系統任務,并在編譯時開啟調試選項。
initial begin$vcdpluson();
end
3)FSDB (Fast Signal Database)的生成
//需要Verdi的環境支持,并在Testbench中調用特定系統任務。
initial begin$fsdbDumpfile("tb.fsdb");$fsdbDumpvars(0, "top_module_name");
end
$fsdbDumpfile(fsdb_name[,limit_size])
指定波形文件名,第二個參數可選擇用來限制波形的大小(MB)。
$fsdbDumpvars([depth, instance][, “option”])
depth表示要加載波形的層次:
0表示當前instance下的所有變量以及其它module實例的波形;
1表示當前instance中的變量的波形,不包括當前instance中的其它module實例的波形;
2表示包含當前instance以及其中的第一級子instance的波形;以此類推。
instance指定要加載波形的module名。
option加載波形的選項:
+IO_Only – 只加載IO port信號;
+Reg_Only – 只加載reg類型信號;
+mda – 加載memory和MDA信號;
+packedmda – 加載packed MDA;
+struct – 加載structs;
+parameter – 加載parameter;
+fsdbfile+filename – 指定fsdb文件名字。(可覆蓋dumpfile操作)
三、DVE/Verdi波形查看
1. DVE查看波形
??DVE的啟動很簡單,只需要在vcs執行完生成vpd/vcd波形文件后,即可用以下指令打開。
dve -vpd vcdplus.vpd &
dve -vcd tb.vcd &
2. Verdi查看波形
??Verdi的啟動也很簡單,只需要在vcs執行完生成vpd/vcd/fsdb波形文件后,即可用以下指令打開。
verdi -f filelist.f -ssf tb.fsdb &
四、VCS-Verdi lab(入門)
1. 文件管理
??首先,第一步就是進行文件管理。一般文件管理我采用以下結構,rtl用來放置RTL代碼,makefile為運行腳本,sim用來保存vcs仿真的結果和波形,tb用來放置testbench文件。此外,還有一個比較重要的便是設計文件列表filelist.f(注意文件的路徑正確)。
2. VCS編譯和仿真
1)一步(推薦)
??在sim路徑下打開terminal并執行以下指令
??單步執行的在編譯vcs時候加入了-R選項,使得vcs在編譯完后直接運行./simv。
# -kdb為生成fsdb所需,否則無法使用verdi打開
vcs -R -full64 -debug_access+all -timescale=1ns/1ps -f filelist.f
??執行完后得到一些文件,可見 第3小節文件生成物。值得關注的便是tb.fsdb波形文件。
??單步編譯后可以直接查看波形。
Verdi查看波形
??在sim路徑下打開terminal并執行以下指令,啟動verdi
verdi -f filelist.f -ssf tb.fsdb &
??一開始可以看到沒有波形,需要右鍵選中alu,添加波形。
??添加波形后
DVE查看波形(需要修改tb中的波形生成部分成vpd和vcd)
# 使用dve查看波形(vcd,vpd)
dve -vpd vcdplus.vpd &
dve -vcd my_tb.vcd &
2)兩步
??兩步執行的步驟在于先用vcs進行編譯得到simv可執行文件,然后再運行./simv文件產生波形文件,./simv可以指定DVE或者Verdi來查看仿真結果。
DVE查看波形
??在sim路徑下打開terminal并執行以下指令
# 步驟一,編譯,生成simv可執行文件
vcs -full64 -debug_access+all -timescale=1ns/1ps -f filelist.f
# 步驟二,仿真并使用dve打開gui界面
./simv -gui=dve &
添加波形
在命令行中運行run,開始仿真
Verdi查看波形
??在sim路徑下打開terminal并執行以下指令
# 步驟一,編譯,生成simv可執行文件
vcs -full64 -debug_access+all -kdb -timescale=1ns/1ps -f filelist.f
# 步驟二,仿真并使用verdi打開gui界面
./simv -gui=verdi &
NOTE:需要注意的是這里vcs的編譯需要加-kdb選項,不然會無法打開verdi
3. makefile
??可以將上述命令,添加到makefile腳本中,提高工作效率。
附錄
1. ALU代碼
module alu(input clk,input rst_n,input [7:0] in1,input [7:0] in2,input [1:0] in_ctrl,output [7:0] out
);reg [7:0] A,B;reg [1:0] C;reg [7:0] D;always @(posedge clk or negedge rst_n)beginif(!rst_n)beginA <= 8'd0;B <= 8'd0;C <= 2'd0;endelse beginA <= in1;B <= in2;C <= in_ctrl;endendalways @(posedge clk or negedge rst_n)beginif(!rst_n)D <= 8'd0;else case (C)2'b00 : D <= A + B;2'b01 : D <= ~A;2'b10 : D <= A & B;2'b11 : D <= A | B; default: D <= 8'd0;endcaseendassign out = D;
endmodule
2. TestBench代碼
`timescale 1ns/1ps
module tb();reg clk=0;reg rst_n=1;reg [7:0] in1=0;reg [7:0] in2=0;reg [1:0] in_ctrl=0;wire [7:0] out;always #5 clk=~clk;initial begin#10 rst_n=0;#10 rst_n=1;#100repeat(10)begin@(posedge clk) in1 = {$random}%(2**8);in2 = {$random}%(2**8);in_ctrl = {$random}%(2**2);end#100 $finish();endalu alu(.clk(clk),.rst_n(rst_n),.in1(in1),.in2(in2),.in_ctrl(in_ctrl),.out(out));initial begin$fsdbDumpfile("tb.fsdb");$fsdbDumpvars();end
/*initial begin$dumpfile("alu.vcd");$dumpvars(0, tb);end
*/
endmodule