# 2017q1 Homework04 (microarch)
contriduted by <`king1224`>
###### tags: `king1224`
## 複習[計算機組織](https://hackmd.io/s/H1sZHv4R)
* $CPU\ Time = \frac{Seconds}{Program} = \frac{Instructions}{Program} \times \frac{Clock\ Cycles}{Instruction} \times \frac{Seconds}{Clock\ Cycle}$
* 真心每次都會搞錯 MIPS 和 MIPS
* Millions of Instruction Per Second
* Microprocessor without Interlocked Pipeline Stages
* [MIPS 指令集](http://blog.xuite.net/tzeng015/twblog/113272086-MIPS+%E6%8C%87%E4%BB%A4%E9%9B%86),有寫出下指令時 rs, rt, rd 的位置順序,常常記不起來 rs, rt 的位置呢
* MIPS Division
我想放一下這個,因為~~我完全忘光光了~~,老師說不會就不會,不要說忘記。
__devide algorithm__

>問題: 為什麼在步驟一要先左移一個 bit?
>回答: 不論正負,都先以無號數計算
>[name=洪正皇][color=#ea4331]
__divide hardware__

* IEEE 表示法
這些特殊值很有趣,因為我不知道
special value:
|Exponent|Significand|Object|
|--------|-----------|------|
|0|0|+/- 0|
|0|nonzero|denormalized underflow|
|1-254|anything|normalized floating number|
|255|0|+/- infinity|
|255|nonzero|NaN|
* ALU control
下面的 ALUop 是不是該改成 ALU control
|ALUop|Function|
|----|----|
|0000|and|
|0001|or|
|0010|add|
|0110|subtract|
|0111|set on less than|
|1100|nor|
* logic equation:
從來沒有這樣想過,都只是死背的 opcode + function 得到的 ALUcontrol
* ALUctr2 = ALUop0 + ALUop1‧func2’‧func1‧func0’

* ALUctr1 = ALUop1’ + ALUop1‧func2’‧func0’

* ALUctr0 = ALUop1‧func3’‧func2‧func1’‧func0 + ALUop1’‧func3‧func2’‧func1‧func0’

提問: 為什麼 func3, func2, func1, func0 不是 don't care?
回答: 如果設成 don't care 的話,就不能分辨是哪一項 R type
* internal forwarding
* write in first half clock and read in second half
* 原來這個方式叫這個名字
## 問題討論
考慮以下 MIPS 實作,其 data path 如下:

上圖紅色的 `1`, `2`, `3` 對 MIPS 做了對應的修改,請考慮以下狀況,分別解釋對應的程式碼是否能運作:
## 修改1
做了 `1: Stuck at 0 left of cut` 的修改,`sw $s1, 0($s2)` 能否運作?這樣的修改會使得哪些程式無法運作,請列出至少兩項組合語言列表

* __可以運作__
從圖中可以看到 WB 是控制著 MemtoReg, RegWr 這兩條訊號線的,切掉之後 register block 會一直以為訊號線的值為 0,因此無法將資料寫回 register,而 `sw $s1, 0($s2)` 是將資料寫入記憶體,__因此可以運作__。
* __不能運作的情況__
`lw $s1, 0($s2)`
`add $s1, $t1, $t2`
## 修改2
做了 `2` 的修改後,以下程式能否運作?解釋並提出可運作的版本
```
add $s1, $s1, $s1
add $s1, $t0, $t1
```
* 可以運作
這條線是 rs 的 forwarding 資料線,而從[這裡](http://blog.xuite.net/tzeng015/twblog/113272086-MIPS+%E6%8C%87%E4%BB%A4%E9%9B%86)可以看到第二行 add 指令的 $s1 是 rd,根本不會造成 forwarding 阿!!!
> 差點被騙了
>hazard conditions:
>1. EX/MEM.RegisterRd = ID/EX.registerRs
>2. EX/MEM.RegisterRd = ID/EX.registerRt
>3. MEM/WB.RegisterRd = ID/EX.registerRs
>4. MEM/WB.RegisterRd = ID/EX.registerRt
>[name=洪正皇][color=#ef7c9f]
## 修改3
做了 `3` 的修改後,以下程式能否運作?
```
addi $s2, $zero, 2
addi $s1, $zero, 2
beq $s2, $s1, exit
```
這條線所傳遞的值為 PC+4+(imm*4),需要將目標 address 經過 sign-extend 的 branch 指令將會無法計算要跳去的目的地,如圖中的表格第三行

> 但這張圖是還沒提前判斷 branch 的架構
> 原題目中將是否 equal 提前到 ID 階段判斷,也另外用一個加法器來提早得到目標位址
> [name=洪正皇][color=#db6ba1]
因此 beq, bnq ...等 branch 指令皆無法運作,而 jump 的指令如 j, jr ...等可以正常運作
#### 修改過後的 code
```
addi $s2, $zero, 2
addi $s1, $zero, 2
j exit
```
經過我人工 assembler 後,s1 跟 s2 不是本來就一樣的嗎...
__正常版 beq 改寫,看過 [csielee 大大](https://hackmd.io/s/Byl8yvFse#)的版本後就回不去了,目前我想不到更好的解法,但~~直接抄過來~~似乎也不太好__
改善 csielee 大大的暫時版:
將 slt 改成 xor,可以少判斷一行,xor 有值代表不同,沒值代表相同,而 slt 需要做兩次才能判斷是否相同,但 xor 的值出來不知道怎麼處理
```
cmp:
xor $t1, $s1, $s2
or $t1, $t1, $zero
sll $t1, $t1, 2
add $ra, $ra, $t1
jr $ra
addi $s2, $zero, 2
addi $s1, $zero, 2
jal cmp
j exit
```