利用 Icarus Verilog 在 macOS / Linux (甚至 Android) 上撰寫和測試 Verilog
Available in English
你是不是也跟我一樣,上課被要求用 Quartus II 寫 Verilog,結果發現它竟然只有 Windows 版?Σ(’◉⌓◉’) 搞得我們這些拿 Mac 或灌 Linux 的學生,只能對著螢幕乾瞪眼。別擔心!這篇文章就是要來告訴你,如何在 macOS 和 Linux 上搞定 Verilog 設計,還能順便做概念驗證!*(甚至可以跑在 Android 手機/平板上跑)
軟體安裝
我會推薦這兩個軟體,如果沒其他偏好可以直接用下列工具開始:
- Icarus Verilog
- GTKWave
- 如果你想要全純 CLI,可以用 yne/vcd。(參見下面的介紹)
Icarus Verilog*
在晶片設計流程中,iverilog 主要處理的是 Verilog 程式碼的「功能驗證」。這表示它能讓你編譯 Verilog 程式碼(這通常被稱為 RTL 設計,即寄存器傳輸級設計),然後透過其內建的模擬器 vvp
執行,確認邏輯行為是否符合預期。模擬完成後,它會產生 vcd
波形檔 (Value Change Dump File),方便你分析訊號變化。
Icarus Verilog ` 專注於程式碼的編譯與功能模擬,但無法處理後續的「硬體實作」部分,例如邏輯合成 (Synthesis)、佈局 (Layout) 或燒錄到 FPGA/ASIC 等。因此,這篇文章的目標是幫助你專注在「把程式寫對」上,而不涉及真實硬體的實現喔!(ゝ∀・)
安裝方法很簡單,都可以使用套件管理器安裝:
Linux
sudo apt update
sudo apt install iverilog
Android (w/ Termux)
如果你有 android 手機或平板也可以通過 termux 裝在裝置上。
pkg update
pkg install iverilog
macOS
(請確保你已經安裝好了 brew )
brew install icarus-verilog
有很多軟體可以瀏覽 vcd
,這裡介紹的都是開源的方案:
GTKWave (GUI)
GTKWave 是一個開源、圖形化、用於檢視 vcd
波形檔的瀏覽器。它能打開 Icarus Verilog 產生的 .vcd 波形檔案,讓你以圖形化的方式檢查設計中各個訊號的時序和邏輯狀態。
安裝
Linux
sudo apt update
sudo apt install gtkwave
android 的部分因為跑 GUI 要多講一道手續,我推薦用 yne/vcd 比較省事。
macOS
目前 GTKWave on macOS Sonoma 似乎遇到了一些問題,需要一些補丁才能跑起來。如果真的跑不起來可以用接下來的方法 (#250)
# 請確保你已經安裝好了 brew: https://brew.sh
brew install --cask gtkwave
yne/vcd (CLI)
如果你偏好純文字介面,或者希望在遠端伺服器上快速檢視波形,我推薦 yne 的 vcd: https://github.com/yne/vcd
作為要教作業的學生⋯⋯之前遇到很機車的助教,說看不懂 yne/vcd 的波形圖 ( ・∇・?)
編譯+安裝
git clone https://github.com/yne/vcd.git; cd vcd
make
# install into your environmet
sudo make install
# or directly use it
cd ../
vcd/vcd --help
使用方法
yne/vcd 是通過 stdin/stdout 輸入輸出的,可以直接 bash pipe 進去然後輸出到檔案裡,也可以直接 print 到 terminal 中:
# input from file and output to a file
vcd/vcd < result.vcd > result.yml
結果會像下面這樣
其他方案
我還有找到其他方案,用法也都不盡相同
vcdrom (Web App)
vcdrom 是一個網頁應用程式版的 vcd viewer。
Website: https://vc.drom.io Github repository: https://github.com/wavedrom/vcdrom
VaporView (VSCode Extension)
VaporView 是一個 VSCode 插件的 vcd viewer
Github repository: https://github.com/Lramseyer/vaporview
自己動手寫一個 VCD 檢視器?
檔案格式其實並不複雜,它主要紀錄了離散時間點上各個測試訊號的狀態變化。如果你對圖形化程式設計有興趣,甚至可以嘗試使用像是 processing 自己寫一個簡單的 VCD 波形檢視器優
٩( ᐛ )و
iVerilog + GTKWave
Testbench 的結構大致會呈現如下:
你一定會有一個 main module,這裡假設是 main.v
和 main:
module main(
...
);
... your code here ...
endmodule
testbench 基本上就是一個程式測資,和任何程式的 unit test 一樣,他是一個可以運作的程式(在這裏是電路)
你一定會這幾個段落:
- 測試的輸入和輸出 變數/wire/暫存器,偶爾可能還會有一些測試資料
- 你需要在 tester 裡調用你自己的 main module(top level entry )
- 你需要 clock 和留有一些 delay 給你的程式,如下定義
main_test.v
`timescale 1ns/ 1ns
`include "main.v"
module tester();
// inputs for your main module
reg clk;
reg reset;
reg start;
reg din;
// outputs for your main module
// > outputs should always be "wire"
wire count_out;
wire[0:3] count_one;
wire dout_valid;
wire dout;
// your constants data
reg[0:7] data = 8'b01010010;
// This part will
// connect your main module into tester module
main m(
.reset(reset),
.clk(clk),
.start(start),
.din(din),
.count_out(count_out),
.count_one(count_one),
.dout_valid(dout_valid),
.dout(dout)
);
// maybe some integer to count on
integer i;
// the part of only run once
initial begin
// this part is very important!
// this define the vvp (runtime) to output
// the wave file result main_test.vcd
// for later with the signals inside tester module
$dumpfile("main_test.vcd");
$dumpvars(0, tester);
clk = 0;
reset = 0;
start = 0;
din = 0;
// send a reset signal
// this means waiting 2 unit of time
// as well as defined in $timescale
#2;
reset = 1;
#2;
reset = 0;
// ...
for (i = 0; i < 8; i = i + 1) begin
din = data[i];
#2;
end
// ...
// This is also very important!
// To stop the vvp simulation,
// you'll need this line
$finish;
end
// generate clock signal for every 1 unit of time
//
// why not #2? because one cycle of clock
// required two changes, high and low,
// so the program above will wait every 2 unit of time
always #1 clk = ~clk;
endmodule
最後再執行這個 tester 就可以了。
vvp 是 iverilog 的模擬環境,用來模擬你編譯好的 verilog。
iverilog -o main_test.vvp main_test.v
vvp main_test.vvp
模擬完後理論上會出現一個 main_test.vcd
- 在你的資料夾內,用 GTKWave File > Open Tab 開啟這個檔案
- 再SST裡選擇你的 module
- 在下方選擇要觀測的訊號,按下最下面的 Insert
- 然後就可以看到你的執行結果了。
如果你再次模擬了程式,只需要 File > Reload Waveform 或按下快捷鍵 Ctrl+Shift+R 即可載入最新結果
Example: iVerilog + yne/vcd
如果你是用 termux 或你 ssh 到 remote machine,推薦採用這個純文字的方法。
下面是一個簡單 counter 的範例:
main.v
module main (
input wire clk, // Clock input
input wire rst, // Asynchronous reset input (active high)
output reg [1:0] count // 2-bit output for the counter value
);
always @(posedge clk or posedge rst) begin
if (rst) begin
count <= 2'b00; // Reset count to 00
end else begin
count <= count + 2'b01; // Increment count by 1
end
end
endmodule
main_test.v
`timescale 1ns / 1ns
`include "main.v"
module tester ();
reg clk;
reg rst;
wire [1:0] count;
main m (
.clk (clk),
.rst (rst),
.count(count)
);
initial begin
$dumpfile("result.vcd");
$dumpvars(0, tester);
// Initialize inputs
clk = 0;
rst = 0;
#1; // Wait for 2ns
rst = 1; // Assert reset
#1; // Hold reset for 2ns
rst = 0; // De-assert reset
for (integer i = 0; i < 10; i = i + 1) begin
#1; // Wait for 10ns (5 clock cycles)
end
$finish;
end
always #1 clk = ~clk;
endmodule
iverilog -o main_test.vvp main_test.v
vvp main_test.vvp
vcd/vcd < result.vcd > result.yml
下列是 result.yml
:
unknown token : ivl_for_loop0
unknown token : dumpall
global:
zoom: 9
date: Mon Jun 9 05:22:45 2025
total: 13
skip: 0
time:
scale: 1.00
unit: ns
line : "0 10 "
channels:
tester:
count [1:0] : "x 0 0 1 1 2 2 3 3 0 0 1 1 "
m:
clk : "▁▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁"
rst : "▁▁▁▁▁▁▁▁▁╱▔▔▔▔▔▔▔▔╲▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁"
count [1:0] : "x 0 0 1 1 2 2 3 3 0 0 1 1 "
:
i [31:0] : "x x 0 1 2 3 4 5 6 7 8 9 A "
有些助教對這種圖似乎有點「閱讀障礙」呢 ( ・∇・ ???) 還說我放這種圖就是在耍酷給他看(我:???
具體是哪位我就不公開了,大家心裡有數就行 ( ◠‿◠ )b
因此,如果你未來也要批改作業,建議可以留意一下,有些助教在評斷上可能會比較「有自己的想法」。 (因為我確實有過一些不太愉快的經驗,當時真的感到蠻沮喪的 (/ _ ; ))
總結
恭喜你!現在你可以在 macOS、Linux 甚至是你的 android 手機、平板上快快樂樂寫 Verilog 了。
Reference
- Insighted and suggested by Gemini 2.5 Flash
- https://ithelp.ithome.com.tw/articles/10192465
- https://easonchang.com/posts/verilog-on-macosx
- https://fpgatek.com/fpga-design-flow/
- https://hackmd.io/@ljcucc/rydRFzhCT
AI Contents:
- *: Refined by Gemini 2,5 Pro and Flash