右側のサイズを変更するVerilog
私は何かを示すために次のような基本的なモジュールを持っています。
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;
これは私の疑いが正しいことを確認します。だから、私はそのような解決策を持っています、はい。しかし、私はそれについてはあまり満足していません。そのような行動を防ぐ方法があるはずだと思います。
どんな助けでもいただければ幸いです。
回答
異なる幅が混在するオペランドがある場合、Verilogには、式のコンテキストに基づいて、各オペランドを最大のオペランドの幅にサイズ変更するためのルールがあります。LHSは4ビットであり、RHSのオペランドは4ビットに拡張されることに正しく注意してください。これは、操作を適用する前に発生します。
連結のオペランドが自己決定コンテキストであるという事実を利用することで、これを修正できます。
{E, C} = U + {~T} + 1'b1;
現在、の幅はの幅~T
によってのみ決定されT
ます。