0

I have some troubles with unsigned reg subtraction in Verilog.

The following Verilog code is designed for a 4-bit 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 

Problem1: For the case in_1=4'b0000,in_2=4'b0001,s=2'b01

I think in_1-in_2 should be: 0000-0001=0000+(1110+1)=1111

So 1111 should be zero-extended(due to unsigned subtraction) to 01111,

then is assigned to out=5'b01111

However,the correct result show that out=5'b11111

Why?

Problem2: For the case in_1=4'b0001,in_2=4'b0001,s=2'b01

I think in_1-in_2 should be: 0001-0001=0001+(1110+1)=10000

Then it is assigned to out=5'b10000

However,the correct result show that out=5'b00000

Why?

唐正杰
  • 3
  • 1
  • 1
  • 4

1 Answers1

4

For physical hardware, a register contains only the binary data, signed unsigned are of just a matter of human interpretations.

Here, in your case, it is a matter of Expression width evaluation. Referring to SystemVerilog LRM 1800-2012, section 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.

Referring to example given in 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

The mistake you are making here is calculating 2's complement for 4-bits and expecting a 5-bit output. While the language uses maximum bit length in an expression to do the same.

Here, out is a 5-bit register. So the 2's complement of minuend is taken for five bits. That is, 2's complement of 4'b0001 is 5'b11111. Adding this to an extension of 4'b0000 as 5'b00000, we get 5'b11111. Henceforth your first problem's result.

Similar, comments applies for your Problem-2, Adding 5'b11111 to 5'b00001 results in 5'b00000.

For more information about signed subtraction, refer to this, this and this links.

Community
  • 1
  • 1
sharvil111
  • 4,301
  • 1
  • 14
  • 29