지난 게시물에서 AND, OR, NOT 같은 논리 게이트들을 조합하여 덧셈을 수행하는 계산기를 만들 수 있음을 배웠습니다. 하지만 이 계산기에는 한 가지 큰 한계가 있었습니다. 바로 계산 결과를 기억하지 못한다는 점입니다.
마치 벽의 전등 스위치를 누르는 동안만 불이 켜지고 손을 떼면 즉시 불이 꺼지는 것과 같습니다. 일반적인 전등 스위치는 한 번 누르면 불이 켜지고, 다시 누르면 불이 꺼지는 토글 방식으로 작동하는데, 지금까지 배운걸로는 이런게 불가능하죠.
이를 위해서는 이전 상태가 무엇이었는지(전구가 꺼져있음/켜져있음)를 기억해 새로운 상태(꺼졌으면 켬/켜졌으면 끔)를 계산하는 회로가 필요합니다.
오늘은 컴퓨터의 기억상실증을 고쳐줄 회로, 바로 순차 논리 회로를 알아봅시다.
지난 시간에 다뤘던 가산기처럼 현재의 입력값에 의해서만 출력이 즉시 결정되는 회로를 조합 논리 회로(Combinational Logic Circuit) 라고 부릅니다. 과거의 입력이나 상태는 현재 출력에 아무런 영향을 주지 않습니다.
반면 기억 능력을 가진 회로를 순차 논리 회로(Sequential Logic Circuit) 라고 합니다. 순차 논리 회로는 현재 입력뿐만 아니라 이전 상태(기억된 값)에도 의존하여 출력을 결정합니다.
그렇다면 순차 논리 회로는 어떻게 정보를 기억하는 걸까요? 피드백(Feedback), 즉 회로의 출력이 다시 입력으로 돌아가는 구조가 핵심입니다. 이 피드백 루프를 활용하여 가장 단순한 형태의 기억 장치인 SR 래치(SR Latch) 를 만들 수 있습니다.
놀랍게도 SR 래치는 NOR 게이트 단 두 개만으로도 만들 수 있습니다.
S를 1로 만들어 Q를 세팅한 뒤, 다시 S를 0으로 만들어도 Q의 값이 유지됨을 확인해보세요!
SR 래치는 두 가지 입력과 두 가지 출력을 가집니다:
S | R | Q | Q̅ | 동작 |
---|---|---|---|---|
0 | 0 | 이전 상태 유지 | 이전 상태 유지 | 유지 (Hold) |
0 | 1 | 0 | 1 | 리셋 (Reset) |
1 | 0 | 1 | 0 | 설정 (Set) |
1 | 1 | 불안정 | 불안정 | 금지 상태 |
각 입력과 출력의 역할을 살펴보면:
S와 R 입력이 모두 0으로 돌아갔을 때 래치는 이전에 기억했던 값을 계속 유지한다는 점이 가장 큰 특징입니다.
SR 래치는 기본적인 '기억' 기능을 제공하지만, 실제 컴퓨터에서 사용하기에는 몇 가지 문제가 있습니다.
가장 큰 문제는 S와 R이 동시에 1이 될 때 발생하는 불안정한 상태입니다. S와 R이 모두 1이면 두 NOR 게이트의 출력은 강제로 0이 됩니다. 즉, Q=0, Q̅=0이 되는데, 이는 SR 래치의 기본 정의인 "Q와 Q̅는 항상 반대 값"이라는 조건을 위배합니다.
더 큰 문제는 이 상태에서 다시 S=0, R=0으로 바꿀 때 발생합니다. 자세히 살펴보지는 않겠지만 이때는 어떤 상태로 전이될지 예측할 수 없게 됩니다. 즉 때로는 Q=1이 되고 때로는 Q=0이 될 수 있습니다. (참고로 블로그 예제에서는 이러한 물리적인 불확실성이 구현되어있지 않습니다 🥲)
이러한 SR 래치의 문제를 해결하기 위해 등장한 것이 바로 D 래치(D Latch) 입니다. D 래치는 AND를 활용해 SR 래치의 입력 회로를 변형하여 S와 R이 동시에 활성화되는 불안정한 상태를 원천적으로 방지합니다.
D 래치는 하나의 '데이터(Data, D)' 입력과 '활성화(Enable, E)' 입력만을 가집니다.
활성화(E) 신호가 켜져 있는 동안에만 데이터(D) 입력의 값이 Q에 반영됩니다. 활성화 신호가 꺼지면 D 입력이 아무리 변해도 래치는 이전 값을 유지합니다.
Q를 잠그는 자물쇠가 E라고 생각해도 좋겠네요!
앞서 살펴본 D 래치는 입력을 저장하는 간단하고 유용한 회로입니다. 그러나 D 래치의 작동 방식에는 한 가지 근본적인 한계가 있습니다.
D 래치는 활성화(Enable, E) 신호가 켜져 있는 동안에는 D 입력의 변화를 그대로 따라갑니다. 즉, E가 켜진 동안 D 값이 여러 번 바뀌면, 출력 Q도 계속해서 흔들리게 됩니다. 이로 인해 안정적으로 딱 한 순간의 데이터만을 전달받기 어렵습니다.
예를 들어, A → B → C 순서로 데이터를 전달해야 하는 세 개의 래치가 있다고 가정합시다. A에서 계산된 값이 B를 거쳐 C로 가야 하는데, B가 너무 빨리 활성화되면 어떻게 될까요? A가 아직 계산 중인 불완전한 값을 B가 먼저 받아버릴 수 있습니다. 또는 A의 출력이 짧은 시간 동안 여러 번 요동치는 경우, B가 그 요동 중간의 값들을 마구잡이로 받아들이는 일이 벌어질 수 있습니다.
이처럼 각 회로가 각기 다른 시점에 동작한다면, 데이터가 잘못 전달되거나 충돌이 발생하여 전체 시스템이 오작동할 수 있습니다.
따라서 우리는 모든 회로가 같은 타이밍에 동작하도록 동기화할 필요가 있습니다. 바로 이 동기화를 책임지는 것이 클럭(Clock) 입니다.
클럭은 컴퓨터 내부에서 일정한 주기로 반복되는 정기적인 신호입니다. 마치 오케스트라에서 지휘자가 지휘봉으로 연주자들의 타이밍을 맞추는 것처럼, 클럭은 모든 회로에 “지금 동작해!”라는 박자를 동시에 알려줍니다.
f(x) = x * 2
1 → 2
f(x) = x + 10
- → -
f(x) = x - 3
- → -
f(x) = x * x
- → -
클럭이 없다면, 회로들은 저마다의 속도로 움직이게 되고, 결국 데이터의 흐름은 엉망이 됩니다.
여러분이 컴퓨터 사양에서 "3.2GHz" 같은 숫자를 본 적이 있을 겁니다. 이것은 클럭의 주파수를 의미하며, 1초에 32억 번의 박자를 보내는 속도를 뜻합니다. 이 클럭 주파수가 높을수록 회로는 더 자주 동작할 수 있어, 더 많은 계산을 빠르게 처리할 수 있습니다.
즉, 클럭은 단지 타이밍을 맞추는 역할을 넘어, 컴퓨터 성능 자체를 좌우하는 핵심 요소이기도 합니다.
그럼 구체적으로 메모리는 클럭의 변화에 따라 어떻게 작동할까요? D 플립플롭(D Flip-Flop) 의 구현을 보며 이해해봅시다.
D 플립플롭은 D 래치처럼 데이터를 입력받아 저장하지만, 클럭의 특정 순간(엣지) 에서만 데이터를 받아들입니다. 상승 엣지 혹은 하강 엣지 중 하나를 선택할 수 있습니다.
상승 엣지 / 하강 엣지
엣지 트리거 방식은 입력 신호가 아무리 요동쳐도, 정해진 클럭 엣지에서만 데이터를 받아들이므로 결과가 예측 가능하고 안정적입니다.
상승 엣지 D 플립플롭은 두 개의 D 래치를 사용해 아래와 같이 구현할 수 있습니다. CLK이 0에서 1이 될때 Q가 바뀌는걸 테스트해보세요:
D 플립플롭 하나는 단 하나의 비트(0 또는 1)만 저장할 수 있습니다. 하지만 컴퓨터는 8비트, 16비트, 32비트, 64비트와 같은 여러 비트가 모인 Word 단위로 숫자를 표현하고 처리합니다.
이러한 여러 비트의 정보를 한 번에 저장하기 위해, 여러 개의 D 플립플롭을 병렬로 연결한 것이 바로 레지스터(Register) 입니다. 예를 들어, 8비트 레지스터는 8개의 D 플립플롭으로 구성되어 8개의 비트를 동시에 저장할 수 있습니다. 모든 플립플롭이 같은 클럭 신호를 공유하므로, 8비트 데이터가 동시에 저장되고 출력됩니다.
레지스터는 CPU 내부에 위치하며, 연산 장치가 계산할 값이나 제어 장치가 다음 명령어를 가져올 주소 등, CPU가 당장 처리해야 할 핵심적인 정보들을 매우 빠르게 임시 저장하는 역할을 합니다. CPU와 같은 칩 내부에 위치하기 때문에 접근 속도가 매우 빠르지만, 그만큼 비싸고 공간을 많이 차지합니다.
우리는 이제 덧셈을 수행할 수 있는 회로뿐만 아니라, 그 계산 결과를 '기억'할 수 있는 능력을 컴퓨터에게 부여하는 방법을 알게 되었습니다.
다음 게시물에서는 이러한 계산 능력과 기억 능력을 가진 회로들을 하나로 묶어 지휘하고 통제하는 컴퓨터의 중앙 처리 장치(CPU) 의 구성과 작동 방식에 대해 자세히 알아보겠습니다. 또한 현대 컴퓨터의 기본 구조인 폰 노이만 구조를 만나게 될 것입니다.
로그인 중...