以【5 Stage pipeline CPU】搜索圖片,選取5幅有代表性的圖列舉如下,并結合Chisel代碼進行理解和點評。
圖1:原文鏈接如下
https://acsweb.ucsd.edu/~dol031/posts/update/2023/04/10/5stage-cpu-pipeline.html
點評:黑色的部分是“數據通路”。藍色的部分是“控制通路”。這個圖的新穎之處就在于數據通路和控制通路在一張圖中呈現并且通過顏色明顯區分!在搜索引擎列出的一大堆圖中很快關注到這個圖,并以此作為“標桿”,關注數據通路+控制通路 都有的“全景圖”,而不是只有數據通路的“裁剪圖”。
圖2:原文鏈接如下:
https://github.com/shivpvtel/Five-Stage-Pipelined-CPU-Verilog
點評:同樣有那個Control Unit單元以及它所控制的信號鏈條,代表了控制通路!此圖的亮點有兩處:一是控制通路帶了箭頭更清晰地表達了控制的過程。二是和ChipCamp/riscv-chise-book的代碼中所展示的5-Stage Pipeline的命名是一致的,都是IF-ID-EXE-MEM-WB這樣5個Stage。其中,ID/EXE的右側寄存器,都增加了一個e代表EXE。EXE/MEM的右側寄存器,將e改為m代表MEM。ME/WB的右側寄存器,將m改為w代表WB。命名也比較規范。
圖3:原文鏈接如下:
https://nlitz88.github.io/projects/mipscpu/mipscpu/
點評:這個圖同樣有一個控制單元CU以及它所控制的信號鏈條,代表了控制通路。此圖相對于上圖來說有更多的細節之處,在于清晰地標識了多個階段的控制信號“反饋”到CU上!也就是mm, mm2reg等指向CU的箭頭。CU對除了Regfile外的各個電路單元的直接控制信號也更加多一些,比如對ID階段的多個Mux的控制,而對EXE階段的ALU及MUX的控制則和上一幅圖基本一樣。
?圖4:原文鏈接如下:
https://github.com/shivpvtel/Five-Stage-Pipelined-CPU-Final-Project-Verilog
點評:這個圖同樣有一個控制單元CU以及它所控制的信號鏈條,代表了控制通路。此圖相對于上圖來說有更多的細節之處,在于反饋和正饋的控制信號都更多了。
圖5:原文鏈接如下:
https://github.com/Ammarkhan561/RISCV-32I-5-Stage-Pipelined-Processor
點評:這個圖其實是和第一幅圖比較接近,但增加了下面的Hazard Unit(冒險單元),和上面的Control Unit相對應。而且合格Hazard Unit直觀一眼看到的“特征”就是全局控制----直接控制位于多個Stage內的電路。與此相對應的是,Control Unit單元是分級正向控制(正饋) + 直接獲取多級反饋。這在前面的圖3和圖4中特別明顯。正向的控制,通過多級模塊之間的寄存器傳輸以及位于級內的控制模塊響應這一側的信號變化,時鐘信號主要用于驅動寄多級模塊之間的寄存器傳輸!
圖6:原文鏈接如下(是圖5文章的一個對照,5-Stage-pipeline-processor vs Single-cycle-processor,意外地收獲到這樣的“對比”,太稀罕了):
https://github.com/Ammar-10xe/RISCV-32I-Single-Cycle-Processor
點評:這個單周期處理器(Single Cycle Processor)同樣也有Control Unit。這個Control Unit有什么特點呢,在上面的圖5的例子中Hazard Unit就是直接控制位于多個Stage內的電路模塊,而本圖中的Control Unit也是!這正是Single Cycle Processor的特點,即控制單元直接控制“全局”的眾多信號。而與此對應,5-Stage Pipeline Processor則是通過多級Inter-Stage的Register來分域控制!Inter-Stage Register在Clock的控制下實現左側->右側的寄存器傳輸,每個Stage的組合電路則受本Stage的Register的變化而實現響應(組合電路響應)。
Control Unit單元是分級正向控制(正饋) + 直接獲取多級反饋。這在前面的圖3和圖4中特別明顯。那么代碼中是怎么樣的呢?
下面的例子是05_riscvtests/Core.scala文件的一部分,其中第87行,在設置if_pc_next的時候(也就是對IF Stage進行正向控制的時候),讀取了exe_br_flg和exe_jmp_flg以及if_inst等變量,這些讀取的變量位于EXE和IF等不同的階段,說明了Control Unit是直接獲取了多級電路模塊的反饋的。事實上,所有這些多級模塊的變量,在整個Control Unit中(也就是Core.scala文件的Core模塊中),都是全局可訪問的,可以直接讀取。當然理論上也可以直接寫入,但5-Stage Pipeline的“范式”就是不要直接寫入,是保持架構原則的“不要”而非"不能"!
繼續這一架構原則,看看Exe階段的執行以及Mem階段的執行,如下圖所示。
Exe階段,就是一個純的組合邏輯電路,直接對exe_reg_exe_fun、exe_reg_op1_data等信號的變化進行響應、響應結果體現在exe_alu_out和exe_br_flag、exe_br_target、exe_jmp_flag中。前面的信號中的任何一個信號變化,都會導致響應結果的變化,這個響應是無條件的、立即的,不需要等待clock信號!只是在exe之前的階段,由Inter-Stage Register(也就是ID/EXE Register),響應(等待)clock邊緣信號到達時才會把exe_reg_exe_func、exe_reg_op1_data等通過賦值進行改變,進而【立即觸發】Mem這個Stage上的組合邏輯電路的響應。
而Exe階段的組合邏輯電路的響應,也僅僅只到達EX/MEM Register的左側,不影響EX/MEM Register的右側!EXE/Mem的右側各值的變化,要等待clock邊緣的到來!當clock邊緣到來后,Ex/Mem Register右側的mem_xxx值才會賦值上。注意注意注意:這里說的左側右側是對照此前的Pipeline示意圖而說的因為示意圖中的Pipeline都是從左邊到右邊(箭頭方向)!下面代碼中的245-255行里面的表達式的左側對應示意圖中的右側,表達式的右側則對應示意圖的左側!
至此,本文結合CPU的多級流水線的架構圖、深入介紹了CPU的多級流水線的代碼原理,并通過對比多級流水線處理器(5-Stage Pipeline Processor)和單周期處理器(Single Cycle Processor),理解它們在代碼原理上的差異和原則。總結一下:
單周期處理器:控制單元全局直接控制整個芯片的眾多端口。
多級流水線:每個流水線階段的電路(組合邏輯電路)局部地響應Inter-Stage Register上的寄存器變量,而這些寄存器變量則是由Inter-Stage Register在Clock的驅動下從左到右傳輸。Inter-Stage Register不是一個啞的Register而是一個有左側寄存器、右側寄存器、寄存器傳輸控制的電路模塊,這個電路模塊的傳輸控制的輸入信號可以來自多個階段,而直接的輸出信號則原則限定在單個Stage內。
PS:Inter-Stage Register的這種電路行為,十分匹配寄存器傳輸級Register Transfer Level的概念,對理解RTL的概念應該很有益處。
PS:Inter-Stage Register是本文使用的一個詞,在業界似乎沒有嚴格的定義,有叫pipeline register的,也有叫interface register的,但在芯片架構圖中這個概念圖卻是高度一致的,都是從左到右的Stage之間過度的高寬比很大的長方形加一個以下邊為邊的三角形。這個圖示非常好,只是業界并沒有架構圖的標準,因此本文把這個圖示稱作"Inter-Stage Register"并進行了解釋(如上)。
PS:從分類學的角度,數字電路被分為組合邏輯電路和時序邏輯電路,這是一個“完備”的分類。高階的思維方式下,(前人所做的)“完備”的分類可以幫助理解復雜事務如CPU。從目前為止的梳理(到5-Stage Pipeline CPU)來看,CPU的設計“套路”十分簡單,就是:
1、一切都是組合邏輯電路、直到寄存器/鎖存器打破組合邏輯電路的“直接響應”!
2、只有Inter-Stage Register實現了時序邏輯,這是通過寄存器傳輸實現的,理解RTL的概念。
3、注意寄存器和連接到寄存器上的導線/信號線/Wire/Signal的區分。Inter-Stage Register的左側和右側,連接的是導線/信號線。
4、Inter-Stage Register右側的Register和這一側的組合邏輯電路,可以看做是一體的(即同一個組合邏輯電路),因為這部分是以Register右側的組合邏輯為主導,組合邏輯是“直接響應”的。
5、Inter-Stage Register左側的Register 和 這一側的組合邏輯電路,也可以看做一體的(即同一個組合邏輯電路),只不過這個是以Register左側的組合邏輯為主導,什么時候寫寄存器/鎖存器,是由左側電路決定的。但左側電路卻不決定左側右側Register之間的傳輸,而是確保在時鐘邊緣到達之前完成對寄存器/鎖存器的寫入。
6、Inter-Stage Register的左側Register和右側Register完全隔離并在控制電路的控制下進行寄存器之間的傳輸,是一個顯著的分界線。單個寄存器/鎖存器也可以通過“時序/時域”控制來實現時序電路(就像Single Cycle Processor所做的那樣),但使用左側Register和右側Register的“空間域”劃分的方式,更解耦更簡單(當然也有代價就是寄存器資源消耗)!這大概是現有的數字電路“分類學”所沒有談到的----ChipCamp從代碼和架構實踐中總結出來的“設計模式”----寄存器復制&賦值。