目前只完成了設計概念和硬件描述,支持部分常用32位MIPS指令(ADD, SUB, LW, SW等)。硬件描述用的是SystemVerilog語言,生成軟件Synplify 9.6.2。昨天我測試了執行單元和指令控制單元,這兩個主要的組件沒大問題,剩下的不敢保證。別抱太大期望,大一計算機工程學生能力有限。下圖是中央處理器的寄存器傳輸層的簡化設計概念。
數據路徑的部分單元改造自Harris & Harris的教材“Digital Design and Computer Architecture“的微架構例子。為了方便,我們假設內存分為數據內存和指令內存。可見CPU擁有常規的5級流水線(Instruction Fetch, Instruction Decode, Execute, Memory, Write Back),并有兩份數據路徑,因此超純量,理想化下每周期可同時執行10個指令。
藍線圈的是流水線的執行組件。
紅線圈的是數據路徑,兩個完全相同
在HDL中,我將命名兩個運行指令為I0和I1或Instr0和Instr1,PC為PC0和PC1,下周期PC為PC0F,PC1F。
CPU的完整硬件生成:
我的設計中最有趣(也是最難完成)的部分是名為IFHU(Instruction Flow and Hazard Unit)的指令流動及數據冒險控制單元。
原稿:
它內置了一個小型三級流水線,目的就是為了儲存(如果存在)指令的RD(Destination Register),Register File的目標地址。地址在IFHU內的流動模擬了真正指令在處理器流水線的執行完成度,因此每次PC從指令內存讀出對應指令后,指令如果是BEQ,R- Type或I-Type,他們的根寄存器的地址(RS,RT)將于存在于IFHU流水線內的RD做對比,如果有相同地址代表會出現數據冒險。這些結果會輸出到IFU(Instruction Flow Unit),指令控制單元,它按照以下原理決定最終指令是否為空指令以及下周期PC的值:
1. I0和I1正常:執行兩個指令,PC0,PC1 + 8
2. I1出現跳躍,分支,或數據冒險:執行I0,PC0 = PC1,PC1 + 4
3. I0出現數據冒險:不執行,PC都不變
4. I0出現跳躍或分支:內部執行,PC0為預測或跳躍后PC,PC1 = PC0 + 4
不出錯的話PC1應該永遠等于PC0。
下面是IFU:
IFHURegSelect:
IFHUXORComp:
IFHU的另一個重要的組件是一個簡單的2位分支預測器。目前我的CPU只支持BEQ(Branch on Equal)這一個分支指令,不過剩下的也都是這一個來的。這是分支預測器FSM:
設三個狀態位元為S2S1S0。主要狀態Predict Taken,Weak Not Taken,和Strong Not Taken分別有自己的子狀態In Progress,In Progress表示已做預測,不知結果,在這個狀態下不會再做預測,確保流水線最多執行一個分支預測。根據上面的FSM,可得出一個下個狀態的真值表:
分支預測器將先把兩個可能的PC存進FF,然后使用預測的方向(S1)選擇預測PC。同時一個相反方向的電路(~S1)將選擇相反的PC,最終由BRsuccess(預測是否成功)來選擇最終輸出到IFU。
接下來的指令解碼流程就比較直接了。MIPS指令需要讀取的寄存器地址直接輸進32x32位的寄存器,結果讀到RDXX。從這里起,將會有兩個數據路徑以及兩個控制單元。
寄存器或許也同時要儲存四個周期前的指令的計算結果或內存數據,WA[4:0]是寫入地址,WD[31:0]是寫入內容,寄存器的CLK依然和處理器同步但 FF在Falling Edge更換,保持同周期完成。SigExt是Sign Extend的縮寫,它負責把指令的Immediate從16位擴到32位。
32x32位的寄存器矩陣:
控制單元:
執行單元的輸出ALUcontrol控制ALU的功能:
RegWrite和MemWrite控制寄存器和內存是否寫入,RISel控制執行單元ALU的第二個輸入使用寄存器內容還是Imm。這些控制電路會如數據電路往流水線的下一個階段進行。
接下來是 EU(Execution Unit),執行單元。EU以目前支持的指令來看,只需要一個多功能ALU,以后可以加一個FPU和支持SIMD擴展的計算單元。另外RD1讀出的內容直接接到WriteData邏輯,在SW指令里,這個將直接寫入數據內存。RegAddr是R-Type或I-Type指令的Write Back地址,因為地址在這兩類指令里的位置不一樣,控制單元根據OPCode輸出的RISel邏輯會選擇對應的地址
R-Type:0000 00ss ssst tttt ddddd000 0010 0101 (Write Back地址為d)
I-Type:1000 11ss ssst ttttiiii iiii iiii iiii (Write Back地址為t)
ALU的設計很簡單,控制單元根據Funct輸出的ALUcontrol[1:0]控制ALU的功能。現在只需要ADD,SUB,AND,OR。我這里懶省事了,本來想自己寫個Carry Look-Ahead Adder但是時間來不及,直接用SV的“+”了。
這是用ModelSim測試EU的結果:
結果都正確。
接下來測一下IFHU,我用以下六個指令
如果正常的話,IFHU應該并行執行指令1和2,到第二個周期,指令4有冒險,因此IFHU應該只執行指令3,并繼續讀取指令4和5,這兩個都依然有冒險,所以在第三周期PC不變。
匯編器的結果:
ModelSIm運行指令:(完全列出來)
結果:
細看一下第一周期的結果:
可見兩個指令都順利通過,PC都加8
第二周期:
這里的I1F為0開頭,代表空指令,PC0 = PC1,而PC1 = PC1 + 4
第三周期:
兩個指令都成空指令,PC也不變,根預料的一樣。目前IFHU未發現大問題,指令流動正常。
剩下的就不多說了,MEM和WB都很直接。如果不是馬上要考期末了,我會再加點指令,再仔細測測所有單元。本來還想來個亂序執行設計,再放個寄存器重命名單元和保留站,但現在的能力有限,我想先讀幾本更深的教材。接下來我把幾個主要Module的描述發出來。
-
cpu
+關注
關注
68文章
10873瀏覽量
212020 -
MIPS32架構
+關注
關注
0文章
1瀏覽量
4477
發布評論請先 登錄
相關推薦
評論