본문내용
1. Verilog를 사용한 MIPS 파이프라인 구현
1.1. Vivado를 이용한 MIPS 파이프라인 모델 분석
1.1.1. ALU 모듈
ALU 모듈은 MIPS 파이프라인 구조에서 중요한 역할을 담당한다. ALU 모듈에서는 ALU_Input1과 ALU_Input2, 그리고 ALU_Control을 입력으로 받아 다양한 연산을 수행한다. 구체적으로 살펴보면, ALU_Control에 따라 ALU_Input1과 ALU_Input2에 대해 add, sub, and, or 등의 연산이 이루어지고 그 결과값이 ALU_Result로 출력된다.
R-type 명령어의 경우, ALU_Input1과 ALU_Input2를 이용하여 산술 및 논리 연산을 수행한다. 반면, branch 명령어는 ALU_Input1과 ALU_Input2가 같은지 다른지에 대한 비교 연산을 수행하고 그 결과를 ALU_Result가 아닌 Zero 신호로 출력한다. 즉, ALU_Input1과 ALU_Input2가 같으면 Zero에 1을 할당하고 다르면 0을 할당한다.
이처럼 ALU 모듈은 MIPS 파이프라인의 연산을 담당하는 핵심적인 부분이며, 연산의 결과와 비교 결과 등을 다음 단계의 모듈로 전달하는 역할을 한다. 이를 통해 MIPS 프로세서의 전체적인 동작이 가능해지는 것이다.
1.1.2. ALUControl 모듈
ALUControl 모듈은 MIPS 파이프라인에서 ALU의 연산 동작을 결정하는 중요한 역할을 한다. 이 모듈은 main control에서 나온 ALUOp 코드와 instruction의 function code를 입력으로 받아 ALUControl 신호를 출력한다. 즉, main control에서 명령어의 유형을 파악하여 전달한 ALUOp 코드와 instruction의 function code를 토대로 ALU의 연산 방식을 결정하는 것이다.
예를 들어, ALUOp가 00이면 load/store 연산을 위한 add 동작을, 01이면 branch 비교 연산을 위한 subtract 동작을, 10이면 R-type 연산을 위한 동작을 수행하게 된다. 그리고 R-type 연산의 경우 function code에 따라 add, sub, and, or 등 다양한 ALU 연산이 이루어진다.
이처럼 ALUControl 모듈은 MIPS 파이프라인에서 ALU의 동작을 정확히 제어하는 중요한 역할을 한다. 명령어의 유형과 function code를 종합적으로 분석하여 적절한 ALU 연산을 수행하도록 하는 것이 이 모듈의 핵심 기능이라고 할 수 있다.
1.1.3. CONTROL 모듈
CONTROL 모듈은 명령어와 clock을 input으로 받아 여러 제어 신호들을 output으로 출력한다. 모듈 내부에서는 명령어의 상위 6비트를 Opcode로 할당하여, Opcode에 따라 각각의 명령어들을 결정한다.
Opcode가 0이면 R-type instruction, Opcode가 4이면 beq 명령어 등과 같이 Opcode에 따라 명령어의 종류를 구분한다. 이를 통해 각 명령어의 실행을 위한 적절한 제어 신호를 생성한다.
제어 신호에는 RegWrite, RegDst, ALUOp, ALUSrc, Branch, MemRead, MemWrite, MemtoReg 등이 포함된다. 이들 신호는 파이프라인의 각 단계에서 데이터 경로와 제어 흐름을 결정하는데 사용된다.
예를 들어 R-type instruction의 경우 EX 단계에서 RegDst=1, ALUOp1=1, ALUOp0=0, ALUSrc=0의 제어 신호가 출력된다. 이에 따라 ALU 연산이 수행되고, 그 결과가 destination register rd에 쓰이게 된다.
또한 Branch 명령어의 경우 MEM 단계에서 Branch=1, MemRead=0, MemWrite=0의 제어 신호가 출력된다. 이를 통해 ALU의 비교 결과를 기반으로 branch 여부가 결정되고, 필요 시 PC가 업데이트 된다.
이와 같이 CONTROL 모듈은 명령어의 종류를 분석하고, 각 파이프라인 단계에 적합한 제어 신호를 생성함으로써 MIPS 프로세서의 전체적인 동작을 제어한다.
1.1.4. DataMemory 및 DMEMORY 모듈
DataMemory 모듈과 DMEMORY 모듈은 lw와 sw 등 데이터 메모리에 접근하는 명령어의 경우에 사용된다. 이 모듈들은 메모리의 주소와 데이터를 다룬다.
DataMemory 모듈에서는 MEMWrite=1과 MemRead=1에 의해 ALUOut을 데이터 메모리의 주소로 사용하고, 데이터 메모리 주소의 하위 8비트를 ReadData에 쓴다. 즉, ALUOut을 통해 데이터 메모리의 주소를 지정하고, 그 메모리 주소의 데이터를 읽어 ReadData에 출력하는 역할을 한다.
DMEMORY 모듈도 유사한 기능을 수행한다. 데이터 메모리에 접근할 때 사용되는 모듈로, ALUOut을 메모리 주소로 받아 해당 주소의 데이터를 읽고 쓰는 역할을 담당한다.
이를 통해 lw와 sw 명령어가 데이터 메모리에 접근할 수 있게 된다. lw 명령어는 데이터 메모리의 내용을 읽어 레지스터에 저장하고, sw 명령어는 레지스터의 내용을 데이터 메모리에 저장한다.
즉, DataMemory 모듈과 DMEMORY 모듈은 파이프라인 구조에서 메모리 접근 기능을 제공하는 중요한 역할을 한다고 볼 수 있다.
1.1.5. IFETCH 모듈
IFETCH 모듈은 파이프라인 MIPS 구현에서 IF(Instruction Fetch) 단계를 담당하는 모듈이다. IFETCH 모듈에서는 PC(Program Counter)와 파이프라인 레지스터를 매 클럭 사이클마다 사용하므로, 클럭 신호가 입력으로 들어온다.
IFETCH 모듈의 역할은 다음과 같다. 첫째, IFETCH 모듈에서 다음 PC(next PC)의 주소값을 계산한다. 브랜치 명령어가 taken(taken)이면 next PC는 브랜치 타겟 주소가 되고, 그 외의 경우에는 next PC가 PC+4가 된다. 둘째, 계산된 next PC 주소를 통해 명령어 메모리에서 명령어를 가져와 IF/ID 파이프라인 레지스터에 쓰는 역할을 한다.
즉, IFETCH 모듈은 PC를 관리하고 명령어를 가져오는 기능을 수행하여, 파이프라인의 IF 단계를 구현하고 있다. 이를 통해 MIPS 프로세서의 명령어 실행이 파이프라인 방식으로 진행될 수 있게 한다.
1.1.6. IDECODE 및 Registers 모듈
IDECODE 및 Registers 모듈은 MIPS 파이프라인의 ID(Instruction Decode) 단계에서 사용되는 주요 모듈이다. 이 모듈은 Instruction을 decode하고, 두 개의 source register 값을 읽어오는 역할을 한다.
IDECODE 모듈에서는 먼저 Instruction을 decode한다. 이를 위해 Instruction의 상위 6비트를 Opcode로 할당하여, Opcode=0인 경우 R-type instruction, Opcode=4인 경우 beq 명령어 등 Opcode에 따라 각각의 명령어들을 결정한다. 또한 rs, rt, rd, shamt, funct 필드를 분리하여 이후 단계에서 사용할 수 있도록 한다.
그 다음으로 IDECODE 모듈에서는 두 개의 source register 값을 읽어온다. 명령어에 따라 두 개의 source register 값과 Sign_Ext(imm) 중 두 개를 택하여 ALU 연산의 input으로 사용한다. 예를 들어, R-type instruction의 경우 rs와 rt register 값을, lw/sw 명령어의 경우 rs register 값과 S...