I am trying to write some simple verilog code for a comparator of two 4 bit two's complement numbers. I have two 4-bit inputs (A[3:0], B[3:0]), and 3 outputs (AeqB, AgtB, AltB) to show if A and B are equal, if A is greater than B, or A is less than B. There is also a third input named sign, which if 0 means that the numbers are unsigned, and if 1, the numbers are signed.
So i know that two signed two's complement numbers can be compared by subtracting them, but i cannot get that to work properly in my design. Here is what i have tried:
if(sign==0)
begin
if(({sign,A}-{sign,B})==0)
AeqB = 1;
else if(({sign,A}-{sign,B}) > 0)
AgtB = 1;
else if (({sign,A}-{sign,B}) < 0
AltB = 1;
end
It seems as though this should work. I concatenate the sign bit to the front of the 4 bit numbers, subtract them, and then check to see if they are greater than or equal to zero. If A-B<0, then B is less than A because they are both negative numbers.
However when i simulate this design, it is correct whenever A=B, but shows AgtB in every other case, never AltB.
Any ideas on what i am doing wrong?
I am not sure what you are doing with {sign,A}
. This would force the numbers to be negative when they have a signed format. Unless sign forces them to be negative?
you could define inputs to be signed or force a signed comparison, and 0 pad the msb in the unsigned case to share hardware, what you have implied is three subtractors in parallel. Synthesis might do a great job and share the hardware but you would have to check each time that it has given you what you want.
if (sign) begin
A_i = {A[3], A};
B_i = {B[3], B};
end
else begin
A_i = {1'b0, A};
B_i = {1'b0, B};
end
AgtB = $signed(A_i) > $signed(B_i) ;
AltB = ~AgtB ;
When adding subtracting numbers the result the bit growth is the largest bit width input +1. for unsigned 0 pad and interrupt result as unsigned. For signed numbers, sign extend by repeating the MSB.
To help with the understanding of 2's complement I have included some 4 bit examples of sign unsigned arithmetic.
Unsigned arithmetic:
3 : (0)0011
+ 1 : (0)0001
= 4 : 0 0100
Large Unsigned arithmetic:
15 : (0)1111 //Zero pad for correct bitwidths
+ 1 : (0)0001
=16 : 1 0000
Large Signed (Overflow):
On the result different (01) MSBs indicate overflow for truncation back down to 4 bits
7 : (0)0111
+1 : (0)0001
=8 : 0 1000 bits
Subtraction:
7 : (0)0111
-1 : (1)1111 //(twos complement of 1)
// Sum the bits as you did for unsigned
=6 : 0 0110