Sign Extension은 “작은 비트수의 값을 더 큰 비트수로 확장할 때, 원래의 부호(Sign) 를 유지하기 위해 최상위 비트(MSB)를 복사해서 채우는 것”이에요.
예를 들어, 명령어 안에 있는 9비트 offset(즉, imm9)을 ALU에서 사용하는 64비트 주소 연산에 넣기 위해서는 9비트를 64비트로 바꿔야 하죠. 이때 단순히 앞에 0만 채우면 부호(+, −)가 바뀔 수 있기 때문에 MSB(부호 비트)를 복사해서 확장합니다.
2️⃣ 왜 필요한가?
CPU 명령어 안에는 즉시값(immediate) 이나 offset이 제한된 비트수(예: 9비트, 12비트 등)로 저장돼 있어요.
하지만 실제 계산은 64비트 연산기(ALU)에서 수행하죠.
그래서 크기가 다른 두 데이터를 함께 계산하려면 작은 값을 큰 크기로 확장해야 합니다.
단, “음수 offset”도 올바르게 동작해야 하므로 부호(sign) 를 유지하면서 확장해야 해요.
➡ 그게 바로 Sign Extension의 역할입니다.
3️⃣ 동작 원리 (비트 단위로)
원래 값(9비트)MSB의미부호 확장(64비트)
000000010
0
+2
0000...00000010
111111110
1
−2
1111...11111110
즉,
MSB(맨 왼쪽 비트)가 0이면 → 나머지 상위 비트를 0으로 채움
MSB가 1이면 → 상위 비트를 1로 채움
이걸 식으로 쓰면 👇
ExtendedValue = { (N−M) copies of MSB, OriginalValue[M−1:0] }
예: 9비트 → 64비트 Extended[63:0] = { 55 copies of imm[8], imm[8:0] }
4️⃣ 예시 (Load/Store 명령어)
LDUR X1, [X2, #−8]
offset = −8 = 9비트 2’s complement → 1111 1110 00
부호 확장 후:→ 64비트 전체의 상위 비트가 전부 1로 채워짐.
1111 1111 1111...1111 1110 00
그 다음 ALU는 Address = X2 + (SignExtended(offset)) 으로 실제 메모리 주소를 계산합니다. 음수 offset이므로 기준 주소보다 8바이트 이전 주소를 가리키게 됩니다.
5️⃣ 하드웨어 구현
Sign Extension은 단순한 논리 회로로 구성됩니다.
Input: imm[8:0] Output: ext[63:0] for i in range(9, 64): ext[i] = imm[8] // MSB 복사for i in range(0, 9): ext[i] = imm[i]
즉, “MSB를 그대로 복제해서 나머지 비트를 채우는 회로”입니다. 보통 이 기능을 수행하는 작은 블록이 Datapath 내에 따로 들어가 있습니다. (그림에서도 Registers 옆의 Sign-extend 블록이 그 역할이에요.)
6️⃣ Zero Extension과의 차이점
구분Sign ExtensionZero Extension
상위 비트 채우기
MSB를 복제
전부 0으로 채움
부호 유지
O (음수/양수 보존)
X (항상 양수로 인식)
사용 예
LDUR, STUR, Branch offset 등
논리 연산 즉시값, 주소 인덱스 등
✅ 정리 문장
Sign Extension은 명령어 안의 작은 비트수 즉시값(offset 등)을 더 큰 데이터 크기(예: 64비트 ALU 입력)로 확장할 때 원래의 부호를 유지하기 위해 MSB를 복사해서 채우는 회로다.
즉, 양수면 0으로, 음수면 1로 상위 비트를 채워 ALU가 올바른 덧셈/뺄셈 결과를 낼 수 있게 한다.
Datapath 비교: R-type vs D-type
구분
R-type (연산)
D-type( Load / Store)
ALU 역할
두 레지스터 값 계산
메모리 주소 계산 (base + offset)
결과 저장 위치
레지스터
메모리(또는 레지스터)
입력
Rn, Rm
Rn(기준 주소), Offset
출력
Rd
Rt (load) 또는 메모리 주소
요약:
R-type은 연산 중심,
D-type은 주소 계산 + 메모리 접근 중심 구조
Datapath 통합 (R/D형 공통 구조)
두 형태의 명령어를 모두 실행할 수 있도록 하나의 Datapath에 MUX(멀티플렉서) 를 추가한다.
이 MUX는 ALU 결과와 메모리 출력을 선택해 “어떤 데이터가 레지스터에 기록될지”를 결정한다.
즉,
R-type이면 → ALU 결과가 선택
Load이면 → Memory 출력이 선택
이 제어 신호는 MemtoReg 이라고 하며, Control Unit이 제어한다.
🔴 빨간색 선: 데이터가 실제로 “흐르는 경로” (Datapath)
🔵 파란색 선: 각 블록의 동작을 제어하는 신호 (Control Path)
1️⃣ Registers (레지스터 파일)
명령어(Instruction)는 Register File에서 읽을 레지스터 2개(Read Register 1, 2) 와 쓸 레지스터(Write Register) 의 번호를 지정함.
두 입력값(Read data 1, Read data 2)이 ALU로 전달되어 연산에 사용됨.
Write data는 결과를 다시 저장하는 경로이며, Control 신호 RegWrite가 1일 때만 실제로 레지스터에 써짐.
2️⃣ Sign-Extend
D-type 명령어(Load/Store)는 명령어의 9비트 offset을 사용하기 때문에 이 값을 64비트로 부호 확장(Sign-extend) 해야 ALU에서 주소 계산 가능함.
결과는 MUX의 아래쪽 입력으로 연결되어 있음 (즉, ALU의 두 번째 입력 후보).
3️⃣ ALU & ALUSrc MUX
ALU는 두 입력값을 받아 계산을 수행함.
위쪽 입력: Read data 1 (첫 번째 레지스터 값)
아래쪽 입력: MUX를 통해 선택된 값
이 MUX의 선택 신호가 ALUSrc
0 → 두 번째 입력은 레지스터의 값(Read data 2) → R-type (ADD, SUB 등)
1 → 두 번째 입력은 Sign-extend된 offset → D-type (Load/Store 주소 계산)
즉, ALUSrc는 “ALU가 두 번째 입력으로 무엇을 쓸지” 결정함.
4️⃣ Data Memory
ALU 결과는 주소(Address) 로 사용됨. → D-type 명령어의 경우 실제 메모리 접근 주소임.
Control 신호에 따라 동작이 결정됨:
MemRead = 1 → 메모리에서 읽기 (LDUR)
MemWrite = 1 → 메모리에 쓰기 (STUR)
둘 다 0 → 메모리 접근 없음 (R-type 연산)
5️⃣ MemtoReg MUX
레지스터에 써야 할 값은 두 가지 경우가 있음:
ALU 결과 (R-type 연산)
Memory에서 읽은 값 (LDUR)
이 선택을 담당하는 신호가 MemtoReg
0 → ALU 결과를 저장
1 → Memory에서 읽은 데이터를 저장
따라서 Load 명령에서는 MemtoReg = 1, R-type에서는 0.
6️⃣ Control Signals 요약
제어 신호
의미
1일때 동
RegWrite
레지스터 쓰기 허용
결과를 레지스터에 저장
ALUSrc
ALU 두 번째 입력 선택
1 → Offset, 0 → 레지스터
MemRead
메모리 읽기
메모리 접근 허용
MemWrite
메모리 쓰기
메모리 쓰기 허용
MemtoReg
레지스터에 쓸 데이터 선택
1 → 메모리, 0 → ALU 결과
🔁 명령어별 동작 요약
명령어 유형
ALUSrc
MemRead
MemWrite
MemtoReg
RegWrite
설명
R-type (ADD, SUB)
0
0
0
0
1
ALU 결과를 레지스터에 저장
Load (LDUR)
1
1
0
1
1
메모리에서 읽은 값을 레지스터에 저장
Store (STUR)
1
0
1
X
0
레지스터 값을 메모리에 저장
전체 흐름 요약 (그림 중심으로 보기)
1️⃣ Instruction → Register 번호 해석 2️⃣ Registers에서 필요한 데이터 읽기 3️⃣ ALUSrc에 따라 ALU 입력 결정 4️⃣ ALU가 연산 수행 (연산 or 주소 계산) 5️⃣ Data Memory에서 읽기/쓰기 (Load/Store 시) 6️⃣ MemtoReg로 결과 선택 → RegWrite로 레지스터에 저장
Instruction Fetch 단계에서 PC와 명령어 메모리를 통해 명령을 읽고
R-type에서는 ALU를 이용해 레지스터 간 연산을 수행하며
D-type에서는 ALU로 메모리 주소를 계산하고 Load/Store를 수행한다.
마지막으로 R-type과 D-type을 하나의 공통 구조로 통합하기 위해 MUX(MemtoReg)를 추가하여 CPU가 명령어 종류에 따라 ALU 또는 Memory 데이터를 선택하도록 만든다