補足 - 符号付き変数
符号付きの変数・定数: (1) 関数 $signed( )で囲った変数や定数 (例:$signed(b), $signed(4'd1)) (2) 宣言にsigned がついている変数 (例:reg signed[15:0] a) (3) 基数にsがついている定数 (例:4'sd1, 4'sb0001) (4) 基数がない定数 (例:1,10) |
符号付きと符号なしの違いは解釈が変わるだけで、ビットパターン自体は同じものである。
すなわち最上位ビット(MSB)が1のとき、符号付きならば負数、符号なしならば正数と解釈される。
例) ビットパターン1111は符号付きならば-1、符号なしならば15
したがって、符号付き定数はMSBが1だと負数になって紛らわしいので、MSBが0(正数)になるように書いた方がよい。
例) 1'sb1と書くと+1ではなく-1、2'sd1と書いた方がよい。
◇
加減算のとき、符号付きなら符号拡張、符号なしならゼロ拡張されるので結果のビットパターンが異なる。
例)同符号の加算のときビットパターンは同じ
符号なし 1111 + 1000 はゼロ拡張して 01111 + 01000 = 10111 (15 + 8 = 23)
符号付き 1111 + 1000 は符号拡張して 11111 + 11000 = 10111 (-1 + -8 = -9)
例)異符号の加算のときビットパターンは異なる
符号なし 1111 + 0001 はゼロ拡張して 01111 + 00001= 10000 (15 + 1 = 16)
符号付き 1111 + 0001 は符号拡張して 11111 + 00001= 00000 (-1 + 1 = 0)
◇◇
乗算も加減算の繰り返しなので、符号付きかなしかで結果のビットパターンが異なる。
例)乗算
符号なし 1111 * 1000 = 01111000 (15 * 8 = 120)
符号付き 1111 * 1000 = 00001000 (-1 * -8 = 8)
◇◇◇
次のケースは、符号付き変数が符号なし変数とみなされるので注意。
(1) 演算のオペランドに1つでも符号なしがあると他のオペランドも符号なしとみなされる
例)reg signed[7:0] a; に対して、a+1'b1と書くとaも符号なしとみなされる
(2) ビット範囲を指定すると符号なしとみなされる(全ビット幅を指定してもだめ)
例)reg signed[7:0] a; に対して、aは符号付きだがa[7:0]と書くと符号なしとみなされる
(3) 連結は符号なしとみなされる
例)reg signed[9:0] a; reg signed[7:0] b;に対して{a,b}は符号なしとみなされる