# 2017q1 Homework4 (microarch) contributed by <`csielee`> ## 重新複習MIPS 上次這個小測驗一出,真的是備受打擊 居然把計算機組織忘光光了 了解 CPU 可是資工人的浪漫,複習之路 go! 重新把[計算機組織結構](https://hackmd.io/s/H1sZHv4R#)看過 真的覺得整理的很好 ## 開始解題 ![](https://i.imgur.com/Y80lxhP.png) ### 分析題目 該題目是一個 piplining 的CPU 能夠偵測 Harazd並解決 Data Hazard * forwarding * 提早將 M or WB 階段的資料給 EX * forwarding unit 會決定要不要 forwarding 跟要 forwarding 誰 * Stalling(Load and R-Type) * 因為從 memory 取得資料需要等 M 階段結束,就算 forwarding 也來不及,因此讓 IF ID EX 都暫停一下 Control Hazard * flush * 同時在 IF/ID 跟 ID/EX 間就判斷是否要 branch,能夠猜錯也只要 flush 一個指令 ## 修改 1 :::info 做了 1: Stuck at 0 left of cut 的修改,`sw $s1, 0($s2)` 能否運作?這樣的修改會使得哪些程式無法運作,請列出至少兩項組合語言列表 ::: :::success `sw $s1, 0($s2)` 可以運作 ::: 因為沒有需要存進暫存器,是要把資料存進記憶體 cut 掉這條線造成在 WriteBack(WB) 階段,無法告訴 register 要將資料存進暫存器,因為 RegWrite 永遠是 0 ==無法運作的指令== ``` lw $s1, 0($s2) add $s1,$2,$3 ``` ## 修改 2 :::info 做了 2 的修改後,以下程式能否運作?解釋並提出可運作的版本 add $s1, $s1, $s1 add $s1, $t0, $t1 ::: :::success 可以運作 ::: cut 掉這條線,會造成 Rs 的 forwarding 失效 但是在這個範例中 `add $s1, $t0, $t1` 的 `$s1` 是 Rd 所以沒有 Data hazard 的問題 ## 修改 3 :::info 做了 3 的修改後,以下程式能否運作? addi $s2, $zero, 2 addi $s1, $zero, 2 beq $s2, $s1, exit ::: :::danger 不能運作 ::: ~~把這條線 cut 掉,會造成所有 branch 指令失效 因為在 ID 階段,如果 condition 成立會將 label 的值加在 PC 上並給 PC 但是這部份被 cut 掉,所以當然就失效了~~ ~~而且因為所有 branch 指令失效 基本上也不能使用 while、for、if 等結構~~ :::danger 這結論下太早了,並不是所有類型的 branch 都會失敗,試著將直接表示的數值變更,思考有沒有能夠運作的程式碼 --jserv ::: > 抱歉,結論下的太早 > 我看到 PC 來源只有 PC+4 跟 PC+4+(imm*4) > 就以為 cut 那條會讓所有 branch 指令失效 [name=東霖] ![](http://ithelp.ithome.com.tw/upload/images/20141008/2014100822281854354a02eb53e_resize_600.png) 重新查詢一些資料 發現這張圖挺不錯的 其實 cut 掉這條線,最主要是會造成 __condition branch 失效__ 也就是無法使用 beq 、 bne 指令 但是直接~~跳轉~~==跳躍==,或是從 $ra($31) 取得 addres 都是可行的 :::danger "jump" 的繁體中文翻譯是「跳躍」,不是「跳轉」,請注意 --jserv ::: 因此上述的 code 能夠修改成 :::success 修改後的版本 cmp: slt $t1, $s1, $s2 slt $t2, $s2, $s1 add $t1, $t1, $t2 sll $t1, $t1, 2 add $ra, $ra, $t1 jr $ra addi $s2, $zero, 2 addi $s1, $zero, 2 jal cmp j exit ::: 利用 jal 會把下一個指令位置存在 $ra 的特性 我們把 j exit 這個指令的位置存在 $ra 並且到 cmp 的部份去操作 $ra ,讓 PC 得到我們想要的結果 因為 `slt $t1, $s1, $2` 跟 `slt $t2, $s2, $s1` 最後會有三種結果 * if ($s1 = $s2), $t1 = 0 & $t2 = 0 * if ($s1 < $s2), $t1 = 1 & $t2 = 0 * if ($s2 < $s1), $t1 = 0 & $t2 = 1 經過 `add $t1, $t1, $t2` 剩兩種 * if ($s1 = $2), $t1 = 0 * if ($s1 != $2), $t1 = 1 因此把 $t1 乘上 4 之後加到 $ra 上 就能控制要不要跳過 `j exit` 這條指令 又不失去讓 $s1, $s2 比較的效果 > 這部份讓我思考很久,一直在想能不能夠直接取得 PC 的值 > 但是我觀察 32 個暫存器,沒有一個是 PC 的暫存器 > 所以我想應該是無法直接存取到 PC > 不知道這部份的想法有沒有錯誤 [name=東霖] > 老師提示說這個修改版本能夠更短 [name=東霖] ## 參考資料 [計算機組織結構](https://hackmd.io/s/H1sZHv4R#) [淺入淺出計組之旅(15)MIPS 體系結構 (5) ](http://ithelp.ithome.com.tw/articles/10158857) [ MIPS 指令集(共31条) ](http://blog.csdn.net/yixilee/article/details/4316617)