1. MIPS指令系統(tǒng)從不同維度的劃分
1.1 從功能維度劃分
<1> 運(yùn)算指令
<2> 訪存指令
<3> 分支指令
1.2 從格式維度劃分
<1> R型指令
<2> I型指令
<3> J型指令
2. 運(yùn)算指令且R型指令的典型 - 加法指令addu
addu rd,rs,rt 該指令實現(xiàn)的功能是rd = rs+rt
該加法指令的指令格式如下圖所示,

減法指令subu和addu非常類似,因此都以addu指令為例進(jìn)行分析,看加法指令的控制信號如何給。
2.1 加法指令的操作步驟
<1> 從指令存儲器取回指令
<2> 執(zhí)行加法操作,R[rd] = R[rs] + R[rt]
<3> 計算下一條指令的地址,因為加法指令是順序執(zhí)行的,因此PC = PC+4
2.1.1 取指
Instruction = MEM[PC]
從指令存儲器中取回指令
所有指令都有這個步驟
取指這個步驟是在IFU中完成的,如下圖所示,

取指的時序如下圖所示,假設(shè)在t0這個上升沿取指,一些延遲后,PC寄存器的輸出穩(wěn)定,再過一定時間延遲后到達(dá)下圖紅色虛線位置,指令存儲器的輸出穩(wěn)定,完成了取指操作。

2.1.2 執(zhí)行加法運(yùn)算
首先要取得操作數(shù),操作數(shù)所在的寄存器編號是放在指令編碼中的,可以根據(jù)加法指令的位域分布從IFU取出的32-bit指令編碼中,輸出操作數(shù)所在寄存器的編號,如下圖所示,

rs、rt、rd分別連接在數(shù)據(jù)通路相應(yīng)的位置,現(xiàn)在再把筆記11中建立的數(shù)據(jù)通路放在這里方便分析?;貞浖拇嫫鞫训奶匦?,當(dāng)寄存器堆的Ra和Rb改變時,busA和busB會立刻輸出相應(yīng)的數(shù)據(jù)(有一定的電路延遲),即不受時鐘信號控制。

為了實現(xiàn)加法操作,那么控制信號應(yīng)該為,
<1> nPC_sel = "+4",即PC寄存器加4,順序執(zhí)行
<2> ALUSrc = 0,即選擇busB上的數(shù)據(jù)作為ALU的第二個輸入
<3> ExtOp = X,因為ALUSrc = 0,因此擴(kuò)展部件的輸出已經(jīng)沒有意義了,擴(kuò)展部件執(zhí)行零擴(kuò)展還是符號擴(kuò)展我們都不關(guān)心
<4> ALUCtr = "ADD",讓ALU執(zhí)行加法操作
經(jīng)過一段時間延遲后,ALU輸出了加法結(jié)果,根據(jù)數(shù)據(jù)通路圖,ALU的輸出連接在一個數(shù)據(jù)存儲器的地址輸入端上和一個2選1多路器上,addu指令不訪問數(shù)據(jù)存儲器,因此輸出存儲器的寫使能必須為0,否則下個時鐘沿,數(shù)據(jù)存儲器會采樣busB上的數(shù)據(jù)并改變數(shù)據(jù)存儲器的內(nèi)容。另外,數(shù)據(jù)存儲器和寄存器堆一樣,Adr輸入端改變,經(jīng)過一段電路延遲后,就會輸出數(shù)據(jù)存儲器內(nèi)對應(yīng)地址的數(shù)據(jù),不受時鐘控制,因此,后面的2選1多路器必須選擇ALU的輸出而不是數(shù)據(jù)存儲器的輸出,
<5> MemWr = 0
<6> MemtoReg = 0
現(xiàn)在ALU的輸出會被送到寄存器堆的busW上,即寫數(shù)據(jù)輸入端口,必須將寄存器堆寫使能置有效,且選擇rd作為寫回寄存器,這樣下個時鐘上升沿來時,就可以將加法結(jié)果寫入rd
<7> RegWr = 1
<8> RegDst = 1
這時考慮電路延遲,時間已經(jīng)過去了一小段,如下圖所示,

再過一定延遲,寄存器堆的busW信號穩(wěn)定,下一個時鐘沿即t1到來時,寄存器堆就可以正確采樣busW上的數(shù)據(jù),并寫入rd指定的寄存器,這樣就完成了這一步操作。
2.1.3 更新PC寄存器的內(nèi)容
PC = PC+4
除了分支指令,其他指令都要執(zhí)行這個步驟。

我們要注意,IFU和數(shù)據(jù)通路的電路是同步執(zhí)行操作的,當(dāng)數(shù)據(jù)通路進(jìn)行加法操作時,IFU也在同時進(jìn)行更新PC的操作,這里控制信號已經(jīng)在2.1.2的<1>給出,即nPC_sel = "+4",在下一個時鐘上升沿即t1到來前,PC的輸入端的信號已經(jīng)穩(wěn)定,這樣,t1到來,PC就能正確更新。
再過一定延遲,PC+4對應(yīng)的指令就又被取出,這樣取指 - 執(zhí)行 - 再取指 - 再執(zhí)行,每條指令都會得到執(zhí)行,且每條指令都在一個時鐘周期內(nèi)完成。
3. 運(yùn)算指令且I型指令的典型 - ori指令
首先來看ori指令的格式,

3.1 ori指令執(zhí)行步驟
<1> MEM[PC] 從指令存儲器中取回指令
<2> R[rt] = R[rs] | ZeroExt[imm16] 指令指定的操作
<3> PC = PC+4 順序執(zhí)行
可以看出,第<1>步和第<3>步和addu指令是一樣的,直接看第<2>步。

控制信號應(yīng)該這樣給出,
<1> nPC_sel? = "+4"
<2> ALUSrc = 1,這里與addu不同,ori指令選擇立即數(shù)為ALU的第二個輸入
<3> ExtOp = "zero",擴(kuò)展部件對imm16應(yīng)該進(jìn)行零擴(kuò)展
<4> ALUCtr = "OR",ALU執(zhí)行or運(yùn)算
<5> MemWr = 0,因為這條指令不需要寫數(shù)據(jù)存儲器
<6> MemtoReg = 0,選擇ALU的運(yùn)算結(jié)果送到寄存器堆的寫數(shù)據(jù)輸入端口
<7> RegWr = 1,寄存器堆的寫使能有效
<8> RegDst = 0,這里與addu不同,ori的寫回寄存器由rt字段指定
這樣,我們就可以在1個時鐘周期內(nèi)完成ori指令的操作。