一、无符号:
直接运算
二、有符号与无符号:
强制当作无符号运算
如c=a+b,a、b四位,c五位,计算时Verilog会将a和b扩展到五位再做加法,如果ab中有无符号数,则展宽会按照无符号数来,就是高位补0,因此有符号数结果将不正确。
解决:$signed(),c=a+$signed(b),扩展会按照有符号数的方式扩展,高位补符号位(1负,0正)。
三、乘法:
原码:原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。
如:八位数
[+1]原 = 0000 0001
[-1]原 = 1000 0001
反码:正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
补码:正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1。 (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
正负数相乘,负数要取补码
1、a与b均为正数
假设a=+5,b=+3
![](https://i-blog.csdnimg.cn/blog_migrate/d696e7a8a288cde4caa030f454213ce8.png)
直接相乘,然后用最高位补齐8位(标蓝色的为扩展的符号位),再相加。又因为正数的补码就是其本身,所以得到结果00001111,化为十进制就是+15,正确。
2、a为正数,b为负数
假设a=+5,b=-3,则a的补码为0101,b的补码为1101。
![](https://i-blog.csdnimg.cn/blog_migrate/267bab76f232dba1ecb10400fc0bc3fc.png)
3、a为负数,b为正数
![](https://i-blog.csdnimg.cn/blog_migrate/cfff8748ec4b6d6b4586c262661329bd.png)
4、a与b均为负数
![](https://i-blog.csdnimg.cn/blog_migrate/2ea424b5bde5754126cfc50d0ff65035.png)
先补再乘,补的是两个乘数,符号位乘乘数时,整体取反加一。