Verilog RTL級低功耗設(shè)計(下)

2022-05-20 14:37 更新

門控時鐘

通常情況下,時鐘樹由大量的緩沖器和反相器組成。而時鐘信號為設(shè)計中翻轉(zhuǎn)率最高的信號,時鐘樹的功耗可高達(dá)整個設(shè)計功耗 30%。加入門控時鐘(clock gating)電路,可減少時鐘樹的開關(guān)行為,能節(jié)省開關(guān)功耗。同時,時鐘引腳開關(guān)行為的減少,寄存器的內(nèi)部功耗也會減少。所以,采用門控時鐘,可以有效地降低功耗。

實現(xiàn)原理

通俗來講,當(dāng)模塊或觸發(fā)器不工作時,將時鐘關(guān)閉而不影響正常功能的邏輯,可以稱之為門控時鐘邏輯。此時時鐘并不是一直存在的,所以可以形象的稱之為門控時鐘。


實現(xiàn)門控時鐘的方法主要有以下 3 種。

1、使用與邏輯

最簡單的方法,是直接將時鐘使能控制(門控)信號與時鐘做"與"邏輯。

例如對一塊 ram 的時鐘進(jìn)行該操作,代碼如下:

// use and-logic
module  clkgate_basic
    (
        input           clk ,
        input           clken ,
        input           rstn ,
        input           wr_en ,
        input [3:0]     addr ,
        input [7:0]     data ,
        output [7:0]    q
     );

   //clk gate
  wire                 clk_gate = clk & clken ;
   ram #(4, 8)
      u1_ram16x8
        (
         .CLK   (clk_gate),
         .A     (addr),
         .D     (data),
         .EN    (clken),
         .WR    (wr_en),
         .Q     (q));

endmodule

ram 模型如下:

module  ram
    #(  parameter       AW = 2 ,
        parameter       DW = 3 )
    (
        input                   CLK ,
        input [AW-1:0]          A ,
        input [DW-1:0]          D ,
        input                   EN ,
        input                   WR ,    //1 for write and 0 for read
        output reg [DW-1:0]     Q
     );

   parameter            MASK = 3 ;

   reg [DW-1:0]         mem [0:(1<<AW)-1] ;
   always @(posedge CLK) begin
      if (EN && WR) begin
         mem[A]  <= D ;
      end
      else if (EN && !WR) begin
         Q       <= mem[A] ;
      end
   end

endmodule

testbench 代碼如下:

`timescale 1ns/1ns
module test ;
   //signals declaration
   reg          rstn ;
   reg          clk ;
   reg          clken ;
   reg          wr_en ;
   reg [3:0]    addr ;
   reg [7:0]    data ;
   wire [7:0]   q ;

   initial begin
      rstn      = 0 ;
      #7 rstn   = 0 ;
   end

   always begin
      #50 clk = 0 ;
      #50 clk = 1 ;
   end

   //data logic
   initial begin
      clken     = 0 ;
      wr_en     = 0 ;
      addr      = 4'h3 ;
      data      = 8'h31 ;
      # 53 ;
      //(1) normal write and read
      clken     = 1 ;
      wr_en     = 1 ;
      repeat(9) begin
         @(negedge clk) ;
         data   = data + 1 ;
         addr   = addr + 1 ;
      end
      @(negedge clk) ;
      clken     = 0 ;
      wr_en     = 0 ;

      //read
      #211;
      addr      = 4'h3 ;
      clken     = 1 ;
      repeat(9) begin
         @(negedge clk) ;
         addr   = addr + 1 ;
      end
      @(negedge clk) ;
      //end
      clken     = 0 ;
   end // initial begin

   clkgate_basic u_ram_clkgate
    (
        .clk    (clk),
        .clken  (clken),
        .rstn   (rstn),
        .wr_en  (wr_en),
        .addr   (addr),
        .data   (data),
        .q      (q)
     );

   //simulation finish
   always begin
      #100;
      if ($time >= 10000)  begin
         #1 ;
         $finish ;
      end
   end

endmodule

抓取 ram 端口信號,測試結(jié)果如下。

如圖可知在讀、寫操作中間,ram 時鐘有一段一直為 0 的時刻。時鐘在 ram 沒有工作的時候不會翻轉(zhuǎn),實際中也會減少很多的功耗。


該方法缺點也非常明顯。由于時序或抖動的原因,時鐘使能信號與時鐘進(jìn)行"與"邏輯后,容易產(chǎn)生毛刺,會對數(shù)字電路產(chǎn)生嚴(yán)重影響。

在 testbench 中對時鐘使能信號進(jìn)行非理想的模擬,加入如下仿真代碼:

      //(2) jitter at the end of read
      #985;
      addr      = 4'h3 ;
      clken     = 1 ;
      repeat(9) begin
         @(negedge clk) ;
         addr   = addr + 1 ;
      end
      @(negedge clk) ;
      clken     = 0 ;
      #20 clken = 1 ;
      #21 clken = 0 ;
      #31 clken = 1 ;
      #13 clken = 0 ;

讀 ram 的仿真結(jié)果如下。


由圖可知,因為信號 clken 的異步或抖動問題,導(dǎo)致輸入到 ram 的時鐘已經(jīng)出現(xiàn)了毛刺。地址為 0x3 的數(shù)據(jù)被遺漏(和使能信號時序有關(guān)),地址為 0xC 的數(shù)據(jù)讀了 2 次。顯然該門控時鐘的邏輯設(shè)計非常的危險。

為解決此類問題,需要使用 latch 結(jié)構(gòu)來消除毛刺。

2、使用 latch

在 《Verilog 教程》章節(jié)《Verilog 避免Latch》中講到,數(shù)字設(shè)計中應(yīng)當(dāng)避免 Latch 的產(chǎn)生,但 clock gating 是個例外。所以在進(jìn)行時序分析時,不用關(guān)心 clock gating 部分產(chǎn)生的 Latch。

使用 latch 消除門控時鐘毛刺的電路圖如下所示。

在時鐘下降沿對時鐘使能信號進(jìn)行鎖存,并保持一個時鐘周期內(nèi)不變。鎖存后的信號再與時鐘進(jìn)行"與"邏輯操作,可將門控時鐘中的毛刺消除掉。


將仿真例程鐘直接"與"操作的門控時鐘邏輯部分,改寫為使用 latch 邏輯,修改如下:

   //(2) using latch
   reg                  en_latch ;
   always @(*) begin
      if (!clk) begin
         en_latch       = clken ;
      end
   end
   wire clk_gate = clk & en_latch ;

仿真結(jié)果如下。

雖然地址為 0x3 的數(shù)據(jù)仍然被遺漏(和使能信號時序有關(guān)),但 ram 的時鐘已經(jīng)是正常時鐘,不再出現(xiàn)毛刺(標(biāo)黃的 CLK 信號)。


3、使用標(biāo)準(zhǔn)單元庫

雖然使用 latch 可以解決門控時鐘毛刺的出現(xiàn),但是時序也需要嚴(yán)格的約束。

FPGA 或 IC 設(shè)計時,綜合庫中往往會有集成門控邏輯單元。此類門控邏輯單元經(jīng)過了大量的更新迭代和驗證,使用起來更加的方便、安全。

因此一般情況下,門控時鐘的設(shè)計也都會直接調(diào)用專用的集成門控邏輯單元。調(diào)用方式和基本的與門、緩沖器等基本單元類似,直接例化即可。

使用方式

合理的使用門控時鐘邏輯,對電路時鐘進(jìn)行控制,也會有效的減少功耗。

1、手動 gating

增加時鐘使能信號,人為的控制模塊工作時鐘的有無。

模塊工作時,將使能信號有效,時鐘打開;模塊空閑時,將使能信號無效,時鐘關(guān)閉,節(jié)省功耗。

上一節(jié)的仿真設(shè)計,就可以看做是手動 gating 的例子。ram 讀寫時,使能信號為高,ram 時鐘打開,ram 開始工作;使能信號為低時,ram 不工作,此時無輸入時鐘。

2、自動 gating

模塊在工作時,可以自動檢測自己的工作狀態(tài),并輸出一個 busy(忙碌) 信號。外部可以通過該指示信號,對模塊內(nèi)部的部分邏輯進(jìn)行時鐘門控,來減少時鐘的翻轉(zhuǎn),達(dá)到自動 gating 的控制。

與手動 gating 不同的是,這些模塊在工作時,會有短暫的空閑狀態(tài)。自動 gating 就是要在這短暫的空閑狀態(tài)時間內(nèi)關(guān)閉掉無用的時鐘,而不是像手動 gating 直接關(guān)閉掉整個模塊的時鐘,否則該模塊就不能再正常工作。

例如 uart 在完成一次傳輸數(shù)據(jù)時會有一段空閑的狀態(tài),此時可將一些 fifo 邏輯、波特率產(chǎn)生邏輯等模塊的時鐘自動關(guān)閉。

例如在包含 cpu 的設(shè)計中,可加入檢測 bus 總線空閑狀態(tài)的邏輯,自動控制開關(guān) bus 總線的時鐘,以此降低功耗。

限于篇幅,這里先不再舉例仿真。

3、自動插入 gating

當(dāng) RTL 設(shè)計完成之后進(jìn)行邏輯綜合時,編譯器也會對代碼的邏輯進(jìn)行自動優(yōu)化,這就包括將一些觸發(fā)器的時鐘端進(jìn)行 gating。例如一個帶使能端的同步 D 觸發(fā)器的 RTL 描述如下:

   //(2) Flip-Flop with enable port
   always @(posedge CLK) begin
      if (EN) begin
         Q       = D ;
      end
   end

其 RTL 前級仿真如下圖所示:


綜合后的仿真波形往往會如下圖所示:


對比可知,綜合后已經(jīng)沒有了 EN 信號,時鐘(CP 端)經(jīng)過 clock gating 后也不是一直存在。既保證了邏輯的正確性,又減少了時鐘翻轉(zhuǎn),降低了功耗。

點擊這里下載源碼


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號