grace8WordPress主题/seo最新
有符号和无符号数
在电路设计中肯定会使用到有符号数无符号数的运算,今天简单说说具体怎么使用有符号数无符号数进行运算,这里以减法为例。
我们知道计算机运算都是以二进制的形式进行的,不过遇到负数,通常用二进制补码来表示。如下代码,我们需要计算 a - b 的值
`timescale 1ns/1ps
module signed_num (input [15:0] a ,input [15:0] b ,output [16:0] out0 ,output [16:0] out1 ,output [16:0] out2
);assign out0 = {a[15], a} - {b[15], b};assign out1 = a - b;assign out2 = $signed(a) - $signed(b);endmodule
首先介绍一下out0, out1 out2是分别如何运算的:
1、out0, 我们手动补符号位,a[15]是a的最高位即符号位,b[15]同样;
2、out1,我们等着计算机帮我们自动补符号位,默认全部补0;
3、out2, 我们使用系统函数$signed()补充符号位,默认正数补0,负数补1。使用signed定义的类型,做加法或乘法时,对操作数扩位处理时高位补符号位;即负数补1,正数补0;不使用signed的无符号类型,高位默认补0。
我们知道在位宽不匹配时候,计算机会帮我们自动扩展符号位,不过计算机默认全部扩展符号位为0,也就是对于正数运算是不会出现问题,因为确实需要扩展0,所以计算结果不会出错,如下计算 16‘h0001 - 16’h0005
但是如果计算16‘h0001 - 16’hfffb 即(1-(-5)= 6)就会出现错误。这里顺便说一下计算-5的补码,即对正数的原码取反加一,16‘b0000_0000_0000_0101取反加一16’h1111_1111_1111_1011,在做运算时候补符号位1,即为17‘h1fffb’如下:
那么计算机是怎样运算16’h0001 - 16’hfffb的呢?
首先补符号位17’h00001 - 17’h1fffb,所以计算结果就是1 - (-5) = 6。
可以看到out1计算结果不正确,这就说明计算机补的符号位为0,但是我们是有符号数,应该扩展符号位为1。
结论
在做有符号数运算时候,直接采用系统函数$signed()最为方便,不需要我们手动扩展符号位。