Verilog case文の理解:効率的なマルチプレクサ実装
case文は、与えられた式がリスト内の他の式のいずれかと一致するかどうかをチェックし、それに応じて分岐します。通常、マルチプレクサの実装に使用されます。条件が多い場合、if-else構造は適さず、マルチプレクサではなくプライオリティエンコーダに合成されてしまいます。
構文
Verilogのcase文はcaseキーワードで始まり、endcaseキーワードで終わります。括弧内の式は正確に1回評価され、記述順に代替案のリストと比較され、与えられた式と一致する代替案の文が実行されます。複数の文のブロックはbeginとendでグループ化する必要があります。
// 'expression'は項目(item 1,2,3,4)のいずれかと一致する必要がある
case (<expression>)
case_item1 : <単一の文>
case_item2, case_item3 : <単一の文>
case_item4 : begin
<複数の文>
end
default : <文>
endcase
どのcase項目も与えられた式と一致しない場合、default項目の文が実行されます。default文は省略可能で、case文内に1つだけ記述できます。case文はネスト可能です。
どの項目も式と一致せず、default文もない場合、caseブロックを何もしないで抜けます。
例
以下の設計モジュールは、2ビットの選択信号を持ち、他の3つの3ビット入力のいずれかを出力信号outにルーティングします。case文を使用して、selの値に基づいて正しい入力を出力に代入します。selは2ビット信号なので、22通りの組み合わせ、0から3を取り得ます。default文はselが3の場合に出力を0に設定するのに役立ちます。
module my_mux (
input [2:0] a, b, c, // 3つの3ビット入力
[1:0] sel, // a,b,cから選択する2ビット選択信号
output reg [2:0] out // 出力3ビット信号
);
// このalwaysブロックはa,b,c,selのいずれかが値を変えると実行される
always @ (a, b, c, sel) begin
case(sel)
2'b00 : out = a; // sel=0なら出力はa
2'b01 : out = b; // sel=1なら出力はb
2'b10 : out = c; // sel=2なら出力はc
default : out = 0; // selがそれ以外なら出力は常に0
endcase
end
endmodule
ハードウェア回路図
RTLコードを展開して、4対1マルチプレクサを表すハードウェア回路図を取得します。
selが3のとき出力がゼロになり、他の値では対応する入力が割り当てられていることがわかります。
ncsim> run [0] a=0x4 b=0x1 c=0x1 sel=0b11 out=0x0 [10] a=0x5 b=0x5 c=0x5 sel=0b10 out=0x5 [20] a=0x1 b=0x5 c=0x6 sel=0b01 out=0x5 [30] a=0x5 b=0x4 c=0x1 sel=0b10 out=0x1 [40] a=0x5 b=0x2 c=0x5 sel=0b11 out=0x0 ncsim: *W,RNQUIE: Simulation is complete.
case文では、式の各ビットが代替案の0、1、x、zを含めて一致する場合にのみ比較が成功します。上記の例では、selのいずれかのビットがxまたはzの場合、他の代替案のいずれも一致しないためdefault文が実行され、出力はすべてゼロになります。
ncsim> run [0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x0 [10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x0 [20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x0 [30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x0 [40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x0 [50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x0 [60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x0 [70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0 [80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x0 [90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x0 ncsim: *W,RNQUIE: Simulation is complete.
設計のcase文にxとzがcase項目の代替案に含まれている場合、結果はかなり異なります。
module my_mux (
input [2:0] a, b, c,
[1:0] sel,
output reg [2:0] out
);
// case項目にxとzがあり、selが正確な値と一致する場合にのみ
// 対応する入力で出力が代入される
always @ (a, b, c, sel) begin
case(sel)
2'bxz : out = a;
2'bzx : out = b;
2'bxx : out = c;
default : out = 0;
endcase
end
endmodule
ncsim> run [0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x1 [10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x5 [20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x1 [30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x6 [40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x5 [50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x6 [60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x7 [70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0 [80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x4 [90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x5 ncsim: *W,RNQUIE: Simulation is complete.
case文とif-elseの違い
case文はif-else-ifと以下の2点で異なります:
if-elseブロックの式はより汎用的ですが、caseブロックでは単一の式が複数の項目とマッチングされますcaseは、式にXとZの値がある場合に確定的な結果を提供します
Verilog
- C# switch 文をマスターする:構文、例、ベストプラクティス
- C# break 文:使い方とタイミングを徹底解説
- C# continue 文をマスターする:ループ反復を効果的にスキップする方法
- C++ switch文をマスター:構文、使い方、実践例
- Verilog基礎:最初のANDゲートを設計する
- Verilogマスター:デジタル回路設計のための完全チュートリアル
- Verilog連結マスター:実践ガイド
- Verilog代入文の理解:種類、構文、ベストプラクティス
- Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
- Verilog関数のマスター:効率的なRTL設計のために
- Verilogタスクの理解:関数との違い、構文、使用法