8비트 가감산기와 7세그먼트 디스플레이로 간단한 덧셈/뺄셈 계산기 만들기
포스트
취소

8비트 가감산기와 7세그먼트 디스플레이로 간단한 덧셈/뺄셈 계산기 만들기

개요

가감산기7세그먼트 디스플레이, IC 74147 등을 구현하여 조잡한 8비트 (덧셈/뺄셈만 가능한)계산기를 만들어보겠습니다.

완성된 결과물은 여기에서 확인할 수 있습니다.

1. 핵심 - 가산기 (Adder)

가산기 두개의 2진수의 덧셈을 수행하는 논리회로입니다. ALU의 핵심이 되는 회로이기도 합니다.

반가산기 (Half Adder)

HA

두개의 입력 AB를 받고, S(Sum, 합)과 C(Carry, 자리올림)를 출력하는 논리회로입니다.

ABSC
0000
0110
1010
1101

전가산기와 다르게 자리올림 입력이 없기 때문에, 거의 사용되지 않습니다.

전가산기 (Full Adder)

FA C = Cout

2개의 반가산기와 OR 게이트로 구성되어 있습니다. A, B, Cin(Carry in, 자리올림 입력)을 받고, S, Cout(Carry out, 자리올림 출력)을 출력합니다.

ABCinSCout
00000
00110
01010
01101
10010
10101
11001
11111

이는 1비트 2진수 덧셈을 수행하므로, 2비트 이상의 덧셈을 수행하기 위해선 전가산기 여러개를 연결해서 사용합니다.

다중 비트 가산기

다중 비트 가산기에도 RCA(Ripple Carry Adder), CLA(Carry Lookahead Adder) 등의 여러 종류가 있습니다.

이 계산기에서 사용할 다중 비트 가산기는 RCA입니다.

RCA (Ripple Carry Adder)

RCA 4비트 RCA, + 기호가 있는 부분은 전가산기입니다.

단순히 전가산기를 병렬로 연결한 구조입니다. 비트의 수가 많아진다면, 자리올림이 전달되고 판단되는 시간이 길어지는 단점이 있습니다.

가감산기 (Adder/Subtractor)

AS 4비트 가감산기, SignM(Minus)라고도 불립니다.

가감산기는 덧셈과 뺄셈을 모두 수행할 수 있는 논리회로입니다. 위에서 만든 4비트 RCA에 Bn xor Sign을 통해 Sign이 1이라면 B를 보수로 만들어 뺄셈을 수행합니다.

예시:

ABSignSCout
0010b (2)0011b (3)0 (Add)0101b (5)0
0101b (5)0011b (3)1 (Sub)0010b (2)1

감산기에서 Cout(MSB = 최상위 비트)는 무시하며, 가산기에서 Cout1이라면 Overflow가 발생한 것입니다.

지금까진 4비트 회로를 만들었지만, 같은 논리로 8비트로 확장하면 8비트 계산기를 만들 수 있습니다.

2. 입력/출력 데이터 표시하기 - BCD 코드와 7세그먼트 디스플레이

BCD 코드

BCD(Binary Coded Decimal) 코드는 10진수를 2진수로 표현하는 방법입니다. 4비트를 사용하며, 0부터 9까지의 숫자를 표현할 수 있습니다:

BinaryBCDBinaryBCD
0000001015
0001101106
0010201117
0011310008
0100410019

만약 2진수가 9보다 크다면, 6(= 0110b)을 더해 보정하여 사용합니다. 예를 들어, 1100b(= 12)은 9보다 크므로, 1100b + 0110b = 1 0010b를 사용합니다.

7세그먼트 디스플레이 (7-Segment Display)

7세그먼트 디스플레이는 7개의 획으로 숫자나 문자를 표시하는 디스플레이입니다. 아래와 같이 A..G까지의 획이 있습니다.

7SD DP = Decimal Point

디스플레이에 숫자를 표시하기 위해 BCD to 7-Segment Decoder가 필요합니다.

해당 디코더는 아래와 같은 진리표를 가지고 있습니다:

BCD (A, B, C, D)7 Segment (A, B, C, D, E, F, G)
0 0 0 01 1 1 1 1 1 0
0 0 0 10 1 1 0 0 0 0
0 0 1 01 1 0 1 1 0 1
0 0 1 11 1 1 1 0 0 1
0 1 0 00 1 1 0 0 1 1
0 1 0 11 0 1 1 0 1 1
0 1 1 01 0 1 1 1 1 1
0 1 1 11 1 1 0 0 0 0
1 0 0 01 1 1 1 1 1 1
1 0 0 11 1 1 1 0 1 1

Binary to BCD

그런데 여러 자리의 10진을 7세그먼트 디스플레이에 표시하기 위해선 어떻게 해야할까요?

당연하겠지만 2개의 디스플레이를 사용하며, 이때 자릿수를 나눠서 BCD로 변환하는 Binary to BCD가 필요합니다. 해당 변환기는 Double Dabble 알고리즘을 사용하여 구현할 수 있습니다.

예를 들어, 2진수 10110110b(= 182)를 BCD로 변환한다면, 아래와 같이 출력됩니다:

100의 자리10의 자리1의 자리
0001bcd1000bcd0010bcd

자세한 내용은 링크된 Wikipedia 문서를 참조해주세요.

3. 키패드 구현하기

지금까지 구현한것만 해도 8비트 계산기를 만들 수 있지만, 일반적으로 사용하는 계산기의 형태는 아닙니다. 이 차례에서 키패드를 통한 입력을 받을 수 있도록 구현해보겠습니다.

이 회로의 핵심은 10진수 입력을 BCD 코드로 변환하는 IC 74147D flip flop을 사용한 레지스터입니다.

IC 74147

IC 74147은 10진수 입력을 BCD 코드로 변환하는 인코더입니다. 아래와 같은 진리표를 가지고 있습니다:

DecimalInputs (1, 2, 3, 4, 5, 6, 7, 8, 9)Outputs (A, B, C, D)
01 1 1 1 1 1 1 1 11 1 1 1
10 1 1 1 1 1 1 1 11 1 1 0
21 0 1 1 1 1 1 1 11 1 0 1
31 1 0 1 1 1 1 1 11 1 0 0
41 1 1 0 1 1 1 1 11 0 1 1
51 1 1 1 0 1 1 1 11 0 1 0
61 1 1 1 1 0 1 1 11 0 0 1
71 1 1 1 1 1 0 1 11 0 0 0
81 1 1 1 1 1 1 0 10 1 1 1
91 1 1 1 1 1 1 1 00 1 1 0

눈치를 챘다면, 해당 칩을 사용할땐 입력/출력에 NOT 게이트를 사용해야 작동합니다.

회로도는 아래와 같습니다:

ic74147

레지스터로 자릿수 구분하기

우리가 만들 계산기는 8비트 계산기이기 때문에, 총 3 자릿수의 숫자를 입력받아야 합니다. 때문에 위 IC 74147SIPO(Serial-in Parallel-out, 직렬 입력 - 병렬 출력) 시프트 레지스터를 활용하여 3 자릿수의 숫자를 입력받을 수 있도록 구현해보겠습니다.

먼저, 키패드 버튼를 눌렀을때 레지스터에 BCD 값을 저장하고, 레지스터의 클럭은 버튼을 눌렀을 때 발생하는 펄스를 사용합니다.

예시:

  1. 키패드에서 3을 누름
  2. 레지스터 1에 0011b 저장 => 병렬 출력: 0011b 0000b 0000b
  3. 키패드에서 5를 누름
  4. 레지스터 1에 저장된 값(3)을 레지스터 2로 이동하고, 레지스터 1에 0101b 저장 => 병렬 출력: 0101b 0011b 0000b
  5. 키패드에서 1을 누름
  6. 같은 방법으로 시프트하고, 레지스터 1에 0001b 저장 => 병렬 출력: 0001b 0101b 0011b

이렇게 입력을 받을 수 있습니다.

입력받은 숫자를 8비트 2진수로 변환하기

이제 입력받은 숫자를 8비트 2진수로 변환해야 합니다. 저같은 경우엔 100의 자리는 값에 100을 곱하고, 10의 자리는 값에 10을 곱하고, 1의 자리는 값에 1을 곱하여 더하는 방식으로 구현했습니다. (더 좋은 방법이 있다면 피드백 부탁드립니다.)

그리고 이렇게 만들어진 피연산자 하나를 SIPO 레지스터에 저장하고 레지스터를 리셋한 다음, 같은 절차로 2번째 피연산자를 저장합니다. 피연산자를 저장하기 위한 펄스는 Enter, +, - 버튼이며, Enter는 단순히 펄스만 제공, +-는 펄스를 제공하고 D Flip Flop을 통해 Sign을 지정합니다.

이렇게 완성된 회로도는 아래와 같습니다:

keypad

마지막: 부가적인 기능 추가하기

이제 마지막으로 + -와 같은 기호를 표시하기 위한 LED 매트릭스를 추가하고, 계산 결과가 Overflow가 발생했는지 확인하기 위한 LED를 추가하면 8비트 계산기가 완성됩니다.


result