天天看點

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

背景介紹

晶片功耗組成中,有高達 40%甚至更多是由時鐘樹消耗掉的。這個結果的原因也很直覺,因 為這些時鐘樹在系統中具有最高的切換頻率,而且有很多時鐘 buffer,而且為了最小化時鐘 延時,它們通常具有很高的驅動強度。 那麼減少時鐘網絡的功耗消耗,最直接的辦法就是如果不需要時鐘的時候,就把時鐘關掉。 這種方法就是大家熟悉的門控時鐘:clock gating。 如果讓我們設計一個門控時鐘的電路,我們會怎麼設計呢?最直接的方法,不需要時鐘的時 候關掉時鐘,這就是與操作,我們隻需要把 enable 和 CLK 進行“與”操作不就行了麼,電路 圖如下 :

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

這種直接将控制 EN 信号和時鐘 CLK 進行與操作完成門控的方式,可以完成 EN 為 0 時,時 鐘被關掉。但是同時帶來另外一個很大的問題:毛刺

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

如上圖所示,EN 是不受控制的,随時可能跳變,這樣純組合輸出 GCLK 就完全可能會有毛刺産生,時鐘信号上産生毛刺是很危險的。

很自然的我們會想到解決方法,用觸發器,隻要把 EN 用 CLK 寄存一下,那麼輸出就是以 CLK 為基準了。其實還有一種辦法是鎖存器,把 EN 用鎖存器鎖存的輸出,也是以 CLK 為基準的。

鎖存門控

先來談第二種方法,利用鎖存器做clock gating,電路如下:

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

波形如下:

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

可以看到,隻有在 CLK 為高的時候,GCLK 才可能會輸出高,這樣就能消除 EN 帶來的毛刺。 這是因為 D 鎖存器是電平觸發,在 clk=1 時,資料通過 D 鎖存器流到了 Q;在 Clk=0 時, Q 保持原來的值不變。

雖然達到了我們消除毛刺的目的,但是這個電路還有兩個缺點: 1 如果在電路中,鎖存器與與門相隔很遠,到達鎖存器的時鐘與到達與門的時鐘有較大的延 遲差别,則仍會出現毛刺。 2 如果在電路中,時鐘使能信号距離鎖存器很近,可能會不滿足鎖存器的建立時間,會造成 鎖存器輸出出現亞穩态。

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

上述的右上圖中,B 點的時鐘比 A 時鐘遲到,并且 Skew > delay,這種情況下,産生了毛刺。 為了消除毛刺,要控制 Clock Skew,使它滿足 Skew >Latch delay(也就是鎖存器的 clk-q 的 延時)。上述的右下圖中,B 點的時鐘比 A 時鐘早到,并且|Skew| > ENsetup 一 (D->Q),這 種情況下,也産生了毛刺。為了消除毛刺,要控制 Clock Skew,使它滿足|Skew|< ENsetup 一(D->Q)。

寄存門控

對于clock gating,我們還有另外的解決辦法,就是用寄存器來寄存 EN 信号再與上 CLK 得到 GCLK,電路圖如下所示:

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

時序圖如下所示:

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

由于 DFF 輸出會 delay 一個周期,是以除非 CLKB 上升沿提前 CLKA 很多,快半個周期,才 會出現毛刺,而這種情況一般很難發生。但是,這種情況 CLKB 比 CLKA 遲到,是不會出現毛刺的。 當然,如果第一個 D 觸發器不能滿足 setup 時間,還是有可能産生亞穩态。

提問:SOC 晶片設計中使用最多的是鎖存結構的門控時鐘,為什麼? 原因是:在實際的 SOC 晶片中,要使用大量的門控時鐘單元。是以通常會把門控時鐘做出一 個标準單元,有工藝廠商提供。那麼鎖存器結構中線延時帶來的問題就不存在了,因為是做成一個單元,線延時是可控和不變的。而且也可以通過挑選鎖存器和增加延時,總是能滿足 鎖存器的建立時間,這樣通過工藝廠預先把門控時鐘做出标準單元,這些問題都解決了。

那麼用寄存器結構也可以達到這種效果,為什麼不用寄存器結構呢?那是因為面積!一個 DFF 是由兩個 D 鎖存器組成的,采樣 D 鎖存器組成門控時鐘單元,可以節省一個鎖存器的 面積。當大量的門控時鐘插入到 SOC 晶片中時,這個節省的面積就相當可觀了

代碼(寄存器門控)

module clk_gating(
    input         clk      ,
    input         rst_n    , 
    input         out_en   ,
    input [63:0]  data     ,
    
    output reg out
);
 
reg en1;
wire clk_en;
 
always@(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        en1 <= 1'b0;
    end
    else begin
        en1 <= out_en;
    end
end
assign clk_en = clk & en1;
always @(posedge clk_en or negedge rst_n) begin
    if(rst_n==1'b0)
        out <= 64'b0;
    else
        out<= data;
end
endmodule
           

綜合出來電路如下,和我們預想的一樣。

數字IC手撕代碼--低功耗設計 Clock Gating背景介紹鎖存門控 寄存門控代碼(寄存器門控)

繼續閱讀