请求解析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
核心原因解析
$typename的局限性$typename仅能返回操作数的基础类型(如reg),无法区分该类型是否带有signed属性。你看到两个结果都是reg,但它们在算术运算中的符号处理规则完全不同。逻辑非
!的运算逻辑
!是逻辑非运算符,其结果始终是无符号布尔值(0或1),与原操作数的符号属性无关。- 当
!ubit(值为1'b1)与有符号数signed_reg3进行减法运算时,会被零扩展到4位,变为4'b0001(无符号值1)。 - 最终运算:
4 - 1 = 3,与输出结果一致。
- 按位取反
~的运算逻辑
~是按位取反运算符,其结果的符号属性与原操作数完全一致。这里ubit是无符号reg,因此~ubit也是无符号reg(值为1'b1)。- 在主流仿真器遵循的SystemVerilog规则中,当无符号操作数与有符号数进行算术运算时,无符号操作数会被视为有符号数处理,进行符号扩展:1'b1的最高位为1,扩展为4位后是4'b1111,对应有符号数的-1。
- 最终运算:
4 - (-1) = 5,与输出结果一致。
- 两类运算符的本质差异
- 逻辑运算符(
!/&&/||)的结果是布尔型,算术运算中始终按无符号零扩展处理。 - 按位运算符(
~/&/|/^)的结果继承原操作数的类型属性,当与有符号数运算时,会被当作有符号数进行符号扩展。
内容的提问来源于stack exchange,提问作者Eugene Sh.
相关产品推荐
相关产品推荐

