赞
踩
运用 算数左移符号 <<<,此时会将符号位填补在最低位上。
a = {{8{b[7]}},xin}; 即需要将符号位扩展。
无符号相减时,无论结果变量是否定义为有符号数,结果的二进制数值是完全一样的,本文做了如下实验:
module test(
input[7:0] a,
input[7:0] b,
output[7:0] a_b,
output signed[7:0] a_b_signed
);
assign a_b = a - b;
assign a_b_signed = a - b;
endmodule
当a b 取不同的值仿真结果如下:
由上图可知若都按16进制形式看数据,数值都是一致的。但当无符号数以无符号形式看,有符号数以有符号形式看时,结果不一致。
此处仅看无符号数结果,如下表:
a | b | a_b_signed |
---|---|---|
255 | 1 | -2 |
1 | 255 | 2 |
1 | 2 | -1 |
7 | 2 | 5 |
由上表可知,若将无符数相减,若位宽不变,直接视为有符号数,结果产生溢出导致计算结果不正确。因此,若无符号数减法运算可能产生负数时,需要保证结果的位宽比被减数和减数位宽的最大值大一位宽。 | ||
加一位宽后仿真结果如下,当两个结果均以有符号形式看时 | ||
由上图可知,两种方式计算结果均正确。因此可得出结论: |
1. 无符号数相减变有符号数时,首先需要保证结果的位宽比被减数和减数位宽的最大值大一位宽。
2. 结果变量是否有定义为signed对结果数据不会有影响。
module test(
input[7:0] a,
input[7:0] b,
output[8:0] a_b,
output signed[8:0] a_b_singed
);
assign a_b = a - b;
assign a_b_singed = $signed(a) - $signed(b);
endmodule
将无符号数转化为有符号数进行运算时,应当确保无符号数的最高位为0,若最高位不为零应当扩展一位0,否则会直接被视为负数进行运算。
示例代码如下,(可直接运行的仿真代码)
`timescale 1ns / 1ps module test(); reg signed[4:0] a_unsigned; reg signed[8:0] b_signed; reg signed[15:0] c_signed; reg clk; always #5 clk = ~clk; initial begin clk = 0; b_signed = -9'd7; #50 b_signed = -9'd100; #50 b_signed = -9'd128; #50 b_signed = 9'd100; end always @(posedge clk) begin a_unsigned <= b_signed; c_signed <= b_signed; end endmodule
仿真结果如下图所示:
因此可以得出结论:
1.当一个有符号数赋值给一个位宽更大的量时(无论结果量是否定义符号位),都会自动的在高位补充符号位;
2.当一个有符号数赋值给一个位宽更小的量时(无论结果量是否定义符号位),都只会截取低位的数据。
待续,,,
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。