Verilog中的无符号reg减法

时间:2015-11-21 15:54:26

标签: 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'b0000in_2=4'b0001s=2'b01

我认为in_1-in_2应该是:0000-0001=0000+(1110+1)=1111

所以1111应该零扩展(由于无符号减法)到01111

然后被分配到out=5'b01111

但是,正确的结果显示out=5'b11111

为什么?

Problem2: 对于案例in_1=4'b0001in_2=4'b0001s=2'b01

我认为in_1-in_2应该是:0001-0001=0001+(1110+1)=10000

然后将其分配到out=5'b10000

但是,正确的结果显示out=5'b00000

为什么?

1 个答案:

答案 0 :(得分:1)

对于物理硬件,寄存器仅包含二进制数据,无符号签名只是人类解释的问题。

在这种情况下,这是表达式宽度评估的问题。参考SystemVerilog LRM 1800-2012,第11.6节:

  

表达式的位数由操作数和上下文决定。

     

SystemVerilog使用操作数的位长来确定在计算表达式时要使用的位数。

     

比特长度规则在11.6.1中给出。在加法运算符的情况下,比特长度   应使用最大 操作数,包括作业的左侧

     

表达式的位数(称为表达式的大小)应由   参与表达式的操作数和给出表达式的上下文。

参考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

你在这里犯的错误是计算2位的2位补码并期望5位输出。虽然该语言在表达式中使用最大位长来执行相同的操作。

此处,out 5位寄存器。因此2的补充的minuend用于 5位。也就是说,4'b0001的2的补码是5'b11111。将其添加到4'b0000 5'b00000的扩展名中,我们得到5'b11111。从此以后就是你的第一个问题了。

类似地,评论适用于您的问题-2,将5'b11111添加到5'b00001会导致5'b00000

有关签名减法的详细信息,请参阅thisthisthis链接。