컴퓨터구조론은 우리가 쓰고있는 CPU의 구조를 탐구하는 학문이다.
논리회로에서 어떻게 단순한 0, 1이 덧셈 뺄셈, 곱셈 등 연산기가 되는지 배웠다면
컴퓨터구조에선 어떻게 단순한 연산기가 모여 현대 CPU 구조를 이루는지 배운다.
이번장에선 CPU의 Basic of basic structure를 알아본다.
구조를 알기전에 CPU가 유일하게 알아먹는 언어인 ISA에 대해 간략히 짚고 넘어가자.
C++, python 등 고급 컴퓨터 언어는 인류 언어와 비슷하다. CPU는 그냥 덧셈 뺄셈 계산기 이므로 이해할 수 없다.
이를 무조건 CPU가 알아들을 수 있는 원시 언어로 바꿔줘야 한다.
CPU는 오로지 메모리간 덧셈 뺄셈, 이동만 수행할 수 있다.
ISA는 그러한 CPU를 컨트롤 하기 위한 명령어 집합체이며 원시언어다.
따라서 메모리 내용물 간 덧셈 뺄셈 곱셈, 또는 메모리 주소 이동에 초점을 맞추고 있다.
ISA 명령어들은 3가지 타입이 있다.
- add, sub, and, or, slt 의 명령어는 두 메모리에서 값을 불러와 계산 후 다른 한 메모리에 저장한다. (R타입)
- lw, sw 은 load, save로 한 메모리 공간의 변수를 다른 한 메모리 공간에 옮겨 저장한다. (I타입)
- beq, j는 별다른 연산 없이 명령어 간 이동을 컨트롤 한다. (J타입)
그래서 CPU 구조를 알아보는데 왜 ISA를 알아야 하냐고?
ISA 타입별로 CPU 내 데이터 흐름이 다르기 때문이다.
R타입은 두 메모리를 참조하지만 I타입은 한 개만 참조하고, J타입은 하나도 참조하지 않는다.
Data path가 다를 수 밖에 없다. 따라서 한 개 CPU에는 3개 Data path가 모두 적용되어 있다.
CPU 내의 구성요소는 큰 틀로 다음과 같다
Instruction memory – register – ALU – data memory
Instruction memory : 메모리에서 명령어를 읽어와 레지스터 또는 ALU로 뿌린다.
register : 명령어 내 레지스터에서 값을 불러오거나 값을 쓴다.
ALU : 계산한다.
Data memory : 계산 후 도출된 값을 읽어 메모리에 쓰거나 추가 필요 정보를 읽어온다.
CPU내 3개 Data path들 모두 4개 요소 사이의 길을 이리저리 바꿔가며 구성된다.
그렇다면 타입을 어떻게 구분할까?
3개 타입 모두 내용물만 다를 뿐 32자리 숫자다.
간단하다. 자릿수로 쪼갠다.
- 먼저 제일 간단하게 생긴 R타입 Data path를 보자

Instruction memory에서 32자리 명령어를 받으면
rs(25-21), rt(20-16), rd(15-11) 만 추출해 각 register 입력부 넣는다.
(rs, rt는 데이터를 읽어오기 떄문에 read register 1,2 / rd는 계산값 저장해야하므로 write register)
register 출력부가 rs, rt 내 변수를 내보내면 ALU가 그걸 받아 계산하고
그 결과를 다시 register 입력부 (Write data)로 넣는다. (넣은 변수는 rd에 저장됨)
- 다음 R타입 Data path위에 I타입 Data path를 쌓아 올려보자.

R타입에서 rt가 read 였다면 I타입에선 write 으로 쓰일 수 있다. 따라서 Mux를 추가해서 둘중 하나를 고를 수 있게 할 수 있다. (RegDst)
RegDst로 I타입을 선택했다면 rs 와 address를 연산해 주소를 달리한 후 rt에 넣는다.
이떄 address는 16비트이므로 앞에 0을 도배해서 32비트로 Sign extend 한 후 ALU에 넣어준다.
그런 다음 계산된 결과를 write data로 넣어준다. 이 역시 mux로 선택 가능하다 (MemToReg)
- 다음 I타입 Data path 위에 Branch를 쌓아 올려보자 (beq : rs rt가 같을 때 지정된 주소로 점프함)


여기부턴 PC 구조가 포함된다. PC란 program counter로, 명령어의 진행 척도를 나타낸다. 명령어가 한줄 수행될 때 4씩 더해진다. 이때 j나 beq등으로 명령어가 점프한다면 4 이상 더해질 수 있다.
Instruction memory 서 32자리 명령어를 따와 rs, rt를 뽑아온다.
ALU에서 rs rt가 같은지 판별한다. (다르면 0, 같으면 1)
ALU 결과값이 0이라면 PCSrc 시그널이 0이 되므로 진행하던대로 PC값에 4만 더해진다.
ALU 결과값이 01이라면 PCSrc 시그널이 1이 되므로 PC값에 일정량만큼 더해져서 점프해야한다.
우리에게 주어진건 address다. address는 Shift left 2 를 통해 offset으로 변환되고, 이를 4 곱해 그 일정량을 구할 수 있다. 즉 PC = PC + 4 + (offset * 4)이다.
- Branch 위에 J타입 Data path를 쌓아보자. (j : 실행 순서와 관계없이 지정된 명령어로 점프)

j 명령어는 주어진 address로 바로 이동하면 된다. 이때 PC에 뭘 더해줘야 할까?
j 명령어의 address는 26bit다. 이를 Shift left 2 시켜 하위 2bit를 날린다. (26번, 25번째 숫자를 없애고 왼쪽으로 두칸 밀어낸다는 뜻, 4byte단위이므로 00으로 고정 되어있어 날려먹어도 됨) . 그렇다면 이것은 28비트다.
그리고 상위 4bit를 현재 PC값으로 채운다. 그 결과 address는 32비트가 된다.
이것이 곧 새로운 PC 값이 되고, 그 주소대로 점프한 모양새가 된다.
- 모든 Data path가 적용된 모양은 다음과 같다.

3개의 Data path는 각 MUX와 래자스터가 구분하고 있다고 해도 과언이 아니다.
RegDST, RegWrite, ALUSrc, ALUop, PCSrc, MemWrite, MemRead, MemToReg, JToPC 의 9개 중요 MUX 및 Control unit에 따라 Data path가 확확 달라지므로, 이 모든걸 총괄할 또하나의 Control unit이 필요하다. Control unit은 operation (31-26) 에 따라 각 MUX 및 Unit을 통제한다.

- Data path + Control Unit이 모두 적용된 Single Cycle은 다음과 같다.
