系列文章 : 使用 Verilog 實作 in-order CPU
decode-stage 負責 :

在 decode-stage 階段,會用到
相關程式碼
在認識 decode 階段以前,我們可以先認識一下,每個我們需要支援的 instruction,他們的 format 會是長什麼樣子。

實作 CPU 的暫存器,從程式碼可以看到,這邊的設計總共有 32 個 registers。
我們可以把資料暫時地儲存在裡面,並在 instruction 需要他們的時候,再將他們給提取出來。
rd_addr_in 就是我們想要取用的 register 的位置。因為總共有 32 個 registers,所以 rd_addr_in 的寬度是 5 bits ( 2 ** 5 = 32 )。
rd_addr_*_out 就是從 regfile 裡面提楚出的暫存器的內容。
在這個設計,是要到 wb-stage 才會知道要不要寫入 register。以下的幾個 signals 都是從 wb-stage,不經由 pipeline-register 傳過來的。
note :
上一個 instruction 會對 a register 進行 lw ( load ),也就是從 memory 把值載入到 register當下的這一個 instruction 會想要使用 a register這時候會發生什麼事情呢 ?
上一個 instruction 要到 wb-stage 才會更新 register 的值當下的這一個 instruction 在 ex-stage 就需要使用當下的這一個 instruction 在 ex-stage 的時候,上一個 instruction 還停留在 mem-stage !!!這導致了 當下的這一個 instruction 在 ex-stage 的時候,會取得舊的,不正確的值。這時候我們就需要使用到 hazard detection 跟 forwarding unit 的組合技了。
這邊有一個小巧思。
assign rd_data_1_out = ((rd_addr_1_in == wr_addr_in) && reg_write_in) ? wr_data_in : reg_file[rd_addr_1_in];
假如寫入的位址跟輸出的位址相同,就直接輸出寫入的值,這樣可以節省一個 cycle。
把 instruction format 裡的 imm[15:0] 從 16 bits,利用 signed extension 擴展成 32 bits。
在 decoder 裡,我們會把 instruction 解析出許多的控制訊號。
不是 一個 branch instruction是 一個 branch instructionalu 的結果交給 reg-filememory 的結果交給 reg-fileex-stage 的 ALU Control 的訊號。我這邊比較懶惰,直接把 instruction 的 [5:0] 丟給 ALUCtrl,該有更好的設計。rt register 的值,還是在 instruction imm[15:0] 裡面的值 ?rt register 的值交給 ALU來個範例吧
add instruction 會需要什麼樣的控制訊號呢 ?
rt register。rd 指向的 register,而不是 rt 指向的 register。note : 假如控制訊號通通都是 0 ,會發生什麼事 ?
不會改變 CPU 狀態 … 所以假如我們想要在 CPU pipeline 裡面插入一個 bubble ( nop ),在這個設計裡,我們只需要把所有控制訊號設為 0。
把需要從 decode-stage 交給 ex-stage 傳進 pipeline register
decode-stage 會跟以下單元互動