[컴퓨터 구조] 기본 컴퓨터의 구조와 설계
컴퓨터의 구조는 레지스터 (하드웨어 리소스) / 명령어 집합 / 타이밍과 제어 도구들로 정의된다.
컴퓨터 명령어는 마이크로 연산을 기술한 이진 코드이고, 데이터와 함께 메모리에 저장된다.
제어 신호는 명령어를 메모리로부터 읽고 제어 레지스터에 가져다놓는다. (저장)
이후 제어 신호가 명령어를 해석해 제어 함수를 발생시켜 명령어를 실행한다.
명령어 코드는 컴퓨터가 특정 연산을 하도록 지시하는 비트 집합이다.
연산 코드 부분과 주소 부분으로 구성되고, 연산 코드는 연산을 지정하고 주소는 피연산자의 주소를 가리킨다.
메모리로부터 읽혀진 피연산자는 레지스터에 저장된 데이터와 연산을 수행한다.
여기서 연산과 마이크로 연산은 다르다. 연산 내부에 마이크로 연산을 수행하는 부분이 포함되어있다고 생각하자.
명령어 코드의 구성은 설계자에 따라 세 가지로 나뉜다.
1. Immediate Addressing
명령어 코드에서 address bit가 피연산자의 주소가 아니고 피연산자 자체를 의미하는 경우이다. (기본 컴퓨터에서 거의 안 쓴다)
2. Direct Addressing
address bit가 피연산자의 주소를 의미하는 경우이다. operand = M[address]
3. Indirect Addressing
한 다리 더 건너야 한다. 주소를 따라가면 주소가 나오고 그 주소를 따라가면 피연산자가 있다. operand = M[M[address]]
보통 비트 하나를 사용해 명령어 코드의 주소 부분이 어떻게 설계됐는지 구별한다.
(a)
명령어 코드가 3비트의 연산 코드와 12비트의 주소, 1비트로 주소 모드를 표현하고 있다. (I == indirect. 0 == direct)
(b)
직접 주소 명령어는 메모리 주소 22에 위치한다.
주소 457의 피연산자를 읽고 레지스터 AC에 내용을 더한다.
(c)
한 다리 더 건너는거 말고는 똑같다.
따라가면 피연산자가 나오는 주소를 유효 주소라고 한다.
컴퓨터 명령어는 연속적인 메모리에 위치하는 경우가 많고, 한 번에 하나씩 순차적으로 수행돼야 한다.
따라서 다음에 수행될 명령어의 주소를 알 수 있어야 하고, 메모리에서 읽어온 명령어 코드를 저장할 수 있는 레지스터와 데이터를 조작하기 위한 프로세서 레지스터, 메모리의 주소를 가지는 레지스터가 필요하다.
메모리 장치는 4096워드로 구성돼있고, 각 워드는 16비트이니 피연산자의 주소에 12비트 / 명령어 코드에 3비트 / 주소 모드에 1비트를 할당한다.
DR : Data Register. 메모리에서 읽어온 피연산자를 저장한다. (16bit)
AC : Accumulator. 범용 처리 레지스터로 사용된다. (16bit)
IR : Instruction Register. 메모리에서 읽어온 명령어를 저장한다. (16bit)
TR : Temporary Register. 계산 도중 임시 데이터를 저장한다. (16bit)
AR : Address Register. 메모리의 주소를 나타낸다. (12bit)
PC : Program Counter. 다음 수행될 명령어의 주소를 지정한다. (12bit)
INPR : Input Register. (8bit)
OUTR : Output Register. (8bit)
레지스터와 레지스터 / 레지스터와 메모리 사이를 연결하는 경로로 버스 시스템을 사용한다.
선택 입력 S0 S1 S2 으로 버스 위에 놓이게 될 출력을 결정한다.
로드 입력이 enabled 상태인 레지스터는 다음 클럭 펄스에서 버스의 데이터를 받아서 저장한다.
선택 입력이 111이고 읽기 입력이 활성화되면 16비트 출력을 버스에 올린다.
이 때 AR과 PC는 상위4비트를 0으로 채우고 하위 12비트만 전송된다.
명령어 코드는 연산 코드에 따라 다시 세 가지로 분류할 수 있다.
1. Memory-reference instruction
연산 코드가 000 ~ 110 이다.
12비트를 피연산자의 주소를 지정하는데 사용하고, 주소 모드에 1비트를 사용한다.
2. Register-reference instruction
최상위 비트가 0이고 Operation Code (연산 코드) 가 111 이다.
12비트를 피연산자의 주소를 지정하는데 사용하는 대신 주로 AC 레지스터에 대한 연산을 지정한다.
3. Input-output instruction
최상위 비트가 1이고 연산 코드가 111이다.
12비트를 입출력 연산의 종류를 나타내는데 사용한다.
표를 참고하면 명령어의 종류 25가지를 확인할 수 있다.
레지스터 참조 명령어나 입출력 명령어에서는 12비트가 연산 코드로 사용돼 실제로 가능한 동작수가 훨씬 많아지지만, 여기서는 25가지를 선택했다. (이 부분은 저자인 mano의 판단. 25개로 충분히 설명 가능하다고 판단했겠지..)
1. 산술 논리 시프트 명령어
2. 메모리와 프로세서 레지스터 사이에 정보를 이동시킬 수 있는 명령어
3. 상태 조건을 검사하는 명령과 프로그램 제어 명령어
4. 입출력 명령어
명령어 집합이 위의 네 가지 분류에 해당하는 충분한 명령어를 가지고 있으면 해당 명령어 집합은 완전하다고 할 수 있다.
컴퓨터는 기본적으로 순차회로로 설계된다.
즉, 클럭 펄스와 제어 신호가 갖춰져야 레지스터의 상태를 변경할 수 있다.
제어 장치는 hardwired와 microprogrammed 방식이 있다.
전자는 제어 논리를 다른 디지털 회로를 사용해 구현하기 때문에 후자보다 훨씬 빠르지만 설계와 수정이 매우 어렵고, 후자는 제어 정보가 제어 메모리에 저장돼 수정이 쉽다.
메모리에서 읽어온 명령어는 IR에 저장된다.
연산 코드 부분은 디코더에 의해 0 ~ 7 로 구분되고, 순차 카운터는 디코더에 의해 0 ~ 15 까지 16개의 타이밍 신호를 생성한다. (타이밍 신호를 생성한다)
CLR 신호가 1 이면 SC가 0으로 초기화된다. (T0 신호를 만든다)
매 클럭마다 순차 카운터는 타이밍 신호를 생성하고, 연산 코드 디코더의 출력과 타이밍 신호가 정해진 입력과 일치하면 CLR 신호를 1로 설정한다.
(https://13months.tistory.com/477) 에서 공부했듯, 컴퓨터의 각 명령어 사이클은 4단계로 구성돼있다.
1. 인출 (fetch) : Program Counter에 의거해 명령어를 가져온다.
2. 해독 (decode) : 명령어를 해석해 제어 신호를 생성한다.
3. 간접 주소 방식이면 유효 주소를 읽어온다.
3. 실행 (execution) : 가져온 명령어를 실행한다.
fetch와 decode
컴퓨터를 처음 실행했을 때 PC는 첫 명령어에 대한 주소를 가지고, SC는 T0를 가리킨다.
fetch와 decode 단계에 대한 마이크로 연산들은 위와 같은 레지스터 전송문으로 표시된다.
T0동안 PC에서 명령어를 읽어 AR에 저장한다.
T1동안 IR에 T0에서 읽어온 명령어를 저장하고, PC에는 다음 명령어 주소가 저장된다.
T2동안 IR의 연산 코드 부분이 디코드되고 주소 모드 비트가 I 플립플롭에 저장되며 주소 부분은 AR로 전송된다.
레지스터 전송문을 버스 시스템으로 구현하면 위와 같다.
1. 선택 입력을 010으로 설정해 PC내용에 버스에 놓이도록 하고, AR의 LD(로드) 입력을 enable해서 PC의 내용을 AR로 전송한다.
2. 메모리의 읽기 입력을 enable해서 AR의 주소를 읽어온다.
3. 선택 입력을 111로 설정해 메모리가 버스에 놓이도록 하고, IR의 LD를 enable해서 메모리의 내용을 IR로 전송한다.
4. PC의 INR 입력을 enable해서 PC값을 하나 증가시킨다.
(여기까지 T0 ~ T1)
T3동안 제어장치는 명령어의 종류를 결정한다.
T2에서 얻은 D7 값이 1이면 명령어는 레지스터 참조 혹은 입출력이고, D7 값이 0이면 메모리 참조 명령어이다. (7(10) = 111(2))
이후 플립플롭 I값을 검사해 주소방식을 얻어오고 방식에 따라 적절하게 처리해준다.
T3에서는 D7값과 I플립플롭의 값에 따라 네 가지 경우로 구분해서 동작한다.
T3까지 수행됐고 해당 명령어가 레지스터 참조 명령어인 경우 한 명령어가 다 수행됐다는거고, SC의 값이 클리어된다. (T0)
플로우차트는 위와 같다.
I가 0이고 D7값이 1인 경우 해당 명령어는 레지스터 참조 명령어이다.
부울식 D7I'T3를 간단하게 기호 r로 표현했다.
0111 1000 0000 0000 이진 코드는 I' D7 B11이 1을 가리킨다. (B는 우측에서부터 11번째가 1이다)
앞에서도 언급했듯, 완료된 후 타이밍 신호를 T0로 초기화한다.
HLT명령어는 플립플롭 S를 클리어하고 순차 카운터의 동작을 멈춘다.
메모리 참조 명령어는 I에 상관없이 디코딩 된 값 중 D1~D6에서 1인 경우이다.
피연산자의 유효 주소는 T2혹은 T3에 AR 레지스터로 전송되고, 메모리 참조 명령어는 T4에서 시작된다. (이해하기!!)
BSA (Branch and Save Return Address)
현재 PC에 저장된 값을 유효 주소로 지정된 메모리에 저장하고 유효 주소보다 1 큰 값이 PC로 전송된다.
T4 : BSA가 실행되기 전 / T5 : BSA가 실행된 후
나머지 명령어들은 한 번 읽어보고 이해하자.
메모리 참조 명령어의 플로우차트는 위와 같다.
각각 다른 경로를 형성하고, 각 경로의 마지막 타이밍 신호에서는 SC를 0으로 클리어한다.
이제 입출력 장치에 대해 살펴보자.
사용자는 키보드 등의 입력 장치를 통해 컴퓨터에게 입력을 주고, 컴퓨터는 프린터같은 출력 장치를 사용해 사용자와 소통한다.
CPU는 입력과 출력이 들어왔는지 계속 확인해야 하는데, CPU 사이클을 돌면서 올 때 까지 계속 확인하는 방식은 비효율적이다.
I/O 장치는 비동기적으로 동작한다.
즉, 언제 도착할 지 시간을 알 수 없다는건데.. 전화를 생각하면 이해하기 쉽다.
전화가 언제 올지 핸드폰은 전혀 알 수 없다. 그러면 전화가 올 때까지 하염없이 체크해야 할까?
그렇지 않다. 전화가 오면 벨소리가 울리든 진동이 울려서 전화가 왔음을 알려준다.
I/O는 비동기적으로 동작하기 때문에 벨소리처럼 CPU에게 신호가 도착했음을 알려주는 장치가 필요하다.
이렇게 비동기 이벤트가 발생함을 알려주는 방식을 인터럽트 방식이라고 한다.
CPU는 사이클을 계속 돌다가 비동기 이벤트의 발생을 감지하면 하던 작업을 멈추고 입출력을 실행한다.
(실행이 끝나면 다시 하던 일을 계속한다)
인터럽트를 지원하기 위해 IEN (Interrupt Enable Flip-flop)과 인터럽트 플립플롭 R이 사용된다.
플로우차트를 통해 동작 과정을 살펴보자.
인터럽트 플립플롭 R은 CPU 내부에 위치하고, R이 0이면 명령어 사이클을 수행하고 R이 1이면 인터럽트 사이클을 실행한다.
입력 값이 있으면 FGI(Flag Input) 제어 플립플롭의 값을 1로 설정한다. (플래그가 설정되면 입력 정보를 변화시킬 수 없다)
R이 0일 때 IEN과 FGI / FGO 값을 검사하고, IEN이 1이고 플래그 값의 || 결과가 1이면 R은 1로 설정되고 CPU는 인터럽트 사이클로 전환한다.
인터럽트 사이클이 수행되는 과정을 살펴보자.
인터럽트가 발생하면 그 때 수행되던 명령어 주소를 복귀 주소로 설정하고 메모리에 저장하고, 다른 인터럽트가 발생하는걸 방지하기 위해 R과 IEN값을 클리어한다. (IEN == 1 : 현재 인터럽트를 수행할 수 있는 상태를 의미)
메모리 주소 0번지에는 복귀 주소가 저장되고, 1번지에는 인터럽트 사이클의 첫 번째 명령어가 저장된다.
입출력 작업이 완료되면 IEN값을 1로 설정하고 BUN명령으로 인터럽트가 발생했던 지점으로 복귀시킨다.
지금까지의 내용을 플로우차트로 확인해보자.
'Computer Science > Computer Architecture' 카테고리의 다른 글
[컴퓨터 구조] 기본 컴퓨터 프로그래밍 (0) | 2022.10.09 |
---|---|
[컴퓨터 구조] 레지스터와 마이크로 연산 (0) | 2022.10.02 |
[컴퓨터 구조] 데이터의 표현 (0) | 2022.10.02 |
댓글
이 글 공유하기
다른 글
-
[컴퓨터 구조] 기본 컴퓨터 프로그래밍
[컴퓨터 구조] 기본 컴퓨터 프로그래밍
2022.10.09 -
[컴퓨터 구조] 레지스터와 마이크로 연산
[컴퓨터 구조] 레지스터와 마이크로 연산
2022.10.02 -
[컴퓨터 구조] 데이터의 표현
[컴퓨터 구조] 데이터의 표현
2022.10.02