【问题标题】:How does Verilog behave with negative numbers?Verilog 如何处理负数?
【发布时间】:2012-09-13 05:33:39
【问题描述】:

例如,假设我有一个reg [7:0] myReg 我给它赋值-8'D69

我知道 Verilog 将它存储为 2 的补码,因此它应该存储为

10111011

我现在的问题是我是否要对其执行操作,比如 myReg/2

它会评估为 -34 吗?还是把 10111011 变成 187 然后除法,返回 93?

【问题讨论】:

  • 你也应该这样声明带符号的数字。 reg signed [7:0] my_reg
  • 您可以使用 >>> 1 执行符号扩展除以 2。(如果它被声明为有符号类型)。

标签: verilog negative-number


【解决方案1】:

您需要记住-8d69 只是一个位模式。 reg 是一种保存位模式的类型。它是指示/ 执行有符号或无符号运算的变量类型。

如果这是为了综合考虑你想尽量避免使用分隔符,你真的想尝试避免有符号的分隔符。它可能会用>>> 1 合成更小

reg [7:0] a;
reg signed [7:0] b;
reg [7:0] c;
reg signed [7:0] d;

initial begin
  a =  -8'd69 ;
  b =  -8'd69 ;
  c =  -8'd69 ;
  d =  -8'd69 ;
  #10ns;
  a = a/2     ;
  b = b/2     ;
  #10ns;
  $display("a      : %8b, %d", a, a);
  $display("b      : %8b, %d", b, b);
  $display("c >>>1 : %8b, %d", c>>>1, c>>>1);
  $display("d >>>1 : %8b, %d", d>>>1, d>>>1);
end

给予:

a      : 01011101,  93
b      : 11011110,  -34 
c >>>1 : 01011101,  93
d >>>1 : 11011101,  -35

>> x 右移 x 位,>>> x 右移 x 位,但符号扩展为有符号类型。

注意:在我的示例中,/2 也向上舍入,>>> 将向下舍入/截断。

【讨论】:

    【解决方案2】:

    例如,假设我有一个 reg [7:0] myReg 我给它赋值 -8'D69

    这实际上不是一个有符号数,而是一个由应用于正常数的一元否定组成的表达式。如果表达式是-8'd130,结果会溢出。有符号常量声明为 8'sd69 或只是 69

    我现在的问题是,如果我要对其进行操作, 说 myReg/2

    myReg 是无符号的,因此表达式结果也将是无符号的*。如果您需要对结果进行签名,则必须对 all 操作数进行签名。有几种方法可以实现这一点:

    //Declare the reg as signed and divide by a signed value
    reg signed [7:0] myReg;
    assign result = myReg/2;
    
    //Use system functions
    assign result = $signed(myReg)/2;
    

    *关于表达式求值的完整规则要复杂得多,但基本上任何表达式的结果都是无符号的,除非所有操作数都有符号。

    reg signed [7:0] a;
    reg [7:0] b;
    
    initial
    begin
    result = a;            //Signed
    result = a * a;        //Signed
    result = a * 10;       //Signed
    result = $unsigned(a); //Unsigned
    result = a[0];         //Unsigned
    result = a[7:0];       //Unsigned
    result = {a,a};        //Unsigned
    result = 10{a};        //Unsigned
    result = a + b;        //Unsigned
    result = a * b;        //Unsigned
    end
    

    【讨论】:

      【解决方案3】:

      我会补充的 1. 默认情况下,数据类型 bit 和 reg 是无符号的。 2. 默认情况下,数据类型 int、integer、longint、shortint 和 byte 是有符号的。 3. 所有这些数据类型都可以使用有符号或无符号限定符来更改默认值。

      因此,将 -8'D69 分配给 myReg 会隐式转换为 187。然后,myReg/2 = 187/2 = 93,无符号。了解 SystemVerilog 何时以及如何在表达式和赋值中进行隐式类型转换非常重要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-10
        • 2014-01-23
        • 1970-01-01
        • 2022-11-26
        • 1970-01-01
        • 2019-04-06
        • 2018-01-28
        相关资源
        最近更新 更多