一、流水線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的一點總結,供復習所用,若能幫到讀者就最好不過了。
感謝閱讀,若有錯誤,請評論給出,萬分感謝。
