黄金法则是: 所有 operands 必须是 signed。
似乎 Verilog 强烈倾向于 unsigned 数字。以下任何一项都会产生 unsigned 值:
- 对两个 operands的任何操作,除非两个 operands 都是 signed 。
- 使用显式 base 给出的数字(例如 12′d10),除非使用显式“s”修饰符)
- bit-select的结果
- part-select的结果
- Concatenations
所以底线是要么使用 $signed system function,要么定义 signed wires 和 signed registers。
例如,要将 signed register 与 unsigned register相乘,将结果视为 signed 值(当然),请执行以下操作:
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”宽一个 bit ,所以 sign bit有一个位置,它总是为零。如果不是因为这个额外的 bit, a的 MSb 将被视为 signed_a (MSb = most significant bit) 中的 sign bit 。
似乎有必要用 {1′b0, a} 之类的东西来明确地确定 signed_a的 MSb ,而不仅仅是“a”。但是, Verilog standard 明确表示只有表达式确定数字是 signed 还是 unsigned。因此,左侧对此事没有影响。因此“a”被视为 unsigned 值,因此扩展为零。