# 計算機組織期末筆記 早上起床要看的 ALUOP ![](https://i.imgur.com/HOiOWe7.png) #### OP code R-type : 00 0000 lw : 10 0011 sw : 10 1011 beq: 00 0100 ## Single ### instructions : R = op | rs | rt | rd | shamt | func I = op | rs | rt | imm16 J = op | imm26 | Inst | Reg transfer | | ---- | -------- | | ADD | R[rd] = R[rs] + R[rt] | | LW | R[rt] = MEM[ R[rs] + sign_ext(imm16) ] | | SW | MEM[ R[rs] + sign_ext(imm16) ] = R[rt] | ### pipeline : - Write back 的 reg 位置要多一個 mux #### structural hazard 1. 兩個 instructions 要用同一坨硬體(Load > R-type) ![](https://i.imgur.com/htPATkn.png) ![](https://i.imgur.com/beac0Ll.png) 2. 解決方法: - 用2個 Memory : Data Memory & Instruction Memory #### Data Hazards 1. **問題** - RAW:前面的還沒寫,後面就讀出來(讀到舊資料),**MIPS只有這個** - WAW:後面的先寫了(寫到舊資料) - WAR:前面的還沒讀,後面的就先寫了(讀到新資料) 2. **解決方法** - Compiler inserts NOP (軟件解法,變慢) - Stall (硬件解法,變慢) - Forward (硬件解法) b![](https://i.imgur.com/02yrtL9.png) #### Forwarding ![](https://i.imgur.com/gWqrftu.png) - EX stage: ```EX/MEM.RegWrite && EX/MEM.RegRd != 0 && EX/MEM.RegRd = ID/EX.RegRs``` 檢查前一個指令是否需寫入暫存器 && 暫存器編號不為零 && id相同 - MEM stage: ```MEM/WB.RegWrite and MEM/WB.RegRd != 0 && MEM/WB.RegRd = ID/EX.RegRs``` 檢查前兩個指令是否需寫入暫存器 && 暫存器編號不為零 && id相同 - 兩個都行的話要選近的 #### Stall ![](https://i.imgur.com/ReLmbUX.png) - 偵測 ```(ID/EX.MemRead == 1 && ID/EX.RegisterRt = IF/ID.RegisterRs/Rt)``` 檢查前一個是否為 lw 且寫入暫存器的編號與rs/rt相同 - 產生bubble 不更新 PC、IF/ID 暫存器,寫 0 進 ID/EX 暫存器的控制訊號讓 ALU 不做事 #### Control hazards 需要做決定,而做決定需要前面的東東,但還沒算出來 #### Brench hazards - Static 預設不會跳,beq taken 之後,前面會有一個 bubble - Dynamic brench prediction 根據歷史資料猜要不要跳,可以省掉 bubble,因為迴圈所以會差很多 - Delayed Branch(sw) 預設不跳、branch decision at ID,這時塞一個非執行不可的指令在 beq 後面 ## Memory ### Write Stragety #### Write-Back 只更新 block,透過 dirty bit 檢查 #### Write Allocation Allocate on miss : fetch the block Write around : don't fetch the flock (when initialize) #### 實務上的搭配 write through + write around write back + write allocation ## Virtual Memory disk -> pages memory -> frame