右側のサイズを変更するVerilog

Jan 14 2021

私は何かを示すために次のような基本的なモジュールを持っています。

module tb();

reg [2:0] U;
reg [2:0] T;
reg [2:0] C;
reg E;

initial begin

    U = 5;
    T = 3;
    {E, C} = U + ~T + 1'b1;
    #1000;

end

endmodule

私が期待しているのは、Eが1であるということです。

U です 101

T です 011

そしてU + ~T + 001

   101
   100
   001
+______
= 1010 

したがって、Cは010部分を取得し、Eは1を取得します。これは予想される動作ですが、Cは同じですが、Eは0です。左側が4ビットであるため、verilogはRHS変数のサイズを4ビットに増やしていると思います( 1 + 3)。ただし、Tの場合、Tを補完する前に先行0を追加するため、Tは0011になり、その補完は、T補完の4ビットバージョンである0100ではなく1100になります。

そしてこれは、

   0101
   1100
   0001
+______
= 10010 

これにより、Eは0になります。

これがなぜそうなのか理解できず、先行ゼロを追加する前に補完を実現する方法を見つけることができませんでした。

代わりに次のことを行うと、正常に動作し、Eは1を取得します。

    U = 5;
    T = 3;
    T = ~T;
    {E, C} = U + T + 1'b1;

これは私の疑いが正しいことを確認します。だから、私はそのような解決策を持っています、はい。しかし、私はそれについてはあまり満足していません。そのような行動を防ぐ方法があるはずだと思います。

どんな助けでもいただければ幸いです。

回答

3 dave_59 Jan 14 2021 at 05:55

異なる幅が混在するオペランドがある場合、Verilogには、式のコンテキストに基づいて、各オペランドを最大のオペランドの幅にサイズ変更するためのルールがあります。LHSは4ビットであり、RHSのオペランドは4ビットに拡張されることに正しく注意してください。これは、操作を適用する前に発生します。

連結のオペランドが自己決定コンテキストであるという事実を利用することで、これを修正できます。

{E, C} = U + {~T} + 1'b1;

現在、の幅はの幅~Tによってのみ決定されTます。