You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求解析Verilog中逻辑非!与按位非~在算术表达式中的差异

Verilog中!与~运算的算术行为差异解析

测试代码与输出

测试代码:

module test;
  reg signed [3:0] signed_reg3 = 4;
  reg ubit = 0;
  
  initial begin
    $display("! => typename: %s, size: %d, %d", $typename(!ubit), $bits(!ubit), signed_reg3 - !ubit);
    $display("~ => typename: %s, size: %d, %d", $typename(~ubit), $bits(~ubit), signed_reg3 - ~ubit );
  end
endmodule

仿真输出:

! => typename: reg, size:           1,  3
~ => typename: reg, size:           1,  5

核心原因解析

  1. $typename的局限性
    $typename仅能返回操作数的基础类型(如reg),无法区分该类型是否带有signed属性。你看到两个结果都是reg,但它们在算术运算中的符号处理规则完全不同。

  2. 逻辑非!的运算逻辑

  • !是逻辑非运算符,其结果始终是无符号布尔值(0或1),与原操作数的符号属性无关。
  • 当!ubit(值为1'b1)与有符号数signed_reg3进行减法运算时,会被零扩展到4位,变为4'b0001(无符号值1)。
  • 最终运算:4 - 1 = 3,与输出结果一致。
  1. 按位取反~的运算逻辑
  • ~是按位取反运算符,其结果的符号属性与原操作数完全一致。这里ubit是无符号reg,因此~ubit也是无符号reg(值为1'b1)。
  • 在主流仿真器遵循的SystemVerilog规则中,当无符号操作数与有符号数进行算术运算时,无符号操作数会被视为有符号数处理,进行符号扩展:1'b1的最高位为1,扩展为4位后是4'b1111,对应有符号数的-1。
  • 最终运算:4 - (-1) = 5,与输出结果一致。
  1. 两类运算符的本质差异
  • 逻辑运算符(!/&&/||)的结果是布尔型,算术运算中始终按无符号零扩展处理。
  • 按位运算符(~/&/|/^)的结果继承原操作数的类型属性,当与有符号数运算时,会被当作有符号数进行符号扩展。

内容的提问来源于stack exchange,提问作者Eugene Sh.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:07:22