系列文章 : 使用 Verilog 實作 in-order CPU
execute-stage
execute stage 負責
- 計算出 branch 發生的話,要跳到的位址
- 使用 ALU 進行計算

在 execute-stage,會用到
- Shift_Left_Two_32
- Mux_4to1
- Mux_2to1
- Full_Adder_32
- ALU_Ctrl
- ALU
- Pipeline_Reg_EX_MEM
相關程式碼
Shift_Left_Two_32 shift_left
會把輸入的值左移 2 位 ( 乘以 4 )。
假如 instruction 是 branch 指令,且 imm 表示的是 pc 值的偏移量的時候。
- 當 imm 是 1,實際上 pc 值會偏移 4
- 當 imm 是 4,實際上 pc 值會偏移 16
簡單來說,就是需要乘以 4。
Mux_4to1 #(.size(32)) forward_regfile_1
這個 mux 是要選擇 regfile 是要用
- decode-stage 傳來的 regfile 值
- mem-stage
forward 來的 regfile 值
- wb-stage
forward 來的 regfile 值
而要選擇哪一個值,則是仰賴 forwarding unit 傳來的 forward_1_i 訊號來決定
Mux_2to1 #(.size(32)) mux_alusrc
ALU 進行計算的時候,會有兩個 source
- 第一個 source 永遠都會是 instruction format 裡的
rs 所指向的 reg-file 值。
- 第二個 source 可能是
rt 所指向的 reg-file 值,或是 instruction format 裡的 imm[15:0]
這個 mux 就是在選擇,這次 ALU 的第二個參數是
Mux_2to1 #(.size(5)) mux_regdst
這邊是要選擇,假如我們需要對 reg-file 進行寫入的話,該寫入哪一個 regfile
- 寫入到
rt 所指向的 regfile
- 寫入到
rd 所指向的 regfile
Full_Adder_32 branch_adder
假如目前執行到了 branch 指令的話,我們可能會需要替 (pc + 4),再加上 branch 的偏移量。
這個 full adder 就是來計算 branch 的偏移量。
ALU_Ctrl alu_ctrl
把 input 的訊號,轉換成交給 alu 的控制訊號
- funct_i : instruction format 的 funct_i[5:0] 欄位。
- ALUOp_i : instruction fomat 的 ALUOp_i[31:26] 欄位
舉幾個簡單的例子
- add 指令
- ALUOp_i 是 6b’000000
- funct_i 是 6b’100000
- 我希望做的是
src_1_i + src_2_i
- 那我的
output [3:0] ALUCtrl_o 會希望是 4b’0010
- slt 指令
- ALUOp_i 是 6b’000000
- funct_i 是 6b’101010
- 我希望做的是
src_1_i < src_2_i
- 那我的
output [3:0] ALUCtrl_o 會希望是 4b’0111
- sub 指令
- ALUOp_i 是 6b’000000
- funct_i 是 6b’100010
- 我希望做的事
src_1_i - src_2_i
- 那我的
output [3:0] ALUCtrl_o 會希望是 4b’0101
ALU alu
接受來自 ALU_Ctrl 的訊號,並對 src1, src2 做出相對應的操作。
- result_o : 計算的結果
- zero_o : 計算的結果是否為 0
Pipeline_Reg_EX_MEM pipeline_reg_ex_mem
- regfile_2_o
- 這個 instruction 的 rt 該是什麼值。
- mem-stage 會需要 rt,對 mem-stage 來說,rt 可能是需要存入 data-memory 的
value。例如說 lw $rt, offset($rs)。
- decoder_signals_o
- regdst_o
- 假如這個 instruction 會對 reg-file 進行寫入的話,
regdst 是需要被寫入的 reg-file 的位址
- branch_adder_o
- 假如這個 instruction 是一個 branch,這個值是發生 branch 後要跳去的位址。
- alu_result_o
- 對 mem-stage 來說,alu_result ( rs + imm ) 可能是需要存入 data-memory 的
address。
- 對 mem-stage 來說,會需要 alu_result 來判斷說要不要 branch
- alu_zero_o
- mem-stage 會需要 alu_zero_o 來判斷說要不要 branch