Architecture / ISA
Intermediate
MIPS32 Architecture / MARS Simulator
MIPS 32비트 명령어 포맷(R/I/J) 및 5단계 파이프라인 해저드(Hazard) 해결
MIPS 아키텍처의 3대 명령어 포맷(R, I, J-Type) 비트 필드 구조와 5단계 파이프라인(IF-ID-EX-MEM-WB)의 데이터 해저드 포워딩 및 분기 지연 슬롯(Branch Delay Slot) 동작 원리.
#MIPS #Assembly #Computer Architecture #Pipeline #Hazard
핵심 개념MIPS(Microprocessor without Interlocked Pipeline Stages)는 고정된 32비트 명령어 크기와 3가지 단순한 포맷(R, I, J)으로 하드웨어 복잡도를 극단적으로 낮춘 고전 RISC의 정수입니다. 5단계 파이프라인(IF-ID-EX-MEM-WB)을 거치는 과정에서 선행 명령어의 결과를 후행 명령어가 즉시 필요로 하는 데이터 해저드(Data Hazard)를 해결하기 위해 포워딩(Forwarding / Bypassing)과 분기 지연 슬롯(Branch Delay Slot)을 도입했습니다.
1. MIPS 3대 명령어 포맷 구조
모든 MIPS 명령어는 정확히 32비트(4바이트)로 고정되어 있으며 메모리 워드 경계(Word-aligned)에 정렬됩니다.
| 포맷 유형 | 비트 필드 구성 (총 32비트) | 용도 및 대표 명령어 |
|---|---|---|
| R-Type (Register) | opcode (6) | rs (5) | rt (5) | rd (5) | shamt (5) | funct (6) | 레지스터 간 산술/논리/시프트 연산 (add, sub, and, sll) |
| I-Type (Immediate) | opcode (6) | rs (5) | rt (5) | immediate (16) | 상수 연산, 메모리 로드/스토어, 조건 분기 (addi, lw, sw, beq) |
| J-Type (Jump) | opcode (6) | target address (26) | 무조건 장거리 점프 및 서브루틴 호출 (j, jal) |
2. 5단계 파이프라인 구조와 해저드(Hazard)
- IF (Instruction Fetch): PC가 가리키는 메모리 주소에서 명령어를 인출하고 PC를 4 증가.
- ID (Instruction Decode / Register Read): 명령어를 디코드하고 소스 레지스터(rs, rt)의 값을 읽음.
- EX (Execute / Address Calculation): ALU에서 산술 연산 수행 또는 메모리 주소(base + offset) 계산.
- MEM (Memory Access): 데이터 메모리 읽기(lw) 또는 쓰기(sw) 수행.
- WB (Write Back): 연산 결과나 로드된 데이터를 목적지 레지스터(rd 또는 rt)에 기록.
3. 데이터 해저드 해결: 포워딩(Forwarding)
선행 명령어의 연산 결과는 이미 EX 단계 끝에서 나오지만, 정규 절차대로라면 WB 단계(5단계)가 끝날 때까지 레지스터 파일에 기록되지 않습니다. 이때 EX/MEM 또는 MEM/WB 파이프라인 레지스터에서 결과값을 가로채 다음 명령어의 ALU 입력으로 직결하는 기법을 포워딩(Forwarding / Bypassing)이라고 부릅니다.
# 1. 포워딩으로 해결 가능한 데이터 해저드 (Stall 불필요)
add $s0, $t0, $t1 # $s0 = $t0 + $t1 (EX 단계에서 결과 산출)
sub $t2, $s0, $t3 # EX/MEM 레지스터의 $s0 값을 ALU 입력으로 직접 바이패스(Forwarding)
# 2. 포워딩만으로 불가능한 Load-Use 해저드 (1-Cycle Stall 필수)
lw $s0, 0($sp) # 메모리에서 $s0 값은 MEM 단계가 끝나야 확보됨
nop # 1-사이클 버블(Stall) 삽입 필요 (하드웨어가 자동 삽입)
add $t1, $s0, $t2 # MEM/WB 파이프라인 레지스터에서 EX 단계로 포워딩
# 3. 분기 지연 슬롯 (Branch Delay Slot)
beq $t0, $t1, target # 분기 여부와 상관없이 바로 다음 1개 명령어가 무조건 실행됨
add $v0, $zero, $zero # <- 지연 슬롯에 유용한 명령어 배치 (없으면 nop)
4. 실무 주의점 및 특징
- 지연 슬롯(Delay Slot)의 유산: 초기 파이프라인 하드웨어의 분기 페널티를 숨기기 위해 분기 명령어 바로 다음 칸을 무조건 실행하도록 설계되었으나, 후대 superscalar 프로세서에서는 컴파일러 최적화와 인터럽트 복귀를 극도로 복잡하게 만들어 현대 아키텍처(RISC-V 등)에서는 완전히 폐지되었습니다.
- $zero 레지스터(하드웨어 0):
$0은 항상 0으로 하드와이어링되어 있어 레지스터 초기화나 복사(add $t0, $s0, $zero)를 단일 명령어로 구현할 수 있습니다.