8 / 37 · 概念
2 の補数・符号拡張・オーバーフロー
式と反例を使い、ビット列の signed 解釈と加算のオーバーフロー条件を区別します。
レッスンは無料で読めます。受講登録すると進捗を保存できます。
最上位ビットの重みが変わります
ビットの 2 の補数2 の補数 固定幅のビット列で符号付き整数を表す方式です。n ビットの範囲は −2^(n−1) から 2^(n−1)−1 です。整数は、次のように解釈します。
4 ビットの 1010 は unsignedunsigned ビット列を非負整数として解釈する規則です。n ビットの範囲は 0 から 2^n−1 で、同じビット列の signed 解釈と異なる場合があります。 詳しく見る で 10、signed で -6 です。符号ビットを除いた残りを絶対値として読む方式ではありません。固定幅で を作るにはビット否定否定 0 を 1 に、1 を 0 に変える NOT 演算です。式の上の線は、その下の式全体に NOT を適用することを表します。 詳しく見る後に 1 を加えますが、最小値 -8 に対応する正の +8 は同じ 4 ビット signed の範囲外です。
拡張は値を保存しなければなりません
unsigned の拡張では上位に 0、signed の拡張では元の符号ビットを埋めます。1010 を 00001010 にすれば +10、11111010 にすれば -6 です。同じビットを広げても、解釈が違えば必要な回路が異なります。
logic signed [3:0] a, b;
logic signed [4:0] exact;
logic [3:0] result;
logic overflow;
assign exact = {a[3], a} + {b[3], b};
assign result = exact[3:0];
assign overflow = (a[3] == b[3]) && (result[3] != a[3]);この例はキャリー入力のない二オペランドの符号付き加算です。exact に 5 ビットの和を保存し、幅を狭めた結果の符号が正しいか検査します。
初期値を 11111010 にしています。unsigned の 250 と signed の −6 が同じビット列であることを確認してください。b7 を変えると、二つの解釈で値が逆方向に変わります。
11111010 → unsigned 250 · signed -6 · hex 0xFA
キャリーと符号付きオーバーフローは異なります
同じ符号同士を足して結果の符号が変われば、オーバーフローです。4 ビットで は 1010 として格納され -6 に見え、 は 0111 として格納され +7 に見えます。異なる符号の二数の加算では、この範囲超過は発生しません。
signed と unsigned を混ぜた RTL 式は、比較・拡張規則を混乱させやすくなります。両オペランドの幅と符号属性を明示し、最小値・-1・0・最大値を境界テストに含めてください。
自分で考えてみましょう
4 ビット signed で と の格納ビット列とオーバーフローを求めてください。 の符号を反転した結果も説明してください。
解説を見る
は 1001 で、オーバーフローはありません。10 は範囲外で 1010(-6)として格納されるため、オーバーフローです。-8 をビット反転して 1 を加えると、再び 1000 が残ります。+8 を表せないためで、これを正しい絶対値計算として使ってはいけません。