对verilog中有符号数和无符号数的理解
verilog中使用signed表示有符号数,比如:
wire signed [7:0] din;
assign din = -8'd1;
虽然书写上din等于十进制的 -1 ,但是在编译器会自动将din编译成补码的形式保存
所以虽然书写上可以将一个信号写成负数的形式,但是在电路中并不存在真正的负数,负数只会被转换为补码的形式进行运算。
如果撇去signed类型不谈。我们依旧可以将reg或者wire类型的数据看作有符号或者无符号的。如果看作有符号的,那么就是补码的形式,如果看作无符号的,就是源码的形式。比如1111如果看作无符号的就是7,如果看作有符号的就是-1。
对于两个无符号数,什么时候相加会出现错误(溢出)的情况呢?
reg [7:0] din1;
reg [7:0] din2;
wire [7:0] dout;
wire ov;
{ov,dout} = din1 + din2;
很明显,如果ov的值为1的话,就说明发生了溢出,即出错了。
对于两个有符号数,什么时候相加会出现错误呢?
reg [7:0] din1;
reg [7:0] din2;
wire [7:0] dout;
wire ov;
assign dout = din1 + din2;
assign ov = ((~dout[7]) & din1[7] & din2[7]) | (dout[7] & (~din1[7]) & (~din2[7]));
这里将din1和din2都看作有符号数(即使用了补码的形式,表示的取值范围在-128-127之间)。那么当两个整数相加结果却为负数,或者两个负数相加结果却为正数的时候就说明结果出错了,即ov等于1的时候结果就出错了。
比如1001是-7,1110是-2,1001+1110 = 10111,取后四位的话就是7,明显错了。
1110是-2,1101是-3,1110 + 1101 = 11011,取后四位就是-5,结果就对了。
当然如果加上溢出位的话,那么结果就都是对的了。