plplplpo 2024-05-06 14:51 采纳率: 0%
浏览 10

verilog位扩展规则

verilog标准 2005版 47页 有这样一个例子

img

关于intA=-4'd12,我个人的理解是这样的:

-4'd12用补码表示是(1)0100,最高位(符号位)被截断

如果把-4'd12看作一个unsigned常数,则应该用0扩展高位,即扩展成 0000_0000_0000_0100
如果把-4'd12看作一个signed的常数,-4’d12的符号位也因为宽度原因被截断了,实际的最高位(符号位)是0,也应该扩展成 0000_0000_0000_0100

可是根据注释来看,-4’d12 被扩展成了1111_1111_1111_0100,这是为什么呢?

  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-05-06 14:51
    关注

    引自免费微信小程序:皆我百晓生

    在Verilog 2005标准中,整型变量(integer类型)和有符号整型变量(signed类型的reg或wire)在处理时有一些特殊的规则。当将一个整型变量赋值给一个具有不同数据宽度的有符号或无符号整型变量时,会进行位扩展。

    对于intA = -4'd12; 这一行语句, -4'd12 是一个带符号的十进制整数常量,其二进制补码表示为 1111111111111101,因为 Verilog 规定负数的表示方式为补码,并且这个常量前面的 -4'd 指定了它是一个长度为4位的整数。

    由于 intA 是一个整型变量,它的长度没有指定,因此它会默认为最宽的整型,通常是32位。所以当 -4'd12 被赋值给 intA 时,按照 Verilog 的规定,整型变量的扩展是通过对最高有效位(MSB)进行零填充来进行的,因为 intA 是正数还是负数并不影响扩展方式。因此,-4'd12 在赋值给 intA 后,会被扩展为 00000000000000000000000001111101

    然后,当我们将 intA 的值除以3并赋给 regA 时,regA 是一个16位的无符号整数,所以再次发生位扩展。这里需要注意的是,在Verilog中,除法操作符 / 对于整数来说总是返回一个无符号整数值。由于 intA 是32位的,我们将其转换到16位时,会遵循与整型变量相同的扩展策略,即对最高有效位进行零填充。所以 intA 的值会被扩展为 00000000000000000000000001111101,然后再除以3得到 00000000000000000000000000111111,即十六进制的 65532。

    如果你想要确保结果为有符号整数,你需要显式地转换 intAregS,这是一个16位的有符号整数,这样在扩展时会保持符号信息:

    integer intA;
    reg [15: 0] regA;
    reg signed [15: 0] regS;
    
    intA = -4'd12;
    regA = intA / 3; // expression result is 65532
    regS = $signed(intA) / 3; // expression result will be correct as a signed value
    

    在这个版本中,$signed 函数用于将 intA 的值解释为有符号整数,然后进行除法运算。这将正确地保留符号信息,得到正确的表达式结果。注意,这样做可能会导致溢出错误,因为在有符号和无符号之间的转换过程中可能丢失符号信息。在实际设计中,应当谨慎处理这些转换,以防止意外的行为。

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 5月6日
  • 创建了问题 5月6日