오늘 끝나면
디코더와 제어 유닛
- ✓디코더와 제어 유닛의 핵심 문제를 한 문장으로 설명한다
- ✓오른쪽 실습에서 디코더와이 어떻게 움직이는지 관찰한다
- ✓다음 강의와 이어지는 한계를 말할 수 있다
실습 미션
opcode를 control signal로 — RegWrite·MemRead·ALUSrc 이 문장이 실제로 무슨 뜻인지 실습에서 한 번 손으로 확인한다.
성공 조건
- □실습의 기본값을 먼저 관찰
- □입력값이나 모드를 한 번 이상 바꿔 결과 비교
- □왜 결과가 바뀌었는지 한 문장으로 설명
반도체 설계 · 17
디코더와
제어 유닛
데이터패스는 부품 더미다. 누군가 지금 무엇을 켤지 정해줘야 움직인다.
제어 유닛은 opcode를 읽어 control signal을 켜는 디코더다.
한 비트만 잘못 켜도 명령이 통째로 깨진다. STORE에서 RegWrite를 켜는 실수가 그렇다.
opcode를 control signal로 푼다
명령어는 맨 앞에 무슨 일을 할지 적은 opcode를 달고 있다. 제어 유닛은 그 opcode를 받아 데이터패스 스위치를 켜는 장치다.
데이터패스(ALU·레지스터·메모리)는 스스로 판단하지 않는다. 그냥 켜진 길로 데이터를 흘릴 뿐이다.
그래서 레지스터에 쓸지, ALU 입력을 무엇으로 쓸지, 메모리를 읽을지를 매 명령마다 누군가 정해줘야 한다.
그 결정이 곧 control signal이다. 각각 1비트짜리 켬·끔 스위치다.
opcode 한 덩어리가 들어가면 신호 여러 개가 한꺼번에 켜져 나온다. 13강 디코더가 주소 하나를 word line 한 줄로 풀었듯, 제어 유닛은 opcode 하나를 신호 다발로 푸는 디코더다.
유닛
네 개의 control signal
이 예제 머신(16비트 CPU + 8 레지스터)에선 제어 신호 네 개면 명령 대부분이 풀린다.
RegWrite는 결과를 레지스터 파일에 쓸지 정한다. 1이면 쓰고, 0이면 안 쓴다.
ALUSrc는 ALU 둘째 입력을 레지스터 값으로 쓸지, 명령에 박힌 상수(immediate)로 쓸지 고른다.
MemRead는 메모리에서 값을 읽을지 정한다(load일 때만 1).
MemWrite는 메모리에 값을 쓸지 정한다(store일 때만 1).
이 네 비트의 조합이 곧 이 명령이 데이터패스에서 어떤 길로 흐를지를 정한다. 여기서 고른 신호 집합이 그대로 최종 MyChip 제어 유닛의 출력선이 된다.
제어 표, 명령마다 신호를 적어둔다
제어 유닛 안에는 외울 게 없다. 명령별로 어느 신호를 켤지 미리 적어둔 제어 표 한 장이 전부다.
ADD는 레지스터 둘을 더해 레지스터에 쓴다. RegWrite=1, ALUSrc=0이고 메모리는 안 건드린다.
ADDI는 상수를 더한다. ALUSrc만 1로 바뀐다.
LOAD는 메모리에서 읽어 레지스터에 올린다. MemRead=1, RegWrite=1이다.
STORE는 레지스터 값을 메모리에 내린다. MemWrite=1, 그리고 RegWrite=0이다. 레지스터엔 아무것도 쓰면 안 된다.
이 표를 그대로 게이트로 굳히면 제어 유닛이 된다. opcode가 들어오면 해당 줄의 신호가 켜져 나온다. 표 한 칸이 곧 회로 한 가닥이다.
| opcode | RegW | ALUSrc | MRd | MWr |
|---|---|---|---|---|
| ADD | 1 | 0 | 0 | 0 |
| ADDI | 1 | 1 | 0 | 0 |
| LOAD | 1 | 1 | 1 | 0 |
| STORE | 0 | 1 | 0 | 1 |
ADD · reg+reg → reg
ADDI · reg+상수 → reg
LOAD · mem → reg
STORE · reg → mem
직접 신호를 켜고, 고장을 찾는다
명령을 고르고 control signal을 켜보면 데이터패스 활성 경로가 바뀐다.
신호 직접 켜기에선 명령에 맞게 네 신호를 켠다. 실행 전에 제대로 돌지 버그일지 먼저 찍고 결과와 비교한다. 진한 블록이 켜진 경로, 흐린 블록이 이 명령에서 안 쓰는 길이다.
고장 난 신호 찾기에선 STORE인데 한 신호가 잘못 켜진 표를 주고 어느 줄이 범인인지 짚게 한다. 현재 표와 정답 표를 나란히 두면 어긋난 비트가 진하게 드러난다.
R1 ← mem[R2+ofs] · 메모리에서 읽어 레지스터에 올림
| opcode | RegW | ALUSrc | MRd | MWr |
|---|---|---|---|---|
| ADD | 1 | 0 | 0 | 0 |
| ADDI | 1 | 1 | 0 | 0 |
| LOAD | 1 | 1 | 1 | 0 |
| STORE | 0 | 1 | 0 | 1 |
제어 유닛은 데이터패스의 지휘자다
데이터패스가 오케스트라라면 제어 유닛은 지휘자다. 악기는 똑같은데, 언제 누구를 울릴지는 지휘자가 정한다.
그래서 제어 한 비트가 틀리면 명령 전체가 깨진다.
STORE에서 실수로 RegWrite=1을 켜면, 메모리엔 제대로 쓰면서 동시에 엉뚱한 레지스터가 ALU 결과로 덮어써진다.
무서운 건 컴파일도 되고 메모리도 멀쩡히 써져서 한참 안 들킨다는 점이다. 그러다 덮어써진 레지스터를 쓰는 순간 값이 어긋난다.
그래서 제어 표는 칩 설계에서 가장 꼼꼼히 검증하는 한 장이다. 신호 하나하나가 데이터패스의 어느 길을 여는지 정확히 알아야 한다.
Q. STORE 명령에서 RegWrite가 1로 켜지면 무슨 일이 생기나?
정답은 엉뚱한 레지스터가 덮어써지는 버그다.STORE는 레지스터 값을 메모리에 내리기만 하면 된다. 레지스터엔 아무것도 쓰면 안 된다.
그런데 RegWrite=1이면 ALU가 계산한 주소 값(또는 결과)이 목적지 레지스터에 그대로 박혀 멀쩡한 값을 덮어쓴다. 메모리는 정상이라 한참 안 들키는 게 함정이다.
레지스터엔 안 쓴다, 정상
RegWrite=1이면 엉뚱한 레지스터를 덮어쓴다