01signal.com

Verilog の符号付き演算:知っておくべき唯一のルール

大原則は、すべてのオペランドが符号付き(signed)でなければならない、ということです。

Verilog は、符号なし数(unsigned)に強く偏っているように思えます。次に挙げるものは、どれも 符号なし値を生成します。

つまり、結局のところ、$signed システム関数を使うか、符号付き wire と符号付きレジスタ(reg)を定義するかのどちらかです。

たとえば、符号付きレジスタと符号なしレジスタを乗算して、その結果を(当然のことながら)符号付き値として扱いたい場合は、次のようにします。

reg         [15:0] a; // Unsigned
reg signed  [15:0] b;
wire signed [16:0] signed_a;
wire signed [31:0] a_mult_b;

assign signed_a = a; // Convert to signed
assign a_mult_b = signed_a * b

ここで、signed_a のビット幅は a より 1 ビット広いことに注意してください。そのため、符号ビット用の場所があり、その符号ビットは常に 0 です。この追加ビットがなかったとすると、a の MSb(most significant bit=最上位ビット)が signed_a の符号ビットとして扱われていたでしょう。

ここで、signed_a の MSb を、単に a を使うのではなく、{1'b0, a} のようにして明示的に指定しなければならないと誤解してしまうかもしれません。しかし、Verilog 標準規格は、その数値が符号付きであるか符号なしであるかを決定するのは式だけであると明確に述べています。したがって、左辺はこの判定には影響しません。つまり、a は符号なし値として扱われ、ゼロ拡張されるのです。

このページは英語から機械翻訳されたものです。不明な点があれば、原文を参照してください。
Copyright © 2021-2026. All rights reserved. (dcc38493)