가장 basic한 path : 한 clock사이클 내에 모든 명령어가 끝난다.
를 가정하고 진행해 보자. 이를 single clock cycle CPU라고 한다.
지금부터 고려할 instruciton들은
1) memory-reference instruciton : lw(load), sw(store)
2) arithmetic-logicla instruciton : add, sub, and, or, slt
3) control flow instruciton : beq, j
이다.
이들을 통해 하드웨어를 꾸며보자!
일반적으로 명령어가 실행되는 단계를 생각해보자.
Fetch(메모리에 있는 명령어를 CPU에 가져오는 과정)
-> Decode(가져온 명령어를 해독하는 과정)
-> execute(해독한 명령어를 기준으로 실행하는 과정)
즉, CPU내의 Program counter 레지스터 값을 메모리 주소로 삼아서 메모리의 특정 위치에 있는 데이터를 가져오게 되는데 즉 명령어를 가져오는 것이다. 이 명령어를 해독하고, 실행할 때는 레지스터를 읽고 레지스터를 가지고 무엇을 할지 실행하게 된다.
이번에는 operation을 살펴보자.
우선 아래는 op에 000000이 있기에 R format에서의 산술연산이라고 생각할 수 있다.
그리고 1000000이면 add라고 생각할 수 있다.
(100010 : sub)
여기서는 rs와 rt값을 더해서 rd에 저장한다는 것이다.
1) Fetch instruction : 현재 PC값을 가지고 메모리에서 값을 읽어오는데 명령어를 가져오는 것이다. IR에 저장하는데 Instructino Register로 메모리에서 읽어온 값을 저장하는데 사용된다.
2) ADD operation : rs와 rt field에서 레지스터 값을 읽어오고 이를 rd field에서 가리키는 번호의 레지스터에 저장한다.
3) Calculate next address : PC는 다음 번 명령어를 가져오기 위해 증가한다.
이 동작들이 한 clock cycle 내에 다 동작하도록 하는 것이다!
이번에는 lw operation을 보자.
lw는 메모리의 특정 번지의 데이터값을 CPU 내 rt register로 가져오는 것을 의미한다.
이 때, lw의 메모리 주소를 계산하기 위해 필요한 것이 rs와 imm16의 상수값이다.
이 때 imm16을 32비트로 만들기 위해 sign-extension을 통해 만들어준다.
PC를 통해 메모리에서 값을 읽어와 저장한다.
이후 lw를 위해 32비트로 만들어주어 메모리 주소를 얻고, 이 메모리 주소를 통해 값을 읽어내어 rt에 저장하게 된다.
sw는 lw와 정 반대인데, CPU 내의 rt 레지스터의 값을 메모리에 저장하는 것이다.
이번에는 beq operation을 살펴보자.
이는 rs와 rt값이 동일하면 branch를 하고 그렇지 않으면 branch를 하지 않는 것이다.
동일하게 메모리에서 읽어와서 IR에 저장하고 rs-rt를 수행하여 cond에 저장한다. 이 cond가 0이면 branch를 하게 된다. 이 때 imm16 상수나 jump의 26비트 상수값과 같은 명령어의 주소를 의미할 때는 항상 x4를 하여(즉 왼쪽으로 두 비트를 이동하여) 그 상수를 사용하게된다.
이 상수와 PC값을 더하여 업데이트 해 주는 것이다.