SystemVerilog

2's complement 비교하기

epro-asic 2024. 9. 13. 19:21

2의 보수 방식의 장점을 요약하면 다음과 같습니다 :

- MSB가 0이면 양수, 1이면 음수임을 확신할 수 있음.

- 음수를 더하는 방식으로 뺼셈 수행 가능

- 음수의 비교연산에서 발생하는 모순 해결 (음수끼리 만)

- 0이 단 한 가지 방식으로 표현 가능

- 덧셈 및 뺄셈에서 캐리의 발생시 캐리를 처리하는 회로를 구성할 필요가 없음.

 

==================================================

그럼 4비트 이진수를 예로 들어 설명해 드릴게요.

  1. 숫자 5를 4비트 이진수로 표현하면:
    5 = 0101
  2. 숫자 -3을 2의 보수로 표현하는 과정:
    • 3을 4비트 이진수로 표현하면:
      3 = 0011
    • 이 숫자의 1의 보수를 취하면:
      0011 → 1100
    • 이 1의 보수에 1을 더하면 2의 보수가 됩니다:
      1100 + 1 = 1101
      그래서, -3은 4비트로 1101입니다.

이제, 5와 -3을 더해봅시다:

 
 
 

4비트로 계산하기 때문에 결과에서 가장 왼쪽 비트(5번째 비트)는 무시합니다. 그래서 남는 값은 0010입니다.

이 값은 2진수로 2이므로, 5 + (-3) = 2가 맞다는 것을 확인할 수 있습니다.

이렇게 2의 보수를 사용하면 음수도 양수처럼 간단하게 더할 수 있습니다.

 

==================================================

음수끼리 크기를 비교할 때도 2의 보수를 사용하여 비교할 수 있습니다.

예를 들어, -3-5의 크기를 4비트 이진수로 비교해 볼게요.

  1. -3의 2의 보수를 구하는 과정:
    • 3을 4비트로 표현하면 0011입니다.
    • 1의 보수를 취하면 1100이 되고,
    • 여기에 1을 더하면 1101입니다. 그래서 -3은 2의 보수로 1101입니다.
  2. -5의 2의 보수를 구하는 과정:
    • 5를 4비트로 표현하면 0101입니다.
    • 1의 보수를 취하면 1010이 되고,
    • 여기에 1을 더하면 1011입니다. 그래서 -5는 2의 보수로 1011입니다.

이제 두 값을 비교해 보면:

  • -3: 1101
  • -5: 1011

이진수로 봤을 때, 더 큰 값은 **1101**이므로, -3-5보다 큽니다.

따라서 -3 > -5라는 결론이 나옵니다. 이처럼 2의 보수를 사용해 음수끼리도 간단히 크기를 비교할 수 있습니다.

그러나, 이는 음수끼리의 비교(부호가 같을 때만, < 가 제대로 동작) 이지. 양수 음수를 섞어서 비교하면 당연히 안됨.

 

아래 코드는 입력 부호를 확인하고, 크기를 비교하는 코드이다.

 

module compare_two_numbers (
    input signed [3:0] a,  // 첫 번째 입력 값 (4비트 부호 있는 숫자)
    input signed [3:0] b,  // 두 번째 입력 값 (4비트 부호 있는 숫자)
    output signed [3:0] max_value, // 더 큰 값
    output signed [3:0] min_value  // 더 작은 값
);

    wire a_is_negative, b_is_negative;

    // MSB가 1이면 음수
    assign a_is_negative = a[3];  // a의 부호 비트 (MSB)
    assign b_is_negative = b[3];  // b의 부호 비트 (MSB)

    // 두 수의 부호가 다를 때: 음수와 양수를 구분
    assign max_value = (a_is_negative == 1'b0 && b_is_negative == 1'b1) ? a :  // a가 양수, b가 음수일 때 a가 더 큼
                      (a_is_negative == 1'b1 && b_is_negative == 1'b0) ? b :  // a가 음수, b가 양수일 때 b가 더 큼
                      (a > b) ? a : b;  // 두 수의 부호가 같으면 일반 비교

    assign min_value = (a_is_negative == 1'b0 && b_is_negative == 1'b1) ? b :  // a가 양수, b가 음수일 때 b가 더 작음
                      (a_is_negative == 1'b1 && b_is_negative == 1'b0) ? a :  // a가 음수, b가 양수일 때 a가 더 작음
                      (a < b) ? a : b;  // 두 수의 부호가 같으면 일반 비교

endmodule

 

수정 사항 설명:

  1. 부호 비트 확인:
    • assign a_is_negative = a[3];에서 a[3]은 a의 MSB (최상위 비트)입니다. MSB가 1이면 음수, 0이면 양수임을 나타냅니다. 마찬가지로 b[3]은 b의 부호 비트입니다.
  2. 부호가 다른 경우 처리:
    • assign max_value: 만약 a가 양수(a_is_negative == 1'b0)이고, b가 음수(b_is_negative == 1'b1)이면 무조건 a가 더 큽니다. 반대로 a가 음수이고 b가 양수라면 b가 더 큽니다.
    • assign min_value: 반대로 a가 양수이고 b가 음수면 b가 더 작고, a가 음수이고 b가 양수면 a가 더 작습니다.
  3. 부호가 같은 경우 처리:
    • 두 수의 부호가 같다면(둘 다 양수 또는 둘 다 음수), 일반적인 비교 연산을 수행하여 큰 값과 작은 값을 결정합니다.

이 코드는 음수와 양수를 구분하여 비교하며, 부호가 다른 경우 올바르게 처리할 수 있도록 수정되었습니다.

 

==========================

크기 비교는 부호가 같을 때만 적용되므로, 1차 부호로 크기를 판단하고 2차로 같은 부호일 경우에, 비교하는 것임.

3비트 부호 있는 숫자 범위 (2의 보수 표기):

십진수2진수 (3비트)

3 011
2 010
1 001
0 000
-1 111
-2 110
-3 101
-4 100