一、流水線CPU概述
1、流水線CPU的原理
流水線CPU是為提高吞吐量而創造的,五段式流水線CPU的吞吐量是單周期CPU的五倍,同一時間CPU上最多有五條指令在運行。如何達到同一CPU上五條指令呢?答案就在於把每條指令都拆分成五個階段,按照CPU硬件執行流來拆成五段:IF(instruction fetch)、DEC(decode)、EXE(execute)、ME(memory)、WB(write back),CPU上五段部分分別執行一條指令的一個階段。
因為CPU上五段分別進行不同指令的不同階段,每段都需要自己當前執行指令的數據:IF段所用數據為指令地址,可有pc寄存器提供;DE、EXE、ME、WB段所用數據包含但不限於指令內容,一定需要對應流水線寄存器保存。
2、流水線CPU設計的難點
流水線CPU同時有多條指令運行,一個很重要的設計因素是解決沖突。沖突包含硬件沖突、控制沖突和數據沖突。
-
硬件沖突
硬件沖突是說同一時刻需要對同一互斥硬件(一次只允許一次讀或寫)進行訪問,舉例來說,D段需要從存儲器中取出指令,M段需要對存儲器寫入數據,這兩個操作同時進行就會帶來沖突,在這里IM和DM是獨立的兩個存儲器,因此不必考慮。
-
控制沖突
控制沖突是分支指令和跳轉指令帶來的沖突。分支指令的最終分支地址晚於下一周期到來,導致下一條指令的地址不能及時算出或者決定;跳轉指令的跳轉地址晚於下一周期到來,導致上述同樣沖突。解決這樣的沖突主要是通過假設不跳轉或者延遲槽。假設不跳轉是說先假設不跳轉和分支,正常執行下一條指令,當計算出要跳轉時清楚已執行的結果。延遲槽是說跳轉指令后面加空指令nop,即等待跳轉地址計算出來再決定是繼續下一條指令還是跳轉。
-
數據沖突
數據沖突是關於數據“新鮮性”的沖突。指令的執行離不開寄存器,有的指令會利用寄存器數據,有的指令會寫回寄存器,有的指令兩者皆有,當前序執行的指令的目的寄存器(將要寫回的寄存器)和后序執行的指令的源寄存器(利用其數據的寄存器)相同時,就存在數據關聯。當前序指令數據還未寫入寄存器,后序指令就要用到該數據時,就會產生錯誤(沖突)。解決這種沖突需要暫停或者轉發:當前序指令的“新”將要寫回寄存器的數據(計算)趕不及后序指令使用其數據時就需要暫停后序指令,直到前序指令的“新”數據准備好;當前序指令的“新”數據能趕上后序指令的使用,當前序指令的“新”數據准備好后,轉發給后序指令當前所處階段的流水線寄存器,以達到更新數據的效果。
注意:以下是筆者設計流水線的流程(吃百家飯得來)
二、流水線CPU的功能設計
1、支持指令
str | ld | cal_r | cal_i | lui | b_type | j | jr | jal | jalr | shamt | mod |
---|---|---|---|---|---|---|---|---|---|---|---|
sw | lw | addu | ori | beq | sll | mult | |||||
sb | lb | add | xori | bne | sra | multu | |||||
sh | lh | subu | andi | blez | srl | div | |||||
lbu | sub | addiu | bgtz | divu | |||||||
lhu | sllv | addi | bltz | ||||||||
srav | sltiu | bgez | |||||||||
srlv | slti | ||||||||||
and | |||||||||||
or | |||||||||||
xor | |||||||||||
nor | |||||||||||
slt | |||||||||||
sltu |
2、流水線寄存器
流水線寄存器記錄上一階段的數據並保持,供所在階段使用,因此每階段寄存器所需數據如下:
D | E | M | W |
---|---|---|---|
IR | IR | IR | IR |
RD | |||
AO | AO | ||
RD1 | |||
EXTD | EXTD | EXTD | |
RD2 | RD2 | ||
PC4 | |||
PC8 | PC8 | PC8 | PC8 |
PC | PC | PC | PC |
TNEW_E | TNEW_M | ||
HI | HI | ||
LO | LO |
3、所需硬件
先不考慮所有沖突而只考慮執行指令,和單周期CPU的功能硬件設計一樣,列出所需硬件,不一樣的是指令分五段執行,硬件也可分階段列出。
本表不包含多選器,多選器在整合數據通路時給出。
下面列出的硬件中有三個值得說明:
-
BEEXT和RDEXT
支持指令中有sh,sb,lh,lhu,lb,lbu這些對半字、字節操作的指令,但是存儲器是按照字讀或者寫的,因此對於存儲指令需要BEEXT給出字節選擇信號,對於加載指令需要RDEXT處理讀出的字。
BEEXT接受的輸入為AO_M1_0和三個布爾信號(分別代表指令是否為sw,sh,sb)。AO_M1_0意義是ALU輸出在M段結果的低兩位,也就是寫入地址對4取模的結果(一個字4字節)。BEEXT產生的輸出是四位信號,分別表示將要存儲的數據的四個字節是否存儲。
RDEXT接受的輸入為AO_W1_0、RD_W和五個布爾信號(分別表示指令是否是lw,lh,lhu,lb,lbu)。AO_W1_0是ALU輸出在W段結果的低兩位,也就是讀出地址對4取模的結果。RD_W是DM中讀出的字。按照五條指令的要求分別對RD_W處理,最后根據五個布爾信號選擇一個輸出。
-
MDU
乘除運算單元和hi,lo寄存器所在。whi和wlo是hi,lo寄存器的寫入信號。start是乘除運算的啟動信號,busy是乘除運算進行中的信號。這里乘法模擬用5個時鍾周期完成(start后的第一個上升沿開始,busy高亮五個周期),除法模擬用10個時鍾周期完成。
階段 | module | input | output | 功能描述 |
---|---|---|---|---|
IF | PC | D | Q | |
ADD4 | PC | PC4 | ||
ADD8 | PC | PC8 | ||
IM | IA | IR | ||
DE | RF | A1 | RD1 | 從寄存器堆讀出寄存器數據 |
A2 | RD2 | |||
EXT | I16 | EXTD | 選擇輸出SIMM,LIMM,UIMM | |
EXTOP | ||||
CMP0 | FRSD | LESS | 輸出和0比較的結果,獨熱輸出 | |
GREAT | ||||
LE_EQ | ||||
GR_EQ | ||||
CMP | D1 | RES | 輸出比較結果 | |
D2 | ||||
NPC | PC4 | NEXTPC | 選擇輸出BPC,JPC | |
I26 | ||||
NPCOP | ||||
EX | MDU | NUM1 | BUSY | 乘除模塊,WHI,WLO為寫使能,WDHI,WDLO為寫入數據 |
NUM2 | HI | |||
MDUOP | LO | |||
START | ||||
WHI | ||||
WLO | ||||
ALU | A | AO | 執行不同操作 | |
B | ||||
SHAMT | ||||
ALUOP | ||||
ME | BEEXT | AO_M1_0 | BE | 得到字節寫入使能信號,為1的那一位代表對應dm中的字相應部分寫入字節 |
SW_M | ||||
SH_M | ||||
SB_M | ||||
DM | DA[11:2] | RD | 支持寫入字節、半字、字和讀出字 | |
WD | ||||
WM | ||||
BE[3:0] | ||||
WB | RDEXT | RD_W | RDEXTD | 將dm中取出的字按照指令做相應處理得到將寫入rf的字 |
AO_W1_0 | ||||
LW_W | ||||
LHU_W | ||||
LH_W | ||||
LBU_W | ||||
LB_W | ||||
RF | A3 | |||
WD3 | ||||
WR |
4、數據通路
將流水線寄存器和功能硬件針對每一條指令連接起來。
模塊 | INPUT | NOP | LD | STR | CAL_R | CAL_I | SHAMT | LUI | J | JR | JAL | JALR | B_TYPE | MDU |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
PC | D | |||||||||||||
ADD4 | PC | Q | Q | Q | Q | Q | Q | Q | Q | Q | Q | Q | ||
ADD8 | PC | Q | Q | |||||||||||
IM | IA | Q | Q | Q | Q | Q | Q | Q | Q | Q | Q | Q | Q | Q |
PC | D | PC4 | PC4 | PC4 | PC4 | PC4 | PC4 | PC4 | PC4 | PC4 | ||||
REG_D | IR_D | IR | IR | IR | IR | IR | IR | IR | IR | IR | IR | IR | IR | IR |
PC4_D | PC4 | PC4 | PC4 | |||||||||||
PC8_D | PC8 | PC8 | ||||||||||||
RF | A1 | IR_D[RS] | IR_D[RS] | IR_D[RS] | IR_D[RS] | IR_D[RS] | IR_D[RS] | IR_D[RS] | IR_D[RS] | |||||
A2 | IR_D[RT] | IR_D[RT] | IR_D[RT] | IR_D[RT] | ||||||||||
EXT | I16 | IR_D[I16] | IR_D[I16] | IR_D[I16] | IR_D[I16] | |||||||||
CMP | D1 | RD1 | ||||||||||||
D2 | RD2 | |||||||||||||
CMP0 | FRSD | FRSD | ||||||||||||
NPC | PC4 | PC4_D | PC4_D | PC4_D | ||||||||||
I26 | IR_D[I26] | IR_D[I26] | IR_D[I16] | |||||||||||
PC | D | NEXTPC | RD1 | NEXTPC | RD1 | NEXTPC/PC4 | ||||||||
REG_E | IR_E | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D | IR_D |
RS_E | RD1 | RD1 | RD1 | RD1 | RD1 | |||||||||
EXT_E | EXTD | EXTD | EXTD | EXTD | ||||||||||
RT_E | RD2 | RD2 | RD2 | RD2 | ||||||||||
PC8_E | PC8_D | PC8_D | ||||||||||||
MDU | NUM1 | RS_E | ||||||||||||
NUM2 | RT_E | |||||||||||||
ALU | A | RS_E | RS_E | RS_E | RS_E | |||||||||
B | EXT_E | EXT_E | RT_E | EXT_E | RT_E | |||||||||
SHAMT | IR_E[SH] | |||||||||||||
REG_M | IR_M | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E | IR_E |
AO_M | AO | AO | AO | AO | AO | |||||||||
RT_M | RT_E | |||||||||||||
PC8_M | PC8_E | PC8_E | ||||||||||||
EXT_M | EXT_E | |||||||||||||
HI_M | ||||||||||||||
LO_M | ||||||||||||||
BEEXT | AO_M1_0 | AO_M[1:0] | ||||||||||||
DM | DA | AO_M | AO_M | |||||||||||
WD | RT_M | |||||||||||||
BE | BE | |||||||||||||
REG_W | IR_W | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M | IR_M |
RD_W | RD | |||||||||||||
AO_W | AO_M | AO_M | AO_M | AO_M | ||||||||||
PC8_W | PC8_M | PC8_M | ||||||||||||
EXT_W | EXT_M | |||||||||||||
HI_W | ||||||||||||||
LO_W | ||||||||||||||
RDEXT | RD_W | RD_W | ||||||||||||
AO_W1_0 | AO_W[1:0] | |||||||||||||
RF | A3 | IR_W[RT] | IR_W[RD] | IR_W[RT] | IR_M[RD] | IR_W[RT] | $31 | IR_W[RD] | ||||||
WD3 | RDEXTD | AO_W | AO_W | AO_W | EXT_W | PC8_W | PC8_W |
5、整合數據通路
將上面的數據通路整合起來,得到硬件間的連接情況。當某一硬件的某一端口前輸入來源不唯一時,需添加多選器來選擇一個作為輸入。
外模塊 | 內模塊 | 輸入 | 復用器 | 選擇信號 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
IFU | PC | Q | PC4 | NEXTPC | RD1 | MFPC | PCSEL | ||||
ADD4 | PC | Q | |||||||||
ADD8 | PC | Q | |||||||||
IM | IA | Q | |||||||||
nowstate | |||||||||||
REG_D | IR_D | IR | |||||||||
PC4_D | PC4 | ||||||||||
PC8_D | PC8 | ||||||||||
RFU | RF | A1 | IR_D[RS] | ||||||||
A2 | IR_D[RT] | ||||||||||
A3 | IR_W[RT] | IR_W[RD] | 31 | MFA3 | A3SEL | ||||||
WD3 | RDEXTD | AO_W | EXT_W | PC8_W | HI_W | LO_W | MFWD3 | WD3SEL | |||
IDU | EXT | I16 | IR_D[I16] | ||||||||
CMP0 | FRSD | RD1 | |||||||||
CMP | D1 | RD1 | |||||||||
D2 | RD2 | ||||||||||
NPC | PC4 | PC4_D | |||||||||
I26 | IR_D[I26] | ||||||||||
REG_E | IR_E | IR_D | |||||||||
RS_E | RD1 | ||||||||||
EXT_E | EXTD | ||||||||||
RT_E | RD2 | ||||||||||
PC8_E | PC8_D | ||||||||||
EXU | MDU | NUM1 | RS_E | ||||||||
NUM2 | RT_E | RS_E | MFNUM2 | NUM2SEL | |||||||
ALU | A | RS_E | |||||||||
B | EXT_E | RT_E | MFB | BSEL | |||||||
SHAMT | IR_E[SH] | ||||||||||
REG_M | IR_M | IR_E | |||||||||
AO_M | AO | ||||||||||
RT_M | RT_E | ||||||||||
PC8_M | PC8_E | ||||||||||
EXT_M | EXT_E | ||||||||||
HI_M | HI | ||||||||||
LO_M | LO | ||||||||||
MEU | BEEXT | AO_M1_0 | AO_M[1:0] | ||||||||
DM | DA | AO_M | |||||||||
WD | RT_M | ||||||||||
BE | BE | ||||||||||
REG_W | IR_W | IR_M | |||||||||
RD_W | RD | ||||||||||
AO_W | AO_M | ||||||||||
PC8_W | PC8_M | ||||||||||
EXT_W | EXT_M | ||||||||||
HI_W | HI_M | ||||||||||
LO_W | LO_M | ||||||||||
RFU | RDEXT | RD_W | RD_W | ||||||||
AO_W1_0 | AO_W[1:0] |
6、控制信號
列出所有指令的控制信號表。
TYPE | 指令 | INPUT | OUTPUT | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OP | FUNCT | RT | PCSEL | EXTOP | NPCOP | ALUCTRL | ALUOP | BSEL | START | MDUOP | WHI | WLO | NUM2SEL | WM | A3SEL | WD3SEL | WR | ||
LD | LW | 100011 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 0(不寫) | 0 | 0 | 1 |
LHU | 100101 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 0 | 1 | |
LH | 100001 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 0 | 1 | |
LBU | 100100 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 0 | 1 | |
LB | 100000 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 0 | 1 | |
STR | SW | 101011 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 1 | X | X | 0 |
SH | 101001 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 1 | X | X | 0 | |
SB | 101000 | X | X | 0 | 0 | X | 0 | 0(+) | 0 | 0 | X | 0 | 0 | X | 1 | X | X | 0 | |
CAL_R | ADD | 000000 | 100000 | X | 0 | X | X | 15 | 0 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 |
ADDU | 000000 | 100001 | X | 0 | X | X | 15 | 0 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SUB | 000000 | 100010 | X | 0 | X | X | 15 | 1 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SUBU | 000000 | 100011 | X | 0 | X | X | 15 | 1 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SLLV | 000000 | 000100 | X | 0 | X | X | 15 | 4 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SRAV | 000000 | 000111 | X | 0 | X | X | 15 | 5 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SRLV | 000000 | 000110 | X | 0 | X | X | 15 | 6 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
AND | 000000 | 100100 | X | 0 | X | X | 15 | 10 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
OR | 000000 | 100101 | X | 0 | X | X | 15 | 2 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
XOR | 000000 | 100110 | X | 0 | X | X | 15 | 11 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
NOR | 000000 | 100111 | X | 0 | X | X | 15 | 12 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SLT | 000000 | 101010 | X | 0 | X | X | 15 | 3 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SLTU | 000000 | 101011 | X | 0 | X | X | 15 | 13 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SHAMT | SLL | 000000 | 000000 | X | 0 | X | X | 15 | 7 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 |
SRL | 000000 | 000010 | X | 0 | X | X | 15 | 9 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
SRA | 000000 | 000011 | X | 0 | X | X | 15 | 8 | 1 | 0 | X | 0 | 0 | X | 0 | 1 | 1 | 1 | |
CAL_I | ORI | 001101 | X | X | 0 | 2 | X | 2 | 2 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 |
XORI | 001110 | X | X | 0 | 2 | X | 11 | 11 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 | |
ANDI | 001100 | X | X | 0 | 2 | X | 10 | 10 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 | |
SLTIU | 001011 | X | X | 0 | 0 | X | 13 | 13 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 | |
SLTI | 001010 | X | X | 0 | 0 | X | 3 | 3 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 | |
ADDI | 001000 | X | X | 0 | 0 | X | 0 | 0 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 | |
ADDIU | 001001 | X | X | 0 | 0 | X | 0 | 0 | 0 | 0 | X | 0 | 0 | X | 0 | 0 | 1 | 1 | |
LUI | 001111 | X | X | 0 | 1 | X | X | X | X | 0 | X | 0 | 0 | X | 0 | 0 | 2 | 1 | |
B_TYPE | BEQ | 000100 | X | X | RES | X | 0 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 |
BNE | 000101 | X | X | ~RES | X | 0 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
BLEZ | 000110 | X | X | ~GREAT | X | 0 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
BGTZ | 000111 | X | X | GREAT | X | 0 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
BLTZ | 000001 | X | 00000 | LESS | X | 0 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
BGEZ | 000001 | X | 00001 | ~LESS | X | 0 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
J | 000010 | X | X | 1 | X | 1 | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
JR | 000000 | 001000 | X | 2 | X | X | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
JAL | 000011 | X | X | 1 | X | 1 | X | X | X | 0 | X | 0 | 0 | X | 0 | 2 | 3 | 1 | |
JALR | 000000 | 001001 | X | 2 | X | X | X | X | X | 0 | X | 0 | 0 | X | 0 | 1 | 3 | 1 | |
NOP | 000000 | 000000 | X | 0 | X | X | X | X | X | 0 | X | 0 | 0 | X | 0 | X | X | 0 | |
MOD | MULT | 000000 | 011000 | X | 0 | X | X | X | X | X | 1 | 0 | 0 | 0 | 0 | 0 | X | X | 0 |
MULTU | 000000 | 011001 | X | 0 | X | X | X | X | X | 1 | 1 | 0 | 0 | 0 | 0 | X | X | 0 | |
DIV | 000000 | 011010 | X | 0 | X | X | X | X | X | 1 | 2 | 0 | 0 | 0 | 0 | X | X | 0 | |
DIVU | 000000 | 011011 | X | 0 | X | X | X | X | X | 1 | 3 | 0 | 0 | 0 | 0 | X | X | 0 | |
MFR | MFHI | 000000 | 010000 | X | 0 | X | X | X | X | X | 0 | X | 0 | 0 | X | 0 | 1 | 4 | 1 |
MFLO | 000000 | 010010 | X | 0 | X | X | X | X | X | 0 | X | 0 | 0 | X | 0 | 1 | 5 | 1 | |
MTO | MTHI | 000000 | 010001 | X | 0 | X | X | X | X | X | 0 | X | 1 | 0 | X | 0 | X | X | 0 |
MTLO | 000000 | 010011 | X | 0 | X | X | X | X | X | 0 | X | 0 | 1 | 1 | 0 | X | X | 0 |
三、流水線CPU的沖突解決
0、特別說明
我們現在要考慮流水線CPU的沖突問題,前面說過的三類沖突問題:硬件沖突在這里沒有,因為IM和DM的獨立;控制沖突通過延遲槽解決,因此硬件上也不需要多余設計(如果用假設不跳轉的思路,需要增加流水線寄存器的同步清零信號,以清除錯誤執行指令的結果,且添加同步清零的控制邏輯);數據沖突是我們着重要考慮的問題,關鍵在於什么時候暫停,什么時候轉發,並且邏輯不能太復雜,經過大佬方法點撥和個人揣摩,我采取如下方法。
1、AT法
AT法是大佬的叫法,按我下面的表格,更適合叫做是SDT法,即源頭、目的時間法。
對任意一條標准指令(只涉及通用寄存器的指令),有源頭寄存器和目的寄存器:當一條通用指令i需要寄存器s1、寄存器s2的數據時,s1和s2就是i的源頭寄存器(不需要用到數據時,s1和s2為0);當一條通用指令i需要寫入寄存器des時,des就是i的目的寄存器(不需要寫寄存器時,des為0)。
對於源寄存器s有時間tuseD(/E/M),意思是在從D(/E/M)段開始,過幾個時鍾周期需要使用s里的數據。對於目的寄存器des有數據tnewD(/E/M),意思是從D(/E/M)段開始,過幾個時鍾周期des的數據被更新。
-
什么時候要暫停
暫停的時刻放在D段,每條指令i在D段時,要和它前面的指令j對照判斷,看是否需要暫停:當i的源寄存器和j的目的寄存器相同時(設為寄存器k),i和j存在數據關聯,這時如果i的tuse大於j的tnew,代表k中數據還沒被j准備好(甚至不能轉發過來),這時需要暫停D段指令i,否則i會使用k中舊數據里錯誤運行。
暫停需要做的工作很簡單,將pc和D段流水線寄存器禁止使能,即一直維持當前數據直到D段指令和前序指令沒有數據關聯或者tuse不大於tnew。
-
何時轉發?轉發去哪?轉發什么?
當前序指令的tnew為0時代表新數據已經准備好,需要立刻轉發到前面以備可能的數據沖突。
這里是轉發到前面階段(比如D段)的最開始,緊接着對應階段的寄存器數據源頭(比如RD1、RD2、RS_E、RT_E),和原本流水線寄存器的輸出一起被選擇(比如多選器MFRSD、MFRTD),當數據關聯時就選擇轉發的數據(比如FRSD、FRTD),否則選擇原來數據(比如RD1、RD2)。
轉發的是前序指令已經准備好的數據,在每一階段可以根據指令類別寫出待轉發數據,得到真值表。
特別的對於W段指令到D段指令的轉發,由於W段寫入和D段讀出都是對於寄存器堆,我們采用內部轉發:通過寄存器堆的結構使得,在同一個時鍾上升沿,若有數據寫入寄存器r,也有從寄存器r讀出數據的請求,將將寫入數據直接讀出。這樣一來,W段到D段的數據不再需要外部轉發。
對於非通用指令,比如mult、div、mfhi、mflo、mthi、mtlo,通過下表分析可知:它們內部不存在數據沖突,因為寫回hi/lo和計算出結果在同一周期內完成;它們和通用指令之間的數據沖突處理方式和前面一樣。
S1_D/E/M | TUSE1_ | S1D | MUX | S2_D/E/M | TUSE2_ | S2D | MUX | DES_ | TNEW_ | DESD_ | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
D | STR | IR_D[RS] | 1 | RD1 | MFRSD | IR_D[RT] | 2 | RD2 | MFRTD | X | X | X | ||||
LD | IR_D[RS] | 1 | RD1 | MFRSD | $0 | X | X | X | X | |||||||
CAL_R | IR_D[RS] | 1 | RD1 | MFRSD | IR_D[RT] | 1 | RD2 | MFRTD | X | X | X | |||||
SHAMT | $0 | X | IR_D[RT] | 1 | RD2 | MFRTD | X | X | X | |||||||
CAL_I | IR_D[RS] | 1 | RD1 | MFRSD | $0 | X | X | X | X | |||||||
LUI | $0 | X | $0 | X | X | X | X | |||||||||
B_TYPE | IR_D[RS] | 0 | RD1 | MFRSD | IR_D[RT] | 0 | RD2 | MFRTD | X | X | X | |||||
J | $0 | X | $0 | X | X | X | X | |||||||||
JR | IR_D[RS] | 0 | RD1 | MFRSD | $0 | X | X | X | X | |||||||
JAL | $0 | X | $0 | X | X | X | X | |||||||||
JALR | IR_D[RS] | 0 | RD1 | MFRSD | $0 | X | X | X | X | |||||||
MOD | IR_D[RS] | 1 | RD1 | MFRSD | IR_D[RT] | 1 | RD2 | MFRTD | ||||||||
MFHI | HI/$0 | 3 | $0 | X | ||||||||||||
MFLO | LO/$0 | 3 | $0 | X | ||||||||||||
MTHI | IR_D[RS] | 1 | RD1 | MFRSD | $0 | X | ||||||||||
MTLO | IR_D[RS] | 1 | RD1 | MFRSD | $0 | X | ||||||||||
E | STR | IR_E[RS] | 0 | RS_E | MFRSE | IR_E[RT] | 1 | RT_E | MFRTE | $0 | X | X | ||||
LD | IR_E[RS] | 0 | RS_E | MFRSE | $0 | X | IR_E[RT] | 2 | X | |||||||
CAL_R | IR_E[RS] | 0 | RS_E | MFRSE | IR_E[RT] | 0 | RT_E | MFRTE | IR_E[RD] | 1 | X | |||||
SHAMT | $0 | X | IR_E[RT] | 0 | RT_E | MFRTE | IR_E[RD] | 1 | X | |||||||
CAL_I | IR_E[RS] | 0 | RS_E | MFRSE | $0 | X | IR_E[RT] | 1 | X | |||||||
LUI | $0 | X | $0 | X | IR_E[RT] | 0 | EXT_E | |||||||||
B_TYPE | $0 | X | $0 | X | $0 | X | X | |||||||||
J | $0 | X | $0 | X | $0 | X | X | |||||||||
JR | $0 | X | $0 | X | $0 | X | X | |||||||||
JAL | $0 | X | $0 | X | $31 | 0 | PC8_E | |||||||||
JALR | $0 | X | $0 | X | IR_E[RD] | 0 | PC8_E | |||||||||
MOD | IR_E[RS] | 0 | RS_E | MFRSE | IR_E[RT] | 0 | RT_E | MFRTE | HI,LO/$0 | 5,10/X | X | |||||
MFHI | HI/$0 | 2 | HI/X | $0 | X | IR_E[RD] | 1 | X | ||||||||
MFLO | LO/$0 | 2 | LO/X | $0 | X | IR_E[RD] | 1 | X | ||||||||
MTHI | IR_E[RS] | 0 | RS_E | MFRSE | $0 | X | HI/$0 | 0 | X | |||||||
MTLO | IR_E[RS] | 0 | RS_E | MFRSE | $0 | X | LO/$0 | 0 | X | |||||||
M | STR | $0 | X | IR_M[RT] | 0 | RT_M | MFRTM | $0 | X | X | ||||||
LD | $0 | X | $0 | X | IR_M[RT] | 1 | X | |||||||||
CAL_R | $0 | X | $0 | X | IR_M[RD] | 0 | AO_M | |||||||||
SHAMT | $0 | X | $0 | X | IR_M[RD] | 0 | AO_M | |||||||||
CAL_I | $0 | X | $0 | X | IR_M[RT] | 0 | AO_M | |||||||||
LUI | $0 | X | $0 | X | IR_M[RT] | 0 | EXT_M | |||||||||
B_TYPE | $0 | X | $0 | X | $0 | X | X | |||||||||
J | $0 | X | $0 | X | $0 | X | X | |||||||||
JR | $0 | X | $0 | X | $0 | X | X | |||||||||
JAL | $0 | X | $0 | X | $31 | 0 | PC8_M | |||||||||
JALR | $0 | X | $0 | X | IR_M[RD] | 0 | PC8_M | |||||||||
MOD | $0 | X | $0 | X | $0 | X | X | |||||||||
MFHI | HI/$0 | 1 | HI_M/X | $0 | X | IR_M[RD] | 0 | HI_M | ||||||||
MFLO | LO/$0 | 1 | LO_M/X | $0 | X | IR_M[RD] | 0 | LO_M | ||||||||
MTHI | $0 | X | $0 | X | $0 | X | X | |||||||||
MTLO | $0 | X | $0 | X | $0 | X | X | |||||||||
W | STR | X | X | X | X | $0 | X | X |
2、補充所需硬件
經過AT法的分析,每一階段寄存器數據的源頭不再唯一,還包含從后面階段(前序指令)轉發過來的“最新”數據,需要添加相應多選器,這些多選器mux在上表中已然列出。
階段 | module | input | output | 功能描述 |
---|---|---|---|---|
IF | MFPC | PCSEL | D | 選擇下一個pc值 |
PC4 | ||||
NEXTPC | ||||
RD1/FRSD | ||||
PC | D | Q | ||
ADD4 | PC | PC4 | ||
ADD8 | PC | PC8 | ||
IM | IA | IR | ||
DE | RF | A1 | RD1 | 從寄存器堆讀出寄存器數據 |
A2 | RD2 | |||
MFRSD | FRSDSEL | FRSD | 選擇轉發到D級rs寄存器的值 | |
RD1 | ||||
ETOD | E段轉發到D段的數據,下同 | |||
MTOD | ||||
MFRTD | FRTDSEL | FRTD | 選擇轉發到D級rt寄存器的值 | |
RD2 | ||||
ETOD | ||||
MTOD | ||||
EXT | I16 | EXTD | 選擇輸出SIMM,LIMM,UIMM | |
EXTOP | ||||
CMP0 | FRSD | LESS | 輸出和0比較的結果,獨熱輸出 | |
GREAT | ||||
LE_EQ | ||||
GR_EQ | ||||
CMP | D1 | RES | 輸出比較結果 | |
D2 | ||||
NPC | PC4 | NEXTPC | 選擇輸出BPC,JPC | |
I26 | ||||
NPCOP | ||||
EX | MFRSE | FRSESEL | FRSE | 選擇轉發到E級rs寄存器的值 |
RS_E | ||||
MTOE | ||||
WTOE | ||||
MFRTE | FRTESEL | FRTE | 選擇轉發到E級rt寄存器的值 | |
RT_E | ||||
MTOE | ||||
WTOE | ||||
MFNUM2 | FRTE | NUM2 | 選擇輸入num2 | |
FRSE | ||||
MDU | NUM1 | BUSY | 乘除模塊,WHI,WLO為寫使能,WDHI,WDLO為寫入數據 | |
NUM2 | HI | |||
MDUOP | LO | |||
START | ||||
WHI | ||||
WLO | ||||
MFB | BSEL | B | 選擇alu的b輸入 | |
EXT_E | ||||
FRTE | ||||
ALU | A | AO | 執行不同操作 | |
B | ||||
SHAMT | ||||
ALUOP | ||||
ME | MFRTM | FRTMSEL | FRTM | 選擇轉發到M級rt寄存器的值 |
RT_M | ||||
WTOM | ||||
BEEXT | AO_M1_0 | BE | 得到字節寫入使能信號,為1的那一位代表對應dm中的字相應部分寫入字節 | |
SW_M | ||||
SH_M | ||||
SB_M | ||||
DM | DA[11:2] | RD | 支持寫入字節、半字、字和讀出字 | |
WD | ||||
WM | ||||
BE[3:0] | ||||
WB | RDEXT | RD_W | RDEXTD | 將dm中取出的字按照指令做相應處理得到將寫入rf的字 |
AO_W1_0 | ||||
LW_W | ||||
LHU_W | ||||
LH_W | ||||
LBU_W | ||||
LB_W | ||||
MFA3 | A3SEL | A3 | 選擇a3 | |
IR_W[RT] | ||||
IR_W[RD] | ||||
31 | ||||
MFWD3 | WD3SEL | WD3 | 選擇wd3 | |
RDEXTD | ||||
AO_W | ||||
EXT_W | ||||
PC8_W | ||||
RF | A3 | |||
WD3 | ||||
WR |
3、修改數據通路
經過轉發數據mux選擇后的數據作為新的所在階段寄存器數據的源頭。
外模塊 | 內模塊 | 端口 | 復用器 | 選擇信號 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
IFU | PC | Q | PC4 | NEXTPC | RD1/FRSD | MFPC | PCSEL | ||||
ADD4 | PC | Q | |||||||||
ADD8 | PC | Q | |||||||||
IM | IA | Q | |||||||||
nowstate | |||||||||||
REG_D | IR_D | IR | |||||||||
PC4_D | PC4 | ||||||||||
PC8_D | PC8 | ||||||||||
RFU | RF | A1 | IR_D[RS] | ||||||||
A2 | IR_D[RT] | ||||||||||
A3 | IR_W[RT] | IR_W[RD] | $31 | MFA3 | A3SEL | ||||||
WD3 | RDEXTD | AO_W | EXT_W | PC8_W | HI_W | LO_W | MFWD3 | WD3SEL | |||
MFRSD | FRSDSEL | ||||||||||
RD1 | |||||||||||
ETOD | |||||||||||
MTOD | |||||||||||
MFRTD | FRTDSEL | ||||||||||
RD2 | |||||||||||
ETOD | |||||||||||
MTOD | |||||||||||
IDU | EXT | I16 | IR_D[I16] | ||||||||
CMP0 | FRSD | RD1/FRSD | |||||||||
CMP | D1 | RD1/FRSD | |||||||||
D2 | RD2/FRTD | ||||||||||
NPC | PC4 | PC4_D | |||||||||
I26 | IR_D[I26] | ||||||||||
REG_E | IR_E | IR_D | |||||||||
RS_E | RD1/FRSD | ||||||||||
EXT_E | EXTD | ||||||||||
RT_E | RD2/FRTD | ||||||||||
PC8_E | PC8_D | ||||||||||
EXU | MFRSE | FRSESEL | |||||||||
RS_E | |||||||||||
MTOE | |||||||||||
WTOE | |||||||||||
MFRTE | FRTESEL | ||||||||||
RT_E | |||||||||||
MTOE | |||||||||||
WTOE | |||||||||||
MDU | NUM1 | RS_E/FRSE | |||||||||
NUM2 | RT_E/FRTE | RS_E/FRSE | MFNUM2 | NUM2SEL | |||||||
ALU | A | RS_E/FRSE | |||||||||
B | EXT_E | RT_E/FRTE | MFB | BSEL | |||||||
SHAMT | IR_E[SH] | ||||||||||
REG_M | IR_M | IR_E | |||||||||
AO_M | AO | ||||||||||
RT_M | RT_E/FRTE | ||||||||||
PC8_M | PC8_E | ||||||||||
EXT_M | EXT_E | ||||||||||
HI_M | HI | ||||||||||
LO_M | LO | ||||||||||
MEU | MFRTM | FRTMSEL | |||||||||
RT_M | |||||||||||
WTOM | |||||||||||
BEEXT | AO_M1_0 | AO_M[1:0] | |||||||||
DM | DA | AO_M | |||||||||
WD | RT_M/FRTM | ||||||||||
BE | BE | ||||||||||
REG_W | IR_W | IR_M | |||||||||
RD_W | RD | ||||||||||
AO_W | AO_M | ||||||||||
PC8_W | PC8_M | ||||||||||
EXT_W | EXT_M | ||||||||||
HI_W | HI_M | ||||||||||
LO_W | LO_M | ||||||||||
RFU | RDEXT | RD_W | RD_W | ||||||||
AO_W1_0 | AO_W[1:0] |
四、結束
到此,簡化五段式流水線CPU就已經設計完畢,Verilog代碼就不放出來了,代碼量龐大。
說明一下,文中寫的通用指令和非通用指令是自創的,沒有嚴格定義,只是區分一下。
本文是對筆者學習思考CPU的一點總結,供復習所用,若能幫到讀者就最好不過了。
感謝閱讀,若有錯誤,請評論給出,萬分感謝。