Verilator:操作指令統整

jtsai1120

Verilator

Verilator 是一個開源的 Verilog/SV 編譯器,支援將 .v.sv 編譯成 C++ 模型,再經過 GCC 編譯得到執行檔,執行 HDL Simulation。

為什麼使用 Verilator

目前已知常見、且對學生免費開放的 HDL 模擬套件有如:

  • Vivado (Windows)
  • ModelSim (Windows)
  • Verilator (Unix)
  • Icarus Verilog (Unix)

我最一開始學習 Verilog 是在邏輯設計實驗課程中,使用 Xilinx FPGA 進行測試,自然而然使用 Vivado 進行模擬。
然而自從換了 Macbook 後,雖然也是可以開 VM 跑 Vivado,但 Vivado 笨重、編譯慢的缺點逐漸放大,促使我開始向外尋找其他的開源 HDL 模擬套件。

當初也有在 Reddit 上爬文,看有哪些推薦、可在 MacOS 上運行的 HDL 模擬套件,
然而都是差不多的回答 —— 根本不會有人在 MacOS 上寫硬體。

怎麼不找找自己問題?確實,我得承認用 MacOS 就是處處有學習成本,但跨過這個坎後,會發現一切變的很簡單,然後就能很裝逼 (x

總之,我最後找到 iverilog (Icarus Verilog) 與 Verilator 這兩個選項。
當時(現在偶爾)都是使用 iverilog,原因是它的指令非常簡潔直觀,且對於編譯小型設計較 Verilator 快,也不會生一大坨檔案出來。

然而 iverilog 最大的缺點,就是它不完全支援編譯 SV。

這問題剛好在我修 VLSI/CAD 導論時,某個 Lab 就遇上助教使用 SV 寫 tb 的情況,促使我將頭轉向 Verilator。

補充:iverilog 指令大全

1
2
3
4
5
# iverilog 生出的模擬執行檔格式為 .vvp
$ iverilog -o out.vvp tb.v

# 執行模擬
$ vvp out.vvp

選項:

  • -o:輸出檔案名稱
  • -g:指定 Verilog 版本
    $ iverilog -g2005 tb.v
  • -D{...}:定義巨集 (一次只能定義一個)
    $ iverilog -DWaveform -Dsyn tb.v
  • -Wall:顯示詳細 Warning

而我當初不選擇使用 Verilator 的原因除了會生出一大坨檔案外 (這個方面只能說跟 VCS 不相上下),
Verilator 以前的版本只支援 C++ 所撰寫的 tb,對於長久以來都用 Verilog 寫 tb 的我來說很不習慣。

但好在 Verilator 不確定在哪個版本更新後,就開始支援 Verilog 或 SV 的 tb,讓我有了回頭摸一下的價值。

總結,我會開始使用 Verilator 就是因為它可以編譯 SV,且貌似在大型設計上編譯速度勝過 iverilog (甚至有時比 big-3 快)。

big-3:VCS (Synopsys), NC-Verilog (Cadence), ModelSim (Siemens)

安裝

  • Linux (Ubuntu, Debian)
    1
    2
    apt update
    apt install verilator
  • MacOS
    1
    brew install verilator

快速範例

使用 Verilator 編譯 tb.sv

1
verilator --binary --trace -Dplot -Dsyn -Wno-fatal tb.sv && ./obj_df/Vtb
  • --binary:直接生成執行模擬檔 (不然需要手動make)
  • --trace:生成 VCD 波形檔
  • -Dplot -Dsyn:在巨集中新增定義 plotsyn
  • -Wno-fatal:忽略所有 Warning (不然 Warning 也會阻止 Verilator 繼續編譯)

此時生成出來的模擬執行檔預設會在 obj_dir/ 底下,名稱預設為 V+{原檔案名}
因此接著執行模擬檔: ./obj_dir/Vtb

Lint

在編譯前 Verilator 就會先 Lint,若發現有 Error 或 Warning 就會跳出來叫你修正後再重新編譯一次。
但每次編譯都會產生一坨檔案,所以建議每次編譯前先使用 --lint-only 選項加上 -Wall 選項單純 Lint 一次,
或許可以免除許多因 Typo 造成 Debug 上不必要的困擾。

1
2
verilator --lint-only -Wall tb.v 
# 可以在 tb.v include 後加上 /* verilator lint_off */ 忽略 tb 的 Warning

編譯 & 模擬

重要選項

  • --binary:直接生成執行模擬檔 (不然需要手動make)
  • --trace:生成 VCD 波形檔 (記得 $dumpfile(), $dumpvars())
    • --trace-fst:生成 FST 波形檔
  • -D{...}:定義巨集 (一次只能定義一個)

次要選項

  • --Mdir:Verilator 生成檔案的資料夾名稱,預設為 obj_dir
  • --prefix:Verilator 生成模擬檔案的前綴名,預設為 top_module 的名稱
  • --cc / --sc:編譯成 C++ / SystemC 模型
  • --main:只生成 C++ / SystemC 模型,不生成 Makefile
  • --exe:生成 C++ / SystemC 模型和 Makefile,但不會自動 make
  • --build: 等價於 --binary,生成 C++ / SystemC 模型和 Makefile 且會自動 make
  • --E:只做 Preprocessing
  • --xml-only:生成 .xml 格式 (類似 .json) 的模型,可用於其他工具使用

Warning & Error

Verilator 預設情況下會將 Warning 視為 Error,因此阻止編譯繼續進行,
可啟用以下選項來暫時忽略部分 Warning 或所有 Warning。

  • -Wall:啟用所有詳細的 Warning
  • -Wwarn-style:只啟用 Style Warning
  • -Wno-fatal:忽略所有 Warning
  • -Wno-UNUSED:忽略所有 未使用 的 Signal 所產生的 Warning
  • -Wno-WIDTH:忽略所有 寬度不匹配 的 Signal 所產生的 Warning
  • -Wno-UNDRIVEN:忽略所有 未被驅動 的 Signal 所產生的 Warning

也可以在程式碼中加入以下註解,告訴 Verilator 忽略此片段的部分 Warning

  • /* verilator lint_off */:關閉所有 Warning 種類
  • /* verilator lint_off {...} */:關閉特定 Warning 種類
1
2
3
4
5
/* verilator lint_off WIDTH UNUSED UNDRIVEN */
module my_module(...);
...
endmodule
/* verilator lint_on WIDTH UNUSED UNDRIVEN */

補充:Style Warning

Style Warning 最好都解決,不然高機率無法跑合成

  • CASEINCOMPLETE:case 語句不完整(沒有 default 分支)
  • CASEOVERLAP:case 項重疊
  • CASEWITHX:case 語句中使用了 X(不確定)值
  • CASEXZ:使用了 casex/casez(建議使用 unique case)
  • LITENDIAN:字面量的位寬指定使用了非標準端序
  • PINCONNECTEMPTY:模塊實例化時有空連接
  • PINMISSING:模塊實例化時缺少引腳連接
  • PINNOCONNECT:模塊引腳未連接
  • STYLE:一般風格問題
  • SYMRSVDWORD:使用了保留關鍵字作為標識符

參考