単純な条件式はif文より3項演算子を使った方がよいという話 Verilog

はじめに

RTLで、単純な条件式はif文ではなく3項演算子を使用した方がよいという話をどこかで聞いたが
なぜだかわからなかったため、調べてみました。

3項演算子の方が実機での動作に近いから、ということかなと思いました。

ifの条件式と3項演算子

if文で下記のような条件式を書くとき、

if (sel) begin
<式1>
else begin
<式2>
end

3項演算子では下記のようになると思います。

sel ? <式1> : <式2>;

しかし、両者は動作が異なります。

selにx、zが入ったとき、if文ではelse項に行きますが、

3項演算子では、<式1>, <式2>がマルチアサインされます。

実機では不定がないので0 or 1です。つまり真偽どちらになるかわかりません。

なので、必ずelse項が評価されるif文より、マルチアサインとなり場合によっては不定が伝播する3項演算子の方が実機とシミュレーションで整合性が高いと思われます。

不定が伝播していることがシミュレーションの波形上で分かり、RTLを修正することができます。

動作確認

if文

tb.sv
module tb;
    bit clk = 0;
    always #5 clk = ~clk;

    logic sel;
    logic [5:0] sig;
    always_comb begin
        if (sel) begin
            sig = 6'b10z001;
        end
        else begin
            sig = 6'b10z1zz;
        end
    end

    initial begin
        sel = 1'b0;
        @(posedge clk);
        $display("%b", sig);

        sel = 1'b1;
        @(posedge clk);
        $display("%b", sig);

        sel = 1'bz;
        @(posedge clk);
        $display("%b", sig);

        $finish;
    end
endmodule
出力

selが0, 1のときは、真偽の値がそのままsigに代入されています。

selがzのときは、else項に入りselが0のときと同じ値がsigに代入されています。

sel: 0 sig: 10z1zz
sel: 1 sig: 10z001
sel: z sig: 10z1zz

3項演算子

tb.sv
module tb;
    bit clk = 0;
    always #5 clk = ~clk;

    logic sel;
    logic [5:0] sig;
    assign sig = sel ? 6'b10z001 : 6'b10z1zz;

    initial begin
        sel = 1'b0;
        @(posedge clk);
        $display("%b", sig);

        sel = 1'b1;
        @(posedge clk);
        $display("%b", sig);

        sel = 1'bz;
        @(posedge clk);
        $display("%b", sig);

        $finish;
    end
endmodule
出力

selが0, 1のときは、真偽の値がそのままsigに代入されています。

selがzのときは、
5ビット目は真偽で両方1のため1、
4ビット目は真偽で両方0のため0、
3ビット目は真偽でどちらかがzのためx
2、1、0ビット目は真偽で異なる値のためxになっています。

sel: 0 sig: 10z1zz
sel: 1 sig: 10z001
sel: z sig: 10xxxx

まとめ

3項演算子の動作について調査しました。

コメント

タイトルとURLをコピーしました