提问人:xyz 提问时间:11/6/2023 最后编辑:Mikefxyz 更新时间:11/10/2023 访问量:118
Verilog - 负数除法
Verilog - division with negative numbers
问:
module test;
reg [3:0]a;
initial
begin
a= -4'b1100 / 6;
$display(a);
end
endmodule
为什么输出是 8?
我在 EDA playground 中尝试了这段代码,得到的输出为 8。
我无法理解它背后的逻辑。
请帮帮我
答:
因为是一个无符号变量,所以它的值永远不会被视为负数。a
请参阅有符号二进制乘法和有符号二进制除法
除法是Verilog中的上下文确定运算符。
这意味着操作数的大小和操作的有符号性(有符号或无符号)会根据 Verilog 的上下文确定规则进行修改。
看
IEEE 1800-2017 第 11.8 节表达式评估规则
萨瑟兰·戈萨斯幻灯片 14-16
对于已发布的代码,操作数被修改为 32 位,并且执行除法运算,就好像操作数是无符号的一样。
数字 6 是无符号的 Verilog 文本,它会导致所有操作数扩展到 32 位,并将 RHS 上的操作视为无符号。
如果任何运算符是无符号的,则执行的操作是无符号的。
帖子的 LHS 已经未签名,因此帖子中的所有内容都是未签名的(一元减号除外)。
分子将零扩展到 32 位 0000_0000_0000_0000 0000_0000_
0000_1100
然后一元减号取 2 的补码 1111_1111_1111_1111
1111_1111_1111_0011
这是十六进制ffff_fff3
Verilog 还将 LHS 的内部表示扩展到 32 位。
要了解它是如何工作的,让我们获取已发布的代码并更改操作数
显式地按照 Verilog 更改它们的方式(32 位,无符号)进行操作。
让我们将 32 位值显示为二进制和十进制。
module test;
reg [31:0] a;
initial
begin
a= 32'hffff_fff3 / 32'd6;
$display("%b, %d", a, a[3:0]);
end
endmodule
生产
00101010101010101010101010101000, 8
为什么输出是 8?
值 8 是 LHS(变量 a)的 4 LSB,由于 LHS 只有 4 位,因此在发布的代码中,前 28 位被截断。
让我们重新编写这篇文章,通过将所有操作数更改为 4 位有符号除法来执行一些 4 位有符号除法的示例
module test;
reg signed [3:0] a;
initial
begin
// minus 4 divided by 6 = 0
a= 4'sb1100 / 4'sd6;
$display("%b, %d", a, a);
//
// minus 4 divided by 1 = -4
a= 4'sb1100 / 4'sd1;
$display("%b, %d", a, a);
//
// minus 4 divided by 2 = -2
a= 4'sb1100 / 4'sd2;
$display("%b, %d", a, a);
end
endmodule
生产
0000, 0
1100, -4
1110, -2
这似乎是这篇文章的意图:
4 位操作数,4 位结果使用有符号除法。
评论