0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google ColabでVerilogコードをPythonから実行する方法

Last updated at Posted at 2025-03-23

Verilogはハードウェア記述言語(HDL)として、論理回路やデジタルシステムの設計に使われます。この記事では、Google Colab上でVerilogコードをPythonから実行する方法を、iverilogツールを使って解説します。


必要な準備

Google Colabはデフォルトで Verilog のコンパイラを持っていないため、まず iverilog をインストールします。

!apt-get update
!apt-get install -y iverilog

このコマンドで、Colabに Verilog のコンパイラ iverilog とシミュレータ vvp を追加できます。


今回の題材:AND回路のテストベンチ

以下のVerilogコードでは、シンプルな AND ゲートを設計し、その出力が正しく動作するかを確認する**テストベンチ(検証モジュール)**を定義しています。

module and_gate (
    input a,
    input b,
    output y
);
assign y = a & b;
endmodule

and_gate モジュールは2つの入力信号 a, b を受け取り、AND演算をした結果 y を出力します。


テストベンチの内容

次に、実際にこの回路をテストするための testbench モジュールを作成します。

module testbench;
    reg a, b;
    wire y;

    and_gate uut ( .a(a), .b(b), .y(y) );

    initial begin
        $display("a b | y");
        a = 0; b = 0; #10 $display("%b %b | %b", a, b, y);
        a = 0; b = 1; #10 $display("%b %b | %b", a, b, y);
        a = 1; b = 0; #10 $display("%b %b | %b", a, b, y);
        a = 1; b = 1; #10 $display("%b %b | %b", a, b, y);
        $finish;
    end
endmodule
  • reg は入力信号に使われるレジスタ変数。
  • wire は出力信号に使われる接続線。
  • #10 はシミュレーションで10単位時間の待機を意味します。
  • $display により、各組み合わせの結果がターミナルに表示されます。

Pythonコードでの操作手順

Python側では、次のようにこの Verilog コードを .v ファイルに書き出し、iverilog でコンパイル、vvp で実行します。

import subprocess

# Verilogコードをファイルに書き出し
verilog_code = """(上記と同様のVerilogコード)"""
with open("and_test.v", "w") as f:
    f.write(verilog_code)

# コンパイル
subprocess.run(["iverilog", "-o", "and_test", "and_test.v"])

# 実行
result = subprocess.run(["vvp", "and_test"], capture_output=True, text=True)

# 結果表示
print(result.stdout)

出力結果(例)

a b | y
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1

このように、AND回路の出力が正しく表示されていれば、Verilogコードとテストベンチは正常に動作しています。


まとめ

  • iverilogvvpを使えば、Colabでも手軽にVerilogシミュレーションが可能
  • Pythonとの連携により、自動化や繰り返し検証がしやすくなる
  • 複雑な論理設計やFSMなども応用可能。

応用したい方へ

この仕組みを応用すれば、

  • 加算器・減算器などの算術回路
  • クロック・リセットを含むFSM(状態機械)
  • テストデータ生成と自動検証

などに広げることもできます。ご希望あれば、ぜひお知らせください!

# 必要なツールのインストール(初回のみ実行)
!apt-get update -qq
!apt-get install -y iverilog  # iverilog: Verilogコンパイラ / Verilog compiler
import subprocess

# Verilogコードを文字列として定義
# Define Verilog code (AND gate + testbench)
verilog_code = """
// ANDゲートのモジュール定義 / AND gate module
module and_gate (
    input a,
    input b,
    output y
);
assign y = a & b;
endmodule

// テストベンチモジュール / Testbench module
module testbench;
    reg a, b;      // 入力信号(レジスタ)/ input signals (registers)
    wire y;        // 出力信号(ワイヤ)/ output signal (wire)

    // テスト対象のインスタンス化 / Instantiate the DUT (Device Under Test)
    and_gate uut (
        .a(a),
        .b(b),
        .y(y)
    );

    // 初期処理 / Initial block for test sequence
    initial begin
        $display("a b | y");  // ヘッダー出力 / Print header
        a = 0; b = 0; #10 $display("%b %b | %b", a, b, y);
        a = 0; b = 1; #10 $display("%b %b | %b", a, b, y);
        a = 1; b = 0; #10 $display("%b %b | %b", a, b, y);
        a = 1; b = 1; #10 $display("%b %b | %b", a, b, y);
        $finish;  // シミュレーション終了 / End simulation
    end
endmodule
"""

# Verilogコードをファイルに保存 / Save Verilog code to a file
with open("and_test.v", "w") as f:
    f.write(verilog_code)

# Verilogコードをiverilogでコンパイル / Compile Verilog code
subprocess.run(["iverilog", "-o", "and_test", "and_test.v"])

# vvpでシミュレーション実行 / Run the simulation
result = subprocess.run(["vvp", "and_test"], capture_output=True, text=True)

# 実行結果の出力 / Display the simulation result
print("▼ 実行結果 / Simulation Output ▼\n")
print(result.stdout)


# Verilogシミュレーション環境をColabに構築(1回だけ実行)
!apt-get update -qq
!apt-get install -y iverilog
import subprocess

verilog_code = """
module logic_gates(input a, input b, output and_out, output or_out, output not_a);
    assign and_out = a & b;
    assign or_out  = a | b;
    assign not_a   = ~a;
endmodule

module testbench;
    reg a, b;
    wire and_out, or_out, not_a;

    logic_gates uut(.a(a), .b(b), .and_out(and_out), .or_out(or_out), .not_a(not_a));

    initial begin
        $display("a b | AND OR NOT");
        a = 0; b = 0; #10 $display("%b %b |  %b   %b   %b", a, b, and_out, or_out, not_a);
        a = 0; b = 1; #10 $display("%b %b |  %b   %b   %b", a, b, and_out, or_out, not_a);
        a = 1; b = 0; #10 $display("%b %b |  %b   %b   %b", a, b, and_out, or_out, not_a);
        a = 1; b = 1; #10 $display("%b %b |  %b   %b   %b", a, b, and_out, or_out, not_a);
        $finish;
    end
endmodule
"""

with open("logic_test.v", "w") as f:
    f.write(verilog_code)

subprocess.run(["iverilog", "-o", "logic_test", "logic_test.v"])
result = subprocess.run(["vvp", "logic_test"], capture_output=True, text=True)
print(result.stdout)

verilog_dff = """
module dff(input clk, input reset, input d, output reg q);
    always @(posedge clk) begin
        if (reset) q <= 0;
        else       q <= d;
    end
endmodule

module testbench;
    reg clk, reset, d;
    wire q;

    dff uut (.clk(clk), .reset(reset), .d(d), .q(q));

    initial begin
        $display("clk reset d | q");
        clk = 0; reset = 1; d = 0;
        #5 clk = 1; #5 clk = 0;  // リセット
        reset = 0; d = 1;
        #5 clk = 1; #5 $display("%b %b %b | %b", clk, reset, d, q);
        clk = 0; d = 0;
        #5 clk = 1; #5 $display("%b %b %b | %b", clk, reset, d, q);
        $finish;
    end
endmodule
"""

with open("dff.v", "w") as f:
    f.write(verilog_dff)

subprocess.run(["iverilog", "-o", "dff", "dff.v"])
result = subprocess.run(["vvp", "dff"], capture_output=True, text=True)
print(result.stdout)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?