系列文章 : [gem5] 從零開始的 gem5 學習筆記
在 Inside the Minor CPU model 這一篇的 Fetch2 stage 章節已經講述的很清楚了,這邊簡單做個中文的筆記!
在 Fetch2 會做兩件很重要的事情
這兩件事情都是蠻大的主題,值得好好花時間來研究一下。
Fetch2 會從 Latch 拿取來自 Fetch1 的資料,並填進自己的 inputBuffer 裡面。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L244
值得一提的是,在 Fetch1 Stage,就會去 reserve Fetch2 Stage 的 InputBuffer。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch1.cc#L657
在 Fetch2 Stage 裡,會把資料從 inputBuffer 提取出來,並將資料 decode 成一個個 instructions。這些 instructions 後續會被打包,送進 Decode stage。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L404
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L488
Fetch2 包含了 branch prediction 的功能。這邊的 branch prediction 使用 gem5 本身已經實作好的 branch predictor ( gem5/cpu/pred/… )。
https://github.com/gem5/gem5/tree/v25.1.0.0/src/cpu/pred
當 Fetch2 遇到會進行 branch 的 instruction 的時候,都會嘗試去進行分支預測。
假如 branch predictor 嘗試對一個 instruction 進行分支預測,這個 instruction 的 MinorDynInst::triedToPredict flag 會被設定起來。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L197-L198
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L202
當分支預設的結果是要跳的話,MinorDynInst::predictedTaken 會被設定,並且 MinorDynInst::predictedTarget 會被設定成要跳過去的 PC( program counter ) 值。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L210
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L211
這個分支預測的結果會把 predictionSeqNum + 1。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L225
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L230
並且會經由 Latch 送給 Fetch1,所以 Fetch1 要到下一個 Cycle 才會收到這個分支預測的結果。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L539
當一個分支預測的結果是要跳的話, Fetch2 會把 input buffer 給拋棄掉。
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L509
並且會拒絕所有 ( (相同 streamSeqNum) && (不同 predictionSeqNum) ) 的資料。
streamSeqNum) && (不同 predictionSeqNum) ),表示這個資料已經過時了。明明分支預測的結果說要跳 ( predictionSeqNum + 1 ),但這個資料的 predictionSeqNum 卻還是舊的,表示這個資料需要被丟棄。streamSeqNum ),表示 Execute stage 有確定好的 Branch ( 於是 streamSeqNum + 1 ),這個資料就不能被丟棄。streamSeqNum) && (相同 predictionSeqNum) ),表示這個資料是根據分支預測的結果走的,這個資料不能被丟棄。https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L320-L322
Fetch2::havePC 代表了 Fetch2::pc 是否有效
當 Fetch2::pc 有效的時候,就可以將 Fetch::pc 交給 instruction
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L370
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L413
Fetch::havePC 原本就是 true 的話,會在 instruction decode 完之後,去更新 pc 值
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L458
Fetch2::havePC 想從 false 變為 true 的話,就需要對 fetch_info.pc 直接進行設定
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L340
Fetch2::havePC 會從 true 變為 false 的話,通常是當前的 inputBuffer 的資料需要被丟棄,導致當前的 Fetch2::pc 失效
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L261-L262
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L283-L284
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L509-L510
https://github.com/gem5/gem5/blob/v25.1.0.0/src/cpu/minor/fetch2.cc#L509-L510