How to use clock gating in RTL?
Asked Answered
M

2

11

I am clock gating some latch and logic in my design. I don't have much experience in synthesis and place & route. What is the proper way to implement clock gating in RTL?

Example1:

always_comb begin
    gated_clk  = clk & latch_update_en;
end

always_latch begin
    if(gated_clk) begin
         latch_data <= new_data;
    end
end

Example2: I stumbled into a RTL examples while doing some research about good practices in RTL clock gating. That example implemented the above code like this:

clock_gator cg_cell (.clk(clk), .en(latch_update_en), .scan_en(scan_en_in), .gated_clk(gated_clk));

always_latch begin
    if(gated_clk) begin
         latch_data <= new_data;
    end
end

What is the purpose of using custom clock gating cell? Does the tool have hard time in synthesis if clk is directly "and"-ed in a always_comb block with another enable signal? I am having a feeling that using special clock gating cell is a standard approach to generated gated clock signal. I am trying to understand why this is the case.

Mourant answered 27/7, 2014 at 4:30 Comment(4)
For a clock to be properly gated, the register must only accept a new value on the rising edge of the clock if the gate is high (assuming active high enable). Simply ANDing the clock and the enable together is insufficient, as this will produce a spurious clock on the rising edge of the gate if the clock is high.Forgetmenot
I made some edit. I'm not actually using clock-enables for registers. I've some latches in my design. So, the idea is to capture data in latch when latch_enable is high. So, I'm ANDing enable with clock to create half cycle positive clock and using it to capture data in level sensitive (positive) latch.Mourant
clock_gator is not a standard Verilog module; it's being pulled in somewhere by your code. You'll have to show us how it's implemented if you want us to make sense of it.Forgetmenot
The clock_gator cell should be a glitch-free implementation I think. In your example 1, it is the very basic idea of using clock gating. However, it would produce glitches and cause wrong behavior.Clavicorn
E
14

What is the proper way to implement clock gating in RTL?

The clock gating signal should only toggle when the latch is closed, otherwise there is a chance for glitches and metastability issues. For an active high latch, the gating signal should toggle on the falling edge of the clock. Rising edge for active low latches.

Normally you would use an edge sensitive flop to hold latch_update_en to prevent noise on the gating signal.

always_ff @(negedge clk)
  latch_update_en <= next_latch_update_en;

always_comb
    gated_clk = (* clock_gating = "clk" *) clk & latch_update_en;

always_latch
    if(gated_clk)
         latch_data <= new_data;

Reminder: if you have a latch only deign: edge trigger flops are just master/slave latches

always_latch 
    if (clk)
      sync_latch_update_en <= next_latch_update_en;
always_latch 
    if (!clk)
      latch_update_en <= sync_latch_update_en;

Does the tool have hard time in synthesis if clk is directly "and"-ed in a always_comb block with another enable signal?

Most synthesis do have have issues with directly AND-ing a clocking. It is not always intuitive how the gating should be used. A synthesizer often has many AND gates in the library to choose from, each one has different slew, skew, and loading that very on input combinations. Though functionally the same, A & B will get different time results then B & A.

Instantiating an explicit cell from the synthesizer's library narrows the possibilities to know and anticipated behavior. A predefined clock gating cell also has attributes used by the synthesizer. Attributes include timing information for balancing the clock tree (buffer placement in the design for managing loads and parasitic).

Some synthesizers support setting attributes tags in RTL (ex: // synthesis attributes or (* attributes *)) instead of needing to explicitly instantiate a cell. There isn't a standard for how this is do so refer to your user manual.

What is the purpose of using custom clock gating cell?

The custom cell is a per-defined cell in the synthesis library with know timing information, load balancing, and other attributes. With this information, the synthesizer knows where and how to add or calibrate the buffer delay in the clock tree. This making sure the non-gated flop doesn't see the clock edge before gated flop.

                 _____       _____
IN -------------|D   Q|-----|D   Q|--- OUT
                |     |     |     |
       |\ |\    |     |     |     |
     +-| >| >---|>    |   +-|>    |
     | |/ |/    |_____|   | |_____|
     |  ___               |
CLK -+-|   \              |
       | &  )-------------+   BALANCED CLOCK : correct data sampled
GATE --|___/

Without the guidance, the gated flop's could get a delayed clock. The skew would cause the wrong data to get sampled.

                 _____       _____
IN -------------|D   Q|-----|D   Q|--- OUT
                |     |     |     |
                |     |     |     |
     +----------|>    |   +-|>    |
     |          |_____|   | |_____|
     |  ___               |
CLK -+-|   \    |\ |\     |
       | &  )---| >| >----+   UNBALANCED CLOCK : wrong data sampled
GATE --|___/    |/ |/
Ellieellinger answered 28/7, 2014 at 20:41 Comment(1)
Side note: Clock gating should be used for gating the clock of a large module that need to be dynamically suspended or turned off/on; not for handful of flops. Clock gating is rarely beneficial for small edge trigger designs. Typically using an enable pin or Q to D feedback is sufficient power/area savings.Ellieellinger
F
0

Read Yu-Yun Dai thesis : Verification and Synthesis of Clock-Gated Circuits which says:

Sequential equivalence checking (SEC) of clock-gated circuits is required

Besides, try https://github.com/YosysHQ/yosys-bigsim/blob/master/openmsp430/rtl/omsp_clock_gate.v in which the code is pasted as follows:

//----------------------------------------------------------------------------
// Copyright (C) 2009 , Olivier Girard
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the authors nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE
//
//----------------------------------------------------------------------------
//
// *File Name: omsp_clock_gate.v
// 
// *Module Description:
//                       Generic clock gate cell for the openMSP430
//
// *Author(s):
//              - Olivier Girard,    [email protected]
//
//----------------------------------------------------------------------------
// $Rev: 103 $
// $LastChangedBy: olivier.girard $
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
//----------------------------------------------------------------------------

module  omsp_clock_gate (

// OUTPUTs
    gclk,                      // Gated clock

// INPUTs
    clk,                       // Clock
    enable,                    // Clock enable
    scan_enable                // Scan enable (active during scan shifting)
);

// OUTPUTs
//=========
output         gclk;           // Gated clock

// INPUTs
//=========
input          clk;            // Clock
input          enable;         // Clock enable
input          scan_enable;    // Scan enable (active during scan shifting)


//=============================================================================
// CLOCK GATE: LATCH + AND
//=============================================================================

// Enable clock gate during scan shift
// (the gate itself is checked with the scan capture cycle)
wire    enable_in =   (enable | scan_enable);

// LATCH the enable signal
reg     enable_latch;
always @(clk or enable_in)
  if (~clk)
    enable_latch <= enable_in;

// AND gate
assign  gclk      =  (clk & enable_latch);


endmodule // omsp_clock_gate
Ferriferous answered 14/1, 2019 at 13:47 Comment(6)
I confused that here is no register, How does tool recognize this for clock gating?Glutelin
@Glutelin See reddit.com/r/chipdesign/comments/kv2ebv/…Ferriferous
Sorry but I didn't get the point of reddit answer even there is explain about glitch free gating.Glutelin
@Glutelin There are mainly 2 types (AND-type, OR-type) of latch-based clock gating cells. See also the glitch-free waveform if the latch inside the AND-type clock gating cell is not removedFerriferous
I see, I wondering that if we use clock gating approaching, then is this needed to be set as a false path or generate clock in SDC?Glutelin
@Glutelin See set_clock_gating_checkFerriferous

© 2022 - 2024 — McMap. All rights reserved.