合仿真及Verdi調(diào)試實(shí)戰(zhàn)指南)
1. 為什么還要折騰 Vivado 與 VCS 的聯(lián)合仿真如果你平時(shí)用 Vivado 自帶的仿真器跑 RTL小規(guī)模設(shè)計(jì)還能忍一旦設(shè)計(jì)里塞進(jìn) DDR 控制器、PCIe 硬核、或者帶 Memory 的 SoC 子系統(tǒng)仿真速度會(huì)慢到讓人懷疑人生。Vivado Simulator 在編譯大型仿真模型時(shí)編譯時(shí)間動(dòng)輒十幾分鐘跑一個(gè)后仿真的 Memory 初始化流程可能一晚上都出不來波形。這時(shí)候把仿真任務(wù)交給 VCS再用 Verdi 看波形是數(shù)字前端和 FPGA 驗(yàn)證工程師比較常見的組合。Vivado 2025.1 是 Xilinx 較新的版本VCS 2024.SP1 是 Synopsys 的仿真工具版本兩者聯(lián)合仿真的核心思路并不復(fù)雜用 Vivado 生成仿真所需的庫文件把 Xilinx 的 IP 仿真模型編譯成 VCS 能識別的庫然后在 VCS 里調(diào)用這些庫跑仿真最后用 Verdi 加載 FSDB 波形進(jìn)行調(diào)試。聽起來簡單但實(shí)際操作中編譯庫的選項(xiàng)、仿真精度、Memory 初始化文件的路徑、Verdi 的加載方式每一步都有坑。這篇文章適合兩類人一類是剛接觸 FPGA 驗(yàn)證、想從 Vivado Simulator 遷移到 VCS 的工程師另一類是被后仿真 Memory 初始化問題折磨過、想找一套穩(wěn)定流程的從業(yè)者。我會(huì)把整個(gè)流程拆開從庫編譯的底層邏輯講到 Verdi 波形調(diào)試的實(shí)操細(xì)節(jié)盡量把每個(gè)參數(shù)為什么這么設(shè)講清楚。提示本文涉及的 Vivado 和 VCS 版本組合是 Vivado 2025.1 與 VCS 2024.SP1其他版本在庫編譯選項(xiàng)上可能有差異但整體思路一致。2. 聯(lián)合仿真的底層邏輯Vivado 編譯庫到底在編譯什么2.1 仿真庫的本質(zhì)是預(yù)編譯的 Verilog/VHDL 模型Xilinx 的 IP 核和原語在仿真時(shí)并不是直接拿綜合用的網(wǎng)表去跑而是使用行為級或結(jié)構(gòu)級的仿真模型。這些模型分散在 Vivado 安裝目錄下的data/verilog、data/vhdl等路徑里。Vivado 自帶的仿真器在啟動(dòng)時(shí)會(huì)自動(dòng)編譯這些模型但 VCS 不認(rèn)識 Vivado 的工程結(jié)構(gòu)所以需要提前把這些模型編譯成 VCS 的庫格式。編譯庫的過程本質(zhì)上就是調(diào)用 VCS 的vlogan和vhdlan命令把 Xilinx 的仿真源文件編譯成 VCS 的庫文件存放在指定的庫目錄中。編譯完成后VCS 在仿真時(shí)通過-y或-v選項(xiàng)引用這些庫就能找到對應(yīng)的模塊定義。這里有個(gè)關(guān)鍵點(diǎn)仿真庫的編譯選項(xiàng)必須和后續(xù)仿真時(shí)的選項(xiàng)一致尤其是-sverilog、-full64、-timescale這些。如果編譯庫時(shí)用了-sverilog仿真時(shí)沒用或者反過來都會(huì)導(dǎo)致模塊找不到或者參數(shù)不匹配的錯(cuò)誤。2.2 為什么不用 Vivado 自動(dòng)生成的仿真腳本Vivado 在導(dǎo)出仿真時(shí)會(huì)生成一個(gè)compile.sh或simulate.sh腳本里面包含了仿真庫的路徑和編譯選項(xiàng)。很多人直接拿這個(gè)腳本改一改就用結(jié)果發(fā)現(xiàn) VCS 報(bào)一堆錯(cuò)。原因在于Vivado 生成的腳本默認(rèn)是給 Vivado Simulator 用的里面的庫路徑和編譯選項(xiàng)并不完全適配 VCS。比如Vivado 生成的腳本里可能會(huì)引用xsim相關(guān)的庫而 VCS 需要的是unisims_ver、simprims_ver、secureip這些庫。另外Vivado 2025.1 的 IP 仿真模型可能依賴一些 SystemVerilog 的包如果編譯庫時(shí)沒有加-sverilog這些包就無法解析。所以比較穩(wěn)妥的做法是用 Vivado 的compile_simlib命令手動(dòng)編譯庫而不是依賴自動(dòng)生成的腳本。compile_simlib是 Vivado 提供的一個(gè) Tcl 命令專門用來為第三方仿真器編譯仿真庫。2.3 compile_simlib 的關(guān)鍵參數(shù)拆解compile_simlib的常用參數(shù)如下compile_simlib -directory 庫輸出目錄 \ -simulator vcs \ -simulator_exec_path VCS安裝路徑/bin \ -family all \ -language all \ -library all \ -verbose-directory指定編譯后的庫文件存放路徑。建議放在一個(gè)獨(dú)立的目錄比如/home/user/vivado_lib/vcs_2024不要放在 Vivado 工程目錄里避免工程清理時(shí)誤刪。-simulator vcs指定目標(biāo)仿真器為 VCS。-simulator_exec_pathVCS 的可執(zhí)行文件路徑通常是VCS安裝目錄/bin。這個(gè)路徑必須正確否則 Vivado 找不到 VCS 的編譯器。-family all編譯所有器件系列的庫。如果只針對特定器件可以指定-family zynq或-family kintex7等減少編譯時(shí)間。-language all同時(shí)編譯 Verilog 和 VHDL 庫。如果設(shè)計(jì)里只有 Verilog可以只編譯 Verilog節(jié)省時(shí)間。-library all編譯所有庫包括unisims_ver、simprims_ver、secureip、xpm等。編譯時(shí)間取決于器件系列和語言數(shù)量全系列全語言編譯可能需要 30 分鐘到 1 小時(shí)。如果只是跑某個(gè)具體器件的仿真可以只編譯該器件系列的庫時(shí)間會(huì)縮短到 10 分鐘左右。注意編譯庫時(shí)Vivado 會(huì)調(diào)用 VCS 的vlogan和vhdlan如果 VCS 的環(huán)境變量沒有配置好編譯會(huì)中途失敗。建議先在終端里執(zhí)行which vlogan確認(rèn) VCS 命令可用。3. 從零搭建聯(lián)合仿真環(huán)境庫編譯與工程配置3.1 環(huán)境準(zhǔn)備VCS 和 Verdi 的環(huán)境變量在 Linux 環(huán)境下VCS 和 Verdi 的安裝通常由 IT 或 CAD 部門完成但環(huán)境變量需要自己配置。典型的配置如下export VCS_HOME/opt/synopsys/vcs/2024.06-SP1 export VERDI_HOME/opt/synopsys/verdi/2024.06-SP1 export PATH$VCS_HOME/bin:$VERDI_HOME/bin:$PATH export LD_LIBRARY_PATH$VCS_HOME/linux64/lib:$VERDI_HOME/linux64/lib:$LD_LIBRARY_PATH配置完成后執(zhí)行vcs -ID和verdi -version確認(rèn)版本信息。如果vcs -ID報(bào)錯(cuò)說明 License 或者安裝路徑有問題需要先解決。Vivado 2025.1 的安裝路徑也需要加入 PATH方便調(diào)用vivado和compile_simlibexport XILINX_VIVADO/opt/Xilinx/Vivado/2025.1 export PATH$XILINX_VIVADO/bin:$PATH3.2 用 compile_simlib 編譯 VCS 庫的完整命令假設(shè) VCS 安裝在/opt/synopsys/vcs/2024.06-SP1庫輸出目錄為/home/user/vivado_lib/vcs_2024編譯 Zynq UltraScale 系列的庫命令如下compile_simlib -directory /home/user/vivado_lib/vcs_2024 \ -simulator vcs \ -simulator_exec_path /opt/synopsys/vcs/2024.06-SP1/bin \ -family zynqultrascaleplus \ -language verilog \ -library all \ -verbose執(zhí)行后Vivado 會(huì)輸出編譯日志顯示每個(gè)庫的編譯進(jìn)度。編譯完成后庫目錄下會(huì)生成unisims_ver、simprims_ver、secureip、xpm等子目錄每個(gè)子目錄里包含編譯好的庫文件和synopsys_sim.setup文件。synopsys_sim.setup是 VCS 的庫映射文件里面定義了邏輯庫名和物理路徑的對應(yīng)關(guān)系。在仿真時(shí)需要通過-synopsys_sim.setup選項(xiàng)指定這個(gè)文件或者在當(dāng)前工作目錄下創(chuàng)建一個(gè)同名的文件。3.3 仿真工程目錄結(jié)構(gòu)的設(shè)計(jì)一個(gè)清晰的仿真工程目錄結(jié)構(gòu)能省去很多路徑問題。我通常這樣組織sim_project/ ├── rtl/ # RTL 源碼 ├── tb/ # 測試平臺 ├── ip/ # Vivado IP 生成的仿真模型 ├── lib/ # 編譯好的 Vivado 仿真庫 ├── waves/ # 波形輸出目錄 ├── filelist.f # 仿真文件列表 ├── run_vcs.sh # VCS 編譯和仿真腳本 └── synopsys_sim.setup # 庫映射文件filelist.f里列出所有需要編譯的 RTL 和 TB 文件以及 IP 仿真模型文件。IP 仿真模型通常在 Vivado 工程的project.srcs/sources_1/ip/ip_name/simulation目錄下需要把這些文件路徑加入filelist.f。synopsys_sim.setup的內(nèi)容示例unisims_ver : /home/user/vivado_lib/vcs_2024/unisims_ver simprims_ver : /home/user/vivado_lib/vcs_2024/simprims_ver secureip : /home/user/vivado_lib/vcs_2024/secureip xpm : /home/user/vivado_lib/vcs_2024/xpm這樣 VCS 在編譯時(shí)就能通過邏輯庫名找到對應(yīng)的物理路徑。3.4 VCS 編譯命令的選項(xiàng)拆解一個(gè)典型的 VCS 編譯命令如下vcs -full64 -sverilog -debug_accessall \ -timescale1ns/1ps \ -f filelist.f \ -y /home/user/vivado_lib/vcs_2024/unisims_ver \ libext.v.sv \ -synopsys_sim.setup ./synopsys_sim.setup \ -l compile.log \ -o simv-full64編譯 64 位仿真器處理大規(guī)模設(shè)計(jì)時(shí)必須加。-sverilog支持 SystemVerilogXilinx 的 IP 仿真模型大量使用 SV 語法。-debug_accessall開啟調(diào)試功能Verdi 需要這個(gè)選項(xiàng)才能加載波形和查看信號。-timescale1ns/1ps指定時(shí)間精度必須和 RTL 中的 timescale 一致否則時(shí)序會(huì)錯(cuò)亂。-f filelist.f指定文件列表。-y指定庫搜索路徑VCS 會(huì)在這些路徑下查找模塊定義。libext.v.sv指定庫文件的擴(kuò)展名。-synopsys_sim.setup指定庫映射文件。-l compile.log輸出編譯日志。-o simv指定輸出可執(zhí)行文件名。編譯成功后會(huì)生成simv可執(zhí)行文件。運(yùn)行./simv即可啟動(dòng)仿真。提示如果編譯時(shí)報(bào)module not found先檢查-y路徑是否正確以及synopsys_sim.setup里的庫映射是否匹配。4. 后仿真 Memory 初始化最容易翻車的環(huán)節(jié)4.1 后仿真為什么需要 Memory 初始化后仿真Post-Synthesis/Post-Implementation Simulation使用的是綜合或?qū)崿F(xiàn)后的網(wǎng)表網(wǎng)表里的 Memory如 BRAM、URAM通常沒有初始值。如果設(shè)計(jì)里有一個(gè)從 Memory 讀取數(shù)據(jù)的啟動(dòng)流程仿真時(shí) Memory 里全是 X讀出來的數(shù)據(jù)也是 X導(dǎo)致仿真結(jié)果無意義。解決方法是在仿真開始時(shí)通過$readmemh或$readmemb把初始化文件加載到 Memory 中。但在后仿真中Memory 被映射成了 Xilinx 的原語如RAMB36E2這些原語沒有直接的$readmemh接口需要通過defparam或者initial塊來加載。4.2 用-g選項(xiàng)傳遞 Memory 初始化文件路徑VCS 支持通過-g選項(xiàng)在編譯時(shí)傳遞參數(shù)可以在 RTL 或網(wǎng)表中用$value$plusargs獲取。但在后仿真中更常見的做法是修改網(wǎng)表在 Memory 原語的initial塊里加入$readmemh。不過直接修改網(wǎng)表不是好習(xí)慣因?yàn)槊看尉C合后網(wǎng)表都會(huì)變。更好的做法是在測試平臺里用force或者deposit的方式在仿真開始時(shí)把數(shù)據(jù)寫入 Memory。但這種方法對大型 Memory 效率很低。我比較推薦的做法是在 Vivado 生成網(wǎng)表時(shí)勾選“Write Memory Initialization File”選項(xiàng)生成.mem文件然后在測試平臺里用$readmemh加載到對應(yīng)的 Memory 信號上。具體操作是在 Vivado 的 Implementation 設(shè)置里找到Write Memory Initialization File選項(xiàng)設(shè)置為true。實(shí)現(xiàn)完成后Vivado 會(huì)在project.runs/impl_1/目錄下生成.mem文件。在測試平臺里用$readmemh(path/to/memory.mem, dut.memory_instance.mem_array)加載。但這里有個(gè)問題后仿真網(wǎng)表里的 Memory 實(shí)例名可能和 RTL 不一樣需要先在網(wǎng)表里找到對應(yīng)的實(shí)例路徑??梢杂胓rep在網(wǎng)表里搜索RAMB或URAM關(guān)鍵字找到實(shí)例名。4.3 Memory 初始化文件的格式陷阱.mem文件的格式必須和 Memory 的位寬、深度匹配。如果 Memory 是 32 位寬、1024 深度.mem文件里每行應(yīng)該是一個(gè) 8 位十六進(jìn)制數(shù)32 位 8 個(gè)十六進(jìn)制字符。如果格式不對$readmemh會(huì)報(bào)錯(cuò)或者加載錯(cuò)誤的數(shù)據(jù)。另外.mem文件里的地址順序也很重要。有些 Memory 原語的地址是線性的有些是交織的interleaved需要根據(jù)原語的數(shù)據(jù)手冊確認(rèn)。如果加載后發(fā)現(xiàn)數(shù)據(jù)錯(cuò)位大概率是地址映射搞錯(cuò)了。注意后仿真中 Memory 初始化失敗最常見的報(bào)錯(cuò)是$readmemh: not enough data in file或$readmemh: too much data in file前者說明文件行數(shù)不夠后者說明行數(shù)過多。檢查.mem文件的行數(shù)和 Memory 深度是否一致。4.4 用 Verdi 的 nWave 查看 Memory 內(nèi)容Verdi 的 nWave 支持直接查看 Memory 數(shù)組的內(nèi)容。在 nWave 里選中 Memory 信號右鍵選擇Memory-View Memory可以以表格形式查看 Memory 的每個(gè)地址和對應(yīng)的數(shù)據(jù)。如果發(fā)現(xiàn)某些地址是 X說明初始化沒有覆蓋到這些地址。另外Verdi 的fsdbDumpvars系統(tǒng)任務(wù)可以指定 dump Memory 的深度。如果 Memory 很大全 dump 會(huì)導(dǎo)致 FSDB 文件巨大仿真速度變慢??梢杂胒sdbDumpMDA只 dump 需要的 Memory 部分。5. Verdi 波形調(diào)試從 FSDB 生成到信號追蹤5.1 在測試平臺里加入 FSDB dump 代碼VCS 默認(rèn)生成 VCD 波形但 VCD 文件大、加載慢Verdi 更推薦 FSDB 格式。要在仿真中生成 FSDB需要在測試平臺里加入以下代碼initial begin $fsdbDumpfile(waves/tb.fsdb); $fsdbDumpvars(0, tb); $fsdbDumpMDA(0, tb); end$fsdbDumpfile指定 FSDB 文件名和路徑。$fsdbDumpvars(0, tb)dumptb模塊下所有層次的信號0表示不限深度。$fsdbDumpMDA(0, tb)dump Memory 數(shù)組后仿真中查看 Memory 內(nèi)容必須加這個(gè)。編譯時(shí)需要鏈接 Verdi 的 FSDB 庫。VCS 的命令里加上vcs -full64 -sverilog -debug_accessall \ -P $VERDI_HOME/share/PLI/VCS/LINUX64/novas.tab \ $VERDI_HOME/share/PLI/VCS/LINUX64/pli.a \ ...-P選項(xiàng)指定 Verdi 的 PLI 接口文件pli.a是靜態(tài)庫。如果 VCS 版本和 Verdi 版本不匹配PLI 接口可能會(huì)報(bào)錯(cuò)需要確認(rèn)兩個(gè)工具的版本兼容性。5.2 Verdi 加載 FSDB 的兩種方式仿真運(yùn)行結(jié)束后FSDB 文件會(huì)生成在指定目錄下。用 Verdi 打開有兩種方式方式一命令行直接打開verdi -ssf waves/tb.fsdb -ssf選項(xiàng)直接加載 FSDB 文件Verdi 啟動(dòng)后會(huì)自動(dòng)打開 nWave 窗口。方式二先啟動(dòng) Verdi再加載 FSDBverdi 然后在 Verdi 的 nWave 窗口里選擇File-Open-FSDB選擇對應(yīng)的 FSDB 文件。兩種方式效果一樣但方式一更適合腳本化流程。如果仿真和調(diào)試是分開的比如仿真在服務(wù)器上跑調(diào)試在本地做可以把 FSDB 文件拷貝到本地再用方式一打開。5.3 用 nWave 做信號追蹤和調(diào)試Verdi 的 nWave 功能很強(qiáng)但很多人只用了基礎(chǔ)的波形查看。以下幾個(gè)功能在后仿真調(diào)試中特別有用Signal Search在 nWave 里按CtrlF可以搜索信號名。后仿真網(wǎng)表里的信號名可能被優(yōu)化過用搜索功能可以快速定位。Trace Driver/Load選中一個(gè)信號右鍵選擇Trace-Driver可以追蹤這個(gè)信號的驅(qū)動(dòng)源。后仿真中信號被優(yōu)化時(shí)這個(gè)功能能幫你找到實(shí)際的驅(qū)動(dòng)路徑。Event Search在 nWave 里選擇Tools-Event Search可以搜索特定的事件比如某個(gè)信號從 0 變 1 的時(shí)刻。Memory View前面提到的 Memory 查看功能在 nWave 里選中 Memory 信號右鍵選擇Memory-View Memory。另外Verdi 的Hierarchy窗口可以查看設(shè)計(jì)的層次結(jié)構(gòu)。后仿真網(wǎng)表的層次可能和 RTL 不一樣用 Hierarchy 窗口可以快速了解網(wǎng)表的模塊結(jié)構(gòu)。5.4 FSDB 文件過大的處理技巧后仿真中如果 dump 了所有信號和 MemoryFSDB 文件可能達(dá)到幾十 GB加載和查看都很慢。幾個(gè)優(yōu)化技巧只 dump 需要的信號用$fsdbDumpvars(1, tb)只 dump 一層信號或者用$fsdbDumpvars(0, tb.u_dut)只 dump DUT 內(nèi)部的信號。設(shè)置 dump 起始時(shí)間用$fsdbDumpoff和$fsdbDumpon控制 dump 的時(shí)間窗口只在關(guān)鍵時(shí)間段 dump。壓縮 FSDBVerdi 支持 FSDB 壓縮在$fsdbDumpfile里加上-compress選項(xiàng)可以減小文件大小但會(huì)增加仿真時(shí)的 CPU 開銷。提示如果 FSDB 文件已經(jīng)生成但太大可以用 Verdi 的fsdbedit工具裁剪只保留需要的信號和時(shí)間段。6. 聯(lián)合仿真中那些讓人抓狂的報(bào)錯(cuò)與解決思路6.1module not found的排查鏈路這是聯(lián)合仿真中最常見的報(bào)錯(cuò)。排查順序如下確認(rèn)synopsys_sim.setup里的庫映射路徑是否正確。可以用ls命令檢查庫目錄下是否有對應(yīng)的.v或.sv文件。確認(rèn) VCS 命令里的-y路徑是否指向庫目錄。-y路徑應(yīng)該指向包含庫文件的目錄而不是庫文件的父目錄。確認(rèn)libext選項(xiàng)是否包含了庫文件的擴(kuò)展名。Xilinx 的庫文件通常是.v或.sv如果只寫了libext.vSV 文件就找不到。確認(rèn)編譯庫時(shí)的選項(xiàng)和仿真時(shí)的選項(xiàng)是否一致。比如編譯庫時(shí)用了-sverilog仿真時(shí)也必須用。如果以上都確認(rèn)無誤但還是報(bào)module not found可以在 VCS 命令里加上-debug_pp或者-v選項(xiàng)查看詳細(xì)的庫搜索過程。6.2timescale不一致導(dǎo)致的時(shí)序錯(cuò)亂Vivado 的 IP 仿真模型通常有自己的timescale如果測試平臺的timescale和 IP 模型不一致仿真時(shí)序會(huì)錯(cuò)亂。比如測試平臺是1ns/1psIP 模型是1ps/1ps仿真時(shí) IP 內(nèi)部的延遲會(huì)被放大 1000 倍。解決方法在 VCS 命令里用-timescale1ns/1ps統(tǒng)一指定或者在測試平臺里用timescale 1ns/1ps覆蓋。但注意-timescale選項(xiàng)只對沒有指定timescale的模塊生效如果模塊里已經(jīng)指定了以模塊內(nèi)的為準(zhǔn)。6.3 Verdi 加載 FSDB 時(shí)報(bào)PLI錯(cuò)誤如果 Verdi 加載 FSDB 時(shí)報(bào)PLI相關(guān)錯(cuò)誤通常是 VCS 和 Verdi 的版本不匹配或者 PLI 庫路徑不對。檢查以下幾點(diǎn)VCS 和 Verdi 的版本是否來自同一個(gè) Synopsys 發(fā)布版本。比如 VCS 2024.06-SP1 應(yīng)該搭配 Verdi 2024.06-SP1。-P選項(xiàng)指定的novas.tab和pli.a路徑是否正確。路徑通常在$VERDI_HOME/share/PLI/VCS/LINUX64/下。LD_LIBRARY_PATH是否包含了 Verdi 的庫路徑。如果版本確實(shí)不匹配可以嘗試用-P指定其他版本的 PLI 庫但兼容性無法保證。最好的辦法還是統(tǒng)一版本。6.4 后仿真中 Memory 讀出 X 的排查后仿真中 Memory 讀出 X原因可能有Memory 初始化文件沒有加載成功。檢查$readmemh的路徑是否正確文件是否存在。Memory 實(shí)例路徑不對。后仿真網(wǎng)表里的實(shí)例名可能和 RTL 不一樣需要在網(wǎng)表里搜索確認(rèn)。Memory 的地址映射不對。有些 Memory 原語的地址是交織的需要根據(jù)數(shù)據(jù)手冊調(diào)整。初始化文件格式不對。檢查文件的行數(shù)和每行的數(shù)據(jù)寬度是否匹配。排查時(shí)可以在測試平臺里加入$display語句打印 Memory 的初始值確認(rèn)初始化是否成功。6.5 仿真速度慢的優(yōu)化方向聯(lián)合仿真速度慢除了設(shè)計(jì)本身規(guī)模大之外還有幾個(gè)優(yōu)化方向減少 dump 的信號數(shù)量只 dump 關(guān)鍵信號避免全量 dump。使用-debug_accessall的替代選項(xiàng)如果不需要 Verdi 的調(diào)試功能可以用-debug_accesspp或者-debug_access減少調(diào)試信息的生成。關(guān)閉不必要的庫編譯只編譯設(shè)計(jì)用到的器件系列和語言減少庫文件數(shù)量。使用 VCS 的增量編譯如果只修改了少量文件可以用-Mupdate選項(xiàng)做增量編譯避免全量重新編譯。7. 一些讓流程更順手的個(gè)人經(jīng)驗(yàn)聯(lián)合仿真這套流程我踩過的坑主要集中在庫編譯和 Memory 初始化上。庫編譯最怕的是 VCS 環(huán)境變量沒配好compile_simlib跑到一半報(bào)錯(cuò)日志里只顯示vlogan: command not found。所以每次編譯庫之前我都會(huì)先在終端里執(zhí)行which vlogan和which vhdlan確認(rèn)命令可用。Memory 初始化這塊我現(xiàn)在的習(xí)慣是在 Vivado 里生成.mem文件后先用 Python 腳本檢查一下文件的行數(shù)和數(shù)據(jù)寬度確認(rèn)和 Memory 的配置匹配再放到仿真目錄里。這個(gè)檢查腳本很簡單就是讀文件、統(tǒng)計(jì)行數(shù)、檢查每行的字符數(shù)但能省去很多仿真跑了一半才發(fā)現(xiàn)數(shù)據(jù)不對的時(shí)間。Verdi 的 FSDB dump 代碼我通常放在測試平臺的initial塊里但會(huì)加一個(gè)ifdef開關(guān)方便在不需要波形時(shí)關(guān)閉 dump。比如ifdef DUMP_FSDB initial begin $fsdbDumpfile(waves/tb.fsdb); $fsdbDumpvars(0, tb); $fsdbDumpMDA(0, tb); end endif編譯時(shí)用defineDUMP_FSDB開啟不定義就關(guān)閉。這樣同一套測試平臺可以用于快速回歸和詳細(xì)調(diào)試兩種場景。最后說一個(gè) Verdi 的小技巧在 nWave 里按Shift鼠標(biāo)滾輪可以橫向縮放波形按Ctrl鼠標(biāo)滾輪可以縱向縮放。后仿真波形通常很長用這兩個(gè)快捷鍵可以快速定位到感興趣的區(qū)間。另外Verdi 的Marker功能可以標(biāo)記多個(gè)時(shí)間點(diǎn)方便對比不同時(shí)刻的信號狀態(tài)。