Verilog 4-to-1マルチプレクサ:assign文とcase文の2つの実装比較
マルチプレクサ(MUX)とは
マルチプレクサは、N個の入力から選択信号selに基づいて1つを出力に通す組み合わせ回路です。4:1 MUXでは、2ビットのselで4つの入力(a, b, c, d)から1つを選択します。
選択真理値表
| sel | 選択入力 | 出力 |
|---|---|---|
| 00 | a | a |
| 01 | b | b |
| 10 | c | c |
| 11 | d | d |
実装方法1:assign文(継続代入)
ネストした条件演算子(?:)で記述。組み合わせ回路として最もシンプルで、合成結果も最適化されやすい形式です。
module mux_4to1_assign (
input [3:0] a, b, c, d,
input [1:0] sel,
output [3:0] out
);
// sel[1]で上位2組/下位2組を選び、sel[0]で最終選択
assign out = sel[1] ? (sel[0] ? d : c) : (sel[0] ? b : a);
endmodule
assign文の特徴
- 継続代入なので
outはwire型(output wire) - 感度リスト不要、入力変化で自動再評価
- 組み合わせ回路記述に最適、ラッチ生成リスクなし
実装方法2:case文(手続き的代入)
alwaysブロック内でcase文を使用。outはreg型で宣言必要。
module mux_4to1_case (
input [3:0] a, b, c, d,
input [1:0] sel,
output reg [3:0] out
);
always @(a or b or c or d or sel) begin
case (sel)
2'b00: out <= a;
2'b01: out <= b;
2'b10: out <= c;
2'b11: out <= d;
endcase
end
endmodule
case文の特徴
- 手続き的代入なので
outはreg型 - 感度リストに全入力を明記(
always @(*)推奨) - 複雑な条件分岐やデフォルト処理が書きやすい
- 全ケース網羅でないとラッチ生成のリスク(ここでは全網羅済み)
ハードウェア回路図(両実装共通)
論理合成後は同一のゲートレベルネットリスト(4入力マルチプレクサツリー)になります。
テストベンチ
module tb_4to1_mux;
reg [3:0] a, b, c, d;
wire [3:0] out;
reg [1:0] sel;
integer i;
// case文版をインスタンス化
mux_4to1_case mux0 (
.a(a), .b(b), .c(c), .d(d),
.sel(sel), .out(out)
);
initial begin
$monitor("[%0t] sel=0x%0h a=0x%0h b=0x%0h c=0x%0h d=0x%0h out=0x%0h",
$time, sel, a, b, c, d, out);
sel <= 0;
a <= $random; b <= $random; c <= $random; d <= $random;
for (i = 1; i < 4; i = i + 1)
#5 sel <= i;
#5 $finish;
end
endmodule
シミュレーション結果
ncsim> run [0] sel=0x0 a=0x4 b=0x1 c=0x9 d=0x3 out=0x4 // a選択 [5] sel=0x1 a=0x4 b=0x1 c=0x9 d=0x3 out=0x1 // b選択 [10] sel=0x2 a=0x4 b=0x1 c=0x9 d=0x3 out=0x9 // c選択 [15] sel=0x3 a=0x4 b=0x1 c=0x9 d=0x3 out=0x3 // d選択 Simulation complete via $finish(1) at time 20 NS + 0
波形確認
assign文 vs case文:どちらを使うべきか
| 観点 | assign文 | case文 |
|---|---|---|
| 記述量 | 短い(1行) | やや長い |
| 可読性 | 単純な選択なら良い | 複雑な条件で優位 |
| デフォルト処理 | ネスト深くなりがち | defaultで明示的 |
| デバッグ | 波形で中間値見えにくい | ブレークポイント設定可 |
| 合成結果 | 同等 | 同等 |
推奨プラクティス
- 単純な2:1, 4:1 MUX → assign文
- 複雑な選択ロジック、優先度付き、デフォルト値必要 → case文
- SystemVerilogなら
always_combとcase、またはassignと?:の使い分け - パラメータ化して汎用MUXモジュールとしてライブラリ化すると再利用性向上
Verilog
- Verilogマスター:デジタル回路設計のための完全チュートリアル
- Verilog連結マスター:実践ガイド
- Verilog代入文の理解:種類、構文、ベストプラクティス
- Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
- Verilog関数のマスター:効率的なRTL設計のために
- Verilogタスクの理解:関数との違い、構文、使用法
- Verilogクロックジェネレータ:設計と実装ガイド
- Verilog数学関数のマスター:効率的なハードウェア設計のために
- Verilog $timeformatのマスター:精度と表示制御
- 任意のスコープでのVerilog timescale理解と表示
- VerilogファイルI/Oの完全ガイド:オープン、読み取り、書き込み、クローズ