컴퓨터 구조 및 설계 4장
4장 프로세서
4.2 논리 설계 관례
MIPS 구현에 쓰이는 데이터패스 요소는 2가지 종류의 논리 소자들로 구성된다.
- 조합소자(combinational element)
- 데이터 값에만 동작하는 소자
- 출력이 현재의 입력에만 의존한다.
- 같은 입력이 주어지면 항상 같은 출력을 낸다.
- ex) ALU: 내부 기억소자가 없기 때문에 주어진 입력에 대하여 항상 같은 출력을 낸다.
- 상태소자(state element)
- 상태를 갖는다.
- 소자에 내부 기억장소가 있으면 상태를 갖게 된다.
- 플러그를 빼도 소자가 가지고 있던 값들로 상태소자를 적재하면 다시 시작시킬 수 있다.
- ex) 명령어 메모리, 데이터 메모리 및 레지스터
- 적어도 2개의 입력과 1개의 출력을 갖는다. (꼭 있어야 되는 입력은 기록할 데이터와 클럭이다.)
- 클럭 입력은 데이터 값이 소자에 기록되는 시점을 결정한다.
- 상태소자의 출력은 이전 클럭 사이클에 기록된 값이다.
- 상태소자의 값을 읽는 것은 언제라도 가능하다.
- 순차회로(sequential circuit)
- 상태를 포함하는 논리소자들
- 출력이 입력뿐만 아니라 내부 상태에도 의존한다.
클러킹 방법론
신호를 언제 읽을 수 있고 언제 쓸 수 있는지를 정의한다. 예측 가능성을 보장하기 위해 고안되었다.
단순화를 위해 에지 구동 클러킹(edge-triggered clocking) 방법론을 가정한다. 이는 순차논리소자에 저장된 값은 클럭 에지에서만 바꿀 수 있다는 것을 의미한다. 이때, 클럭 에지는 낮은 값에서 높은 값 혹은 그 반대로의 빠른 변이를 말한다. 모든 조합회로는 상태소자에서 입력을 받고 상태소자로 출력을 내보낸다. 입력은 이전 클럭 사이클에서 쓴 값이고 출력은 다음 클럭 사이클에서 사용할 수 있는 값이다.
클럭 신호와 쓰기 제어 신호는 상태소자의 입력이며, 쓰기 제어신호가 인가되고 활성화 클럭 에지일 때만 상태소자가 변하게 된다. 여기서 인가된(asserted)라는 용어는 논리적으로 높은 신호를 표시한다. 논리적으로 낮은 값을 표시하기 위해서는 비인가된(deasserted)라는 용어를 사용한다.
에지 구동 방법론은 레지스터의 내용을 읽고 그 값을 조합회로로 보내고 같은 레지스터에 쓰는 작업 모두가 한 클럭 사이클에 일어나는 것을 허용한다. 조합회로에 대한 입력은 선택된 클럭 에지에서만 변한다. 또한, 한 클럭 사이클 내에는 피드백(feedback)이 되지 않는다.
32비트 MIPS가 취급하는 거의 모든 데이터는 32비트 폭을 갖는다. 그렇기 때문에 프로세서의 상태소자와 논리소자의 입력과 출력 폭은 거의 다 32비트이다. 그림에서 버스(bus)는 굵은 선으로 표시할 것이다. 버스는 폭이 2비트 이상인 신호들이다. 여러 버스들을 합쳐서 더 넓은 버스를 만드는 경우, 버스선에 레이블을 붙여서 버스를 합쳤다는 것을 명확하게 나타낸다. 소자 간의 데이터 흐름 방향을 명확하게 하기 위해 화살표를 붙이기도 한다. 끝으로 데이터를 운반하는 신호와 구별하기 위해 제어신호는 파란색으로 나타낸다.
4.3 데이터패스 만들기
프로세서의 범용 레지스터 32개는 레지스터 파일이라고 하는 구조 속에 들어있다. 레지스터 파일은 레지스터들을 모아 놓은 것인데, 파일 내의 레지스터의 번호를 지정하면 어느 레지스터라도 읽고 쓸 수 있다. 레지스터 파일은 컴퓨터의 레지스터 상태를 갖고 있다.
R 형식 명령어
R 형식 명령어들은 레지스터 피연산자 3개를 가지고 있기 때문에, 매 명령어마다 레지스터 파일에서 두 데이터 워드를 읽고 데이터 워드 하나를 써야 한다.
- 레지스터에서 데이터 워드를 읽기 위해서는 레지스터의 입력 1개와 출력 1개가 필요하다.
- 읽을 레지스터 번호를 지정하는 입력
- 레지스터에서 읽은 값을 내보내는 출력
- 데이터 워드를 쓰기 위해서는 입력이 2개 필요하다.
- 레지스터 번호를 지정
- 레지스터에 쓸 데이터 값
레지스터 파일은 Read register 입력에 실리는 번호에 해당하는 레지스터 내용을 항상 출력한다. 하지만, 쓰기는 제어신호에 의해 제어되기 때문에 클럭 에지에서 쓰기가 일어나기 위해 제어 신호가 인가되어야 한다.
즉, R형식 명령어는 4개의 입력(레지스터 번호용 3개, 데이터용 1개)와 2개의 출력(데이터용 2개)이 필요하다.
데이터 메모리 유닛
- 데이터가 있는 메모리 주소 입력
- 메모리에서 읽은 데이터 출력
- 메모리에 쓸 데이터 입력
- 쓰기 제어 신호
- 저장 명령어일 때만 쓰기를 해야한다.
- 읽기 제어 신호
- 레지스터 파일과는 달리 메모리 유닛은 읽기 신호가 필요하다.
- 올바르지 않은 주소의 값을 읽으면 문제를 일으킨다.
beq 명령어
비교할 레지스터 2개와 16비트 변위로 3개의 피연산자를 갖는다. 변위는 분기 명령어 주소에 대한 상대적인 분기 목적지 주소를 계산하는데 사용된다.
분기 명령어의 정의 중 주의를 기울여야 하는 점
- 명령어 집합 구조는 분기 주소 계산의 베이스 주소가 분기 명령어 다음 명령어의 주소라고 서술하고 있다. 명령어 인출 데이터패스에서 PC+4(다음 명령어의 주소)를 계산하기 때문에 이 값을 분기 목적지 주소 계산의 베이스로 사용하는 것이 편하다.
- 구조는 또한 변위 필드를 2비트만큼 왼쪽 자리이동하여 워드 변위가 된다고 서술한다. 이렇게 함으로써 변위 필드의 유효 범위를 4배만큼 증가시킨다.
분기 목적지 주소를 계산하는 것 외에 실행할 다음 명령어가 뒤에 있는 명령어가 될지 아니면 분기 목적지 주소에 있는 명령어가 될지를 판단해야 한다.
- 조건이 사실일 때, 분기 목적지 주소가 새로운 PC값이 된다. (분기가 일어났다)
- 조건이 거짓일 때(피연산자 값이 같지 않으면), 증가된 PC값이 새로운 PC값이 된다. (분기가 일어나지 않았다)
즉, 분기 데이터패스는 분기 목적지 주소를 계산하고 레지스터 내용을 비교하는 2가지 일을 해야 한다.
- 분기 목적 주소 계산
- 부호확장 유닛과 덧셈기를 포함한다.
- 분기 목적지 주소 = 증가한 PC값 + 명령어의 하위 16비트(분기 변위)를 부호확장한 후 왼쪽으로 2비트 자리이동한 값
- 부호확장 후 왼쪽으로 2비트 자리이동하기 떄문에, 복제된 부호 비트만 2개 없애 버리게 된다.
- 레지스터 내용 비교
- 레지스터 피연산자 2개, 이를 읽기 위한 레지스터 파일이 필요하다.
- ALU로 비교 연산을 한다.
- ALU에는 결과가 0인지를 나타내는 출력 신호를 제공하기 때문에 두 레지스터 피연산자를 제어신호와 함께 ALU에 보내 뺄셈을 한다.
- ALU의 Zero 신호가 인가되면, 두개의 값이 같다는 것을 알 수 있다.
- 즉, ALU의 Zero 신호를 분기 명령어의 같은지 여부 테스트에서 사용하도록 한다.
점프(jump) 명령어
명령어의 하위 26비트를 2비트만큼 왼쪽으로 자리이동한 값으로 PC의 하위 28비트를 대체한다. 이 자리이동은 점프 변위 뒤에 00을 덧붙이면 된다.