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.
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:
Large Unsigned arithmetic:
Large Signed (Overflow):
On the result different (01) MSBs indicate overflow for truncation back down to 4 bits
Subtraction: