CPU: Data Hazard Conditions
MIPS의 데이터 해저드 조건
이 조건들은 현재
ID
또는EX
단계에 있는 명령어가 값을 읽으려고 하는데, 그 값이 아직 레지스터 파일에 기록되지 않고 이전 명령어의 파이프라인 레지스터에 중간 결과로 존재하는 경우를 감지합니다.이 조건들이 현재 instruction이 읽는 (Rs 또는 Rt) register 번호와 이전 instruction이 write 하는 register 번호(Rd)와 같은지 체크하는 것입니다. 만약 같다면 (그리고
RegWrite
신호가 활성화되어 있다면), 해당 조건에 맞는 포워딩이 수행됩니다.1.
EX/MEM.RegisterRd == ID/EX.RegisterRs
/EX/MEM.RegisterRd == ID/EX.RegisterRt
설명: 현재
EX
단계에 있는 명령어(이전 명령어)가MEM
단계로 넘겨줄Rd
(목적지 레지스터 번호)와, 현재ID
단계에서EX
단계로 넘어온 명령어(현재 명령어)가 읽으려는Rs/Rt
가 같은 경우입니다.상황:
EX
단계의 명령어가 방금 계산을 마친 결과를EX/MEM
레지스터에 저장했습니다. 이 결과는 아직 레지스터 파일에 쓰여지지 않았지만, 바로 다음EX
단계에 있는 명령어가Rs
로 이 값을 필요로 합니다.처리:
EX/MEM
레지스터에 있는 ALU 결과(또는 메모리 주소)를 바로EX
단계의 ALU 입력으로 포워딩합니다. (EX -> EX 포워딩)
2.
MEM/WB.RegisterRd == ID/EX.RegisterRs
/MEM/WB.RegisterRd == ID/EX.RegisterRt
설명: 현재
MEM
단계에 있는 명령어(더 이전 명령어)가WB
단계로 넘겨줄Rd
(목적지 레지스터 번호)와, 현재ID
단계에서EX
단계로 넘어온 명령어(현재 명령어)가 읽으려는Rs
(첫 번째 소스 레지스터 번호)가 같은 경우입니다.상황:
MEM
단계의 명령어가 계산을 마치고 결과를MEM/WB
레지스터에 저장했습니다. 이 결과는 아직 레지스터 파일에 쓰여지지 않았지만,EX
단계에 있는 명령어가Rs
로 이 값을 필요로 합니다. (이 경우는 EX/MEM에서 포워딩하는 것보다 더 오래된 값입니다.)처리:
MEM/WB
레지스터에 있는 ALU 결과 또는 메모리 로드 결과(load 명령어의 경우)를 바로EX
단계의 ALU 입력으로 포워딩합니다. (MEM -> EX 포워딩)
Detecting data hazards
if (EX/MEM.RegWrite
and (EX/MEM.RegisterRd =! 0)
and (EX/MEM.RegisterRd == ID/EX.RegisterRs)) FowardA=10
if (EX/MEM.RegWrite
and (EX/MEM.RegisterRd =! 0)
and (EX/MEM.RegisterRd == ID/EX.RegisterRs)) FowardB=10
이 조건들은 현재
EX
단계에 있는 명령어가 읽으려는 레지스터 값이, 바로 이전 명령어(EX/MEM
레지스터에 있는 명령어)가 계산한 결과인 경우를 감지합니다. 이 경우가 가장 우선순위가 높습니다.
EX/MEM.RegWrite
:EX/MEM
레지스터에 있는 명령어가 레지스터 파일에 값을 쓸 예정인가? (RegWrite
신호가 1인가?) 레지스터에 쓰지 않는 명령어(예:sw
,beq
)라면 포워딩할 결과값이 없으므로 이 조건은false
가 됩니다.(EX/MEM.RegisterRd != 0)
:EX/MEM
레지스터에 있는 명령어가 값을 쓸 목적지 레지스터 번호가$zero
레지스터($0
)가 아닌가?$zero
레지스터는 항상 0이므로, 여기에 값을 써도 실제 의미 있는 변경은 없으며,$zero
를 쓰는 명령어에 대해서는 포워딩할 필요가 없습니다. (혹은 쓰지 않는다고 간주합니다.)(EX/MEM.RegisterRd == ID/EX.RegisterRs)
:EX/MEM
레지스터에 있는 명령어의 목적지 레지스터 번호(Rd
)가, 현재EX
단계에 있는 명령어의 첫 번째 소스 레지스터 번호(Rs
)와 같은가?결과:
ForwardA=10
이 세 가지 조건이 모두 참이면, 현재EX
단계에 있는 명령어의 첫 번째 ALU 피연산자(Rs
의 값)를EX/MEM
레지스터에서 포워딩 받도록ForwardA
신호를10
으로 설정합니다.
if (MEM/WB.RegWrite
and (MEM/WB.RegisterRd =! 0)
and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0)
and (EX/MEM.RegisterRd == ID/EX.RegisterRs)))
and (MEM/WB.RegisterRd == ID/EX.RegisterRs)) FowardA=01
if (MEM/WB.RegWrite
and (MEM/WB.RegisterRd =! 0)
and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0)
and (EX/MEM.RegisterRd == ID/EX.RegisterRt)))
and (MEM/WB.RegisterRd == ID/EX.RegisterRs)) FowardB=01
이 조건들은 현재
EX
단계에 있는 명령어가 읽으려는 레지스터 값이, 두 단계 이전에 실행된 명령어(MEM/WB
레지스터에 있는 명령어)가 계산한 결과인 경우를 감지합니다. 이 조건은EX/MEM
에서의 포워딩 조건보다 낮은 우선순위를 가집니다. 즉,EX/MEM
에서 포워딩할 수 없는 경우에만MEM/WB
에서 포워딩을 고려합니다.
MEM/WB.RegWrite
:MEM/WB
레지스터에 있는 명령어가 레지스터 파일에 값을 쓸 예정인가?(MEM/WB.RegisterRd != 0)
:MEM/WB
레지스터에 있는 명령어의 목적지 레지스터 번호가$zero
가 아닌가?(MEM/WB.RegisterRd == ID/EX.RegisterRs)
:MEM/WB
레지스터에 있는 명령어의 목적지 레지스터 번호(Rd
)가, 현재EX
단계에 있는 명령어의 첫 번째 소스 레지스터 번호(Rs
)와 같은가?결과:
ForwardA=01
이 세 가지 조건이 모두 참이면, 현재EX
단계에 있는 명령어의 첫 번째 ALU 피연산자(Rs
의 값)를MEM/WB
레지스터에서 포워딩 받도록ForwardA
신호를01
으로 설정합니다.
우선순위와 not
조건 (EX/MEM
vs MEM/WB
)
코드에서 not
이 포함된 조건이 보입니다. 이는 포워딩 우선순위를 나타내는 핵심입니다.
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd != 0) and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0) and (EX/MEM.RegisterRd == ID/EX.RegisterRs)))
이 긴 조건은 다음을 의미합니다:
MEM/WB
에서 포워딩할 준비가 되어 있고 (앞의 두 조건)AND (
not
부분):EX/MEM
에서 이Rs
에 대한 포워딩을 할 수 있는 상황이 아니라면 (EX/MEM
에서 포워딩하는 조건이 거짓이라면 --> 다음 조건으로 넘어가서MEM/WB
결과를 포워딩 하겠다.)
즉, EX/MEM
에서 포워딩할 수 있는 더 최근의 결과가 있는 경우에는 MEM/WB
의 결과를 사용하지 않겠다는 의미입니다. 이는 항상 가장 최근의 정확한 데이터를 사용하기 위한 중요한 로직입니다.
Load-use data hazards conditions
if (ID/EX.MemRead and
((ID/EX.RegisterRt == IF/ID.RegisterRs) or
(ID/EX.RegisterRt == IF/ID.RegisterRt))) stall the pipeline
ID/EX.MemRead
:ID/EX
파이프라인 레지스터에 있는 명령어 (현재EX
단계로 들어가려는 명령어)가 메모리 읽기(Load) 명령어인가? (즉,MemRead
제어 신호가 1인가?)이것은 로드 명령어(
lw
)에 한정된 해저드임을 명확히 합니다.add
,sub
같은 연산 명령어는 이 조건을 만족하지 않습니다.
((ID/EX.RegisterRt == IF/ID.RegisterRs) or (ID/EX.RegisterRt == IF/ID.RegisterRt))
:이 부분이 다음 명령어(현재
ID
단계에 있는 명령어)가 방금 로드된 값을 사용하려는지를 확인하는 조건입니다.ID/EX.RegisterRt
: 현재EX
단계로 진입하려는 로드 명령어(lw
)가 값을 로드하여 쓸 목적지 레지스터 번호(Rt
)입니다. (MIPSlw
명령어는Rt
필드를 목적지 레지스터로 사용합니다.)IF/ID.RegisterRs
: 현재ID
단계에 있는 명령어(로드 명령어의 바로 다음 명령어)의 첫 번째 소스 레지스터(Rs
) 번호입니다.IF/ID.RegisterRt
: 현재ID
단계에 있는 명령어(로드 명령어의 바로 다음 명령어)의 두 번째 소스 레지스터(Rt
) 번호입니다.이 두 조건을
or
로 묶은 것은, 다음 명령어가 로드된 값을Rs
로 사용하든,Rt
로 사용하든 상관없이 모두 감지하기 위함입니다.
Stall 은 어떻게 할까?
nop(no operation) 을 삽입합니다.
Nop : state를 변화시키지 않는 instruction