Ryuz's tech blog

FPGAなどの技術ブログ

Verilog の演算時の幅拡張でしくじった話

なにが起きたのか

下記のようなシーンで何やら Verilator が

Operator NOT expects 5 bits on the LHS, but LHS's VARREF 'b' generates 4 bits.

というワーニングを出してきた。

    logic  [3:0]  a;
    logic  [3:0]  b;
    logic  [4:0]  c;
    assign c = a + ~b;

4bit同士の加算を5bit に入れるので何の問題も無かろうと思っていたら、問題ありありだったという話です。

どういうことか

下記のようなコードだと少しわかりやすいかと思います。

    logic  [3:0]  a = '0;
    logic  [3:0]  b = '1;
    logic  [4:0]  c;
    initial begin
        c = a + ~b;
        $display("a + ~b : 0x%x", a + ~b);
        $display("c      : 0x%x", c     );
    end

結果は

a + ~b : 0x0
c      : 0x10

となります。

何が起こっているかというと 4'b1111 が、先に式の幅である 5'b01111 に幅拡張されて、その後にビット反転されて 5'b10000 となって加算されていました。

b は オール 1 にしているのだから bit 反転させれば 0 だろうと安直に考えてしまいそうですが、そうはならないという事です。でもちゃんと Verilator の lint は教えてくれるので偉いなと思いました。