1、流水線簡(jiǎn)介
概念
所謂流水線設(shè)計(jì)實(shí)際上是把規(guī)模較大、層次較多的組合邏輯電路分為幾個(gè)級(jí),在每一級(jí)插入寄存器組并暫存中間數(shù)據(jù)。
K級(jí)的流水線就是從組合邏輯的輸入到輸出恰好有K個(gè)寄存器組(分為K 級(jí),每一級(jí)都有一個(gè)寄存器組),上一級(jí)的輸出是下一級(jí)的輸入而又無(wú)反饋的電路。
流水線本質(zhì)上可以理解為一種以面積換性能( Trade Area for Performance )、以空間換時(shí)間( Trade Space for Timing )的手段
流水線設(shè)計(jì)在性能上的提高是以消耗較多的寄存器資源為代價(jià)的。 流水線處理是提高組合邏輯設(shè)計(jì)的處理速度和吞吐量的最常用手段。
MIPS五級(jí)流水線簡(jiǎn)單介紹
在此流水線中一條指令的生命周期分為如下步驟 。
(1)取指 IF(Instruction Fetch )
- 指令取指是指將指令從存儲(chǔ)器中讀取出來(lái)的過(guò)程。
(2)譯碼 ID( Instruction Decode )
- 指令譯碼是指將從存儲(chǔ)器中取出的指令進(jìn)行翻譯的過(guò)程。經(jīng)過(guò) 譯碼之后得到指令需要的操作數(shù)寄存器索引,可以使用此索引從通用寄存器組 (Register File, Regfile )中將操作數(shù)讀出。
(3)執(zhí)行 EX(Instruction Execute )
- 指令譯碼之后所需要進(jìn)行的計(jì)算類型都己得知,并且己經(jīng)從通用寄存器組中讀取出 了所需的操作數(shù),那么接下來(lái)便進(jìn)行指令執(zhí)行。指令執(zhí)行是指 對(duì)指令進(jìn)行真正運(yùn)算的過(guò)程。 譬如,如果指令是一條加法運(yùn)算指令,則對(duì)操作數(shù)進(jìn)行加法操作;如果是減法運(yùn)算指令,則進(jìn)行減法操作。
- 在“執(zhí)行”階段的最常見(jiàn)部件為算術(shù)邏輯部件運(yùn)算器( Arithmetic Logical Unit, ALU), 作為實(shí)施具體運(yùn)算的硬件功能單元 。
(4)訪存 MEM( Memory Access )
- 存儲(chǔ)器訪問(wèn)指令往往是指令集中最重要的指令類型之一, 訪存是指存儲(chǔ)器訪問(wèn)指令將數(shù)據(jù)從存儲(chǔ)器中讀出,或者寫(xiě)入存儲(chǔ)器的過(guò)程 。
(5)寫(xiě)回 WB( Write-Back )
- 寫(xiě)回是指將指令執(zhí)行的結(jié)果寫(xiě)回通用寄存器組的過(guò)程 。 如果是普通運(yùn)算指令,該結(jié)果值來(lái)自于“執(zhí)行”階段計(jì)算的結(jié)果:如果是存儲(chǔ)器讀指令,該結(jié)果來(lái)自于“訪存”階段從存儲(chǔ)器中讀取出來(lái)的數(shù)據(jù)。
2、Pipeline的作用
- 提高了性能
- 優(yōu)化了時(shí)序
- 提高吞吐率
Notes:狀態(tài)機(jī)與之相反
3、Pipeline的深度
主任務(wù)分割的子任務(wù)數(shù)量成為流水線深度。
深度越大,每個(gè)處理單元越小,每一級(jí)流水線內(nèi)容納的硬件邏輯便越少,并且每個(gè)單元完成子任務(wù)的時(shí)間越小。
- 在兩級(jí)寄存器(每一級(jí)流水線由寄存器組成)之間的硬件邏輯越少,則意味能夠運(yùn)行到更高的主頻。主頻越高也意味著流水線的吞吐率越高,從而性能越高,這是流水線加深的正面意義。
- 由于每一級(jí)流水線都由寄存器組成,更多的流水線級(jí)數(shù)要消耗更多的寄存器,以及更多的面積開(kāi)銷。這是流水線加深的負(fù)面意義。
- 由于每一級(jí)流水線需要進(jìn)行握手,流水線最后 一級(jí)的反壓信號(hào)可能會(huì)一直串?dāng)_到最前一級(jí)造成嚴(yán)重的時(shí)序問(wèn)題,需要使用 一些比較高級(jí)的技巧來(lái)解決此類反壓時(shí)序問(wèn)題。 這是流水線加深的負(fù)面意義。
- 較深的處理器流水線還有一個(gè)問(wèn)題,那就是由于在流水線的取指令階段無(wú)法得知條件跳轉(zhuǎn)的結(jié)果是到底跳還是不跳,因此只能進(jìn)行預(yù)測(cè),而到了流水線的末端才能夠 通過(guò)實(shí)際的運(yùn)算得知該分支是真的該跳還是不該跳。如果發(fā)現(xiàn)真實(shí)的結(jié)果(譬如該 跳〉與之前預(yù)測(cè)的結(jié)果(譬如預(yù)測(cè)為不跳)不相符,則意味著預(yù)測(cè)失敗,需要將所 有預(yù)取的錯(cuò)誤指令流全部丟棄掉。重新取正確的指令流,這個(gè)過(guò)程叫作“流水線沖刷( Pipeline Flush )”。 雖然可以使用分支預(yù)測(cè)器來(lái)保證前期的分支預(yù)測(cè)盡可能準(zhǔn)確, 但是也無(wú)法做到萬(wàn)無(wú) 一 失。那么,流水線的深度越深,意味著己經(jīng)預(yù)取了更多的錯(cuò)誤指令流,需要將其全部拋棄然后重啟,不僅白白浪費(fèi)了功耗,還造成了性能的損失 。 流水線越深,則意味著浪費(fèi)和損失越嚴(yán)重;流水線越淺,則浪費(fèi)和損失越少 。 這是流水線加深的另 一個(gè)主要的負(fù)面意義。
流水線的不同深度皆有其優(yōu)缺點(diǎn), 需要根據(jù)不同的應(yīng)用背景進(jìn)行合理的選擇。
4、流水線中的反壓
流水線越深,由于每一級(jí)流水線需要進(jìn)行握手,流水線最后一級(jí)的反壓信號(hào)可能會(huì)一直串?dāng)_到最前一級(jí)造成嚴(yán)重的反壓 (Back-pressure )時(shí)序問(wèn)題,需要使用一些比較高級(jí)的技巧來(lái)解決這些時(shí)序問(wèn)題。
- 取消握手:此方法能夠杜絕反壓的發(fā)生,時(shí)序表現(xiàn)非常好 。 但是取消握手,即意味 著流水線中的每一級(jí)并不會(huì)與其下一級(jí)進(jìn)行握手,可能會(huì)造成功能錯(cuò)誤或者指令丟 失。因此這種方法往往需要配合其他的機(jī)制, 譬如重執(zhí)行( Replay )、預(yù)留大緩存等。
- 加入乒乓緩存:加入乒乓緩存( Ping-pong Buffer )是一種用面積換時(shí)序的方法,也是在 解決反壓的最簡(jiǎn)單方法 。 通過(guò)使用乒乓緩存(有兩個(gè)表項(xiàng)〉替換掉普通的一級(jí)流水線(只 有一個(gè)表項(xiàng)〉,可以使得此級(jí)流水線向上一級(jí)流水線的握手接收信號(hào)僅關(guān)注乒乓緩存中 是否有一個(gè)以上有空的表項(xiàng)即可,而無(wú)需將下一級(jí)的握手接收信號(hào)串?dāng)_至上一級(jí) 。
- 加入前向旁路緩存:加入前向旁路緩存( Forward Bypass Buffer )也是一種用面積換時(shí)序的方法,是在解決反壓時(shí)的一種非常巧妙的方法 。旁路緩存僅只有一個(gè)表項(xiàng) , 由于增加了這一個(gè)額外的緩存表項(xiàng),可以將后向的握手信號(hào)時(shí)序路徑砍斷,但是對(duì)前向路徑不受影響,因此可以廣泛使用于握手接口。
5、流水線中的沖突
處理器的流水線設(shè)計(jì)中另外 一個(gè)問(wèn)題便是流水線中的沖突( Hazards ),主要分為資源沖突和數(shù)據(jù)沖突。
(a)資源沖突
資源沖突是指流水線中硬件資源的沖突,最常見(jiàn)的是運(yùn)算單元的沖突, 譬如除法器需要多個(gè)時(shí)鐘周期才能完成運(yùn)算。因此在前 一 個(gè)除法指令完成運(yùn)算之前,新的除法指令如果也需 要除法器,則會(huì)存在著資源沖突。
(b)數(shù)據(jù)沖突
數(shù)據(jù)沖突是指不同的指令之間的操作數(shù)存在著數(shù)據(jù)相關(guān)性造成的沖突,常見(jiàn)的數(shù)據(jù)相關(guān) 性如下。
- WAR (Write-After-Read )相關(guān)性,又稱先讀后寫(xiě)相關(guān)性:表示“后序執(zhí)行的指令需要寫(xiě)回的結(jié)果寄存器索引”與“前序執(zhí)行的指令需要讀取的源操作數(shù)寄存器索引” 相同造成的數(shù)據(jù)相關(guān)性 。 因此從理論上來(lái)講,在流水線中“后序指令”一定不能比和它有 WAR 相關(guān)性的“前序指令”先執(zhí)行,否則“后序指令”先寫(xiě)回了結(jié)果至通用寄存器組中,“前序指令”再讀取操作數(shù)時(shí),就會(huì)讀到錯(cuò)誤的數(shù)值。
- WAW (Write-After-Write )相關(guān)性,又稱先寫(xiě)后寫(xiě)相關(guān)性:表示“后序執(zhí)行的指令需要寫(xiě)回的結(jié)果寄存器索引 ”與“前序執(zhí)行的指令需要寫(xiě)田的結(jié)果寄存器索引”相同 造成的數(shù)據(jù)相關(guān)性。因此從理論上來(lái)講,在流水線中“后序指令”一定不能比和它 有 WAW 相關(guān)性的“前序指令”先執(zhí)行,否則“后序指令”先寫(xiě)回了結(jié)果至通用寄存器組中,“前序指令”再寫(xiě)回結(jié)果至通用寄存器組中就會(huì)將其覆蓋。
- RAW (Read-After-Write)相關(guān)性,又稱先寫(xiě)后讀相關(guān)性:表示“后序執(zhí)行的指令需 要讀取的源操作數(shù)寄存器索引 ”與“前序執(zhí)行的指令需要寫(xiě)回的結(jié)果寄存器索引” 相同造成的數(shù)據(jù)相關(guān)性。因此從理論上來(lái)講,在流水線中“后序指令”一定不能比和它有 RAW 相關(guān)性的前序指令”先執(zhí)行,否 則 “后序指令”便會(huì)從通用寄存器組中讀回錯(cuò)誤的源操作數(shù) 。
以上的 3 種相關(guān)性中,RAW屬于真數(shù)據(jù)相關(guān) 。
4、流水線設(shè)計(jì)實(shí)例
(1)流水線加法器
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-787186.html
/*----------------------------------------------------------
Filename : adder_pipelined
Author : deilt
Description : two 32bits_adder to 64bits adder
Called by :
Revision History : 10/25/2022
Revison 1.0
Email : cjdeilt@qq.com
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module adder_pipelined
#(
parameter DATA_WITCH = 64 ,
parameter HALF_DATA_WITCH = 32
)
(
input clk ,
input rstn ,
input [DATA_WITCH-1:0] a ,
input [DATA_WITCH-1:0] b ,
output [DATA_WITCH:0 ] out
);
wire [HALF_DATA_WITCH:0 ] add1 ;
wire [HALF_DATA_WITCH:0 ] add2 ;
reg [HALF_DATA_WITCH:0 ] add1_d1 ;
reg [HALF_DATA_WITCH:0 ] add1_d2 ;
reg [HALF_DATA_WITCH:0 ] add2_d1 ;
reg [HALF_DATA_WITCH-1:0] a_63_32 ;
reg [HALF_DATA_WITCH-1:0] b_63_32 ;
wire add1_carry_d1 ;
assign add1 = a[HALF_DATA_WITCH-1:0] + b[HALF_DATA_WITCH-1:0] ;
assign add1_carry_d1 = add1_d1[HALF_DATA_WITCH] ;
assign add2 = a_63_32 + b_63_32 + add1_carry_d1 ;
assign out = {add2_d1,add1_d2} ;
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
add1_d1 <= 0 ;
add2_d1 <= 0 ;
a_63_32 <= 0 ;
b_63_32 <= 0 ;
add1_d2 <= 0 ;
end
else
add1_d1 <= add1 ;
add1_d2 <= add1_d1;
add2_d1 <= add2 ;
a_63_32 <= a[DATA_WITCH-1:HALF_DATA_WITCH] ;
b_63_32 <= b[DATA_WITCH-1:HALF_DATA_WITCH] ;
end
endmodule
(2)并行加法器
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-787186.html
/*----------------------------------------------------------
Filename : adder_parallel
Author : deilt
Description :
Called by :
Revision History : 10/26/2022
Revison 1.0
Email : cjdeilt@qq.com
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module adder_parallel
#(
parameter DATA_WITCH = 64
)
(
input clk ,
input rstn ,
input [DATA_WITCH-1:0] a ,
input [DATA_WITCH-1:0] b ,
input alternate ,//low choice adder1,high choice high adder2
output[DATA_WITCH:0] Finalsum
);
reg [DATA_WITCH-1:0] a_d1 ;
reg [DATA_WITCH-1:0] b_d1 ;
reg [DATA_WITCH-1:0] a_alte_d1 ;
reg [DATA_WITCH-1:0] b_alte_d1 ;
wire [DATA_WITCH:0] sum1 ;
wire [DATA_WITCH:0] sum2 ;
reg [DATA_WITCH:0] sum1_d1 ;
reg [DATA_WITCH:0] sum2_d1 ;
//數(shù)據(jù)輸入且alternate為低電平時(shí),選擇add1
//數(shù)據(jù)輸入且alternate為高電平時(shí),選擇add2
//輸出時(shí),alternate為高電平選擇sum1,其他選擇sum2
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
a_d1 <= 0 ;
b_d1 <= 0 ;
a_alte_d1 <= 0 ;
b_alte_d1 <= 0 ;
end
else if(alternate)begin
a_d1 <= a ;
b_d1 <= b ;
a_alte_d1 <= a_alte_d1 ;
b_alte_d1 <= b_alte_d1 ;
end
else if(!alternate)begin
a_d1 <= a_d1 ;
b_d1 <= b_d1 ;
a_alte_d1 <= a ;
b_alte_d1 <= b ;
end
end
//add1
assign sum1 = a_d1 + b_d1 ;
//add2
assign sum2 = a_alte_d1 + b_alte_d1 ;
//sum delay
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
sum1_d1 <= 0 ;
sum2_d1 <= 0 ;
end
else
sum1_d1 <= sum1 ;
sum2_d1 <= sum2 ;
end
//choice
assign Finalsum = alternate ? sum2_d1 : sum1_d1 ;
endmodule
到了這里,關(guān)于verilog實(shí)例-流水線(Pipeline)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!