Verilog - 负数除法

Verilog - division with negative numbers

提问人:xyz 提问时间:11/6/2023 最后编辑:Mikefxyz 更新时间:11/10/2023 访问量:118

问:

module test;
    reg [3:0]a;
        initial 
        begin
            a= -4'b1100 / 6;
            $display(a);
        end
endmodule

为什么输出是 8?

我在 EDA playground 中尝试了这段代码,得到的输出为 8。
我无法理解它背后的逻辑。
请帮帮我

Verilog 事业部

评论


答:

0赞 dave_59 11/6/2023 #1

因为是一个无符号变量,所以它的值永远不会被视为负数。a

请参阅有符号二进制乘法和有符号二进制除法

0赞 Mikef 11/7/2023 #2

除法是Verilog中的上下文确定运算符。
这意味着操作数的大小和操作的有符号性(有符号或无符号)会根据 Verilog 的上下文确定规则进行修改。

对于已发布的代码,操作数被修改为 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 位结果使用有符号除法。