Verilog里做有符号数比较最核心的一条是只要参与比较的操作数里有一个是无符号的整个比较就会按无符号数处理负数会变成很大的正数结果自然就错了。✅ 正确做法是保证所有操作数都是有符号的常见方式有这几种声明时加 signed端口或信号声明成 signed比如 input signed [15:0] a这样 a b 就是有符号比较。用 signed()转换如果信号已经声明为无符号可以用signed()转换如果信号已经声明为无符号可以用signed(a) $signed(b) 强制按有符号比较。常量比较要小心localparam THRESHOLD -100; 这种写法THRESHOLD 默认是无符号的直接拿来和变量比较会出错。最好声明成 localparam signed [15:0] THRESHOLD -100;或者比较时用 $signed(THRESHOLD)。⚠️ 有几个容易踩的坑要注意位截断不保留符号从有符号数里直接截取几位比如 adc_data[15:12]截出来的部分不会自动带符号需要再用 $signed() 包一下。带位宽的负数常量要小心像 -4h2 这种写法先按无符号算 4h2 再取负结果在比较时可能还是被当成无符号数建议直接写 -2 或 4hE补码形式。混合运算时类型会“传染”有符号数和无符号数做运算整个表达式都按无符号处理所以尽量别混用。补码表示2’s complement正数的原码、反码、补码相同负数的补码等于反码加1负数的原码与补码之间的相互转化关系均为除了符号位取反再加1。补码的好处在于加减运算不需要判断符号位。B-AB(-A)-A的补码是A的补码所有位取反再加1
阅读完成 · 觉得有帮助?