ljcucc blog

嗨!歡迎來到我的新blog!我會在這裡刊登一些新聞、想法、研究甚至更多⋯⋯歡迎在此久留! 快來加入官方的matrix的討論群組 #ljcucc-blog-discuss:matrix.org

嗨!歡迎來到我的新blog!我會在這裡刊登一些新聞、想法、研究甚至更多⋯⋯歡迎在此久留! 快來加入官方的matrix的討論群組 #ljcucc-blog-discuss:matrix.org

利用 Icarus Verilog 在 macOS / Linux (甚至 Android) 上撰寫和測試 Verilog

閱讀時間大約 5 分鐘

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

結果會像下面這樣

fig2

其他方案

我還有找到其他方案,用法也都不盡相同

vcdrom (Web App)

vcdrom 是一個網頁應用程式版的 vcd viewer。

Website: https://vc.drom.io Github repository: https://github.com/wavedrom/vcdrom

VaporView (VSCode Extension)

fig1

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 一樣,他是一個可以運作的程式(在這裏是電路)

你一定會這幾個段落:

  1. 測試的輸入和輸出 變數/wire/暫存器,偶爾可能還會有一些測試資料
  2. 你需要在 tester 裡調用你自己的 main module(top level entry )
  3. 你需要 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

  1. 在你的資料夾內,用 GTKWave File > Open Tab 開啟這個檔案
  2. 再SST裡選擇你的 module
  3. 在下方選擇要觀測的訊號,按下最下面的 Insert
  4. 然後就可以看到你的執行結果了。

如果你再次模擬了程式,只需要 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

AI Contents:

  • *: Refined by Gemini 2,5 Pro and Flash
本部落格所有文章除特別聲明外,全部採用 CC BY-NC-ND 4.0 許可協議。轉載請註明來自 ljcucc (與本站網址)