HOME    COMMUNITY    BLOGS & FORUMS    Magic Blue Smoke
Magic Blue Smoke
  • About

    Magic Blue Smoke is a blog dedicated to discussing the challenges of low power ASIC Design

    I have worked in the VLSI industry for 14 years as a digital IC designer. My recent work has been focused on low-power challenges associated with multi-voltage/
    multi-supply designs. The goal of this blog is to open a free exchange of ideas with regards to low power. Please participate!

    - Godwin Maben

Clock Gating State Retention

Posted by Godwin Maben on June 3rd, 2010

Recently came across this request for clock gating retention latch. Here are some details on why these are required and what it means to the design.

Clock gating is the most common low power saving technique in use for a long time.  Latch based clock gating logic is typically used to avoid any glitches even during entry and exit from/to sleep mode.  In a power gated design , usually we stop the clock at in-active phase before retaining states and entering sleep mode and same for wake up mode.  Here one of the main challenge is the validity of the enable signal at wakeup, which is typically provided by the restored states in the registers propagating through cloud of logic to the clock gating latches, which stay open during in-active phase.

In a power gated design, where retention registers are not used, this propagation mechanism may not work and we might have to use some kind of state retention for the clock gating latches, which retains the clock gating state when powered down. In one of the design, this is incorporated using retention latch(similar to retention flop) inside the latch based clock gating cell.

It may not be required to use these special cells if retention registers happen to exist in the design, which controls the clock enable signal state. Its also not required if some logic is built in to ensure controllability of the clock during inactive phase while entering and exiting the hibernation mode.

5 Responses to “Clock Gating State Retention”

  1. phuang says:

    Hi Godwin,

    I have got an UPF confusion – rentention cells mapping when I tried to follow the synopsys low power design flow lab.

    The orginal design is simple, an adder and a multiplier,mult_out = (add_in0+add_in1)* (add_in0+add_in1). We want to power gate the module I_ADD, and keep the results of the addition with retention cells.

    The question is that the compile result went wrong if we use the retention cell, while seems right when we didn’t use the retention cell. If we added the retention control as following:

    set_retention a_ret -domain PD_ADD -retention_power_net VDD -retention_ground_net GND
    set_retention_control a_ret -domain PD_ADD -save_signal {I_PWR_CTRL/sr_ctrl low} -restore_signal {I_PWR_CTRL/sr_ctrl high}
    map_retention_cell a_ret -domain PD_ADD -lib_cell_type RSDFCD1

    The register will be taken as a constant and removed, as described in the log file.

    Beginning Mapping Optimizations (Ultra High effort)
    ——————————-
    Information: Added key list ‘DesignWare’ to design ‘ADD’. (DDB-72)
    Information: Added key list ‘DesignWare’ to design ‘MULT’. (DDB-72)
    Information: The register ‘I_ADD/add_out_reg[0]‘ is a constant and will be removed. (OPT-1206)
    Information: The register ‘I_ADD/add_out_reg[1]‘ is a constant and will be removed. (OPT-1206)
    Information: The register ‘I_MULT/mult_out_reg[1]‘ is a constant and will be removed. (OPT-1206)
    Information: The register ‘I_ADD/add_out_reg[2]‘ is a constant and will be removed. (OPT-1206)
    Information: The register ‘I_MULT/mult_out_reg[2]‘ is a constant and will be removed. (OPT-1206)

    ….

    And the ADD module was compiles as just some wires as following:

    module ADD ( add_in0, add_in1, clk, resetn, add_out, a_ret );
    input [7:0] add_in0;
    input [7:0] add_in1;
    output [8:0] add_out;
    input clk, resetn, a_ret;
    wire add_out_0_;
    assign add_out[8] = add_out_0_;
    assign add_out[7] = add_out_0_;
    assign add_out[6] = add_out_0_;
    assign add_out[5] = add_out_0_;
    assign add_out[4] = add_out_0_;
    assign add_out[3] = add_out_0_;
    assign add_out[2] = add_out_0_;
    assign add_out[1] = add_out_0_;
    assign add_out[0] = add_out_0_;

    GTIEL U3 ( .ZN(add_out_0_) );
    endmodule

    It is pretty strange!!!

    If we didn’t use the map_retention_cell command, the compile result will be the same as without retention control.

    What’s the possible problem? How can I fix it if we want to use the intention cell?

    Thank you very much!

    Regards,
    Ping

  2. Wajahat Ali Meer says:

    Hi Ping,

    Which version of DC are you using? There were some issues in older version of tool in terms of mapping retention cells and most of these issues are fixed in latest version of DC(2010.03-SP1). It would be best if you re-run this in 2010.03-SP1 version.

    Regards,
    Wajahat Ali

  3. phuang says:

    Hi Wajahat,

    Thank you for your advice!

    I am using the DC-v2009.06, and I will try the 2010.03-SP1 version, and post the results here.

    Regards,
    Ping

  4. phuang says:

    Hi Wajahat,

    I got the same problem :(

    Ping

  5. Jay-ar says:

    Hi Godwin! I’m currently researching on clock gating. I’m implementing a power reduced DLX processor with partial scan. my primary power reduction technique in normal is cg, as you may have figured out. anyway, everything is fine in RTL. but when it comes to synthesis, glitches come in, mainly due to my enable signals. what can i do to prevent this?

    here is a sample of my cg code for one of my pipeline registers

    reg enable0, enable1, enable2;
    reg enable0_l, enable1_l, enable2_l;
    wire clock_new;

    always @(clock, reset, BISTStart, ScanMode, abort_int, overflow_out, stall_IF, stall_MEM, stall_EXE) begin
    if (reset == 1′b1) begin
    enable0 <= 1'b0;
    enable1 <= 1'b0;
    enable2 <= 1'b0;
    end
    if (reset || BISTStart || ScanMode)
    enable0 <= 1'b1;
    else enable0 <= 1'b0;
    if ((abort_int == 1'b1) || (overflow_out == 1'b1) ||
    (stall_EXE == 1'b1 && stall_IF == 1'b0 && stall_MEM == 1'b0))
    enable1 <= 1'b1;
    else enable1 <= 1'b0;
    if ((stall_MEM == 1'b0) && (stall_IF == 1'b0) && (stall_EXE == 1'b0))
    enable2 <= 1'b1;
    else enable2 <= 1'b0;
    end

    always @(clock) begin
    enable0_l <= enable0;
    enable1_l <= enable1;
    enable2_l <= enable2;
    end

    assign clock_new = clock && (enable0_l || enable1_l || enable2_l);

    always @ (posedge clock_new or posedge reset) begin
    end

    thanks for any help out there!