Verilog 中的无符号寄存器减法
Unsigned reg subtraction in Verilog
我在 Verilog 中进行无符号 reg 减法时遇到了一些麻烦。
以下 Verilog 代码专为 4 位 ALU 设计:
module p2(in_1,in_2,s,out);
input [3:0]in_1,in_2;
input [1:0]s;
output [4:0]out;
reg [4:0]out;
parameter ADD=2'b00;
parameter SUBTRACT=2'b01;
parameter AND=2'b10;
parameter OR=2'b11;
always @(in_1,in_2,s)
begin
case (s)
ADD: out=in_1+in_2;
SUBTRACT: out=in_1-in_2;
AND: out={1'b0,(in_1&in_2)};
OR: out={1'b0,(in_1|in_2)};
endcase
end
endmodule
问题 1:
对于案例 in_1=4'b0000
,in_2=4'b0001
,s=2'b01
我认为in_1-in_2
应该是:0000-0001=0000+(1110+1)=1111
所以 1111
应该被零扩展(由于无符号减法)到 01111
,
然后分配给out=5'b01111
然而,正确的结果显示out=5'b11111
为什么?
问题2:
对于案例 in_1=4'b0001
,in_2=4'b0001
,s=2'b01
我认为in_1-in_2
应该是:0001-0001=0001+(1110+1)=10000
然后赋值给out=5'b10000
然而,正确的结果显示out=5'b00000
为什么?
对于物理硬件,寄存器只包含二进制数据,有符号无符号只是人类解释的问题。
在这里,在你的情况下,这是表达式宽度评估的问题。参考 SystemVerilog LRM 1800-2012,第 11.6 节:
The number of bits of an expression is determined by the operands and the context.
SystemVerilog uses the bit length of the operands to determine how many bits to use while evaluating an expression.
The bit length rules are given in 11.6.1. In the case of the addition operator, the bit length of the
largest operand, including the left-hand side of an assignment, shall be used.
The number of bits of an expression (known as the size of the expression) shall be determined by the
operands involved in the expression and the context in which the expression is given.
参考LRM中给出的例子:
logic [15:0] a, b; // 16-bit variable
logic [15:0] sumA;
logic [16:0] sumB; // 17-bit variable
sumA = a + b; // expression evaluates using 16 bits
sumB = a + b; // expression evaluates using 17 bits
您在这里犯的错误是计算 4 位的 2 的补码并期望得到 5 位输出。虽然该语言在表达式中使用 最大位长度 来执行相同的操作。
这里,out
是一个5位寄存器。所以被减数的2的补码取五位。即4'b0001
的2的补码是5'b11111
。将此添加到 4'b0000
的扩展名 5'b00000
,我们得到 5'b11111
。从今以后你的第一个问题的结果。
类似,注释适用于您的问题 2,将 5'b11111
添加到 5'b00001
结果是 5'b00000
。
有关带符号减法的详细信息,请参阅 this, this and this 链接。
我在 Verilog 中进行无符号 reg 减法时遇到了一些麻烦。
以下 Verilog 代码专为 4 位 ALU 设计:
module p2(in_1,in_2,s,out);
input [3:0]in_1,in_2;
input [1:0]s;
output [4:0]out;
reg [4:0]out;
parameter ADD=2'b00;
parameter SUBTRACT=2'b01;
parameter AND=2'b10;
parameter OR=2'b11;
always @(in_1,in_2,s)
begin
case (s)
ADD: out=in_1+in_2;
SUBTRACT: out=in_1-in_2;
AND: out={1'b0,(in_1&in_2)};
OR: out={1'b0,(in_1|in_2)};
endcase
end
endmodule
问题 1:
对于案例 in_1=4'b0000
,in_2=4'b0001
,s=2'b01
我认为in_1-in_2
应该是:0000-0001=0000+(1110+1)=1111
所以 1111
应该被零扩展(由于无符号减法)到 01111
,
然后分配给out=5'b01111
然而,正确的结果显示out=5'b11111
为什么?
问题2:
对于案例 in_1=4'b0001
,in_2=4'b0001
,s=2'b01
我认为in_1-in_2
应该是:0001-0001=0001+(1110+1)=10000
然后赋值给out=5'b10000
然而,正确的结果显示out=5'b00000
为什么?
对于物理硬件,寄存器只包含二进制数据,有符号无符号只是人类解释的问题。
在这里,在你的情况下,这是表达式宽度评估的问题。参考 SystemVerilog LRM 1800-2012,第 11.6 节:
The number of bits of an expression is determined by the operands and the context.
SystemVerilog uses the bit length of the operands to determine how many bits to use while evaluating an expression.
The bit length rules are given in 11.6.1. In the case of the addition operator, the bit length of the largest operand, including the left-hand side of an assignment, shall be used.
The number of bits of an expression (known as the size of the expression) shall be determined by the operands involved in the expression and the context in which the expression is given.
参考LRM中给出的例子:
logic [15:0] a, b; // 16-bit variable
logic [15:0] sumA;
logic [16:0] sumB; // 17-bit variable
sumA = a + b; // expression evaluates using 16 bits
sumB = a + b; // expression evaluates using 17 bits
您在这里犯的错误是计算 4 位的 2 的补码并期望得到 5 位输出。虽然该语言在表达式中使用 最大位长度 来执行相同的操作。
这里,out
是一个5位寄存器。所以被减数的2的补码取五位。即4'b0001
的2的补码是5'b11111
。将此添加到 4'b0000
的扩展名 5'b00000
,我们得到 5'b11111
。从今以后你的第一个问题的结果。
类似,注释适用于您的问题 2,将 5'b11111
添加到 5'b00001
结果是 5'b00000
。
有关带符号减法的详细信息,请参阅 this, this and this 链接。