01signal.com

Verilog 中的有符号运算:唯一需要知道的规则

黄金法则是:所有操作数都必须是有符号(signed)的。

Verilog 似乎非常偏向于无符号(unsigned)数。以下任何一种情况都会产生 无符号 值:

所以归根结底,要么使用 $signed 系统函数,要么定义有符号的 wire 和有符号的 reg。

例如,要把一个有符号的 reg 变量与一个无符号的 reg 变量相乘,并(当然)把结果当作有符号值来处理,可以像下面这样写:

reg         [15:0] a; // Unsigned
reg signed  [15:0] b;
wire signed [16:0] signed_a;
wire signed [31:0] a_mult_b;

assign signed_a = a; // Convert to signed
assign a_mult_b = signed_a * b

注意,signed_a 比 a 宽 1 位,因此有空间存放符号位(sign bit),而这个符号位始终为 0。如果没有这一位,a 的最高有效位(MSb,most significant bit)在 signed_a 中就会被当作符号位。

有人可能会误以为,必须用 {1'b0, a} 这样的写法来显式指定 signed_a 的 MSb,而不是直接写 a。但 Verilog 标准明确指出:一个数是有符号还是无符号,只由表达式本身决定。赋值左侧(left-hand side)对此没有任何影响。因此,a 被当作无符号值处理,并因此用 0 扩展。

本页由机器从英文翻译而来。如有疑问,请参阅原文
Copyright © 2021-2026. All rights reserved. (dcc38493)