コンピュータの設計 ★★☆ 中級 所要:20–30分

Verilog 入門

ハードウェアを「コード」で設計する言語を、プログラミング経験ゼロから理解しよう。

1. Verilog とは何か?

💻

ソフトウェア(Python など)

コンピュータに「何をするか」を伝える命令書。CPU が命令を上から順番に実行する。

# 2つの数を足す
a = 5
b = 3
print(a + b)  # 8
🔌

Verilog(ハードウェア記述言語)

回路の「配線図」をコードで表現する言語。すべての回路が同時に動くのが特徴。

// 2つの数を足す回路
assign result = a + b;
// a か b が変わると
// result も即座に変わる

🔑 最重要ポイント

Verilog は「命令の実行順序」ではなく「回路の構造」を書く言語です。電線をどうつなぐか、どのゲートを使うかを記述します。

2. モジュール ― 回路の「箱」

Verilog の基本単位は module です。ICチップ(黒い四角いパーツ)をイメージすると分かりやすいです。入力ピン出力ピンがある「箱」です。

    入力 a ─────┐
    入力 b ─────┤  AND ゲート(モジュール)  ├──── 出力 y
                └───────────────────────────┘
// ↓ モジュール名(ICチップの型番に相当)
module and_gate (
    input  a,     // ← 入力ピン a
    input  b,     // ← 入力ピン b
    output y      // ← 出力ピン y
);

    assign y = a & b;  // ← 回路の中身:AND演算

endmodule  // ← 箱の終わり
module … endmodule
箱の外枠。ICチップ全体を定義する。
input / output
入力・出力ピン。外部との接続口。
assign
電線の結び方を書く。常時有効。

3. wire と reg ― 2種類の「信号線」

🔌 wire(電線)

名前のとおり「ただの電線」です。つながれた先の値をそのまま伝えるだけで、値を記憶しません。assign 文と組み合わせて使います。

wire sum;
assign sum = a + b;
// a や b が変わると
// sum もすぐ変わる

→ 組み合わせ回路(加算器など)で使う

💾 reg(レジスタ)

値を記憶できる信号線です。クロックの立ち上がりなど「きっかけ」があったときだけ値が更新されます。always ブロックの中で使います。

reg [7:0] count;
always @(posedge clk)
    count <= count + 1;
// clk の立ち上がりごとに +1

→ 順序回路(カウンタ・CPUなど)で使う

📐 ビット幅の指定

信号が複数ビットの場合は [上位:下位] で幅を指定します。

wire y
1ビット
wire [3:0] y
4ビット (0〜15)
reg [7:0] y
8ビット (0〜255)

4. 回路を書く 3 つの方法

assign ― 組み合わせ回路(ゲートの配線)

「この出力はこの入力たちの演算結果」という常時有効な結線を記述します。プログラムの行と違い、順番に実行されるわけではありません

assign y   = a & b;               // AND
assign sum = a + b;               // 加算
assign sel = (a > b) ? a : b;    // 三項演算子(MUX)
& AND | OR ^ XOR ~ NOT + 加算 - 減算 == 一致 ?: MUX

always @(posedge clk) ― 順序回路(クロックで動く)

クロックの立ち上がり(posedge)ごとに実行されるブロックです。フリップフロップ(記憶素子)の動作を表します。

always @(posedge clk) begin
    if (rst)
        count <= 0;           // リセット
    else
        count <= count + 1; // インクリメント
end
注意: always ブロック内では <=(ノンブロッキング代入)を使います。 = と混同しないよう注意しましょう。

always @(*) ― if / case を使いたい組み合わせ回路

assign では書きにくい if-elsecasealways @(*) で書きます。* は「すべての入力変化に反応する」という意味です。

always @(*) begin
    case (opcode)
        2'b00: result = a + b;  // ADD
        2'b01: result = a - b;  // SUB
        default: result = 0;
    endcase
end

5. 完全な例:1ビット全加算器

論理ゲートのページで学んだ全加算器(Full Adder)を Verilog で書いてみましょう。入力 a, b, cin → 出力 sum, cout を計算します。

真理値表(抜粋)

a b cin sum cout
00000
01010
11001
11111

論理式

sum = a XOR b XOR cin
cout = (a AND b) OR
(cin AND (a XOR b))

これをそのまま Verilog の assign で書けます。

module full_adder (
    input  a, b, cin,   // 3本の入力ピン
    output sum, cout   // 2本の出力ピン
);

    // sum = a XOR b XOR cin
    assign sum  = a ^ b ^ cin;

    // cout = (a AND b) OR (cin AND (a XOR b))
    assign cout = (a & b) | (cin & (a ^ b));

endmodule  // わずか 8 行で 1ビット全加算器が完成!
💡 この全加算器を 4個並べると、授業で見た「4ビット加算器(リップルキャリー)」になります。 モジュールを部品として使いまわせるのが Verilog の強みです。

6. テストベンチ ― 設計を検証する

テストベンチ(Testbench)は「作った回路を試す実験台」です。実際のチップを作る前に、コンピュータ上でシミュレーションしてバグがないか確認します。

テストベンチ(左パネル)        設計(右パネル)
┌─────────────────────┐      ┌──────────────┐
│  a=0, b=0, cin=0    │─────▶│  full_adder  │──▶ sum=0, cout=0
│  a=1, b=1, cin=0    │      └──────────────┘
│  a=1, b=1, cin=1    │
└─────────────────────┘
module tb_full_adder;
    reg  a, b, cin;        // 操作する入力(reg で宣言)
    wire sum, cout;        // 観察する出力(wire で宣言)

    // 設計した full_adder を接続する
    full_adder uut (.a(a), .b(b), .cin(cin),
                    .sum(sum), .cout(cout));

    initial begin
        $dumpfile("dump.vcd");   // 波形ファイル出力
        $dumpvars(0, tb_full_adder);

        // パターン 1: 0+0+0 = 0
        a=0; b=0; cin=0; #10;
        $display("a=%b b=%b cin=%b → sum=%b cout=%b", a,b,cin,sum,cout);

        // パターン 2: 1+1+0 = 2(sum=0, cout=1)
        a=1; b=1; cin=0; #10;
        $display("a=%b b=%b cin=%b → sum=%b cout=%b", a,b,cin,sum,cout);

        $finish;
    end
endmodule
# シミュレーション出力(ログ)
a=0 b=0 cin=0 → sum=0 cout=0 ✅
a=1 b=1 cin=0 → sum=0 cout=1 ✅

7. Verilog の実際の使い道

「Verilog で回路を書いたあと、どうなるの?」という疑問に答えましょう。
現実では大きく 2つの方向 に使われています。

🔧 Path A — FPGA で実機動作

Verilog の回路を論理合成して FPGA(書き換え可能な半導体)に書き込むと、 実際に動くハードウェアになります。チップを製造しなくても設計を即実機で試せます。

📝 Verilog コード
 ↓ 論理合成(Vivado / Quartus)
📦 ビットストリーム
 ↓ FPGA に書き込み
⚡ 実機で動作!
💡 活用例:カメラの画像処理・通信機器・AI アクセラレータ・宇宙探査機の制御回路
🧪 Path B — シミュレーション・ベンチマーク

実チップを作る前にテストベンチで動作検証したり、 新しいアーキテクチャのアイデアをシミュレーションで性能評価します。 研究では「このCPU設計は速いか?」を Verilog で試します。

📝 Verilog + テストベンチ
 ↓ シミュレータ(Icarus Verilog)
📊 波形・ログで動作確認
 ↓ 性能測定・バグ修正
✅ 設計の正しさを証明!
💡 活用例:CPU アーキテクチャ研究・新機能の性能予測・大学や企業の研究開発
📌 この授業では? EDA Playground を使って Path B(シミュレーション) を体験します。 テストベンチが全部パスしたとき、それが「正しい回路を設計できた」証明になります。

▶ EDA Playground で今すぐ試す

インストール不要のブラウザ上 Verilog シミュレータです。上のコードをコピーして動かしてみましょう。

⚙️ 推奨設定

  • Language : Verilog
  • Simulator : Icarus Verilog 12.0
  • 「Open EPWave after run」にチェック ✅(波形表示)
  • テストベンチ → 左パネル 設計コード → 右パネル

8. 次のステップ:Verilog 演習

ここまでの知識で、演習2の課題に挑戦できます。8ビット加算器 → 減算器 → ALU → 小型CPUの順で取り組みましょう。