2 / 24 · 概念
ビット幅、符号拡張、オーバーフロー
数値例を用いて、解釈、拡張、ビット幅の縮小を区別します。
レッスンは無料で読めます。受講登録すると進捗を保存できます。
ビットパターンとその意味を分ける
8ビットのパターン1111_1101は、符号なしでは253、符号付き2の補数では-3を表します。格納されるビットは同じでも、比較と拡張の方法は異なります。8ビット符号付き値の範囲は-128から127、符号なし値の範囲は0から255です。ビット幅は表現可能なパターンの数を決め、符号の有無はその数値的な解釈を決めます。
符号なし253を16ビットに移す際はゼロ拡張します。-3は元の最上位ビットを繰り返して符号拡張し、1111_1111_1111_1101にします。ゼロ拡張すると-3が253に変わります。SystemVerilogでは計算前にオペランドの型とビット幅を明示してください。連結や部分選択が意図した符号付き解釈を保持するとは限りません。
logic [7:0] ua, ub;
logic [8:0] usum;
logic signed [7:0] sa, sb;
logic signed [8:0] sax, sbx, ssum;
assign usum = {1'b0, ua} + {1'b0, ub};
assign sax = {sa[7], sa};
assign sbx = {sb[7], sb};
assign ssum = sax + sbx;ここでは加算前に両入力を9ビットにします。符号なし255+1は256となり、下位8ビットではゼロになります。符号付き127+1も数学的には128ですが、符号付き8ビットに縮小すると-128になります。キャリーは符号なし範囲の境界を、符号付きオーバーフローは符号付き範囲の境界を示します。同符号のオペランドを加算し、結果の符号が変わった場合は符号付きオーバーフローです。-1と1の加算では、符号付きオーバーフローなしにキャリーが生じることがあります。
中間値のビット幅も計画します。符号なし8ビット同士の最大積は65025で、16ビットが必要です。符号なし8ビット値4個の和は1020になり得るので、10ビットが必要です。部分和を毎回8ビットに切り詰めると、最後のレジスタを広げても失われた情報を取り戻せません。
| 演算 | 広いビット幅での結果 | 縮小後の解釈 |
|---|---|---|
| 符号なし255+1 | 256 | 0、キャリーあり |
| 符号付き127+1 | 128 | -128、オーバーフローあり |
| 符号付き-3+2 | -1 | -1、オーバーフローなし |
意図しないビット幅の変化はVerilatorのWIDTH警告で調べてください。このコースのNodeによる検査は数値モデルを実行するもので、このHDL断片を実行するものではありません。よくある正の値の例だけで正しさを判断せず、ゼロ、極値、正負の混在をテストしてください。
自分で考えてみましょう
8ビットの-3と2を9ビットに符号拡張して加算した結果を求めてください。また、符号なし255を4個加算した正確な和に必要な最小ビット幅を求めてください。
解説を見る
9ビットのオペランドは111111101と000000010です。和は111111111、つまり-1です。255を4個足すと1020です。符号なし9ビットの上限は511なので、10ビットが必要です。