본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Computer Science

기본 컴퓨터의 구조와 설계

작성 2026. 10. 21.추가
목차19개 항목
출처와 참고

「클럭 속도의 한계와 조절」 절은 CrashCourse의 「Crash Course Computer Science」 강의를 바탕으로 보강했다. 「수직적·수평적 마이크로프로그래밍」 절과 CBR, 마이크로프로그램 제어 CPU의 설계 순서는 고려사이버대학교 「컴퓨터구조」(2024-1학기) 강의 내용으로 보강했다.

컴퓨터 구조 교재(『컴퓨터 시스템 구조』, Mano)는 설명을 위해 단순한 16비트 기본 컴퓨터(Basic Computer) 를 정의하고, 그 구조와 제어 장치를 처음부터 설계한다. 규모는 작지만 "명령어를 메모리에서 꺼내 해석하고 실행한다"는 현대 CPU의 기본 설계 구조가 그대로 들어 있다.

컴퓨터는 어떻게 동작하나

  • 컴퓨터는 프로그램을 기억 장치에 저장해 두고 명령어를 하나씩 꺼내 실행하는 폰 노이만 구조(프로그램 내장 방식)이다.
  • 각 명령어는 레지스터에 저장된 데이터에 대한 마이크로 연산의 시퀀스로 정의된다(레지스터 전송과 마이크로 연산).
용어의미
명령어 코드컴퓨터에 동작을 지시하는 비트 묶음. 보통 연산 코드(opcode)와 주소로 구성
컴퓨터 명령어(기계어)마이크로 연산들을 묶어 하나의 동작으로 정의한 바이너리 코드. 데이터와 함께 메모리에 저장
프로그램명령어들의 집합. 명령어 처리 과정을 제어하는 추상적인 개념
내장 프로그램실제로 메모리·레지스터에 올라가 있는 명령어들

명령어 형식

모든 명령어는 설계할 때 정해 둔 형식을 따른다. 기본 컴퓨터의 명령어와 레지스터는 16비트다.

 15   14  13  12   11                      0
[ I | Opcode (3) | Address (12)             ]
필드크기역할
I1비트0이면 직접 주소(주소 필드가 곧 피연산자 주소. ADD 457은 457번지 값을 더한다), 1이면 간접 주소(그 번지에 피연산자 주소가 있다. ADD 300 (I)은 300번지에 적힌 1350번지 값을 더한다)
Opcode3비트수행할 연산
Address12비트피연산자의 주소 → 2¹² = 4096워드 메모리를 지정

메모리는 16비트 워드 4096개(4K)이며, 명령어(코드 세그먼트)와 피연산자(데이터 세그먼트), 임시 데이터(스택 세그먼트)를 서로 다른 영역에 둔다. 연산 결과는 누산기(AC)에 저장된다.

레지스터

레지스터비트역할
PC (Program Counter)12다음에 실행할 명령어의 주소
AR (Address Register)12메모리 주소 지정
IR (Instruction Register)16현재 실행 중인 명령어(해독 대상)
DR (Data Register)16메모리에서 읽어 온 피연산자
AC (Accumulator)16연산 결과를 저장하는 누산기
TR (Temporary Register)16임시 데이터
INPR (Input Register)8입력 장치에서 받은 문자
OUTR (Output Register)8출력 장치로 보낼 문자

주소를 다루는 PC와 AR은 메모리 크기에 맞춰 12비트다. 명령어는 보통 연속된 메모리에 놓이고 한 번에 하나씩 순차적으로 실행된다.

공통 버스

공통 버스(common bus)는 CPU 내부 버스를 가리키며(CPU 밖의 메모리·입출력 버스는 메모리 계층 구조), 버스의 폭이 CPU의 워드 크기를 결정한다. 기본 컴퓨터는 16비트 공통 버스에 메모리, AR, PC, DR, AC, IR, TR을 연결하고, 선택 입력(S2 S1 S0)으로 제어되는 멀티플렉서가 버스에 올릴 하나를 고른다. 버스에 실린 데이터는 LD(load) 입력이 활성화된 레지스터가 다음 클럭에 받아 저장한다. 한 순간에 하나의 값만 버스를 지날 수 있다.

명령어의 종류

종류구분 방법개수예
메모리 참조 명령어(MRI)Opcode가 000~1107AND, ADD, LDA, STA, BUN, BSA, ISZ
레지스터 참조 명령어(RRI)Opcode 111, I = 012CLA, CMA, INC, HLT … (주소 필드 12비트가 각각의 연산을 지정)
입출력 명령어(IO)Opcode 111, I = 16INP, OUT, SKI, SKO, ION, IOF

타이밍과 제어

  • IR의 Opcode(1214비트)를 3×8 디코더로 해독해 D0D7 중 하나를 1로 만든다.
  • 4비트 순차 카운터(SC) 의 출력을 4×16 디코더로 해독해 T0~T15 타이밍 신호를 만든다. 매 클럭마다 T0, T1, T2 … 순으로 바뀐다.
  • 제어 신호는 이 둘의 조합으로 표현한다. 예: D3T4: SC ← 0은 D3가 1이고 타이밍이 T4일 때 SC를 0으로 클리어(다음 명령어로).

클럭 속도의 한계와 조절

클럭은 일정한 간격으로 신호를 내어 제어 장치가 인출·해독·실행 단계를 한 걸음씩 넘기게 하는 박자기다. 1초에 한 번이 1Hz이고, 지금 CPU는 수 GHz(초당 수십억 사이클)로 돈다.

  • 클럭을 무한히 올릴 수는 없다. 신호가 선을 따라 퍼지고 게이트 출력이 안정되는 데 시간이 걸리므로, 한 클럭 주기 안에 가장 느린 경로의 신호가 자리를 잡아야 한다. 이보다 빠르면 값이 정해지기 전에 다음 단계가 읽어 엉뚱한 결과가 나온다.
  • 같은 이유로 결과를 바로 입력 레지스터에 다시 쓰지 않는다. ALU 출력을 입력 쪽 레지스터에 곧바로 연결하면 새 값이 다시 ALU로 흘러 들어가 계속 더해진다. 그래서 결과를 내부 임시 레지스터에 잡아 두었다가 다음 단계에서 목적 레지스터로 옮긴다.
  • 오버클럭은 설계 여유를 믿고 클럭을 정격보다 올리는 것이고, 지나치면 발열이나 타이밍 위반으로 오동작한다.
  • 반대로 클럭을 낮추면 전력이 크게 준다. 그래서 현대 CPU는 부하에 따라 클럭과 전압을 함께 올리고 내리는 동적 전압·주파수 조절(DVFS, Dynamic Voltage and Frequency Scaling)을 한다. 배터리로 도는 노트북·스마트폰에서 특히 중요하다. Linux에서는 cpufreq 거버너가 이 정책을 정한다.

명령어 사이클

모든 명령어는 fetch → decode → (간접 주소면) 유효 주소 읽기 → 실행 → 다시 fetch를 반복한다.

T0: AR ← PC                                          ; 다음 명령어 주소를 AR로
T1: IR ← M[AR],  PC ← PC + 1                         ; 명령어를 읽고 PC 증가
T2: D0..D7 ← Decode IR(12-14),  AR ← IR(0-11),  I ← IR(15)
T3: (메모리 참조 명령어이고 I = 1이면) AR ← M[AR]     ; 유효 주소. 이후 타이밍에서 실행

입출력과 인터럽트

입출력 플래그와 명령어

FGI가 1이면 INPR에 새 입력이 있고, FGO가 1이면 출력 장치가 준비됐으며, IEN이 1이면 인터럽트를 허용한다. 입출력 명령어는 앞 4비트가 1111이다.

명령어코드동작
INP / OUTF800 / F400INPR → AC / AC → OUTR
SKI / SKOF200 / F100FGI / FGO가 1이면 다음 명령어를 건너뜀
ION / IOFF080 / F040IEN ← 1 / IEN ← 0

프로그램 인터럽트

CPU가 플래그를 계속 확인(polling)하는 대신, I/O 장치가 준비되면 CPU에 알리는 방식이다. 인터럽트 사이클 진입 여부는 R 플립플롭으로 표시한다.

명령어 사이클(R = 0) 중 T0~T2가 아닐 때 IEN = 1이고 FGI 또는 FGO가 1이면 R을 1로 세운다. R = 1이면 다음 fetch 대신 인터럽트 사이클을 돈다.

RT0: AR ← 0,  TR ← PC
RT1: M[AR] ← TR,  PC ← 0          복귀 주소를 메모리 0번지에 저장
RT2: PC ← PC + 1,  IEN ← 0,  R ← 0,  SC ← 0

1번지에는 입출력 처리 루틴(BIOS 같은 I/O 프로그램)으로 분기하는 명령어가 있어, 그곳으로 가서 인터럽트를 처리한다. IEN을 0으로 만들어 처리 중에 다른 인터럽트가 끼어들지 못하게 하고, 루틴의 마지막에 0번지에 저장된 주소로 간접 분기해 원래 프로그램으로 돌아온다.

현대 컴퓨터는 여러 인터럽트를 인터럽트 벡터 테이블(IVT) 로 관리한다. 인터럽트 우선순위와 처리 흐름은 입출력 구조와 CPU와 명령어 구조를 참고한다.

기본 컴퓨터의 설계

기본 컴퓨터는 16비트 × 4096워드 메모리, 레지스터 9개(AR, PC, DR, AC, IR, TR, OUTR, INPR, SC), 플립플롭 7개(I, S, E, R, IEN, FGI, FGO), 디코더 2개(3×8, 4×16), 16비트 공통 버스, AC 입력 쪽 ALU로 이뤄진다. 설계할 부분은 이들을 움직이는 제어 논리 게이트다.

제어 장치 설계 방법

각 레지스터·플립플롭의 제어 입력(LD, INR, CLR 등)마다 다음을 반복한다.

전체 명령어에서 그 레지스터와 관련된 마이크로 연산을 모두 모으고, 동작 종류별로 나눈 뒤, 같은 동작을 일으키는 조건들을 OR 게이트로 묶는다. AC도 같은 방식으로 AND·ADD·LDA·CLA·INC·INP 등의 조건을 모아 제어 게이트를 만들고, 입력 쪽에 비트마다 가산기·논리 회로를 붙인다.

예: AR과 관련된 동작을 모으면

LD(AR)  = R'T0 + R'T2 + D7'IT3      AR에 값을 적재
CLR(AR) = RT0                        AR을 0으로
INR(AR) = D5T4                       AR을 1 증가

예: IEN (p = D7IT3, 즉 입출력 명령어 실행 시점, Bi는 IR의 i번째 비트)

pB7: IEN ← 1     (ION)
pB6: IEN ← 0     (IOF)
RT2: IEN ← 0     (인터럽트 사이클)

마이크로프로그램 제어

위처럼 게이트·디코더·플립플롭으로 제어 신호를 직접 만드는 방식을 하드와이어드 제어(hardwired control) 라 한다. 다른 방법은 제어 신호의 조합을 비트열로 만들어 메모리에 넣어 두고, 그것을 차례로 읽어 내보내는 마이크로프로그램 제어(microprogrammed control) 다.

용어뜻
제어 워드한 클럭에 켤 제어 신호들을 0/1로 나열한 비트열
마이크로명령어제어 워드 + 다음에 읽을 마이크로명령어의 주소 정보
마이크로프로그램마이크로명령어의 나열. 기계어 명령어 하나는 마이크로명령어 몇 개로 된 루틴 하나에 대응한다
제어 메모리마이크로프로그램을 담는 메모리. 보통 ROM이고, 쓰기 가능한 제어 메모리를 쓰면 동적 마이크로프로그래밍이 된다
CAR (Control Address Register)다음에 읽을 마이크로명령어의 제어 메모리 주소
CBR (Control Buffer Register)제어 메모리에서 방금 읽은 마이크로명령어를 잠시 담는 레지스터
시퀀서(다음 주소 생성기)현재 마이크로명령어와 상태 비트를 보고 다음 CAR 값을 정하는 회로

CPU를 이 방식으로 만드는 순서는 명령어 종류와 비트 패턴 정의 → 실행에 필요한 하드웨어 설계 → 명령어마다 실행 사이클 루틴 작성(마이크로프로그래밍) → 제어 메모리에 저장이다.

flowchart LR
  ir["명령어(IR)"] --> mp["매핑"] --> car["CAR"] --> cm["제어 메모리(ROM)"] --> mi["마이크로명령어"]
  mi --> sq["시퀀서"]
  sb["상태 비트(I, S, Z)"] --> sq
  sq --> car
  mi --> cs["제어 신호"] --> tg["레지스터·ALU·버스"]

주소 시퀀싱

시퀀서가 다음 CAR 값을 고르는 경우는 네 가지다.

경우동작
증가CAR ← CAR + 1. 루틴 안에서 다음 마이크로명령어로
분기무조건, 또는 상태 비트(간접 비트, AC 부호, AC = 0 등)에 따라 마이크로명령어의 주소 필드로
매핑명령어의 opcode 비트로 그 명령어 루틴의 시작 주소를 만든다
서브루틴 호출·복귀복귀 주소를 SBR(Subroutine Register)에 저장했다가 돌아온다. 여러 루틴이 쓰는 간접 주소 처리 등을 공유한다

교재의 예

교재의 마이크로프로그램 예는 opcode 4비트 명령어를 쓰고, 128워드 × 20비트 제어 메모리를 둔다.

 마이크로명령어 20비트
[ F1 (3) | F2 (3) | F3 (3) | CD (2) | BR (2) | AD (7) ]
  마이크로 연산 3개를 동시에   조건    분기 종류  주소
필드값
F1·F2·F3각각 7가지 마이크로 연산 중 하나(또는 NOP)를 고른다
CD (조건)U(항상 참), I(간접 비트), S(AC 부호), Z(AC = 0)
BR (분기)JMP(조건이 참이면 CAR ← AD, 아니면 +1), CALL(SBR에 복귀 주소 저장 후 분기), RET(CAR ← SBR), MAP(opcode로 매핑)

매핑은 opcode xxxx를 주소 0 xxxx 00으로 바꾼다. 명령어마다 마이크로명령어 4개짜리 자리가 생긴다. 인출 루틴은 64번지에 둔다.

        ORG 64
FETCH:  PCTAR        U  JMP  NEXT    / AR ← PC
        READ, INCPC  U  JMP  NEXT    / DR ← M[AR], PC ← PC + 1
        DRTAR        U  MAP          / AR ← DR(0-10), opcode로 루틴 시작 주소로

수직적·수평적 마이크로프로그래밍

마이크로명령어의 연산 필드 비트를 제어 신호로 바꾸는 방법에 따라 나뉜다. 위 교재의 예처럼 F1·F2·F3에 3비트 코드를 넣고 디코더로 푸는 방식은 수직 쪽이다.

방식연산 필드장점단점
수직적(vertical)적은 수의 코드화된 비트를 넣고 디코더로 필요한 수만큼의 제어 신호로 펼친다마이크로명령어가 짧아 제어 메모리가 작다디코딩만큼 지연이 생긴다
수평적(horizontal)제어 신호 하나에 비트 하나를 1:1로 대응시킨다디코더가 없어 하드웨어가 단순하고 지연이 없다. 여러 신호를 자유롭게 동시에 켤 수 있다제어 신호 수만큼 비트가 필요해 마이크로명령어가 길고 제어 메모리가 커진다

하드와이어드와 비교

항목하드와이어드 제어마이크로프로그램 제어
구현게이트·디코더·순차 카운터제어 메모리의 마이크로명령어
속도빠르다매 단계 제어 메모리를 읽어야 해 느리다
변경·확장회로를 다시 설계해야 한다마이크로프로그램만 고치면 된다
복잡한 명령어회로가 급격히 복잡해진다루틴을 길게 쓰면 된다
어울리는 설계RISCCISC

현대 x86 CPU도 대부분의 명령어는 하드웨어 디코더가 바로 μop으로 바꾸고, 복잡한 일부 명령어만 마이크로코드 ROM에서 μop 시퀀스를 꺼낸다(현대 CPU의 마이크로아키텍처). CPU 제조사가 배포하는 마이크로코드 업데이트는 이 부분을 바꿔 출시 후 발견된 결함을 고친다.

핵심 정리

  • 명령어 = I(1) + Opcode(3) + Address(12). I로 직접·간접 주소를 구분한다.
  • 명령어 사이클은 fetch(T0~T1) → decode(T2) → 유효 주소(T3) → 실행. 타이밍은 SC + 4×16 디코더가 만든다.
  • 클럭 주기는 가장 느린 신호 경로가 안정되는 시간보다 길어야 하고, 현대 CPU는 DVFS로 부하에 맞춰 클럭과 전압을 조절한다.
  • 인터럽트는 R 플립플롭으로 감지해 복귀 주소를 0번지에 저장하고 1번지의 처리 루틴으로 간다.
  • 제어 장치 설계는 "관련 동작 수집 → 분류 → OR로 묶기"의 반복이다.
  • 제어 신호를 회로로 만들면 하드와이어드, 제어 메모리의 마이크로명령어로 만들면 마이크로프로그램 제어다. 전자는 빠르고, 후자는 고치기 쉽다.
  • 마이크로명령어의 연산 필드를 코드화해 디코더로 펼치면 수직적(짧지만 느림), 비트와 제어 신호를 1:1로 두면 수평적(빠르지만 김)이다.

관련 노트: 레지스터 전송과 마이크로 연산, 기본 컴퓨터 프로그래밍, CPU와 명령어 구조, 입출력 구조

원본 기록3

댓글

GitHub 계정으로 댓글을 남길 수 있어요.