乘以两个无符号数乘以两个有符号数时乘法结果有什么区别?
将两个有符号数除以两个无符号数时,余数和商之间有什么区别?
答案 0 :(得分:0)
一个例子可能很有启发性。
module top;
reg [3:0] a;
reg [3:0] b;
reg [7:0] r1;
reg [7:0] r2;
initial begin
a = 4'hc;
b = 4'h5;
r1 = a * b; // 12 * 5
r2 = $signed(a) * $signed(b); //-4 * 5
$display("r1 = %b", r1);
$display("r2 = %b", r2);
end
endmodule
结果:
r1 = 00111100 (60)
r2 = 11101100 (-20)
不同之处在于,有符号数字使用向量的MSB作为符号的指示符(请参阅here,实际上没有,请阅读此内容),将可表达数字的范围从[0..2^n-1]
转移到{{ 1}}
有几点需要注意:
[-2^(n-1)..2^(n-1)-1]
或reg signed [3:0] foo
系统任务。如果您要将子表达式视为已签名,则后者通常很有用。例如,即使原始var已签名,取一个向量的位片也始终是无符号的。为了Verilog的行为,除非处理2的严格权力通常不是可合成的,否则行为除法基本相同。
答案 1 :(得分:0)
基于Brian的例子,有点不同的观点
verilog中的有符号vs无符号算法会导致符号传播和关系运算的差异。如果不涉及符号扩展,则对2补码数据的常规算术会产生相同的有符号和无符号结果
所以在这种情况下,如果r1和r2的大小为'4'(作为操作数),你会得到相同的结果:
r1 = 1100 was (60)
r2 = 1100 was (-20)
在Brian的案例中,表达式的结果大小为8; Verilog将扩展您的操作数以占用8位空间。如果签名'a',它会唱歌延长它,这将产生差异:
unsigned a[3:0] <1100> --> tmp[7:0] --> 00001100
signed a[3:0] <1100> --> tmp[7:0] --> 11111100
因此,如果[3]为“1”,则将其视为符号并将符号提升到左侧。现在,您的算术如下所示:
unsigned: tmpa(00001100) * tmpb(00000101) --> 00111100
signed: tmpa(11111100) * tmpb(00000101) --> 11101100
当您将第二个结果显示为整数时,它将被符号扩展为32位并显示为(-20)