首先我们知道,有符号数的运算全都是补码的方式。
在Verilog里面,可以使用有符号数据进行运算,定义时使用signed,例如
reg signed[7:0] data; //定义了一个reg型有符号8位变量 adder
在Verilog中数据是已补码形式存在的,正数的补码是他本身,负数的补码是除符号位取反加一,
上边定义的data赋值为-3,则-3的二进制为1000 0011,这个叫原码,其补码为1111 1101,data中真实存储的是1111 1101(补码)。
在运算的过程中也是使用补码的。那为什么我们在testbench中输出该值的时候(默认十进制)仍然显示的是-3呢,个人觉得是因为在显示的过程中,IDE做好了补码到原码的转换。
在寄存器里面存储的数据是1111 1101,按照有符号十进制显示是-3,按照无符号显示是253,按照十六进制显示FD,当然,按照二进制显示是1111 1101。
所以,无论是-3、253还是FD,对应的二进制都是1111 1101,只不过显示格式不同,那系统是怎么知道一个8位寄存器中1111 1101这个二进制表示的是-3还是253呢,这就是定义该寄存器时使用signed的作用了,signed表示有符号,此时的1111 1101表示的是-3,若是没有signed,则默认是无符号类型,那么此时的1111 1101表示的就是253。
另外,有符号数1000 0000表示的-128(比较特殊,不能用原码补码概念来理解,记住就好),所以8位寄存器表示的数据范围是-128~0~127,共256个数。无符号8位表示的数据范围是0~255,也是256个数。